A strukturált kimenet (structured output) olyan mechanizmus, ami garantálja, hogy az LLM válasza pontosan illeszkedik egy előre definiált JSON Schema-hoz. A különbség a régi "JSON módhoz" képest a kényszerített dekódolásban (constrained decoding) rejlik: a séma véges állapotú automataként (FSM) fordul le, és minden token-generációs lépésnél csak azok a tokenek engedélyezettek, amelyek érvényes úton tartják a kimenetet ezen az automatán.
Az érvénytelen tokenek logitjait a rendszer mínusz végtelenre állítja — vagyis nem rosszallóan figyelmeztetjük a modellt, hanem fizikailag képtelen érvénytelen kimenetet produkálni. Ez nem statisztikai, hanem matematikai garancia. Nagy különbség.
JSON Mode vs. Structured Output (Strict Mode)
- JSON Mode: szintaktikailag valid JSON-t garantál, de a sémát nem. Bármilyen érvényes JSON objektum visszajöhet — más mezőnevekkel, más típusokkal.
- Structured Output (Strict Mode): teljes sémamegfelelést biztosít constrained decoding-gal. Produkcióban ez ma az alapértelmezés.
Ha még tervezési fázisban vagy és nincs kész sémád, a JSON Mode hasznos lehet prototipizáláshoz. Élesben viszont mindig Strict Mode-ot használj — nincs jó kifogás 2026-ban.
Provider-támogatás 2026-ban
A 2026-os helyzet szépen konvergál. A strukturált kimenet ma már nem provider-specifikus trükk, hanem keresztplatformos elvárás:
- OpenAI:
response_format paraméter strict módban (2024 augusztus óta GA).
- Anthropic Claude:
output_schema mező a Messages API-ban, GA 2026 elejétől.
- Google Gemini:
responseSchema a generation config-ban, 2026-ban kibővített típustámogatással.
- Cohere:
response_format JSON Schema-val.
- xAI Grok: OpenAI-kompatibilis structured output API.
- Lokális stack: Ollama, vLLM, SGLang — mindegyik támogatja a grammar-alapú constrained decoding-ot (XGrammar, Outlines, Guidance backendekkel).
Pydantic — a Python ökoszisztéma sztenderdje
Ha Pythonban dolgozol, a Pydantic 2.x ma a strukturált kimenet alapja. A modell osztályok típusos mezőkkel automatikusan generálnak pontos JSON Schema-t, amit közvetlenül átadhatsz az LLM API-nak. Ez két dolgot ad neked:
- A séma mindig szinkronban marad a kóddal (nincs külön YAML/JSON fájl, ami csendben elavul a háttérben).
- A visszakapott választ a modell instance-aként kezelheted, nem nyers stringként vagy diktnérként.
Alap minta — Pydantic + OpenAI
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import Literal
class SzamlaAdatok(BaseModel):
szamla_szam: str = Field(description="A számla egyedi azonosítója")
kibocsato: str = Field(description="A kibocsátó cég neve")
osszeg_huf: float = Field(description="Bruttó összeg forintban")
kelt: str = Field(description="ISO 8601 dátum, pl. 2026-05-08")
statusz: Literal["fizetve", "fuggoben", "lejart"]
client = OpenAI()
response = client.responses.parse(
model="gpt-5",
input=[
{"role": "system", "content": "Számlaadat-kinyerő vagy."},
{"role": "user", "content": szamla_szoveg}
],
text_format=SzamlaAdatok
)
szamla = response.output_parsed
print(szamla.osszeg_huf) # 124500.0 - Pydantic instance, típusosan
Ugyanez Anthropic Claude-dal (2026)
import anthropic
from pydantic import BaseModel, Field
from typing import Literal
class SzamlaAdatok(BaseModel):
szamla_szam: str
kibocsato: str
osszeg_huf: float
kelt: str
statusz: Literal["fizetve", "fuggoben", "lejart"]
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
output_schema=SzamlaAdatok.model_json_schema(),
messages=[
{"role": "user", "content": f"Nyerd ki az adatokat: {szamla_szoveg}"}
]
)
szamla = SzamlaAdatok.model_validate_json(message.content[0].text)
A hét legfontosabb produkciós minta
1. Mindig adj description-t a mezőknek
A Pydantic Field(description=...) nem csak dokumentáció. Bekerül a JSON Schema-ba, és közvetlenül befolyásolja, mit generál a modell. Ez prompt mérnöki munka a sémán belül — ne hagyd ki.
Egy kelt nevű mező leírás nélkül "2026. május 8." formátumot adhat vissza. Ha a leírás "ISO 8601 dátum, pl. 2026-05-08", akkor a modell tartja magát ehhez. Minden mezőhöz írj leírást. Tényleg minden mezőhöz.
2. Korlátozd a beágyazási mélységet
Maximum 2-3 szintű beágyazás. Az 5+ szint mélyen beágyazott struktúrák növelik a hibaarányt és lassítják a séma kompilálását. Ha az adat tényleg komplex, bontsd több, láncolt LLM-hívásra. Ez a legnagyobb hatású séma-tervezési minta — saját tapasztalatból mondom, miután belefutottam egy 6 szintes séma karbantartási rémálmába.
3. Tedd a "reasoning" mezőt elsőnek (séma-szintű chain-of-thought)
Az LLM-ek balról jobbra generálnak tokeneket. Ha a kategoria mező jön elsőként, a modell előbb választ kategóriát, és utána keres rá racionalizációt. Ha a reasoning jön elsőként, először végiggondolja a problémát, majd kategorizál. Ez chain-of-thought a séma struktúrájába építve — ingyen pontossági növekedés.
class TamogatasiJegyOsztalyozas(BaseModel):
indoklas: str = Field(
description="Lépésről-lépésre indoklás, mielőtt a kategóriát választod"
)
kategoria: Literal["szamlazas", "technikai", "panasz", "egyeb"]
surgosseg: Literal["alacsony", "kozepes", "magas"]
bizalmi_pontszam: float = Field(ge=0.0, le=1.0)
4. Használj Enum vagy Literal típust korlátozott mezőkre
Soha ne kérj "kategória" stringet kötöttség nélkül — a modell minden alkalommal új kategóriákat fog kitalálni. (Volt egy projektünk, ahol a "kategória: string" mezőből 47 különböző értéket kaptunk három nap alatt. Tanulságos volt.) A Python Enum vagy Literal típus a JSON Schema enum kulcsára fordul, és a constrained decoding fizikailag csak a felsorolt értékek tokenjeit engedi.
5. Tedd opcionálissá a hiányozható mezőket
Ha egy mező esetleg nem szerepel a forrásszövegben, jelöld Optional-nek. A kötelezővé tett, de hiányzó adatot a modell hallucinálással fogja pótolni — és ez lesz a legnagyobb hibaforrás strukturált kimeneteknél. Garantáltan.
6. Validálj Pydantic-kal — még native strict módban is
A JSON Schema kényszer szintaktikai szinten teljes, de az üzleti logika sosem. Ha van egy bizalmi_pontszam: float meződ 0 és 1 között, a modell hallucinálhat 1.5-öt. A JSON parser elfogadja, de a Pydantic ge=0.0, le=1.0 kényszere ValidationError-t dob. Ez fogja meg azt, amit a séma nem.
7. Implementálj validate-retry hurkot
A produkciós alapminta egyszerű: validáld a kimenetet, és ha nem felel meg, küldd vissza a modellnek a validációs üzenettel együtt javításra. Ez drift-mentes pipeline-t ad. De — és ez fontos — minden retry tokenbe kerül. Ha egy prompt rendszeresen 2+ retry-t igényel, akkor a prompt vagy a séma a hibás. Nem több retry-ra van szükség.
from pydantic import ValidationError
def kinyer_validalva(szoveg: str, max_retry: int = 2):
elozo_hiba = None
for kiserlet in range(max_retry + 1):
prompt = f"Nyerd ki az adatokat: {szoveg}"
if elozo_hiba:
prompt += f"\n\nElozo kiserlet hibaja: {elozo_hiba}\nJavitsd."
valasz = client.responses.parse(
model="gpt-5",
input=[{"role": "user", "content": prompt}],
text_format=SzamlaAdatok
)
try:
return valasz.output_parsed
except ValidationError as e:
elozo_hiba = str(e)
raise RuntimeError(f"Sikertelen kinyeres {max_retry+1} kiserlet utan")
Strukturált kimenet vs. function calling — mikor melyiket?
Ez az a kérdés, ami a legtöbb fejlesztőt összezavarja 2026-ban. A két mechanizmus a felszínen hasonló (mindkettő JSON Schema-t fogad és strukturált választ ad), de architekturálisan teljesen különbözőek.
Egyszerű döntési szabály
- Strukturált kimenet: ha a modell válaszának alakját akarod kényszeríteni — adatkinyerés, osztályozás, formázás, UI-ra szánt strukturált tartalom.
- Function calling: ha a modellnek akciót kell választania egy eszközkészletből — adatbáziskérés, API-hívás, ágenses orkesztráció.
A különbség lényege: strukturált kimenetnél a modell mindig a sémát adja vissza. Function calling-nál a modell eldöntheti, hogy egyáltalán hív-e függvényt, és ha igen, melyiket. A function calling instrukció-finomhangoláson alapul, ami probabilisztikus. Strukturált kimenet constrained decoding-on, ami matematikai garancia.
| Szempont | Strukturált kimenet | Function calling |
| Cél | A válasz alakja | Külső akció kiváltása |
| Kényszerítés | FSM / constrained decoding | Instrukció-finomhangolás |
| Megbízhatóság | ~100% sémamegfelelés | Robusztus hibakezelés kell |
| Tipikus felhasználás | Adatkinyerés, osztályozás | Ágensek, eszközhasználat, API-k |
Sok produkciós rendszer egyébként mindkettőt használja: function calling-ot az orkesztrációhoz, strukturált kimenetet az adatkinyerő lépésekhez a pipeline-ban. Nem kell választani — gyakran kombinálni érdemes.
Ökoszisztéma — melyik könyvtárat válaszd?
Instructor
A 15+ providert egységes API alá hozó Pydantic-alapú könyvtár. Python projektekhez 2026-ban ez az ajánlott kiindulópont. Beépített retry, validation hooks, streaming támogatás — pont az, amit egyébként magadnak kéne megírni.
BAML
Ha cross-language sémaszerződésekre van szükség (TypeScript + Python + Go ugyanazokra a sémákra), a BAML saját DSL-t használ, ami minden nyelvre generál típusbiztos klienst. Multi-team környezetekben hasznos lehet.
LangChain Structured Output
Csak akkor érdemes, ha már LangChain-t használsz az egész stackhez. Önmagában strukturált kimenethez egyszerűen túlzás — az Instructor jóval egyszerűbb.
Self-hosted: XGrammar / Outlines / Guidance
Ha vLLM-en vagy SGLang-on hostolsz modellt, ezek a grammar-alapú backendek adják a constrained decoding-ot. 2026-ban az XGrammar a leggyorsabb — gyakorlatilag zero overhead.
Tipikus produkciós csapdák 2026-ban
Refusals
Ha a modell biztonsági okból megtagadja a választ, a kimenet nem fog a sémához illeszkedni. Mindig ellenőrizd a stop_reason-t (Anthropic) vagy finish_reason-t (OpenAI), mielőtt a parsed objektumhoz nyúlnál. Egy NoneType hibakeresése éles incidens közben nem szórakoztató.
Truncation
Ha a max_tokens elfogy a séma közepén, JSON parse error lesz. Hosszú sémákhoz becsüld meg a maximális kimenetet, és állítsd a max_tokens-t bőven a fölé. (Inkább pazarolj egy kicsit, mint hogy fél kimenetekből próbálj értelmet csiholni.)
Üres tömbök és enum-zavar
Ha a séma List[Item]-et követel, de a forrásban nincs item, néhány modell üres tömb helyett kitalál egyet. Védekezz min_length=0 explicit jelzéssel és Pydantic post-validation-nel.
Cache-busting effektus
Az output schema része a request-nek és befolyásolja a prompt cache hit/miss arányt. Ha sokat változtatod a sémát, kevesebb cache hit lesz. Tartsd a sémákat stabilnak, vagy verzionáld őket.
Költség és teljesítmény 2026-ban
A constrained decoding nem ingyenes — minden lépésnél át kell szűrni az engedélyezett tokenek halmazát az FSM állapota szerint. A modern implementációkban (XGrammar, OpenAI strict mode) ez 1-3% overhead a token/másodperc sebességben. Cserébe nulla parser hibát kapsz. Jó üzlet.
A költségoldal érdekesebb: a strukturált kimenet általában rövidebb választ ad, mert nincs felvezető szöveg ("Itt vannak az adatok:") és nincs trailing magyarázat sem. Egy adatkinyerő pipeline-ban 30-50% output token megtakarítást is láthatsz a "JSON-t kérek a promptban" megközelítéshez képest. Nálunk ez egy kisebb projekten konkrétan 41%-ot hozott — havi szinten az nem mindegy.
Összegzés és checklist
Egy 2026-os produkciós LLM-pipeline strukturált kimenethez ezt a hét lépést érdemes követnie:
- Definiáld a sémát Pydantic
BaseModel-ként, leíró description-ökkel minden mezőn.
- Tedd a
reasoning mezőt elsőnek a chain-of-thought hatásért.
- Használj
Literal vagy Enum típust minden korlátozott értékkészletű mezőre.
- Tedd
Optional-nek azokat a mezőket, amik hiányozhatnak — kerüld a hallucinált pótlást.
- Hívj a provider strict módú API-jával (Pydantic
.model_json_schema()-vel).
- Validálj újra Pydantic-kal a válasz után — fogd meg az üzleti logikai hibákat (range, regex, custom validatorok).
- Implementálj 1-2 körös retry hurkot validációs hibára, és monitorozd a retry rátát — ha tartósan magas, a prompt vagy a séma rossz.
GYIK — Gyakran ismételt kérdések
Mi a különbség a JSON mode és a structured output között?
A JSON Mode garantálja, hogy a kimenet szintaktikailag valid JSON, de bármilyen alakú lehet. A Structured Output (strict mód) constrained decoding-ot használ, hogy a kimenet pontosan illeszkedjen egy előre definiált JSON Schema-hoz — minden mezőnévre, típusra és kényszerre. Produkcióban mindig strict mode-ot használj.
Lassabb-e a strukturált kimenet, mint a sima generálás?
Igen, de marginálisan. A modern implementációk (OpenAI strict, XGrammar a vLLM-ben) 1-3% overhead-et adnak a token/másodperc sebességhez. Cserébe nulla JSON parse hiba — egy validate-retry hurok költsége egyébként nagyságrendekkel nagyobb, mint az overhead.
Pydantic v1 vagy v2 kell?
Pydantic 2.x. Az 1.x életciklusát befejezte 2024-ben, és a JSON Schema generálás v2-ben jelentősen pontosabb és gyorsabb. Az Instructor, OpenAI SDK, Anthropic SDK mind Pydantic v2-re épülnek 2026-ban. Ne ragadj le v1-en.
Mikor érdemes function calling-ot használni a structured output helyett?
Function calling-ot akkor használj, ha a modellnek választania kell több lehetséges akció közül (pl. "kérdezz a DB-től" vs. "küldj e-mailt"), vagy ha a modell több körön keresztül oszt fel egy feladatot. Ha csak egyetlen alakú válaszra van szükséged (adatkinyerés, osztályozás), a structured output egyszerűbb és megbízhatóbb.
Hogyan kezelem, ha a modell biztonsági okból megtagadja a választ?
Mindig ellenőrizd a stop_reason/finish_reason mezőt a válaszban. Ha az értéke refusal (OpenAI) vagy end_turn üres tartalommal (Anthropic), a parsed kimenet üres vagy hibás lesz — ne próbáld a Pydantic objektumhoz nyúlni. Logold az esetet, és vagy újrafogalmazd a promptot, vagy bukj el biztonságosan az ágensben.
Működik a structured output streaming-gel?
Igen. 2026-ban már mind az OpenAI, mind az Anthropic támogatja a strukturált kimenet streaming-et. Az SDK-k inkrementális Pydantic objektumokat adnak vissza, ahogy a séma egyes mezői elkészülnek — UI-akhoz, ahol szeretnél részleges eredményt mutatni, ez kulcsfontosságú minta.