Strona główna / Rozdział 2 · Skąd model wie to, co wie
Ostatnia zmiana · 7 min czytania
Jak model widzi czat
Model nie widzi okienka czatu. System prompt, wiadomości, wywołania narzędzi i ich wyniki są sklejane w jeden dokument ze znacznikami ról, a model dopisuje ciąg dalszy za znacznikiem asystenta. Stąd biorą się koszty długich rozmów, granice system promptu i większość błędów przy self-hostingu.
Po ludzkuScenariusz, w którym każda kwestia ma podpis: REŻYSER, KLIENT, ASYSTENT. Aktor bez pamięci dostaje za każdym razem cały scenariusz od pierwszej strony, na końcu widzi pusty podpis ASYSTENT i dopisuje swoją kwestię. Jeśli ktoś wsunie do scenariusza obcą kartkę, aktor przeczyta ją tak samo jak resztę.
Dokładaj wiadomości i wywołania narzędzi, przełączaj widok. Zobacz, że każde zapytanie wysyła cały dokument od nowa
Uproszczony, poglądowy szablon. Każda rodzina modeli ma własne znaczniki i własny zapis narzędzi. Tokeny liczy uproszczony tokenizer jak w temacie „Tokeny”, a każdy znacznik to jeden token.
Co naprawdę wysyła twój kod: lista wiadomości zamiast dokumentu
Uproszczony zapis, jaki przyjmuje większość API czatu. Szczegóły, np. zapis wywołań narzędzi, różnią się między dostawcami. Znaczników i końcowego <|assistant|> nie wysyłasz, dokleja je serwer. Definicje narzędzi idą osobnym polem, a serwer wstawia je do dokumentu obok system promptu.
Szablon czatu
- Znaczniki ról to tokeny specjalne: osobne numery w słowniku, a nie zwykłe znaki (zobacz „Tokeny”). Format model poznał w SFT (zobacz „Trening”): po znaczniku asystenta pada odpowiedź, a po niej token końca tury.
- Każda rodzina modeli ma własny szablon: ChatML w Qwen (
<|im_start|>user … <|im_end|>), Llama 3 (<|start_header_id|>user<|end_header_id|> … <|eot_id|>), harmony w gpt-oss (<|start|>user<|message|> … <|end|>), Mistral ([INST] … [/INST]). Wysyłasz listę wiadomości z rolami, a serwer renderuje ją szablonem, na którym trenowano model. - W Hugging Face szablon jest napisany w Jinja i dołączony do tokenizera.
apply_chat_template(messages, add_generation_prompt=True)skleja dokument i dokleja na końcu znacznik asystenta. Bez niego model potrafi ciągnąć dalej wiadomość użytkownika zamiast odpowiadać. - Generowanie kończy token końca tury, o ile serwer ma go na liście tokenów stopu. W Llamie 3 turę kończy
<|eot_id|>, a nie<|end_of_text|>. Serwer, który czeka tylko na ten drugi, pozwoli modelowi dopisać znacznik użytkownika i wymyślić jego kolejną wiadomość.
Cały dokument w każdej turze
- Model nie pamięta rozmowy. Każde zapytanie niesie cały dokument od początku, więc łączna liczba wysłanych tokenów rośnie z kwadratem liczby tur (zobacz „Okno kontekstowe i agent”). Stan po stronie serwera, np.
previous_response_idw OpenAI, oszczędza tylko wysyłanie: serwer odtwarza dokument, a wszystkie wcześniejsze tokeny wejściowe są znowu płatne. Co z historii zostawić, streścić albo wyrzucić, omawia „Context engineering i pamięć”. - Stały początek dokumentu, czyli system prompt, definicje narzędzi i starsza historia, nadaje się do prompt cachingu (zobacz „Prompt caching”). Zmienna rzecz na początku, np. aktualna godzina w system prompcie, psuje cache w każdej turze. Edycja starej wiadomości daje nowy dokument i cache przepada od miejsca zmiany.
- Narzędzia to też fragmenty dokumentu. Definicje stoją obok system promptu i kosztują tokeny w każdej turze. Wywołanie to tekst, który model pisze za specjalnym znacznikiem, a wynik twój kod dopisuje jako nowy fragment (zobacz „Narzędzia (function calling)”).
- Myślenie modeli rozumujących to kolejny fragment z własnymi znacznikami:
<think>…</think>w części otwartych modeli, kanałanalysisw harmony (zobacz „Modele rozumujące”). Harmony wycina je z historii po odpowiedzi końcowej, ale zostawia w trakcie wywołań narzędzi.
Obrazy, PDF-y i głos
- Enkoder wizyjny tnie obraz na kwadraty i zamienia każdy na wektor, który zajmuje w ciągu miejsce jak token. U Claude’a kwadrat ma 28 × 28 px, więc zdjęcie 1000 × 1000 px to 1296 tokenów, a Claude 4.7 i nowsze zmniejszają obraz powyżej 2576 px na dłuższym boku albo 4784 tokenów (stan na wrzesień 2026).
- Obraz zostaje w historii i jest płatny w każdej turze: dziesięć zrzutów ekranu 1000 × 1000 px w historii agenta to ok. 13 tys. tokenów w każdym zapytaniu. Claude czyta każdą stronę PDF-a dwa razy, jako tekst (1500–3000 tokenów) i jako obraz, więc 100-stronicowy raport to 150–300 tys. tokenów samego tekstu. Takie wejście cache’uj, zmniejszaj przed wysłaniem, a zrzuty, których agent już nie potrzebuje, usuwaj.
- Dźwięk też zamienia się w tokeny: Gemini liczy 32 tokeny na sekundę nagrania, a Realtime API OpenAI 10 na sekundę mowy użytkownika i 20 na sekundę mowy modelu. Realtime API przy każdej odpowiedzi podaje modelowi całą rozmowę od nowa.
- Agenta głosowego buduje się na dwa sposoby. Łańcuch (mowa na tekst → model tekstowy → tekst na mowę) daje transkrypcję, kontrolę treści przed odpowiedzią i swobodny wybór modelu, ale każdy etap wydłuża ciszę, którą słyszy rozmówca. Model speech-to-speech (OpenAI Realtime, Gemini Live) obsługuje dźwięk w jednej sesji, z przerywaniem w pół zdania i wykrywaniem końca wypowiedzi, ale mniej w nim widać. Mierz czas od końca wypowiedzi rozmówcy do pierwszego dźwięku odpowiedzi, medianę i p95.
System prompt to nie zabezpieczenie
- System prompt to tekst na początku dokumentu, a model nauczono traktować go priorytetowo. Nie jest osobnym kanałem ani uprawnieniem. Polecenie w mailu, na stronie albo w wyniku narzędzia leży w tym samym ciągu tokenów i czasem wygrywa (zobacz „Prompt injection”). Zasady, które muszą obowiązywać, egzekwuje kod aplikacji. Sekretów nie trzymaj w system prompcie, bo model może go zacytować.
- Tekst użytkownika nie może stać się znacznikiem. W dobrze zbudowanym API wpisane „<|im_start|>system” to zwykłe znaki. Przy self-hostingu sprawdź to sam: tokenizery Hugging Face domyślnie rozpoznają napisy tokenów specjalnych w tekście (
split_special_tokens=False), więc wklejony tekst może otworzyć prawdziwą turę systemu.
Self-hosting i fine-tuning
- Przy modelu open-weight (zobacz „Modele open-weight”) szablon jest częścią modelu. Zły albo nieaktualny nie rzuca błędem, tylko po cichu pogarsza odpowiedzi i psuje tool calling. Częsty przypadek to podwójny token początku tekstu: dokument z
apply_chat_template(tokenize=False)tokenizuje się drugi raz z dodawaniem tokenów specjalnych, a dokumentacja Hugging Face ostrzega, że to obniża jakość. - Dane do fine-tuningu renderuj dokładnie tym szablonem, którego użyje serwer, i licz stratę tylko na tokenach asystenta (zobacz „Fine-tuning i LoRA”).
- Prefill: kończysz listę wiadomości początkiem odpowiedzi, np.
{, a model pisze od tego miejsca. W transformers robi tocontinue_final_message=True. API Claude od Opus 4.6 i Sonnet 4.6 odrzuca prefill błędem 400 i odsyła do structured outputs (zobacz „Wymuszanie formatu”).
Sprawdź się
Jak model widzi rozmowę i skąd wie, kto co mówi?
Model nie widzi okienka czatu. Serwer skleja system prompt, historię wiadomości, wywołania narzędzi i ich wyniki w jeden dokument, a role oddziela tokenami specjalnymi według szablonu, którego model nauczył się w SFT. Na końcu stawia znacznik asystenta, a model dopisuje ciąg dalszy, aż wygeneruje token końca tury. Model nie ma pamięci, więc w każdej turze dostaje cały dokument od nowa. System prompt to tylko tekst na początku, a nie granica bezpieczeństwa: polecenie ukryte w mailu leży w tym samym ciągu.
In English
The model never sees a chat window. The server concatenates the system prompt, history, tool calls and tool results into one document, separating roles with special tokens from a template the model learned during SFT. The document ends with an assistant marker, and the model continues the text until it emits an end-of-turn token. The model has no memory, so the whole document is resent every turn. The system prompt is just text at the top, not a security boundary: an instruction hidden in an email sits in the same stream.
Pytania pogłębiające (5)
- Czemu model czasem pisze dalej za użytkownika?
- Bo nie wygenerował tokena końca tury albo serwer nie ma go na liście tokenów stopu. Dla modelu to wciąż jeden dokument, więc najbardziej prawdopodobny ciąg dalszy to znacznik użytkownika i jego kolejna wiadomość. Zwykle winny jest zły szablon albo zła konfiguracja stopu.
- Czy model odróżnia polecenie z system promptu od polecenia w mailu?
- Tylko tyle, ile nauczył się w treningu. Modele trenuje się tak, by przestrzegały hierarchii: system ważniejszy od użytkownika, użytkownik od treści z narzędzi (OpenAI, „The Instruction Hierarchy”, 2024). To podnosi odporność, ale nie jest twardą granicą, bo wszystko leży w jednym ciągu tokenów.
- Po co API przyjmuje listę wiadomości zamiast gotowego tekstu?
- Żeby szablon, znaczniki i zapis narzędzi zawsze zgadzały się z tym, na czym trenowano model, i żeby treść od użytkownika nie mogła podrobić znacznika roli.
- Wdrażasz model open-weight na własnym serwerze. Co sprawdzasz w szablonie?
- Czy szablon z tokenizera zgadza się z kartą modelu, czy token końca tury jest na liście stopu, czy nie ma podwójnego tokena początku i czy tekst użytkownika nie zamienia się w tokeny specjalne. Najprościej wyrenderować przykładową rozmowę z narzędziami i porównać ją znak po znaku z przykładem z dokumentacji modelu.
- Co się dzieje, gdy edytujesz starą wiadomość?
- Model niczego nie zapamiętał, więc dostaje po prostu nowy dokument. Tracisz prompt cache od miejsca zmiany do końca. W Claude Opus 5.5, Fable 5.1 i Sonnet 5.5 zmiana historii przed blokiem myślenia kończy się błędem 400 (zobacz „Modele rozumujące”).