Techsy
Kontakt
Rozpocznij
Powrót do bloga
ai-machine-learning

Niezawodny JSON z dowolnego LLM: Wzorce Pydantic + Zod na rok 2026

Napisane przez Mert Batur Gürbüz
Zaktualizowano May 12, 2026
15 min
Spis treści
Niezawodny JSON z dowolnego LLM: Wzorce Pydantic + Zod na rok 2026

Strukturalne dane wyjściowe LLM to mechanizm, który gwarantuje, że odpowiedź modelu językowego jest zgodna z predefiniowanym schematem – nie tylko poprawnym składniowo JSON-em, ale zgodnym ze schematem JSON-em, zawierającym dokładnie te pola, typy i ograniczenia, które określiłeś. Każdy główny dostawca obsługuje to teraz natywnie, co zmieniło sposób budowania produkcyjnych aplikacji opartych na LLM.

Szybkie podsumowanie: Strukturalne dane wyjściowe w pigułce

Jeśli masz mało czasu, oto przegląd sytuacji w 2026 roku:

AspektSzczegóły
Czym jestOdpowiedzi z LLM wymuszone schematem, gwarantowana struktura, a nie „najlepsze staranie”
Kto wspieraOpenAI, Anthropic, Gemini, Cohere, xAI (Grok), plus lokalnie przez Ollama/vLLM
Kluczowy mechanizmDekodowanie z ograniczeniami, nieważne tokeny są maskowane przed próbkowaniem
Tryb JSON vs Tryb ŚcisłyTryb JSON = tylko poprawna składnia. Tryb Ścisły = pełna zgodność ze schematem
Biblioteka PythonaPydantic (BaseModel + Field) do definiowania schematu
Biblioteka TypeScriptZod (z.object + .describe) do definiowania schematu
Najlepsze podejście na startOpenAI z Pydantic lub Zod przez natywne SDK
Najlepsza biblioteka produkcyjnaInstructor (Python) lub natywne SDK (TypeScript)
Największa pułapkaUmieszczenie pola rozumowania PO polu odpowiedzi; model decyduje przed myśleniem
Narzut czasowy50-200 ms przy pierwszym wywołaniu (kompilacja schematu), później buforowane

Przeanalizujmy teraz każdy element z osobna.

Czym są strukturalne dane wyjściowe LLM?

Strukturalne dane wyjściowe to różnica między nadzieją, że LLM zwróci poprawny JSON, a gwarancją. Gdy włączysz strukturalne dane wyjściowe, model fizycznie nie może wygenerować tokenów łamiących Twój schemat. Definiujesz JSON Schema (lub model Pydantic, albo schemat Zod), przekazujesz go do API i otrzymujesz odpowiedź, która za każdym razem jest z nim zgodna.

Dlaczego to ma znaczenie? Przed wprowadzeniem strukturalnych danych wyjściowych programiści pisali kruche parsery wyrażeń regularnych, otaczali każde wywołanie LLM blokami try/catch JSON.parse i nadal mieli do czynienia z odpowiedziami „prawie dobrymi” – poprawnymi składniowo JSON-ami, którym brakowało pola lub miały zły typ. Cała ta klasa błędów odeszła do lamusa.

Istnieją trzy poziomy wymuszania struktury, które reprezentują wyraźną ewolucję:

  1. Inżynieria promptów: „Proszę zwrócić JSON z tymi polami”. Niezawodne. Model może spełnić prośbę w 80-90% przypadków.
  2. Tryb JSON: Gwarantuje składniowo poprawny JSON, ale nie wymusza Twojego schematu. Możesz otrzymać {"foo": "bar"}, gdy oczekiwałeś {"name": string, "age": number}.
  3. Tryb Ścisły / Dekodowanie z ograniczeniami: Gwarantuje 100% zgodności ze schematem. Model dosłownie nie może wyprowadzić nieważnych tokenów. To właśnie oznacza „strukturalne dane wyjściowe” w 2026 roku.

Na początku 2026 roku OpenAI, Anthropic i Google Gemini obsługują natywne strukturalne dane wyjściowe. Ekosystem się ujednolicił.

Werdykt: Jeśli w środowisku produkcyjnym parsujesz odpowiedzi LLM za pomocą regexów lub JSON.parse, robisz to w trudny sposób. Natywne strukturalne dane wyjściowe eliminują ten cały tryb awarii.

Tryb JSON vs Tryb Ścisły: Co tak naprawdę się zmieniło?

To rozróżnienie myli wielu deweloperów, ponieważ nazwy brzmią podobnie. A jednak nie są takie same.

