Strukturovaný výstup

JSON, schémata, validace, opravné smyčky.

Co se naučíš: Budeš umět z modelu dostat spolehlivý JSON a poznáš, kdy nestačí o formát jen požádat.

6 min čtení + cvičeníNavazuje na:✍️ Prompting

Dokud si s modelem povídáš, stačí text. Jakmile ho zapojíš do aplikace, potřebuješ data, se kterými umí pracovat kód, typicky JSON. A tady začíná potíž: model generuje text a nic mu nebrání přidat „Jistě, tady je váš JSON:“ nebo zapomenout uvozovku. Tahle kapitola je o tom, jak z modelu dostat výstup, na který se dá spolehnout.


Tři úrovně spolehlivosti

1. Poprosit v promptu: nejslabší. Funguje v drtivé většině případů a selže zrovna v produkci.

Vrať odpověď jako JSON: {"kategorie": "...", "priorita": 1}

2. Vynutit formát přes API: dnes standard. Většina poskytovatelů umí JSON mode nebo přímo JSON schema: model pak nemůže vygenerovat nic, co schématu neodpovídá.

{
  "type": "json_schema",
  "schema": {
    "type": "object",
    "properties": {
      "kategorie": { "type": "string", "enum": ["fakturace", "technicke", "ostatni"] },
      "priorita":  { "type": "integer", "minimum": 1, "maximum": 5 }
    },
    "required": ["kategorie", "priorita"],
    "additionalProperties": false
  }
}

3. Zvalidovat u sebe: povinné, i když používáš schéma. Kód, který výstup přijímá, ho musí zkontrolovat (Zod, Pydantic, JSON Schema validátor) a při chybě zareagovat.

⚠️ „Vynucené schéma“ zaručí tvar, ne smysl. Model může vrátit validní JSON s vymyšlenou hodnotou. Kontrola obsahu (existuje to ID? je částka v rozumném rozsahu?) zůstává na tobě.


Opravná smyčka

Když validace selže, nemusíš rovnou padat. Osvědčený postup:

1. zavolej model
2. zvaliduj výstup
3. když neprošel → pošli zpět chybu validátoru a nech opravit
4. max 1–2 pokusy, pak fallback (chyba / ruční řešení)
"Tvůj předchozí výstup neprošel validací: pole 'priorita' musí být 1–5, dostal jsem 9.
Vrať opravený JSON. Nic jiného nepiš."

Limit pokusů je důležitý, bez něj si postavíš nekonečnou (a drahou) smyčku.


Praktické zásady, které šetří nervy

  • Plochá struktura vyhrává. Hluboce zanořené objekty model plete častěji. Když to jde, drž jednu úroveň.
  • Používej enum. Místo volného textu u kategorie dej seznam povolených hodnot. Ušetří ti to polovinu problémů s normalizací („fakturace“ / „Fakturace“ / „faktura“).
  • Definuj, co znamená prázdno. Chybějící údaj musí mít jasné vyjádření: null, prázdné pole, nebo hodnota "neuvedeno". Jinak si model vymyslí.
  • Nemíchej data a vyprávění. Chceš-li i vysvětlení, dej ho jako pole ve struktuře ("zduvodneni": "..."), ne jako text okolo JSONu.
  • Předvyplň začátek odpovědi znakem {, pokud API neumí schéma. Zbaví tě to úvodních frází.
  • Ošetři markdownové obalení. Modely rády zabalí JSON do ```json. Buď to zakaž, nebo to při parsování odstraň.

Kdy strukturovaný výstup nechtít

Když je výsledkem text pro člověka (odpověď zákazníkovi, shrnutí článku), nenuť ho do JSONu jen proto, že to jde. Přidává to tokeny i chybovost. Struktura má smysl tam, kde s výstupem dál pracuje kód.


Kam dál

Jak se formát vynutí už při vzorkování, popisuje vzorkování a řízené dekódování. Když výstup slouží k volání kódu, pokračuj na nástroje a agenty. Validaci a fallbacky zasazuje do provozu LLM v produkci.


Cvičení

  1. Potřebuješ z e-mailu vytáhnout částku, datum splatnosti a IBAN. Navrhni schéma a rozhodni, co udělat, když některé pole v e-mailu není.
  2. Proč je „vrať jen JSON, nic víc“ v promptu slabší záruka než JSON schema na úrovni API?
Náčrt řešení: rozbal, až si cvičení zkusíš sám
  1. Každé pole musí umět být null a schéma musí být povinné. Když necháš model vymyslet, co dělat s chybějícím IBANem, buď si ho vymyslí, nebo vrátí prázdný řetězec, nebo pole vynechá, pokaždé jinak. Explicitní null je jediná varianta, která se dá zpracovat spolehlivě. K tomu patří validace typu na tvé straně: částka jako číslo, datum ve formátu ISO, IBAN proti kontrolnímu součtu. Model formát navrhne, tvůj kód ho ověří.
  2. Protože prompt je prosba, zatímco schéma je omezení při vzorkování. Se schématem poskytovatel při generování maskuje tokeny, které by porušily formát, takže neplatný JSON vzniknout nemůže. Prompt naopak jen posouvá pravděpodobnosti, takže selže vzácně, nepředvídatelně a zrovna v produkci. Viz vzorkování.

Shrnutí

  • Popsat formát v promptu nestačí; vynuť ho přes JSON schema, když to API umí.
  • Validuj vždycky u sebe, schéma hlídá tvar, ne pravdivost obsahu.
  • Při chybě pošli validační hlášku zpět a nech opravit, ale omez počet pokusů.
  • Ploché struktury a enum snižují chybovost víc než delší instrukce.
Používáš JSON schema, takže výstup je vždy validní. Můžeš ho rovnou uložit do databáze?

Ne. Schéma zaručí jen strukturu a typy, ne správnost hodnot, model může vrátit validní JSON s neexistujícím ID nebo nesmyslnou částkou. Obsah je potřeba ověřit proti realitě (databázi, rozsahům, číselníkům).

Model občas vrátí JSON zabalený v markdownovém bloku a parser spadne. Jak to řešit?

Nejlépe vynucením formátu přes API (JSON mode / schéma), kde se obalení nestane. Když to nejde, předvyplň odpověď znakem { a v kódu odstraň případné ohraničení před parsováním.

Kdy má smysl opravná smyčka a co u ní hlídat?

Když validace výstupu selže, modelu se pošle chybová hláška validátoru a nechá se to opravit. Hlídat se musí počet pokusů (jeden až dva) a fallback, jinak vznikne nekonečná a drahá smyčka.