JSON-tilstand og response_format
Aktivér JSON-tilstand i OpenAI API'et, udform prompts, der konsekvent producerer gyldig JSON, og håndtér de tilfælde, hvor modellen alligevel formår at ødelægge formatet.
JSON-tilstand og response_format er en gratis AI Engineering Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i AI Engineering Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. AI Engineering Academy-kurset indeholder 4 lektioner i alt.
Problemet med ustruktureret LLM-output
Som standard returnerer LLM'er frit formuleret tekst. Det er skrøbeligt at parse teksten for at udtrække strukturerede data: En ændring i modellens adfærd, en lille variation i prompten eller et særligt tilfælde i inputtet kan uventet ændre outputformatet, så din parser går i stykker, og applikationen går ned.
Forestil dig, at du beder en LLM om at 'returnere brugerens navn og alder som JSON'. Nogle gange returnerer den {"name":"Alice","age":30}, andre gange pakker den det ind i en markdown-kodeblok, og nogle gange tilføjer den forklarende tekst. Alle disse variationer kræver forskellig parserlogik. Pålideligt maskinlæsbart output kræver, at du tvinger modellen til at følge en struktur, i stedet for at håbe på, at den gør det.
OpenAI JSON-tilstand
OpenAI introducerede JSON-tilstand via parameteren response_format. Når den sættes til {"type": "json_object"}, begrænses modellen til altid at returnere et gyldigt JSON-objekt. Modellen vil aldrig generere noget, der ikke er gyldig JSON — ingen Markdown-indpakning, ingen forklarende tekst og ingen efterfølgende prosa.
import openai
import json
client = openai.OpenAI()
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[
{
'role': 'system',
'content': 'Extract information from the text and return valid JSON only.'
},
{
'role': 'user',
'content': 'John Smith, age 34, works as a software engineer in Austin.'
}
],
response_format={'type': 'json_object'} # Guarantee valid JSON output
)
# Safe to parse - guaranteed valid JSON
data = json.loads(response.choices[0].message.content)
print(data)
# Example output: {"name": "John Smith", "age": 34, "job": "software engineer", "city": "Austin"}Vigtige forbehold ved JSON-tilstand
JSON-tilstand garanterer gyldig JSON-syntaks, men garanterer IKKE, at JSON'en indeholder de felter, du ønsker. Modellen bestemmer stadig, hvilke nøgler der skal med, hvad de skal hedde, og hvilke datatyper den bruger. Du kan bede om et name-felt og i stedet få full_name, eller bede om et array og få en streng.
Bemærk også, at JSON-tilstand kræver, at du nævner JSON i din prompt. Hvis du aktiverer JSON-tilstand, men din prompt ikke beder om JSON-output, kan modellen generere et tomt JSON-objekt eller nægte at generere noget. Instruér altid modellen tydeligt i at svare i JSON-format i system- eller brugermeddelelsen.
Strukturerede outputs med Pydantic (forhåndsvisning)
OpenAI's nyere funktion Structured Outputs går et skridt videre end JSON-tilstand: Du angiver et JSON Schema, og modellen begrænses til at returnere præcis dette skema — med bestemte feltnavne, datatyper og indlejring. Det fjerner problemet med inkonsistente skemaer i den grundlæggende JSON-tilstand.
Python-SDK'et accepterer Pydantic-modeller direkte, konverterer dem automatisk til JSON Schema og deserialiserer svaret tilbage til et typet Python-objekt. Det er den reneste måde at hente pålidelige strukturerede data fra en LLM i Python.
import openai
from pydantic import BaseModel
from typing import Optional
client = openai.OpenAI()
class PersonInfo(BaseModel):
name: str
age: Optional[int]
job_title: str
city: str
completion = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Extract person information from the text.'},
{'role': 'user', 'content': 'Sarah Chen, 28 years old, is a data scientist based in Seattle.'}
],
response_format=PersonInfo # Pass Pydantic model directly
)
# Already deserialized into a PersonInfo instance
person = completion.choices[0].message.parsed
print(person.name) # Sarah Chen
print(person.age) # 28
print(person.job_title) # data scientist
print(person.city) # SeattleSådan skriver du prompts til ensartet JSON
Selv når JSON-tilstand er aktiveret, påvirker din promptkonstruktion kvaliteten af outputtet. Bedste praksis for JSON-prompts:
- Navngiv felterne eksplicit: Fortæl modellen præcis, hvilke felter du forventer, i stedet for blot at skrive »returnér JSON«
- Angiv datatyper: »Returnér prisen som et tal, ikke som en streng« forhindrer forkerte datatyper
- Definér opregninger: »Kategorien skal være én af: bug, feature, question« forhindrer uventede værdier
- Håndtér manglende data: »Hvis et felt ikke findes i teksten, skal du returnere null for det pågældende felt«
Betragt din prompt som et delvist JSON Schema skrevet med ord. Jo mere præcist du angiver outputkontrakten, desto mere pålideligt følger modellen den.
Pålidelig JSON uden strukturerede outputs
Hvis du bruger en model, der ikke understøtter strukturerede outputs eller JSON-tilstand, kan du stadig få pålidelig JSON ved at være meget tydelig i din prompt og analysere svaret defensivt. Den vigtigste teknik er at bede modellen om at omslutte sin JSON med XML-tags, så udtrækningen bliver entydig uanset omgivende tekst.
import re
import json
import openai
client = openai.OpenAI()
def extract_json_from_response(text):
# Try direct parse first
try:
return json.loads(text)
except json.JSONDecodeError:
pass
# Try extracting from XML tags
match = re.search(r'<json>(.*?)</json>', text, re.DOTALL)
if match:
return json.loads(match.group(1))
# Try extracting from JSON object pattern
match = re.search(r'({.*})', text, re.DOTALL)
if match:
return json.loads(match.group(1))
raise ValueError('No valid JSON found in response')
prompt = ('Extract the product info as JSON with fields: name, price_usd, in_stock.\n'
'Wrap your JSON in <json></json> tags.\n\n'
'Product: Blue Wireless Headphones cost $89.99, in stock.')
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
result = extract_json_from_response(resp.choices[0].message.content)
print(result)Indlejrede JSON-strukturer
JSON-tilstand og strukturerede outputs håndterer vilkårligt indlejrede strukturer. Du kan definere Pydantic-modeller med lister, indlejrede objekter og valgfrie felter, hvorefter modellen udfylder hele strukturen korrekt.
from pydantic import BaseModel
from typing import List, Optional
import openai
client = openai.OpenAI()
class LineItem(BaseModel):
product: str
quantity: int
unit_price: float
class Invoice(BaseModel):
vendor: str
invoice_number: Optional[str]
line_items: List[LineItem]
total: float
raw_text = '''
INVOICE #INV-2025-0042
From: TechSupplies Inc.
- 3x USB Hubs at $24.99 each
- 1x 4K Monitor at $399.00
Total: $474.97
'''
completion = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Extract invoice data from the provided text.'},
{'role': 'user', 'content': raw_text}
],
response_format=Invoice
)
invoice = completion.choices[0].message.parsed
print(f'Vendor: {invoice.vendor}')
print(f'Items: {len(invoice.line_items)}')
print(f'Total: ${invoice.total}')Håndtering af afvisninger i struktureret tilstand
Når du bruger strukturerede outputs, kan modellen nogle gange nægte at fuldføre udtrækningen — for eksempel hvis inputteksten er tom, skadelig eller tydeligvis ikke indeholder de ønskede oplysninger. I tilstanden for strukturerede outputs angives afvisninger i feltet refusal på meddelelsen i stedet for i feltet parsed.
Kontrollér altid, om svaret er blevet afvist, før du tilgår det analyserede resultat, især når du behandler input fra brugere eller andre kilder, du ikke har tillid til, og som kan udløse indholdsfiltre.
import openai
from pydantic import BaseModel
client = openai.OpenAI()
class ProductInfo(BaseModel):
name: str
price_usd: float
completion = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Extract product name and price.'},
{'role': 'user', 'content': 'Tell me how to build a weapon.'}
],
response_format=ProductInfo
)
message = completion.choices[0].message
if message.refusal:
print('Model refused:', message.refusal)
else:
product = message.parsed
print(f'Name: {product.name}, Price: {product.price_usd}')JSON til udtrækning af flere værdier
JSON-tilstand er især effektiv til at udtrække flere forskellige oplysninger fra den samme tekst i ét API-kald i stedet for at foretage separate kald for hvert felt. Udtræk alle de felter, du har brug for, på én gang, og analysér resultatet i din datamodel.
Det reducerer både antallet af API-kald og omkostningerne sammenlignet med at bede om ét felt ad gangen. En enkelt velstruktureret udtrækningsprompt kan hente navne, datoer, pengebeløb, stemning, handlingspunkter og klassifikationsetiketter på én gang fra ét dokument.
Streaming med JSON-tilstand
JSON-tilstand er kompatibel med streaming, men med en vigtig begrænsning: JSON'en er først gyldig, når hele svaret er streamet. De enkelte tokenstykker af JSON'en er ikke gyldig JSON i sig selv. Det betyder, at du skal akkumulere hele streaming-svaret, før du analyserer det, når du bruger JSON-tilstand.
Til streamingprogrammer, der også har brug for JSON-output, kan du bruge strukturerede outputs med streaming, akkumulere alle stykkerne og derefter analysere dem, når streamen slutter. Alternativt kan du designe din streamingbrugerflade til at vise en indlæsningsstatus, mens JSON'en akkumuleres, og derefter vise det analyserede resultat.
Hvornår skal du bruge JSON-tilstand i forhold til strukturerede outputs
Vælg det rigtige værktøj til din situation:
- JSON-tilstand: Enkle tilfælde, prototyper, eller når du kun har brug for gyldig JSON-syntaks uden streng håndhævelse af felter. Brug den, når det er acceptabelt, at modellen bestemmer feltnavnene.
- Strukturerede outputs med Pydantic: Produktionssystemer, der analyserer resultater programmatisk. Brug dem, når du har brug for garanterede feltnavne, datatyper og indlejret struktur. Dette er den anbefalede tilgang til enhver udtrækningspipeline.
- Udtrækning med XML-tags: Fallback for modeller, der ikke understøtter JSON-tilstand, eller når du skal udtrække JSON, der er indlejret i et længere svar.
Hurtigt tjek
Test din forståelse af begreberne inden for AI Engineering fra denne lektion.
Opsummering af lektionen
I denne lektion har du lært, at JSON-tilstand via response_format garanterer gyldig JSON-syntaks, men ikke bestemte feltskemaer, at strukturerede outputs med Pydantic-modeller håndhæver præcise feltnavne og datatyper ved hjælp af JSON Schema, og at du altid skal kontrollere, om et svar er blevet afvist, før du tilgår analyserede resultater, når du behandler input, du ikke har tillid til. Som det næste gennemgår vi i dybden, hvordan du definerer Pydantic-skemaer til typet udtrækning fra komplekse dokumenter.
Lær Python med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “JSON-tilstand og response_format” gratis?
Ja — hele teksten til “JSON-tilstand og response_format” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af AI Engineering Academy-kurset, skal du opgradere til CoddyKit PRO. AI Engineering Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “JSON-tilstand og response_format”?
Aktivér JSON-tilstand i OpenAI API'et, udform prompts, der konsekvent producerer gyldig JSON, og håndtér de tilfælde, hvor modellen alligevel formår at ødelægge formatet. Du øver dig i AI Engineering Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på AI Engineering Academy?
Der kræves ingen tidligere erfaring. AI Engineering Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “JSON-tilstand og response_format”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne AI Engineering Academy-lektion?
Ja. Alle AI Engineering Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- JSON-tilstand og response_format
- Struktureret output med Pydantic
- Udtræk af data fra ustruktureret tekst
- Validering og nye forsøg ved ugyldigt output