CechaTryb JSONTryb Ścisły (Strukturalne Dane Wyjściowe)
Parametr APItype: "json_object"type: "json_schema" z strict: true
Gwarantuje poprawny JSONTakTak
Gwarantuje zgodność ze schematemNieTak
MechanizmPost-hoc bias tokenówDekodowanie z ograniczeniami (FSM)
Może zwrócić nieoczekiwane polaTakNie
Może pominąć wymagane polaTakNie
Wymuszanie typówBrakPełne (string, number, array itp.)
Kiedy używaćNie masz z góry określonego schematuWszystko w produkcji

Oś czasu: OpenAI wprowadziło Tryb JSON pod koniec 2023 roku. Był to krok naprzód, ale deweloperzy szybko zrozumieli, że „poprawny JSON” to za mało – potrzebowali JSON-a zgodnego ze schematem. W sierpniu 2024 roku OpenAI uruchomiło Strukturalne Dane Wyjściowe z Trybem Ścisłym, który wykorzystuje dekodowanie z ograniczeniami do zagwarantowania zgodności ze schematem. Do lat 2025-2026 każdy główny dostawca przyjął to samo podejście.

Tryb JSON wciąż ma wąskie zastosowanie: gdy naprawdę nie znasz z góry kształtu odpowiedzi i chcesz po prostu jakiegoś poprawnego JSON-a do nieustrukturyzowanej eksploracji. Ale w produkcji zdarza się to rzadko.

Werdykt: Używaj Trybu Ścisłego do wszystkiego w produkcji. Tryb JSON jest de facto przestarzały dla przypadków użycia związanych ze schematami. Jeśli masz schemat (a powinieneś), użyj type: "json_schema" z strict: true.

Jak właściwie działa dekodowanie z ograniczeniami?

Oto mechanizm, który sprawia, że 100% zgodności ze schematem jest możliwe – nie 99,9%, ale dosłownie 100%.

Gdy wysyłasz JSON Schema do dostawcy z włączonym Trybem Ścisłym, schemat jest kompilowany do automatu skończonego (FSM). Ten FSM reprezentuje każdą poprawną ścieżkę przez Twój schemat. Na każdym etapie generowania tokenów silnik wnioskowania sprawdza, które tokeny utrzymałyby dane wyjściowe na poprawnej ścieżce, a które nie. Nieważne tokeny mają swoje logity ustawione na minus nieskończoność przed próbkowaniem, co oznacza, że mają zerowe prawdopodobieństwo zostania wybranymi.

<!-- IMAGE: constrained-decoding diagram showing FSM token masking during structured output generation -->

Myśl o tym jak o autouzupełnianiu na sterydach. Jeśli model właśnie wyprowadził {"rating":, a Twój schemat mówi, że rating jest liczbą całkowitą, jedynymi dozwolonymi następnymi tokenami są cyfry. Cudzysłowy, litery, nawiasy – wszystkie zamaskowane. Model nie może wyprowadzić "five", nawet jeśli „chce”.

To ten sam podstawowy mechanizm używany przez XGrammar (silnik stojący za vLLM, SGLang i większością lokalnych serwerów wnioskowania) oraz Outlines (bibliotekę open-source w Pythonie do generowania z ograniczeniami). Dostawcy API po prostu wbudowali to w swoją infrastrukturę wnioskowania.

Jest jeden kompromis, o którym warto wiedzieć: pierwsze żądanie z nowym schematem ponosi koszt opóźnienia kompilacji (zazwyczaj 50-200 ms) podczas budowania FSM. Kolejne żądania z tym samym schematem używają buforowanego FSM i dodają bliski zeru narzut. Istnieje też subtelna kwestia jakości: ograniczanie słownika tokenów może czasami obniżać jakość danych wyjściowych dla pól kreatywnych lub swobodnych, dlatego trzymaj swoje schematy skupione na prawdziwie strukturalnych danych.

Werdykt: Dekodowanie z ograniczeniami to to, co oddziela „zazwyczaj działa” od „zawsze działa”. To inżynieria, która sprawia, że strukturalne dane wyjściowe są gotowe do produkcji.

Implementacja u wielu dostawców: OpenAI, Anthropic i Gemini

Oto coś, czego nie pokazują inne przewodniki: to samo zadanie ekstrakcji zaimplementowane u trzech głównych dostawców. Wyekstrahujemy strukturalną recenzję produktu z nieustrukturyzowanego tekstu.

Schemat Pydantic (wspólny dla wszystkich dostawców):

python
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")

Implementacja w OpenAI

python
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 object

Implementacja OpenAI jest najbardziej dojrzała. Metoda parse() przyjmuje bezpośrednio model Pydantic i zwraca obiekt z typami. Jedno ograniczenie: Tryb Ścisły OpenAI obsługuje podzbiór JSON Schema, brak $ref, ograniczone anyOf, a wszystkie pola muszą być wymagane z additionalProperties: false.

Implementacja w Anthropic

python
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)

