
Strukturovaný výstup LLM je mechanismus, který zajišťuje, že odpověď jazykového modelu odpovídá předdefinovanému schématu. Nejde jen o platný JSON, ale o JSON platný podle schématu s přesně těmi poli, typy a omezeními, která jste zadali. Všichni hlavní poskytovatelé jej nyní podporují nativně a změnilo to způsob, jakým se vytvářejí produkční aplikace s LLM.
Rychlé shrnutí: Strukturované výstupy v kostce
Pokud máte málo času, zde je přehled situace v roce 2026:
| Aspekt | Detaily |
|---|---|
| Co to je | Odpovědi z LLM vynucené schématem, garantovaná struktura, ne „snaha co nejlépe“ |
| Kdo to podporuje | OpenAI, Anthropic, Gemini, Cohere, xAI (Grok), plus lokálně přes Ollama/vLLM |
| Klíčový mechanismus | Omezené dekódování, neplatné tokeny jsou maskovány před výběrem |
| JSON Mode vs Strict Mode | JSON Mode = pouze platná syntaxe. Strict Mode = plná shoda se schématem |
| Knihovna pro Python | Pydantic (BaseModel + Field) pro definici schématu |
| Knihovna pro TypeScript | Zod (z.object + .describe) pro definici schématu |
| Nejlepší startovní přístup | OpenAI s Pydantic nebo Zod přes nativní SDK |
| Nejlepší produkční knihovna | Instructor (Python) nebo nativní SDK (TypeScript) |
| Největší úskalí | Umístění pole pro zdůvodnění AŽ za pole s odpovědí, model se rozhodne dříve, než přemýšlí |
| Režie latence | 50–200 ms při prvním volání (kompilace schématu), poté cachováno |
Nyní si rozebereme jednotlivé části.
Co jsou strukturované výstupy LLM?
Strukturovaný výstup je rozdílem mezi doufáním, že LLM vrátí platný JSON, a jeho garantováním. Když povolíte strukturovaný výstup, model fyzicky nemůže vyprodukovat tokeny, které porušují vaše schéma. Definujete JSON Schema (nebo model Pydantic, nebo schéma Zod), předáte jej API a získáte zpět odpověď, která mu pokaždé odpovídá.
Proč na tom záleží? Před érou strukturovaných výstupů vývojáři psali křehké parsery pomocí regulárních výrazů, obalovali každé volání LLM bloky try/catch JSON.parse a stále řešili odpovědi, které byly „téměř správné“ – platný JSON, kterému chybělo pole nebo mělo špatný typ. Celá tato třída chyb je pryč.
Existují tři úrovně vynucování struktury, které představují jasný vývoj:
- Inženýrství promptů: „Prosím, vraťte JSON s těmito poli.“ Nespolehlivé. Model může vyhovět v 80–90 % případů.
- JSON Mode: Garantuje syntakticky platný JSON, ale nevynucuje vaše schéma. Můžete dostat
{"foo": "bar"}, když jste čekali{"name": string, "age": number}. - Strict Mode / Omezené dekódování: Garantuje 100 % shodu se schématem. Model doslova nemůže vypsat neplatné tokeny. To je to, co „strukturovaný výstup“ znamená v roce 2026.
Od začátku roku 2026 OpenAI, Anthropic a Google Gemini všechny podporují nativní strukturovaný výstup. Ekosystém konvergoval.
Verdikt: Pokud v produkci parsujete odpovědi LLM pomocí regexu nebo JSON.parse, děláte to složitou cestou. Nativní strukturovaný výstup eliminuje celý tento režim selhání.
JSON Mode vs Strict Mode: Co se skutečně změnilo?
Tento rozdíl mate mnoho vývojářů, protože názvy znějí podobně. Ale nejsou stejné.
| Funkce | JSON Mode | Strict Mode (Strukturované výstupy) |
|---|---|---|
| Parametr API | type: "json_object" | type: "json_schema" s strict: true |
| Garantuje platný JSON | Ano | Ano |
| Garantuje shodu se schématem | Ne | Ano |
| Mechanismus | Dodatečné zkreslení tokenů | Omezené dekódování (FSM) |
| Může vrátit neočekávaná pole | Ano | Ne |
| Může vynechat povinná pole | Ano | Ne |
| Vynucování typů | Žádné | Plné (string, number, array atd.) |
| Kdy použít | Nemáte předem dané schéma | Vše v produkci |
Časová osa: OpenAI představilo JSON Mode koncem roku 2023. Byl to krok vpřed, ale vývojáři rychle zjistili, že „platný JSON“ nestačí, potřebovali JSON platný podle schématu. V srpnu 2024 OpenAI spustilo Strukturované výstupy se Strict Mode, který využívá omezené dekódování k zaručení shody se schématem. Do let 2025–2026 přijal stejný přístup každý hlavní poskytovatel.
JSON Mode má stále úzké využití: když opravdu neznáte tvar odpovědi předem a chcete jen nějaký platný JSON pro nestrukturovanou exploraci. To je však v produkci vzácné.
Verdikt: Pro vše v produkci používejte Strict Mode. JSON Mode je pro případy vázané na schéma fakticky zastaralý. Pokud máte schéma (a měli byste), použijte type: "json_schema" s strict: true.
Jak vlastně funguje omezené dekódování?
Zde je mechanismus, který umožňuje 100 % shodu se schématem, ne 99,9 %, ale doslova 100 %.
Když odešlete JSON Schema poskytovateli s povoleným Strict Mode, schéma se zkompiluje do konečného automatu (FSM). Tento FSM reprezentuje každou platnou cestu vaším schématem. V každém kroku generování tokenů kontroluje inferenční engine, které tokeny by udržely výstup na platné cestě a které ne. Neplatné tokeny mají své logity nastaveny na záporné nekonečno před výběrem, což znamená, že mají nulovou pravděpodobnost být vybrány.
<!-- IMAGE: constrained-decoding diagram showing FSM token masking during structured output generation -->Představte si to jako autocomplete na steroidy. Pokud model právě vypsal {"rating": a vaše schéma říká, že rating je celé číslo, jedinými povolenými dalšími tokeny jsou číslice. Uvozovky, písmena, závorky – vše je zamaskováno. Model nemůže vypsat "five", i kdyby „chtěl“.
Jedná se o stejný základní mechanismus, který používá XGrammar (engine stojící za vLLM, SGLang a většinou lokálních inferenčních serverů) a Outlines (open-source knihovna Pythonu pro omezenou generaci). Poskytovatelé API jej pouze zabudovali do své inferenční infrastruktury.
Je třeba znát jeden kompromis: první požadavek s novým schématem nese režii kompilace (obvykle 50–200 ms), zatímco se FSM sestavuje. Následné požadavky se stejným schématem používají cachovaný FSM a přidávají téměř nulovou režii. Existuje také jemný aspekt kvality: omezení slovníku tokenů může občas snížit kvalitu výstupu pro kreativní nebo volná pole, takže udržujte svá schémata zaměřená na skutečně strukturovaná data.
Verdikt: Omezené dekódování je tím, co odděluje „obvykle funguje“ od „vždy funguje“. Je to inženýrská práce, která činí strukturovaný výstup připraveným pro produkci.
Implementace u více poskytovatelů: OpenAI, Anthropic a Gemini
Zde je něco, co vám jiné průvodce neukazují: stejný extrakční úkol implementovaný napříč všemi třemi hlavními poskytovateli. Extrahujeme strukturovanou recenzi produktu z nestrukturovaného textu.
Schéma Pydantic (sdílené pro všechny poskytovatele):
from pydantic import BaseModel, Field
from typing import Literal
class ProductReview(BaseModel):
reasoning: str = Field(description="Think through the review before scoring")
rating: int = Field(description="Rating from 1-5", ge=1, le=5)
sentiment: Literal["positive", "negative", "neutral"]
pros: list[str] = Field(description="Key positive points")
cons: list[str] = Field(description="Key negative points")
summary: str = Field(description="One-sentence summary")Implementace OpenAI
from openai import OpenAI
client = OpenAI()
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract a structured review from the text."},
{"role": "user", "content": review_text}
],
response_format=ProductReview, # Pydantic model directly
)
review = response.choices[0].message.parsed # Typed ProductReview objectImplementace OpenAI je nejvyspělejší. Metoda parse() přijímá model Pydantic přímo a vrací typovaný objekt. Jedno omezení: Strict Mode OpenAI podporuje podmnožinu JSON Schema, žádné $ref, omezené anyOf a všechna pole musí být povinná s additionalProperties: false.
Implementace Anthropic
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": f"Extract a structured review:\n\n{review_text}"}
],
output_config={
"format": {
"type": "json_schema",
"json_schema": ProductReview.model_json_schema()
}
}
)
import json
review_data = json.loads(response.content[0].text)
review = ProductReview(**review_data)Nativní strukturovaný výstup Anthropic používá output_config.format s JSON Schema. Dosáhl GA (obecné dostupnosti) na začátku roku 2026. Anthropic také podporuje starší vzor definice „falešného“ nástroje a extrakce přes tool_use, což stále funguje, ale nativní strukturovaný výstup je čistší pro čistou extrakci.
Implementace Gemini
from google import genai
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=f"Extract a structured review:\n\n{review_text}",
config={
"response_mime_type": "application/json",
"response_schema": ProductReview, # Pydantic model directly
}
)
import json
review = ProductReview(**json.loads(response.text))Gemini podporuje modely Pydantic přímo v Python SDK prostřednictvím response_schema. Unikátní funkce: Gemini respektuje propertyOrdering ve schématu, takže můžete řídit pořadí výstupu polí (užitečné pro vzor zdůvodnění na prvním místě).
Porovnání poskytovatelů
| Funkce | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| Parametr API | response_format | output_config.format | response_schema |
| Vstup schématu | Pydantic nebo JSON Schema | JSON Schema | Pydantic nebo JSON Schema |
| Strict mode | strict: true | Implicitní s json_schema | Implicitní |
| Streamování | Ano (částečný JSON) | Ano | Ano |
| Zpracování odmítnutí | Pole message.refusal | Chybová odpověď | Chybová odpověď |
| Alternativa tool-use | Ano | Ano (původní metoda) | Ano |
| Cache kompilace schématu | Ano (na straně serveru) | Ano | Ano |
| Pořadí vlastností | Žádná nativní podpora | Ne | Ano (propertyOrdering) |
Verdikt: OpenAI má nejuhlazenější DX díky metodě parse(). Anthropic nabízí nejschopnější základní modely. Pořadí vlastností Gemini je jedinečně užitečné. Všichni tři odvedou práci, vybírejte na základě vašeho stávajícího vztahu s poskytovatelem.
Vzory Pydantic pro vývojáře v Pythonu
Pydantic je de facto standard pro definici schémat strukturovaného výstupu v Pythonu. Zde jsou vzory, na kterých záleží.
Základní schéma s popisy
from pydantic import BaseModel, Field
from typing import Literal, Optional
class ExtractedEntity(BaseModel):
reasoning: str = Field(description="Think step by step about the entity")
name: str = Field(description="Full name of the entity")
entity_type: Literal["person", "company", "location"]
confidence: float = Field(description="Confidence score 0.0-1.0", ge=0.0, le=1.0)
context: Optional[str] = Field(description="Surrounding context, if relevant")Tyto řetězce description nejsou jen pro dokumentaci, stávají se součástí JSON Schema odeslaného modelu a přímo ovlivňují, co model generuje. Berte je jako inženýrství promptů uvnitř schématu.
Vnořené modely
class Address(BaseModel):
street: str
city: str
country: str
postal_code: Optional[str] = None
class Company(BaseModel):
reasoning: str = Field(description="Analysis of the company details")
name: str
industry: Literal["tech", "finance", "healthcare", "retail", "other"]
headquarters: Address # Nested model
key_products: list[str] = Field(description="Top 3 products or services")Udržujte vnoření maximálně na 2–3 úrovně. Hluboce vnořená schémata zvyšují míru chyb a zpomalují kompilaci schématu.
Vzor „Zdůvodnění na prvním místě“
Toto je jediný nejvlivnější vzor návrhu schématu. Umístěte pole reasoning před pole s odpovědí:
# Reliable JSON from Any LLM: Pydantic + Zod Patterns for 2026
class ClassificationBad(BaseModel):
category: Literal["spam", "ham"]
confidence: float
# Good -- model reasons through the problem first
class ClassificationGood(BaseModel):
reasoning: str = Field(description="Analyze the text before classifying")
category: Literal["spam", "ham"]
confidence: float = Field(ge=0.0, le=1.0)LLM generují tokeny zleva doprava. Pokud přijde category jako první, model vybere kategorii a následně ji racionalizuje. Pokud přijde jako první reasoning, model projde problémem a až potom se zaváže ke kategorii. Je to chain-of-thought zapracovaný přímo do schématu.
Export JSON Schema
# Generate the JSON Schema for any Pydantic model
schema = ProductReview.model_json_schema()
# Pass this to any provider that accepts raw JSON SchemaVerdikt: Pydantic + popisná pole + pořadí zdůvodnění na prvním místě je pythonovská trojice strukturovaného výstupu. Ovládněte tyto tři vzory a zvládnete 90 % případů použití.
Vzory Zod pro vývojáře v TypeScriptu
Zod je ekvivalentem Pydanticu pro TypeScript a je stejně klíčový pro pracovní postupy strukturovaného výstupu.
Základní schéma s popisy
import { z } from "zod";
const ProductReview = z.object({
reasoning: z.string().describe("Think through the review before scoring"),
rating: z.number().int().min(1).max(5),
sentiment: z.enum(["positive", "negative", "neutral"]),
pros: z.array(z.string()).describe("Key positive points"),
cons: z.array(z.string()).describe("Key negative points"),
summary: z.string().describe("One-sentence summary"),
});
// Infer the TypeScript type automatically
type ProductReview = z.infer<typeof ProductReview>;Stejně jako Field(description=...) v Pydanticu se .describe() v Zod stává součástí JSON Schema a navádí výstup modelu.
Integrace s OpenAI Node SDK
import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI();
const response = await client.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "Extract a structured review." },
{ role: "user", content: reviewText },
],
response_format: zodResponseFormat(ProductReview, "product_review"),
});
const review = response.choices[0].message.parsed; // Typed!Integrace s Vercel AI SDK
import { generateObject } from "ai";
import { openai } from "@ai-sdk/openai";
const { object: review } = await generateObject({
model: openai("gpt-4o"),
schema: ProductReview,
prompt: `Extract a structured review:\n\n${reviewText}`,
});
// review is fully typed as ProductReviewVercel AI SDK používá Zod nativně s generateObject(), což z něj činí nejčistší integraci pro TypeScript. Funguje s OpenAI, Anthropic, Gemini a dalšími poskytovateli prostřednictvím jednotného API.
Konverze na JSON Schema
import { zodToJsonSchema } from "zod-to-json-schema";
const jsonSchema = zodToJsonSchema(ProductReview);
// Use with any provider that accepts raw JSON SchemaVerdikt: Zod + .describe() + Vercel AI SDK je stack pro strukturovaný výstup v TypeScriptu. Pokud jste v ekosystému Node/Next.js, toto je cesta nejmenšího odporu.
Strukturovaný výstup vs Volání funkcí: Kdy použít co?
Toto je jeden z nejčastějších zdrojů zmatku. Oba přístupy zahrnují schémata, oba vracejí strukturovaná data, ale řeší různé problémy.
Strukturovaný výstup říká: „Dej mi data v tomto přesném tvaru.“ Je určen pro extrakci, klasifikaci a formátování. Táhnete strukturované informace z nestrukturovaného textu.
Volání funkcí (použití nástrojů) říká: „Zde jsou akce, které můžete provést, rozhodněte se, kterou spustit, a poskytněte argumenty.“ Je určen pro agenty, kde model vybírá z více nástrojů a spouští akce.
Zmatek dává historický smysl. Původní „strukturovaný výstup“ Anthropicu byl doslova volání funkcí – definovali byste falešný nástroj nazvaný extract_review a zachytili argumenty. To stále funguje, ale nativní strukturovaný výstup je pro čistou extrakci jednodušší.
| Scénář | Nejlepší přístup | Proč |
|---|---|---|
| Extrakce dat z textu | Strukturovaný výstup | Přímý, nižší latence, jedno schéma |
| Klasifikace do kategorií | Strukturovaný výstup | Jedna odpověď, jedno schéma |
| Agent rozhodující, který nástroj zavolat | Volání funkcí | Model vybírá z více nástrojů |
| Vícerozměrná orchestrace | Volání funkcí | Sekvenční vyvolávání nástrojů |
| Extrakce dat A rozhodnutí o další akci | Obojí | Strukturovaný výstup pro extrakci, volání funkcí pro orchestraci |
Strukturovaný výstup pohání pipeline volání nástrojů v systémech AI agentů. Podívejte se na náš průvodce AI agenty pro business, jak tyto prvky zapadají do produkčních workflow.
Verdikt: Použijte strukturovaný výstup, když víte, jaký tvar by data měla mít. Použijte volání funkcí, když se model potřebuje rozhodnout pro akci. V praxi většina aplikací používá obojí: strukturovaný výstup pro extrakci dat a volání funkcí pro orchestraci agentů.
Produkční vzory: Chyby, opakování a streamování
Rozchodit strukturovaný výstup v demu je snadné. Udržet ho spolehlivý v produkci vyžaduje řešení tří věcí: odmítnutí, selhání validace a streamování.
Zpracování odmítnutí
Někdy model odmítne vygenerovat váš požadovaný výstup, obvykle proto, že bezpečnostní filtry označily vstup jako problematický. Když k tomu dojde, API pro strukturovaný výstup nevrátí vaše schéma. Vrátí odmítnutí.
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=messages,
response_format=ProductReview,
)
# ALWAYS check for refusal before accessing parsed content
if response.choices[0].message.refusal:
print(f"Model refused: {response.choices[0].message.refusal}")
else:
review = response.choices[0].message.parsedPokud přeskočíte kontrolu odmítnutí a pokusíte se přistoupit k .parsed u odmítnutí, získáte None a matoucí downstream chybu. Vždy kontrolujte jako první.
Vzory opakování s feedbackem z validace
Shoda se schématem je zaručena omezeným dekódováním, ale semantická správnost nikoliv. Model může vrátit {"rating": 1, "sentiment": "positive"}, což je platné schéma, ale obsahově protichůdné. Zde přichází na řadu validace + opakování.
import instructor
client = instructor.from_openai(OpenAI())
# Instructor handles retries automatically
review = client.chat.completions.create(
model="gpt-4o",
response_model=ProductReview,
max_retries=3, # Retries with validation error feedback
messages=[
{"role": "user", "content": review_text}
],
)Instructor při opakování předá modelu chybu z validace, aby se mohl sám opravit. Pro manuální vzory opakování bez Instructoru:
from pydantic import ValidationError
for attempt in range(3):
try:
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=messages,
response_format=ProductReview,
)
review = response.choices[0].message.parsed
# Run additional semantic validation here
break
except ValidationError as e:
messages.append({"role": "assistant", "content": str(response)})
messages.append({"role": "user", "content": f"Validation error: {e}. Fix it."})Streamování strukturovaného výstupu
U velkých strukturovaných odpovědí, dlouhých polí, mnoha polí nebo složitých vnořených objektů umožňuje streamování postupné vykreslování částečných výsledků.
import instructor
client = instructor.from_openai(OpenAI())
# Stream partial results as fields populate
review_stream = client.chat.completions.create_partial(
model="gpt-4o",
response_model=ProductReview,
messages=[{"role": "user", "content": review_text}],
)
for partial_review in review_stream:
# Fields populate one by one as tokens stream in
if partial_review.summary:
print(f"Summary so far: {partial_review.summary}")Jedno úskalí: jednotlivé streamované chunky samy o sobě nejsou platné podle schématu. Pole reasoning může být vyplněno, zatímco rating je stále None. Přizpůsobte tomu své UI, zobrazujte stav načítání pro nevyplněná pole.
Verdikt: Kontroly odmítnutí jsou nepostradatelné. Opakování s feedbackem z validace zachytí semantické chyby. Streamování stojí za to pro jakoukoli odpověď, která trvá déle než pár sekund.
Porovnání knihoven pro strukturovaný výstup
Strukturovaný výstup můžete používat přes nativní API, ale knihovny přidávají validaci, opakování, streamování a podporu více poskytovatelů. Zde je přehled.
Instructor je nejoblíbenější volbou s více než 11 tisíci hvězdičkami na GitHubu a více než 3 miliony měsíčních stažení. Obaluje OpenAI, Anthropic, Gemini, Cohere, Ollama a další s jednotným rozhraním založeným na Pydanticu. Klíčové funkce: automatická opakování s feedbackem z validace, streamování přes create_partial() a velmi jednoduché nastavení (instructor.from_openai(client)). Pokud jste tým v Pythonu, začněte zde.
BAML jde jinou cestou: priorita schématu prostřednictvím vlastního DSL. Schémata definujete v souborech .baml a automaticky generujete klienty pro Python, TypeScript, Ruby a další. Jeho algoritmus SAP (schema-aligned parsing) elegantně zpracovává nepřehledné výstupy modelů. Nejlepší pro týmy pracující s více jazyky nebo když chcete kontrakty mezi vaší LLM vrstvou a aplikační vrstvou. Kompromis: extra krok buildu a nový syntax k naučení.
LangChain nabízí .with_structured_output(schema) pro strukturovaný výstup nezávislý na poskytovateli. Pohodlné, pokud již jste v ekosystému LangChain. Kompromis: je to těžká závislost a abstrakce může skrýt specifické funkce poskytovatelů, které byste mohli potřebovat.
Nativní API, přímá volání s response_format / output_config, vyžadují nulové závislosti nad rámec SDK poskytovatele. Získáte plnou kontrolu a viditelnost. Nejlepší pro jednoduché případy použití nebo týmy, které preferují minimální abstrakci.
| Knihovna | Jazyky | Poskytovatelé | Auto Retries | Streamování | Hvězdičky na GitHubu | Náročnost učení |
|---|---|---|---|---|---|---|
| Instructor | Python, TS | 15+ | Ano | Ano | 11K+ | Nízká |
| BAML | Python, TS, Ruby, Go | Všechny (nezávislé na DSL) | Ano | Ano | 7K+ | Střední |
| LangChain | Python, TS | 20+ | Částečně | Ano | 100K+ | Střední-Vysoká |
| Nativní API | Jakýkoli | 1 na SDK | Ne | Ano | N/A | Nízká |
Výběr správné knihovny pro strukturovaný výstup je součástí širšího rozhodování o AI stacku. Celý stack rozebíráme v našem Průvodci nejlepší AI stack pro SaaS.
Podívejte se na naše Nejlepší knihovny pro strukturované výstupy LLM [brzy] pro podrobné srovnání Instructor, BAML, Mirascope a dalších.
Verdikt: Začněte s Instructor pro Python, nativními API pro TypeScript. Přejděte na BAML, pokud potřebujete kontrakty schémat napříč jazyky. Vyhněte se LangChainu pouze pro strukturovaný výstup, je to zbytečně složité.
Osvědčené postupy návrhu schémat (a běžné chyby)
Váš návrh schématu přímo ovlivňuje kvalitu výstupu. Zde jsou vzory, na kterých záleží, a chyby, které vás stojí přesnost.
Umístěte zdůvodnění před odpovědi
Probrali jsme to v sekci Pydantic, ale stojí za to to zopakovat, protože je to designové rozhodnutí s největším dopadem:
# Before: model guesses the answer, then rationalizes
class Bad(BaseModel):
answer: str
reasoning: str
# After: model thinks first, then commits
class Good(BaseModel):
reasoning: str = Field(description="Think step by step")
answer: strLLM generují zleva doprava. Pořadí polí je pořadím promptu. Zdůvodnění na prvním místě znamená, že model musí projít problémem, než se zaváže k odpovědi.
Tabulka anti-vzorů
| Chyba | Problém | Oprava |
|---|---|---|
| Pole pro zdůvodnění za odpovědí | Model se rozhodne dříve, než přemýšlí | Přesuňte zdůvodnění před odpověď |
| Hluboké vnoření (4+ úrovně) | Vyšší míra chyb, pomalejší kompilace | Zploštěte na 2–3 úrovně |
| Žádné popisy polí | Model hádá, co chcete | Přidejte .describe() / Field(description=...) |
| Chybějící zpracování null | Model halucinuje hodnotu, aby vyplnil pole | Použijte Optional / .nullable() |
| Příliš velká schémata (50+ polí) | Timeout kompilace, degradace kvality | Rozdělte na více volání |
| Nejasné možnosti enum | Model vybere špatnou kategorii | Použijte specifické, nepřekrývající se možnosti |
Explicitně zpracovávejte nuly
Pokud pole nemusí mít data ve zdrojovém textu, udělejte jej volitelné. Vynucování povinného pole, když data neexistují, vede k halucinacím:
class PersonInfo(BaseModel):
name: str # Always present
email: Optional[str] = Field(None, description="Email if mentioned, null otherwise")
phone: Optional[str] = Field(None, description="Phone if mentioned, null otherwise")Udržujte schémata zaměřená
Jedno schéma na úkol. Nesnažte se extrahovat vše v jednom obrovském schématu. Pokud potřebujete 50+ polí, rozdělte extrakci na více volání. Strict Mode OpenAI má praktické limity na složitost schématu a i když to funguje, velmi velká schémata degradují kvalitu výstupu.
Verdikt: Zdůvodnění na prvním místě, popisná pole, explicitní nuly a zaměřená schémata. Zvládněte tyto čtyři věci a přesnost vašeho strukturovaného výstupu znatelně vzroste.
Strukturovaný výstup s lokálními LLM
Pro strukturovaný výstup nepotřebujete poskytovatele API. Lokální inferenční enginy jej podporují prostřednictvím omezeného dekódování založeného na gramatice, stejném základním mechanismu, běží na vašem vlastním hardwaru.
Ollama
Nejsnazší cesta k lokálnímu strukturovanému výstupu. Ollama přijímá JSON Schema prostřednictvím parametru format:
import ollama
from pydantic import BaseModel
class Country(BaseModel):
name: str
capital: str
languages: list[str]
response = ollama.chat(
model="llama3.2",
messages=[{"role": "user", "content": "Tell me about Japan."}],
format=Country.model_json_schema(),
)
import json
country = Country(**json.loads(response.message.content))Ollama používá pod kapotou XGrammar pro omezené dekódování. Stejná garance jako u poskytovatelů API: 100 % shoda se schématem.
vLLM a SGLang
Pro lokální inferenci produkční úrovně vLLM a SGLang oba podporují strukturovaný výstup prostřednictvím parametrů guided_json a guided_regex. XGrammar je výchozí backend, poskytující téměř nulovou režii při generování JSON, až 3,5x rychlejší než alternativní gramatické enginy.
Outlines
Outlines je open-source knihovna Pythonu, která průkopnicky prosadila generaci omezenou gramatikou. Funguje s jakýmkoli modelem Hugging Face a podporuje omezení JSON Schema, regex a plnou bezkontextovou gramatiku (CFG/EBNF). Je také integrována do vLLM a SGLang jako možnost gramatického backendu.
Klíčový rozdíl oproti poskytovatelům API: lokální strukturovaný výstup nemá žádná omezení podmnožiny schématu. Gramatiku ovládáte zcela. Ale kvalita modelů se více liší, lokální model s 7 miliardami parametrů se nebude vyrovnat GPT-4o nebo Claude u složitých extrakčních úloh. Schéma bude vždy platné; kvalita obsahu závisí na modelu.
Verdikt: Ollama pro vývoj, vLLM/SGLang s XGrammar pro produkci. Lokální strukturovaný výstup je dostatečně zralý pro většinu případů použití, s caveat, že menší modely produkují obsah nižší kvality uvnitř schématu.
FAQ
Co je strukturovaný výstup v LLM?
Strukturovaný výstup je mechanismus, který zaručuje, že odpověď LLM odpovídá předdefinovanému JSON Schema. Na rozdíl od prostého textu nebo dokonce JSON Mode používá strukturovaný výstup omezené dekódování k zajištění, že každé pole, typ a omezení ve vašem schématu je splněno – 100 % času, ne „obvykle“.
Jaký je rozdíl mezi JSON Mode a Strukturovanými výstupy?
JSON Mode garantuje syntakticky platný JSON, ale nevynucuje vaše schéma, můžete získat jakýkoli platný JSON objekt. Strukturované výstupy (Strict Mode) garantují plnou shodu se schématem prostřednictvím omezeného dekódování. Pro produkci používejte Strict Mode; JSON Mode je relevantní pouze tehdy, když nemáte předem dané schéma.
Kteří poskytovatelé LLM podporují nativně strukturovaný výstup?
OpenAI (od srpna 2024), Google Gemini (2024, rozšířeno 2026), Anthropic (beta listopad 2025, GA začátek 2026), Cohere a xAI (Grok) všechny podporují nativní strukturovaný výstup. Na lokální straně jej podporují Ollama, vLLM a SGLang prostřednictvím omezeného dekódování založeného na gramatice.
Jak omezené dekódování garantuje shodu se schématem?
JSON Schema je zkompilována do konečného automatu (FSM). V každém kroku generování tokenů jsou povoleny pouze tokeny, které udržují výstup na platné cestě FSM, neplatné tokeny mají své logity nastaveny na záporné nekonečno. To znamená, že neplatné tokeny mají nulovou pravděpodobnost být vygenerovány, což vám dává matematickou garanci, ne statistickou.
Mám používat strukturovaný výstup nebo volání funkcí?
Použijte strukturovaný výstup pro extrakci a klasifikaci, když chcete data v určitém tvaru. Použijte volání funkcí pro workflow agentů, když se model potřebuje rozhodnout, kterou akci provést. Mnoho produkčních aplikací používá obojí: strukturovaný výstup pro extrakci dat a volání funkcí pro orchestraci.
Mohu streamovat strukturovaný výstup?
Ano. OpenAI podporuje streamování s metodou parse() a Instructor poskytuje create_partial() pro streamování modelů Pydantic, které se plní pole po poli. Mějte na paměti, že jednotlivé streamované chunky nejsou samy o sobě platné podle schématu, pole se plní postupně.
Co je knihovna Instructor?
Instructor je nejoblíbenější knihovna pro strukturovaný výstup (11K+ hvězdiček na GitHubu, 3M+ měsíčních stažení). Obaluje SDK poskytovatelů validací založenou na Pydanticu, automatickým opakováním s feedbackem z validace a podporou streamování. Funguje s OpenAI, Anthropic, Gemini, Cohere, Ollama a 10+ dalšími poskytovateli.
Funguje strukturovaný výstup s lokálními LLM?
Ano. Ollama podporuje strukturovaný výstup prostřednictvím parametru format s JSON Schema. vLLM a SGLang jej podporují prostřednictvím parametrů guided_json. Všechny tři používají XGrammar nebo Outlines pro omezené dekódování. Garance shody se schématem je stejná jako u poskytovatelů API; kvalita obsahu závisí na modelu.
Jaké jsou běžné chyby v návrhu schémat?
Nejčastější chyby: umístění pole pro zdůvodnění za pole s odpovědí (model se rozhodne dříve, než přemýšlí), hluboce vnořená schémata (4+ úrovně zvyšují chyby), chybějící popisy polí (model hádá záměr), žádné zpracování null pro volitelná data (vynucuje halucinaci) a příliš velká schémata (50+ polí degraduje kvalitu).
Přidává strukturovaný výstup latenci?
Existuje režie kompilace schématu při prvním požadavku, obvykle 50–200 ms, zatímco se FSM sestavuje. Následné požadavky se stejným schématem používají cachovaný FSM a přidávají téměř nulovou latenci. Pro většinu aplikací je to zanedbatelné ve srovnání s celkovým časem inference modelu.
Mohu použít strukturovaný výstup s obrázky nebo multimodálními vstupy?
Ano. Strukturovaný výstup se týká formátu odpovědi, ne vstupu. Můžete poslat obrázek do GPT-4o nebo Gemini se schématem strukturovaného výstupu a získat zpět analýzu obrázku odpovídající schématu. To je silné pro workflow vizuální extrakce, extrakci strukturovaných dat z účtenek, formulářů nebo obrázků produktů.