Structured Outputs: Ako prinútiť LLM vrátiť spoľahlivé dáta
Jazykové modely sú skvelé v generovaní textu — ale v produkčných aplikáciách potrebujete dáta, nie prózu. Structured Outputs je technika, ktorá zaručuje, že model vráti presne taký formát, aký vaša aplikácia očakáva.
1. Problém: LLM ako nespoľahlivý dátový zdroj
Predstavte si aplikáciu, ktorá má extrahovať meno, vek a email zo životopisu. Poprosite GPT-5 alebo Claude, a on vráti... čo vlastne?
- Niekedy čistý JSON s korektnou štruktúrou.
- Niekedy JSON s komentárom pred otváracou závorkou.
- Niekedy Markdown blok obalený v
```json. - Niekedy celú vetu: „Samozrejme! Tu sú dáta: {...}".
Každý z týchto prípadov vyžaduje iný parsing. V produkčnom systéme, kde volania idú do tisícov denne, jeden neočakávaný formát stačí na pád celého pipeline.
Structured Outputs rieši práve tento problém: namiesto toho, aby ste v prompte prosili model o správny formát, vynútite ho na úrovni API alebo inference enginu — model fyzicky nemôže odchýliť od schémy.
2. Ako to funguje technicky
Existujú tri hlavné mechanizmy, ktorými poskytovatelia garantujú štruktúrovaný výstup:
2.1 Constrained Decoding (obmedzené dekódovanie)
Najrobustnejší prístup. Inference engine pri každom kroku generovania obmedzí pravdepodobnostné rozdelenie tokenov len na tie, ktoré sú konzistentné s požadovanou schémou. Ak JSON objekt ešte nemá uzatváraciu závorku, model jednoducho nemôže vygenerovať token, ktorý by schému porušil — na úrovni logitov.
Implementujú to napríklad:
- llama.cpp cez GBNF gramatiky (Grammar-Based Formal Notation)
- Outlines — open-source Python knižnica pre lokálne modely
- vLLM s integrovanou JSON Schema podporou
- OpenAI API od modelu
gpt-4o-2024-08-06cez parameterresponse_format
2.2 JSON Mode
Jednoduchší variant — model je inštruovaný generovať syntakticky validný JSON, ale bez konkrétnej schémy. Zaručuje, že výstup je parsovateľný, nie že obsahuje správne polia a typy.
2.3 Post-generation Validation + Retry
Najstaršia metóda: vygeneruj, validuj, pri neúspechu opakuj. Pomalé, nespoľahlivé a drahé. Dnes sa používa len ako fallback alebo pre veľmi komplexné schémy.
3. Porovnanie prístupov naprieč providermi
| Provider / nástroj | Metóda | Schéma | Garancie |
|---|---|---|---|
| OpenAI GPT-4o+ | Constrained decoding | JSON Schema (podmnožina) | 100 % validný JSON |
| Anthropic Claude | Tool use + post-validation | Pydantic / JSON Schema | Veľmi vysoká, nie absolútna |
| Google Gemini 1.5+ | response_mime_type + schema |
Upravený JSON Schema | Veľmi vysoká |
| Ollama + llama.cpp | GBNF gramatiky | Vlastná gramatika | 100 % (constrained) |
| Outlines (open-source) | Constrained decoding | Pydantic, JSON Schema, Regex | 100 % (constrained) |
LangChain .with_structured_output() |
Závisí od modelu | Pydantic model | Závisí od backendu |
Dôležité: „100 % validný JSON" neznamená „sémanticky správne hodnoty". Model môže vygenerovať validný objekt, kde vek je -5 alebo email neobsahuje @. Validácia obchodnej logiky zostáva na aplikácii.
4. Praktické použitie
4.1 OpenAI API (Python) — Pydantic integrácia
from openai import OpenAI
from pydantic import BaseModel
class Kandidat(BaseModel):
meno: str
vek: int
email: str
skusenosti_roky: float
client = OpenAI()
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extrahuj dáta z životopisu."},
{"role": "user", "content": zivotopis_text}
],
response_format=Kandidat,
)
kandidat = completion.choices[0].message.parsed
print(kandidat.meno, kandidat.email)
4.2 Anthropic Claude cez tool use
Claude natívne nepodporuje constrained decoding cez API, ale structured outputs možno dosiahnuť definovaním nástroja s požadovanou schémou a vynútením jeho volania cez tool_choice:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
tools=[{
"name": "uloz_kandidata",
"description": "Ulož extrahované dáta kandidáta",
"input_schema": {
"type": "object",
"properties": {
"meno": {"type": "string"},
"vek": {"type": "integer"},
"email": {"type": "string"}
},
"required": ["meno", "vek", "email"]
}
}],
tool_choice={"type": "tool", "name": "uloz_kandidata"},
messages=[{"role": "user", "content": zivotopis_text}]
)
data = response.content[0].input
4.3 Outlines pre lokálne modely
import outlines
model = outlines.models.transformers("mistralai/Mistral-7B-v0.1")
generator = outlines.generate.json(model, Kandidat)
kandidat = generator("Extrahuj dáta: " + zivotopis_text)
Typické produkčné use cases:
- Extrakcia entít z dokumentov — faktúry, zmluvy, životopisy, správy
- Klasifikácia s presnými labeli a skóre namiesto voľného textu
- Generovanie konfigurácií a workflow definícií pre downstream systémy
- Multi-step reasoning kde každý krok vracia štruktúrovaný medzivýsledok
- API wrappery nad LLM pre integráciu s databázami a existujúcimi systémami
5. Limity, riziká a smer vývoja
Obmedzenia schémy u jednotlivých providerov:
OpenAI nepodporuje celú špecifikáciu JSON Schema 2020-12 — chýba napríklad anyOf s viac ako dvoma variantmi alebo niektoré kombinácie if/then/else. Pri návrhu komplexných schém je nutné tieto limity poznať vopred.
Sémantická nesprávnosť zostáva reálnym rizikom:
Constrained decoding garantuje syntaxu, nie zmysel. Ak model vygeneruje do povinného integer poľa vek hodnotu 0 alebo 999, schéma to prepustí. Pridajte post-validáciu pre hodnoty s obchodným dopadom.
Výkonnostný overhead: Constrained decoding pridáva záťaž na inference strane — typicky 5–15 % pomalší throughput oproti voľnému generovaniu. Pre latency-kritické aplikácie je potrebné tento vplyv zmerať.
Problémy s hĺbkou a rekurziou: Hlboko zanorené objekty (napríklad strom s ľubovoľnou hĺbkou) sú problematické. Väčšina providerov má obmedzenie hĺbky schémy alebo rekurzívne typy úplne nepodporuje.
Vendor lock-in:
Každý provider má mierne odlišnú implementáciu a podmnožinu JSON Schema. Abstrakčné vrstvy ako Instructor alebo LangChain .with_structured_output() pomáhajú s prenositeľnosťou, ale pridávajú závislosť.
Kam smeruje budúcnosť: Trend je jednoznačný — štandardizácia okolo JSON Schema draft 2020-12 a hlbšia integrácia so systémami ako MCP, kde structured outputs tvoria základ pre spoľahlivú inter-agent komunikáciu. Constrained decoding sa v roku 2026 stáva de-facto štandardom v akomkoľvek serióznom produkčnom AI pipeline.
Zhrnutie: Structured Outputs transformuje LLM z nepredvídateľného textového generátora na spoľahlivý dátový procesor — čo je nevyhnutný predpoklad pre produkčné AI aplikácie a agentic systémy, kde každý krok pipeline závisí od presného výstupu toho predchádzajúceho.