Natywne strukturalne dane wyjściowe Anthropic używają output_config.format z JSON Schema. Osiągnęły status GA na początku 2026 roku. Anthropic obsługuje również starszy wzorzec definiowania „fałszywego” narzędzia i ekstrakcji przez tool_use, który nadal działa, ale natywne strukturalne dane wyjściowe są czystsze dla samej ekstrakcji.

Implementacja w Gemini

python
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 obsługuje modele Pydantic bezpośrednio w SDK Pythona przez response_schema. Unikalna cecha: Gemini respektuje propertyOrdering w schemacie, więc możesz kontrolować kolejność wyprowadzania pól (przydatne dla wzorca „najpierw rozumowanie”).

Porównanie dostawców

CechaOpenAIAnthropicGemini
Parametr APIresponse_formatoutput_config.formatresponse_schema
Wejście schematuPydantic lub JSON SchemaJSON SchemaPydantic lub JSON Schema
Tryb ścisłystrict: trueImplikowany przez json_schemaImplikowany
StreamingTak (częściowy JSON)TakTak
Obsługa odmowyPole message.refusalOdpowiedź błęduOdpowiedź błędu
Alternatywa tool-useTakTak (oryginalna metoda)Tak
Buforowanie kompilacji schematuTak (po stronie serwera)TakTak
Kolejność właściwościBrak natywnego wsparciaNieTak (propertyOrdering)

Werdykt: OpenAI ma najbardziej dopracowane DX dzięki metodzie parse(). Anthropic oferuje najzdolniejsze modele bazowe. Kolejność właściwości w Gemini jest wyjątkowo przydatna. Wszystkie trzy realizują zadanie, wybierz w oparciu o istniejącą relację z dostawcą.

Wzorce Pydantic dla programistów Pythona

Pydantic to de facto standard definiowania schematów strukturalnych danych wyjściowych w Pythonie. Oto wzorce, które mają znaczenie.

Podstawowy schemat z opisami

python
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")

Te ciągi description nie służą tylko dokumentacji – stają się częścią JSON Schema wysyłanego do modelu i bezpośrednio wpływają na to, co model generuje. Myśl o nich jak o inżynierii promptów wewnątrz schematu.

Zagnieżdżone modele

python
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")

Ogranicz zagnieżdżenie do maksymalnie 2-3 poziomów. Głęboko zagnieżdżone schematy zwiększają wskaźnik błędów i spowalniają kompilację schematu.

Wzorzec „Najpierw Rozumowanie”

To pojedynczy, najbardziej wpływowy wzorzec projektowania schematu. Umieść pole reasoning przed polami odpowiedzi:

python
# 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 od lewej do prawej. Jeśli category jest pierwsze, model wybiera kategorię, a następnie ją racjonalizuje. Jeśli reasoning jest pierwsze, model pracuje nad problemem i dopiero potem zobowiązuje się do kategorii. To chain-of-thought wbudowane w schemat.

Eksport do JSON Schema

python
# Generate the JSON Schema for any Pydantic model
schema = ProductReview.model_json_schema()
# Pass this to any provider that accepts raw JSON Schema

Werdykt: Pydantic + opisowe pola + kolejność „najpierw rozumowanie” to trifecta strukturalnych danych wyjściowych w Pythonie. Opanuj te trzy wzorce, a obsłużysz 90% przypadków użycia.

Wzorce Zod dla programistów TypeScript

Zod to TypeScriptowy odpowiednik Pydantic i jest równie kluczowy dla przepływów pracy ze strukturalnymi danymi wyjściowymi.

Podstawowy schemat z opisami

typescript
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>;

Podobnie jak Field(description=...) w Pydantic, .describe() w Zod staje się częścią JSON Schema i kieruje danymi wyjściowymi modelu.

Integracja z OpenAI Node SDK

typescript
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!

Integracja z Vercel AI SDK

typescript
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 ProductReview

Vercel AI SDK używa Zod natywnie z generateObject(), co czyni go najczystszą integracją w TypeScript. Działa z OpenAI, Anthropic, Gemini i innymi dostawcami przez zunifikowane API.

