Strona główna / Rozdział 5 · Agenci
Ostatnia zmiana · 5 min czytania
Wymuszanie formatu
Structured output w trybie ścisłym nie prosi modelu o format, tylko go wymusza: w każdym kroku sampler zeruje prawdopodobieństwo tokenów, które złamałyby schemat. Dostajesz gwarancję składni, nie poprawności treści.
Po ludzkuFormularz z polami wyboru zamiast pustej kartki. Nie da się wpisać nic spoza dozwolonych opcji, ale zaznaczyć złą kratkę nadal można. A gdy brakuje kratki na właściwą odpowiedź, zaznaczysz najbliższą.
Przejdź krok po kroku przez generowanie. Zobacz, które tokeny maska wycina, i zatrzymaj się przy tokenie 4
Schemat: {"label": "spam" | "ham"}
Prawdopodobieństwa poglądowe. Przekreślone tokeny łamią schemat i dostają zero, a szanse pozostałych są przeskalowane do 100%.
Jak działa maskowanie (constrained decoding)
- Schemat kompiluje się do automatu. Dla wyrażeń regularnych i schematów bez rekurencji wystarcza automat skończony, dla schematów rekurencyjnych i gramatyk bezkontekstowych potrzebny jest automat ze stosem. Stan automatu mówi, jakie znaki mogą paść dalej.
- Tokeny nie pokrywają się ze składnią JSON-a, jeden token to na przykład
{"albo":". Dlatego silnik (Outlines, XGrammar) wylicza dla każdego stanu automatu, które tokeny słownika są dozwolone. Pozostałe dostają logit minus nieskończoność, a sampler losuje z tego, co zostało (temat „Następny token”). - Narzut na token jest bliski zera, bo większość sprawdzeń liczy się z góry. Płaci się przy pierwszym użyciu schematu: kompilacja dodaje opóźnienie, potem gramatyka jest cache’owana (u Anthropic 24 godziny od ostatniego użycia).
JSON mode, structured output i tool calling
- JSON mode gwarantuje poprawny JSON, ale nie zgodność ze schematem. Tryb ścisły gwarantuje schemat:
json_schemazestrict: truew OpenAI,output_config.formatw Anthropic. - Tool calling to ten sam JSON w innej roli: model wypisuje nazwę narzędzia i argumenty (temat „Narzędzia (function calling)”). Bez trybu ścisłego format jest tylko wyuczony, więc argumenty zwykle, ale nie zawsze, pasują do schematu.
strict: trueprzy definicji narzędzia włącza to samo maskowanie. W Responses API OpenAI narzędzia są domyślnie strict, jeśli schemat na to pozwala, a jeśli nie, po cichu wracają do trybu best effort (odpowiedź pokazujestrict: false), więc ustawiaj flagę jawnie. - Tryby ścisłe obsługują podzbiór JSON Schema. OpenAI wymaga, by każde pole było w
required(pole opcjonalne to typ znull) i by obiekty miałyadditionalProperties: false, przy limicie 5000 pól i 10 poziomów zagnieżdżenia. Anthropic nie obsługuje m.in. schematów rekurencyjnych ani limitów długości tekstu, a dopuszcza najwyżej 20 narzędzi strict na request, 24 pola opcjonalne i 16 pól z typem unii łącznie we wszystkich schematach strict. Powyżej tych limitów API zwraca błąd „Schema is too complex for compilation”. - Maska obejmuje tylko odpowiedź. Myślenie modelu rozumującego nie jest ograniczone, więc model może najpierw swobodnie rozumować, a potem wypełnić schemat (temat „Modele rozumujące”).
Czego gwarancja nie obejmuje
- Treści. Model nadal może wpisać zły numer faktury albo zmyśloną datę w poprawnym formacie. Reguły biznesowe (zakresy, sumy, istnienie identyfikatorów) sprawdza kod, a błąd wraca do modelu z konkretnym komunikatem, z limitem prób.
- Odpowiedzi uciętej limitem długości (
stop_reason: "max_tokens",finish_reason: "length") ani odmowy: OpenAI zwraca ją w osobnym polurefusal, Anthropic jakostop_reason: "refusal". W obu przypadkach treść może nie pasować do schematu. Sprawdzaj powód zatrzymania przed parsowaniem. - Wielkości liter w enumach u Anthropic. Wartości
enumiconsttypu string mogą wrócić z inną wielkością liter („Conversation Topic 3” zamiast „Conversation topic 3”), ze zwykłym powodem zatrzymania i bez błędu, w odpowiedziach JSON i w wywołaniach narzędzi w trybie strict. Porównuj je bez rozróżniania wielkości liter i unikaj wartości, które różnią się tylko nią. - Tego, co model chciał powiedzieć. Gdy najbardziej prawdopodobna odpowiedź jest poza schematem, maska wpycha model w najbliższą dozwoloną, jak phishing zamieniony na spam w widżecie. Dodaj wyjście awaryjne: wartość „inne” albo „nie wiem” i pole na komentarz.
- Jakości rozumowania. Model pisze od lewej do prawej, więc decyzja przed uzasadnieniem każe mu zdecydować, zanim cokolwiek policzy. Stawiaj pole z uzasadnieniem przed polem z decyzją i wpisz oba do
required: Anthropic wypisuje pola wymagane przed opcjonalnymi (OpenAI zachowuje kolejność ze schematu, a i tak wymaga wszystkich pól). W badaniu „Let Me Speak Freely?” (2024) ograniczenia formatu obniżały wyniki zadań wymagających rozumowania, częściowo właśnie z tego powodu: w jednym z zadań GPT-3.5 w trybie JSON za każdym razem stawiał odpowiedź przed uzasadnieniem. Wynik jest sporny. Powtórzenie z tymi samymi promptami (.txt, „Say What You Mean”) spadku nie znalazło, a inne prace mierzą koszt samej maski, głównie przy małych modelach i ciasnych schematach (Reddy i in., 2026). Gdy ewaluacje pokazują spadek, pozwól modelowi odpowiedzieć swobodnie, a strukturę wyciągnij drugim, tanim wywołaniem.
Sprawdź się
Jak zagwarantować, że model zwróci JSON zgodny ze schematem, i czego ta gwarancja nie obejmuje?
W trybie ścisłym schemat kompiluje się do gramatyki, a w każdym kroku sampler zeruje prawdopodobieństwo tokenów, które by ją złamały. JSON pasuje do schematu, chyba że limit długości utnie odpowiedź albo model odmówi, co widać po powodzie zatrzymania. U Anthropic wartości enum mogą też wrócić z inną wielkością liter, więc porównuje się je bez jej rozróżniania. Gwarancja dotyczy składni, nie treści: wartości waliduje kod. Schemat dostaje wyjście awaryjne, bo ciasny enum wpycha model w najbliższą opcję, a pole z uzasadnieniem stoi przed decyzją, bo model pisze od lewej do prawej. Tool calling w trybie strict działa tak samo.
In English
In strict mode the schema is compiled into a grammar, and at every step the sampler zeroes out tokens that would break it. The JSON matches the schema unless the length limit cuts it off or the model refuses, which the stop reason shows. At Anthropic, enum values can also come back in a different letter case, so compare them case-insensitively. The guarantee covers syntax, not content: values are validated in code. The schema gets an escape hatch, because a tight enum pushes the model into the nearest option, and the reasoning field goes before the decision, because the model writes left to right. Strict tool calling works the same way.
Pytania pogłębiające (4)
- Czy wymuszanie formatu może obniżyć jakość?
- Tak, gdy schemat każe podać decyzję przed uzasadnieniem albo nie ma opcji „inne”. Pomaga pole na rozumowanie przed decyzją, myślenie modelu rozumującego, którego maska nie obejmuje, albo dwa kroki: swobodna odpowiedź, potem ekstrakcja.
- JSON mode, structured output czy tool calling: kiedy co?
- Structured output, gdy odpowiedź ma zasilić kod. Tool calling, gdy model ma wybrać akcję spośród kilku, z trybem strict dla argumentów. JSON mode tylko tam, gdzie nie ma trybu ścisłego.
- Jak wymusić format na własnym modelu?
- vLLM i SGLang mają wbudowane silniki constrained decoding (m.in. XGrammar i llguidance): schemat zamienia się w automat, a ten w maskę tokenów na każdym kroku. Narzut na token jest mały, kosztem jest kompilacja każdego nowego schematu. Przy modelu rozumującym uruchom serwer z parserem rozumowania (np. --reasoning-parser w vLLM), inaczej gramatyka obowiązuje od pierwszego tokena i odcina myślenie.
- JSON się parsuje, ale dane są złe. Co dalej?
- Walidacja w kodzie (typy z ograniczeniami, reguły biznesowe) i ponowienie z konkretnym komunikatem błędu, z limitem prób. Powtarzający się błąd to sygnał do zmiany schematu albo promptu, a przypadek trafia do zestawu ewaluacyjnego.