Garantera strukturerade LLM-svar med JSON-schema.
Så fort en LLM ska mata in i ett annat system - en databas, ett API, en arbetsflödesmotor - räcker det inte att svaret låter bra. Det måste ha rätt form. Den som tidigt försökt parsa ut JSON ur ett friformssvar känner igen smärtan: ibland kommer det en inledande mening, ibland en kodblocksmarkering, ibland ett kommatecken för mycket. Lösningen heter structured outputs, och både OpenAI och Anthropic stöder det numera - men på olika sätt och med olika garantier.
Jag använder strukturerade svar i nästan varje LLM-integration jag bygger, och nedan går jag igenom hur de två leverantörerna skiljer sig och hur jag gör koden robust oavsett vilken jag använder. Skillnaden mot att be om JSON i fritext och hoppas är inte gradvis utan kategorisk: i det ena fallet bygger du på en garanti, i det andra på tur. Och tur skalar dåligt - en parser som fungerar för nittionio svar av hundra ger dig ett produktionslarm varje gång hundrade kunden gör något ovanligt.
Problemet med att parsa friform
Att be modellen "svara med JSON" och sedan köra en parser på texten fungerar i en demo och fallerar i produktion. Modellen lägger till förklaringar, varierar fältnamn, eller bryter formatet vid ovanliga indata. Varje sådant fall blir en krasch eller, värre, tyst felaktig data. Strukturerade svar löser detta genom att binda utdata till ett schema istället för att hoppas på efterhandstolkning.
Det förrädiska är att friform-parsningen ofta ser ut att fungera länge. Under utveckling och i de första veckorna i drift kommer svaren prydligt, och man invaggas i en falsk trygghet. Sedan dyker det upp en indata man inte tänkt på - ett ovanligt tecken, ett väldigt långt fält, en fråga på fel språk - och modellen svarar med en inledande mening eller en kodblocksmarkering som parsern snubblar på. Nu står man med ett produktionsfel som är svårt att återskapa, eftersom det bara inträffar för vissa indata. Att binda svaret till ett schema från början eliminerar hela den klassen av buggar istället för att jaga dem en i taget.
OpenAI: schema med garanti
OpenAI erbjuder ett läge där du anger ett JSON-schema och modellen garanterat returnerar utdata som följer det. Det är en stark garanti: fält, typer och struktur stämmer. Det betyder dock inte att innehållet är korrekt - bara att formen är det. Modellen kan fortfarande fylla ett giltigt fält med fel värde, så validering av innehållet behövs fortfarande utöver schemat.
Anthropic: verktyg som strukturmekanism
Anthropic närmar sig samma problem via verktygsdefinitioner. Genom att definiera ett verktyg med ett indataschema och styra modellen att använda det får du tillbaka strukturerade argument som följer schemat. Resultatet liknar OpenAIs, men mekanismen och hur strikt garantin är skiljer sig, vilket är värt att känna till om man bygger mot båda. I praktiken kapslar jag in skillnaden bakom ett gemensamt gränssnitt i koden.
Den inkapslingen är värd att lyfta fram, för den är skillnaden mellan en kodbas som är låst till en leverantör och en som inte är det. Jag definierar mitt schema en gång på mitt eget sätt och översätter det till respektive leverantörs format bakom en gemensam funktion. Resten av appen vet inte vilken modell som körs - den ber bara om ett objekt av en viss form och får det. Den dagen prissättning eller kvalitet gör att jag vill byta leverantör blir det en ändring på ett ställe istället för i varje integration, vilket också gör det enkelt att utvärdera två modeller mot varandra på samma uppgift.
Designa schemat med omsorg
Schemat är inte bara en formalitet - det styr hur väl modellen presterar. Mina principer:
- Var explicit. Beskriv varje fält tydligt; beskrivningarna fungerar som instruktioner.
- Undvik onödig nästling. Platta strukturer är lättare för modellen och för dig.
- Tillåt osäkerhet. Ge modellen ett sätt att signalera "vet inte" istället för att hitta på.
- Använd enums där värdemängden är känd, så slipper du normalisera fritext efteråt.
Validera även när formatet är garanterat
Även med en formgaranti validerar jag svaret mot affärsregler: ligger beloppet i ett rimligt intervall, finns referensen faktiskt, är datumet giltigt? Schemat garanterar strukturen, inte sanningen. Den här valideringsnivån hänger ihop med hur jag bygger felhantering i prompt-arkitektur, och den är förutsättningen för att kunna mäta kvalitet systematiskt, vilket jag beskriver i artikeln om evals.
Att göra LLM-svar till pålitliga byggstenar i ett större system är en återkommande del av mina uppdrag inom AI Engineering, och strukturerade svar är nästan alltid en av grundbultarna.
Felhantering även när garantin finns
Formgaranti betyder inte att inget kan gå fel. Modellen kan vägra svara, anropet kan ta timeout, och i vissa lägen - särskilt med svagare modeller eller väldigt komplexa scheman - kan resultatet bli giltigt men uppenbart fel. Jag bygger därför alltid in en plan: ett omförsök vid tekniskt fel, en kontroll mot affärsregler, och en tydlig fallback om svaret inte går att lita på. Det värsta är en integration som tar emot ett välformat men felaktigt objekt och skriver in det rakt i databasen utan att någon märker det förrän långt senare.
Kostnad och kompromisser
Strukturerade svar är inte gratis i alla lägen. Ett komplext schema kostar tokens och kan i vissa fall göra svaren stelare eller långsammare. För enkla fall där ett kort textsvar räcker är det overkill. Jag använder dem där nedströmssystemet kräver struktur - inte reflexmässigt överallt. När de väl behövs sparar de dock mycket i form av uteblivna parsningsfel, vilket också gör kostnadsoptimering enklare.
Relaterat
- RAG i produktion: Chunking, embeddings, reranking och evals
- LangChain vs LangGraph vs LlamaIndex: Vilken passar ert use case?
- Evals för LLM-appar: Bygga test-suiter som faktiskt fångar regressioner
Hur strukturerade svar ersatt en bräcklig parser i en skarp integration finns bland mina kundcase.
Vill du ta det vidare?
Om ni har en integration som då och då kraschar på trasig JSON hjälper jag er lägga om den till garanterad struktur. Boka ett förutsättningslöst samtal så tittar vi på er pipeline.
“Schemat garanterar strukturen, inte sanningen - validera innehållet ändå.”
- Simon Axelsson
Vanliga frågor
- Garanterar structured outputs att svaret är korrekt?
- Nej, bara att formen är korrekt. Modellen returnerar giltig JSON enligt schemat, men kan fortfarande fylla ett giltigt fält med fel värde. Därför validerar jag alltid innehållet mot affärsregler utöver schemat - rimliga intervall, existerande referenser och giltiga datum.
- Skiljer sig OpenAI och Anthropic mycket?
- Mekanismen skiljer sig. OpenAI har ett uttalat schemaläge med stark formgaranti, medan Anthropic uppnår strukturen via verktygsdefinitioner med indataschema. Resultatet liknar varandra, men hur strikt garantin är skiljer sig. Bygger du mot båda kapslar du lämpligen in skillnaden bakom ett gemensamt gränssnitt.
- När är strukturerade svar overkill?
- När nedströmssystemet inte kräver struktur. Ett komplext schema kostar tokens och kan göra svaren stelare. För enkla fall där ett kort textsvar räcker är det onödigt. Använd dem där ett annat system ska konsumera svaret - då sparar de mycket i uteblivna parsningsfel.