Konwersja do JSON Schema

typescript
import { zodToJsonSchema } from "zod-to-json-schema";

const jsonSchema = zodToJsonSchema(ProductReview);
// Use with any provider that accepts raw JSON Schema

Werdykt: Zod + .describe() + Vercel AI SDK to stos strukturalnych danych wyjściowych w TypeScript. Jeśli jesteś w ekosystemie Node/Next.js, to jest droga najmniejszego oporu.

Strukturalne dane wyjściowe vs Wywoływanie funkcji: Kiedy używać którego?

To jedno z najczęstszych źródeł nieporozumień. Obie dotyczą schematów, obie zwracają strukturalne dane, ale rozwiązują różne problemy.

Strukturalne dane wyjściowe mówią: „Daj mi dane w tym dokładnym kształcie”. Służą do ekstrakcji, klasyfikacji i formatowania. Wyciągasz strukturalne informacje z nieustrukturyzowanego tekstu.

Wywoływanie funkcji (użycie narzędzi) mówi: „Oto działania, które możesz podjąć, zdecyduj, które uruchomić i podaj argumenty”. Służy do przepływów pracy agentów, gdzie model wybiera spośród wielu narzędzi i uruchamia działania.

Historyczne nieporozumienie ma sens. Oryginalne „strukturalne dane wyjściowe” Anthropic to było dosłownie wywoływanie funkcji – definiowałeś fałszywe narzędzie o nazwie extract_review i pobierałeś argumenty. To nadal działa, ale natywne strukturalne dane wyjściowe są prostsze dla samej ekstrakcji.

ScenariuszNajlepsze podejścieDlaczego
Ekstrakcja danych z tekstuStrukturalne dane wyjścioweBezpośrednie, mniejsze opóźnienie, pojedynczy schemat
Klasyfikacja do kategoriiStrukturalne dane wyjścioweJedna odpowiedź, jeden schemat
Agent decydujący, które narzędzie wywołaćWywoływanie funkcjiModel wybiera spośród wielu narzędzi
Orkiestracja wieloetapowaWywoływanie funkcjiSekwencyjne wywołania narzędzi
Ekstrakcja danych ORAZ decyzja o następnej akcjiObieStrukturalne dane wyjściowe do ekstrakcji, wywoływanie funkcji do orkiestracji

Strukturalne dane wyjściowe napędzają potoki wywoływania narzędzi w systemach agentów AI. Zobacz nasz przewodnik po agentach AI dla biznesu, aby dowiedzieć się, jak pasują one do przepływów pracy produkcyjnej.

Werdykt: Używaj strukturalnych danych wyjściowych, gdy wiesz, jaki kształt powinny mieć dane. Używaj wywoływania funkcji, gdy model musi wybrać działanie. W praktyce większość aplikacji używa obu: strukturalnych danych wyjściowych do ekstrakcji danych i wywoływania funkcji do orkiestracji agentów.

Wzorce produkcyjne: Błędy, ponowienia i streaming

Uzyskanie działania strukturalnych danych wyjściowych w demo jest łatwe. Utrzymanie niezawodności w produkcji wymaga obsługi trzech rzeczy: odmów, błędów walidacji i streamingu.

Obsługa odmów

Czasami model odmawia wygenerowania żądanych danych wyjściowych, zazwyczaj dlatego, że filtry bezpieczeństwa oznaczyły dane wejściowe. Gdy tak się stanie, API strukturalnych danych wyjściowych nie zwraca Twojego schematu. Zwracają odmowę.

python
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.parsed

Jeśli pominiesz sprawdzanie odmowy i spróbujesz uzyskać dostęp do .parsed przy odmowie, otrzymasz None i mylący błąd downstream. Zawsze sprawdzaj najpierw.

Wzorce ponowień z informacją zwrotną walidacji

Zgodność ze schematem jest gwarantowana przez dekodowanie z ograniczeniami, ale poprawność semantyczna już nie. Model może zwrócić {"rating": 1, "sentiment": "positive"}, co jest poprawnym schematem, ale sprzeczną treścią. Tutaj wchodzą walidacja + ponowienia.

python
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 przekazuje błąd walidacji z powrotem do modelu przy ponowieniu, dzięki czemu może się on samodzielnie skorygować. Dla ręcznych wzorców ponowień bez Instruktora:

python
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."})

Streaming strukturalnych danych wyjściowych

W przypadku dużych strukturalnych odpowiedzi, długich tablic, wielu pól, złożonych zagnieżdżonych obiektów, streaming pozwala na progresywne renderowanie częściowych wyników.

python
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}")

Jedna pułapka: pojedyncze fragmenty streamingu nie są samodzielnie zgodne ze schematem. Pole reasoning może być wypełnione, podczas gdy rating nadal wynosi None. Zaplanuj swój UI odpowiednio, pokazując stan ładowania dla niewypełnionych pól.

Werdykt: Sprawdzanie odmów jest koniecznością. Ponowienia z informacją zwrotną walidacji wychwytują błędy semantyczne. Streaming opłaca się przy każdej odpowiedzi, która zajmuje więcej niż kilka sekund.

Porównanie bibliotek strukturalnych danych wyjściowych

Możesz używać strukturalnych danych wyjściowych przez natywne API, ale biblioteki dodają walidację, ponowienia, streaming i obsługę wielu dostawców. Oto przegląd.

Instructor to najpopularniejsza opcja z ponad 11 tys. gwiazdek na GitHubie i ponad 3 mln miesięcznych pobrań. Otacza OpenAI, Anthropic, Gemini, Cohere, Ollama i inne zunifikowanym interfejsem opartym na Pydantic. Kluczowe funkcje: automatyczne ponowienia z informacją zwrotną walidacji, streaming przez create_partial() i niezwykle prosta konfiguracja (instructor.from_openai(client)). Jeśli jesteś zespołem Pythonowym, zacznij tutaj.

BAML przyjmuje inne podejście: najpierw schemat przez niestandardowy DSL. Definiujesz schematy w plikach .baml i automatycznie generujesz klientów dla Pythona, TypeScript, Ruby i innych. Jego algorytm SAP (parsing zgodny ze schematem) gracefully radzi sobie z bałaganiarskimi danymi wyjściowymi modeli. Najlepszy dla zespołów wielojęzycznych lub gdy chcesz kontraktów między warstwą LLM a warstwą aplikacji. Kompromis: dodatkowy krok budowania i nowa składnia do nauczenia.

LangChain oferuje .with_structured_output(schema) dla strukturalnych danych wyjściowych niezależnych od dostawcy. Wygodne, jeśli jesteś już w ekosystemie LangChain. Kompromis: to ciężka zależność, a abstrakcja może ukrywać specyficzne dla dostawcy funkcje, których możesz potrzebować.

Natywne API, bezpośrednie wywołania z response_format / output_config, wymagają zerowych zależności poza SDK dostawcy. Masz pełną kontrolę i widoczność. Najlepsze dla prostych przypadków użycia lub zespołów preferujących minimalną abstrakcję.

BibliotekaJęzykiDostawcyAuto PonowieniaStreamingGwiazdki GitHubKrzywa nauki
InstructorPython, TS15+TakTak11K+Niska
BAMLPython, TS, Ruby, GoWszystkie (DSL-agnosticzne)TakTak7K+Średnia
LangChainPython, TS20+CzęściowoTak100K+Średnia-Wysoka
Natywne APIDowolny1 na SDKNieTakN/ANiska

Wybór odpowiedniej biblioteki strukturalnych danych wyjściowych jest częścią szerszej decyzji dotyczącej stosu AI. Rozkładamy pełny stos w naszym Przewodniku po najlepszym stosie AI dla SaaS.

Zobacz nasze Najlepsze biblioteki do strukturalnych danych wyjściowych LLM [wkrótce] dla dogłębnego porównania Instructor, BAML, Mirascope i innych.

Werdykt: Zacznij od Instruktora dla Pythona, natywnych API dla TypeScript. Przejdź do BAML, jeśli potrzebujesz kontraktów schematów między językami. Unikaj LangChain tylko dla strukturalnych danych wyjściowych, to przesada.

Najlepsze praktyki projektowania schematów (i typowe błędy)

Twój projekt schematu bezpośrednio wpływa na jakość danych wyjściowych. Oto wzorce, które mają znaczenie, oraz błędy, które kosztują Cię dokładność.

Umieść rozumowanie przed odpowiedziami

Omówiliśmy to w sekcji Pydantic, ale warto powtórzyć, ponieważ jest to decyzja projektowa o największym wpływie:

python
# 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: str

LLM generują od lewej do prawej. Kolejność pól to kolejność promptu. Rozumowanie pierwsze oznacza, że model musi przepracować problem, zanim zobowiąże się do odpowiedzi.

Tabela antywzorców

BłądProblemPoprawka
Pole rozumowania po odpowiedziModel decyduje przed myśleniemPrzenieś rozumowanie przed odpowiedź
Głębokie zagnieżdżenie (4+ poziomy)Wyższy wskaźnik błędów, wolniejsza kompilacjaSpłaszcz do 2-3 poziomów
Brak opisów pólModel zgaduje, czego chceszDodaj .describe() / Field(description=...)
Brak obsługi nullModel halucynuje wartość, by wypełnić poleUżyj Optional / .nullable()
Zbyt duże schematy (50+ pól)Timeout kompilacji, degradacja jakościPodziel na wiele wywołań
Niejasne opcje enumModel wybiera złą kategorięUżyj konkretnych, nie nakładających się opcji

Jawna obsługa wartości Null

Jeśli pole może nie mieć danych w tekście źródłowym, uczyń je opcjonalnym. Wymuszanie wymaganego pola, gdy dane nie istnieją, prowadzi do halucynacji:

python
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")

Trzymaj schematy skupione

Jeden schemat na zadanie. Nie próbuj ekstrahować wszystkiego w jednym ogromnym schemacie. Jeśli potrzebujesz 50+ pól, podziel na wiele wywołań ekstrakcji. Tryb Ścisły OpenAI ma praktyczne limity złożoności schematu, a nawet gdy działa, bardzo duże schematy obniżają jakość danych wyjściowych.

Werdykt: Najpierw rozumowanie, opisowe pola, jawne nulle i skupione schematy. Dopracuj te cztery elementy, a dokładność strukturalnych danych wyjściowych zauważalnie wzrośnie.

Strukturalne dane wyjściowe z lokalnymi LLM

Nie potrzebujesz dostawcy API do strukturalnych danych wyjściowych. Lokalne silniki wnioskowania obsługują je poprzez dekodowanie z ograniczeniami oparte na gramatyce – ten sam podstawowy mechanizm, działający na Twoim własnym sprzęcie.

Ollama

Najłatwiejsza ścieżka do lokalnych strukturalnych danych wyjściowych. Ollama akceptuje JSON Schema przez parametr format:

python
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 używa pod spodem XGrammar do dekodowania z ograniczeniami. Ta sama gwarancja co u dostawców API: 100% zgodności ze schematem.

vLLM i SGLang

Do lokalnego wnioskowania klasy produkcyjnej, vLLM i SGLang obsługują strukturalne dane wyjściowe przez parametry guided_json i guided_regex. XGrammar jest domyślnym backendem, zapewniając bliski zeru narzut przy generowaniu JSON, do 3,5x szybciej niż alternatywne silniki gramatyczne.

Outlines

Outlines to biblioteka open-source w Pythonie, która jako pierwsza wprowadziła generowanie z ograniczeniami oparte na gramatyce. Działa z dowolnym modelem Hugging Face i obsługuje JSON Schema, regex oraz pełne ograniczenia gramatyki bezkontekstowej (CFG/EBNF). Jest również zintegrowana z vLLM i SGLang jako opcja backendu gramatycznego.

Kluczowa różnica w stosunku do dostawców API: lokalne strukturalne dane wyjściowe nie mają ograniczeń podzbioru schematu. Kontrolujesz gramatykę całkowicie. Ale jakość modelu jest bardziej zróżnicowana – lokalny model 7B parametrów nie dorówna GPT-4o ani Claude w złożonych zadaniach ekstrakcji. Schemat zawsze będzie poprawny; jakość treści zależy od modelu.

Werdykt: Ollama do rozwoju, vLLM/SGLang z XGrammar do produkcji. Lokalne strukturalne dane wyjściowe są wystarczająco dojrzałe do większości przypadków użycia, z zastrzeżeniem, że mniejsze modele produkują treści o niższej jakości w ramach schematu.

FAQ

Czym są strukturalne dane wyjściowe w LLM?

Strukturalne dane wyjściowe to mechanizm, który gwarantuje, że odpowiedź LLM jest zgodna z predefiniowanym JSON Schema. W przeciwieństwie do zwykłego tekstu, a nawet Trybu JSON, strukturalne dane wyjściowe używają dekodowania z ograniczeniami, aby zapewnić spełnienie każdego pola, typu i ograniczenia w Twoim schemacie – w 100% przypadków, a nie „zazwyczaj”.

Jaka jest różnica między Trybem JSON a Strukturalnymi Danymi Wyjściowymi?

Tryb JSON gwarantuje składniowo poprawny JSON, ale nie wymusza Twojego schematu – możesz otrzymać dowolny poprawny obiekt JSON. Strukturalne Dane Wyjściowe (Tryb Ścisły) gwarantują pełną zgodność ze schematem poprzez dekodowanie z ograniczeniami. Używaj Trybu Ścisłego w produkcji; Tryb JSON jest istotny tylko wtedy, gdy nie masz z góry określonego schematu.

Którzy dostawcy LLM obsługują natywnie strukturalne dane wyjściowe?

OpenAI (od sierpnia 2024), Google Gemini (2024, rozszerzone 2026), Anthropic (beta listopad 2025, GA początek 2026), Cohere i xAI (Grok) obsługują natywne strukturalne dane wyjściowe. Po stronie lokalnej, Ollama, vLLM i SGLang obsługują je poprzez dekodowanie z ograniczeniami oparte na gramatyce.

Jak dekodowanie z ograniczeniami gwarantuje zgodność ze schematem?

JSON Schema jest kompilowana do automatu skończonego (FSM). Na każdym etapie generowania tokenów dozwolone są tylko tokeny, które utrzymują dane wyjściowe na poprawnej ścieżce przez FSM, nieważne tokeny mają logity ustawione na minus nieskończoność. Oznacza to, że nieważne tokeny mają zerowe prawdopodobieństwo wygenerowania, dając matematyczną gwarancję, a nie statystyczną.

Czy powinienem używać strukturalnych danych wyjściowych, czy wywoływania funkcji?

Używaj strukturalnych danych wyjściowych do ekstrakcji i klasyfikacji, gdy chcesz dane w określonym kształcie. Używaj wywoływania funkcji do przepływów pracy agentów, gdy model musi zdecydować, jakie działanie podjąć. Wiele aplikacji produkcyjnych używa obu: strukturalnych danych wyjściowych do ekstrakcji danych i wywoływania funkcji do orkiestracji.

Czy mogę streamować strukturalne dane wyjściowe?

Tak. OpenAI obsługuje streaming z metodą parse(), a Instructor udostępnia create_partial() do streamowania modeli Pydantic, które wypełniają się pole po polu. Pamiętaj, że pojedyncze fragmenty streamingu nie są indywidualnie zgodne ze schematem, pola wypełniają się stopniowo.

Czym jest biblioteka Instructor?

Instructor to najpopularniejsza biblioteka strukturalnych danych wyjściowych (11K+ gwiazdek na GitHubie, 3M+ miesięcznych pobrań). Otacza SDK dostawców walidacją opartą na Pydantic, automatycznymi ponowieniami z informacją zwrotną walidacji i obsługą streamingu. Działa z OpenAI, Anthropic, Gemini, Cohere, Ollama i 10+ innymi dostawcami.

Czy strukturalne dane wyjściowe działają z lokalnymi LLM?

Tak. Ollama obsługuje strukturalne dane wyjściowe przez parametr format z JSON Schema. vLLM i SGLang obsługują je przez parametry guided_json. Wszystkie trzy używają XGrammar lub Outlines do dekodowania z ograniczeniami. Gwarancja zgodności ze schematem jest taka sama jak u dostawców API; jakość treści zależy od modelu.

Jakie są typowe błędy w projektowaniu schematów?

Najczęstsze błędy: umieszczanie pola rozumowania po polu odpowiedzi (model decyduje przed myśleniem), głęboko zagnieżdżone schematy (4+ poziomy zwiększają błędy), brak opisów pól (model zgaduje intencje), brak obsługi null dla opcjonalnych danych (wymusza halucynacje) i zbyt duże schematy (50+ pól obniża jakość).

Czy strukturalne dane wyjściowe dodają opóźnienie?

Występuje narzut kompilacji schematu przy pierwszym żądaniu, zazwyczaj 50-200 ms podczas budowania FSM. Kolejne żądania z tym samym schematem używają buforowanego FSM i dodają bliskie zeru opóźnienie. Dla większości aplikacji jest to pomijalne w porównaniu do całkowitego czasu wnioskowania modelu.

Czy mogę używać strukturalnych danych wyjściowych z obrazami lub danymi multimodalnymi?

Tak. Strukturalne dane wyjściowe dotyczą formatu odpowiedzi, a nie danych wejściowych. Możesz wysłać obraz do GPT-4o lub Gemini ze schematem strukturalnych danych wyjściowych i otrzymać z powrotem analizę obrazu zgodną ze schematem. Jest to potężne narzędzie do przepływów pracy wizualnej ekstrakcji, wydobywania strukturalnych danych z paragonów, formularzy lub zdjęć produktów.

Źródła

  • Przewodnik po Strukturalnych Danych Wyjściowych OpenAI
  • Dokumentacja Użycia Narzędzi Anthropic
  • Strukturalne Dane Wyjściowe Google Gemini
  • Dokumentacja Biblioteki Instructor
  • Dokumentacja BAML
  • Dokumentacja Pydantic
  • Dokumentacja Zod
  • Biblioteka Outlines
  • XGrammar GitHub
  • Strukturalne Dane Wyjściowe Ollama
  • Vercel AI SDK

Tagi

strukturalne dane wyjściowe llmstrukturalne dane wyjścioweschemat jsonpydanticzodopenaianthropicgemini

Udostępnij artykuł

Powiązane artykuły

Więcej w ai-machine-learning

ai-machine-learning
Jul 24, 2026

Claude Opus 5 już jest: inteligencja bliska Fable 5 za połowę ceny

Anthropic wydał Claude Opus 5 24 lipca 2026. Model ponad dwukrotnie przebija Opus 4.8 w Frontier-Bench i utrzymuje cenę Opus, ale przegrywa kilka testów z Fable 5 i Mythos 5. Oto tabela benchmarków, ceny i rekomendacja: przejść, poczekać czy zostać.

10 min read min
Czytaj
ai-machine-learning
Jul 20, 2026

8 najlepszych API do scrapingu AI w 2026 (przetestowane na naszym stacku agentów)

Przetestowaliśmy 8 API do scrapingu AI z realnymi cenami z 2026 roku, pobranymi przez nasz własny stack agentów. Firecrawl, Bright Data, ScrapingBee i 5 innych — ranking pod kątem wyjścia gotowego dla LLM, omijania antybotów i obsługi MCP.

9 min read min
Czytaj
ai-machine-learning
Jul 20, 2026

Inżynieria promptów dla programistów: 7 wzorców, których używamy codziennie w Claude Code i Cursor (2026)

Większość artykułów o „promptach do kodowania z AI” serwuje 50 szablonów do skopiowania. Ten uczy 7 wzorców, których używamy każdego dnia do obsługi potoku 16 agentów Claude Code, z rzeczywistymi przykładami „przed i po” oraz informacją, gdzie każdy wzorzec stosować w Claude Code, Cursor i Copilot w 2026 roku.

11 min read min
Czytaj
Zobacz wszystkie artykuły
Rozpocznij swój projekt

Gotowi, by zbudować coś co Cię wyróżnia?

Zamieńmy Twoją wizję w rzeczywistość. Nasz zespół jest gotowy, by pomóc Ci stworzyć oprogramowanie, które robi różnicę.

Umów 30-minutowe spotkanie wstępneZobacz nasze realizacje

Z naszej biblioteki

Umiejętności Claude

Zobacz wszystkie
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

Automatyzacje AI

Zobacz wszystkie
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

Z naszej biblioteki

Umiejętności Claude

Zobacz wszystkie
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

Automatyzacje AI

Zobacz wszystkie
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

Usługi

  • Rozwiązania Enterprise
  • Aplikacje mobilne
  • Aplikacje webowe

Rozwiązania

  • Systemy CRM
  • Integracja AI
  • Rozwiązania ERP
  • Agenci głosowi
  • Automatyzacja procesów
  • Cyberbezpieczeństwo

Biblioteka

  • Blog
  • Portfel realizacji

Społeczność

  • Automatyzacje AI
  • Umiejętności Claude

Narzędzia

  • Kalkulator kosztów aplikacji mobilnej
  • Kalkulator kosztów API OpenAI / LLM
  • Kalkulator kosztów MVP
  • Kalkulator kosztów agenta Voice AI

Firma

  • O nas
  • Partnerzy
  • Kontakt

Prawne

  • Polityka prywatności
  • Regulamin
  • Polityka cookies

Usługi

  • Rozwiązania Enterprise
  • Aplikacje mobilne
  • Aplikacje webowe

Rozwiązania

  • Systemy CRM
  • Integracja AI
  • Rozwiązania ERP
  • Agenci głosowi
  • Automatyzacja procesów
  • Cyberbezpieczeństwo

Biblioteka

  • Blog
  • Portfel realizacji

Społeczność

  • Automatyzacje AI
  • Umiejętności Claude

Narzędzia

  • Kalkulator kosztów aplikacji mobilnej
  • Kalkulator kosztów API OpenAI / LLM
  • Kalkulator kosztów MVP
  • Kalkulator kosztów agenta Voice AI

Firma

  • O nas
  • Partnerzy
  • Kontakt
PrawnePolityka prywatnościRegulaminPolityka cookies
TECHSY
© 2026 Techsy. Wszystkie prawa zastrzeżone.