# Structured Output and JSON Mode **Last updated:** 2026-06-24 **Status:** GA **Category:** Prompt Engineering & LLM Optimization --- ## Introduksjon Strukturert output er en teknikk som tvinger LLM-modeller til å følge et spesifikt JSON Schema som du definerer i API-kallet ditt. Dette er en betydelig forbedring over den eldre JSON Mode-funksjonen, som kun garanterte syntaktisk gyldig JSON, men ikke kunne sikre at outputen følger et bestemt skjema. **Strukturert output** gjør det mulig å: - Definere nøyaktig hvilken datastruktur modellen skal returnere - Eliminere parsing-feil og validerings-overhead - Bygge robuste multi-steg workflows og integrasjoner - Bruke type-safe objekter direkte i koden (via Pydantic i Python, for eksempel) **JSON Mode** (eldre metode) garanterer kun at outputen er gyldig JSON, men gir ingen kontroll over strukturen. Microsoft anbefaler å bruke structured outputs fremfor JSON mode for alle nye implementasjoner på GPT-4o og nyere modeller. **Viktig begrensning:** Strukturert output støttes for øyeblikket ikke med "bring your own data"-scenarier (Azure AI Search-integrasjon), Assistants API, eller Foundry Agents Service. --- ## Kjernekomponenter ### Response Format Types | Type | Beskrivelse | Anbefalt bruk | |------|-------------|---------------| | `text` | Standard tekstformat, ingen spesifikk struktur | Generelle tekstrespons, kreativ skriving | | `json_object` | Garanterer syntaktisk gyldig JSON, men ingen schema-validering | **Legacy** — erstattet av `json_schema` | | `json_schema` | Tvinger modellen til å følge et JSON Schema med strict mode | **Anbefalt** for alle strukturerte output-behov | ### Structured Outputs med JSON Schema **Python-eksempel (Microsoft Entra ID auth):** ```python from pydantic import BaseModel from openai import OpenAI from azure.identity import DefaultAzureCredential, get_bearer_token_provider token_provider = get_bearer_token_provider( DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default" ) client = OpenAI( base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/", api_key=token_provider, ) class CalendarEvent(BaseModel): name: str date: str participants: list[str] completion = client.beta.chat.completions.parse( model="gpt-4o", # GPT-4o 2024-08-06 eller nyere messages=[ {"role": "system", "content": "Extract the event information."}, {"role": "user", "content": "Alice and Bob are going to a science fair on Friday."}, ], response_format=CalendarEvent, ) event = completion.choices[0].message.parsed print(event) # name='Science Fair' date='Friday' participants=['Alice', 'Bob'] ``` **REST API-eksempel:** ```bash curl -X POST https://YOUR_RESOURCE_NAME.openai.azure.com/openai/v1/chat/completions \ -H "api-key: $AZURE_OPENAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [ {"role": "system", "content": "Extract the event information."}, {"role": "user", "content": "Alice and Bob are going to a science fair on Friday."} ], "response_format": { "type": "json_schema", "json_schema": { "name": "CalendarEventResponse", "strict": true, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "date": {"type": "string"}, "participants": { "type": "array", "items": {"type": "string"} } }, "required": ["name", "date", "participants"], "additionalProperties": false } } } }' ``` ### Function Calling med Structured Outputs For function calling, aktiver structured outputs ved å sette `strict: true` i function-definisjonen. **Viktig:** Strukturert output støtter ikke parallell function calling. Sett `parallel_tool_calls: false` når du bruker strict mode. ```python from pydantic import BaseModel import openai from openai import OpenAI class GetDeliveryDate(BaseModel): order_id: str tools = [openai.pydantic_function_tool(GetDeliveryDate)] response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "You are a helpful customer support assistant."}, {"role": "user", "content": "What's the delivery date for order #12345?"} ], tools=tools, parallel_tool_calls=False # Påkrevd for structured outputs ) ``` --- ## Arkitekturmønstre ### 1. Data Extraction Pattern **Bruksområde:** Trekk strukturert informasjon fra ustrukturert tekst (e-poster, kundehenvendelser, dokumenter). **Fordeler:** - Ingen parsing-logikk nødvendig i applikasjonskoden - Type-safe objekter direkte fra API-et - Reduserer feilrate drastisk **Ulemper:** - Krever GPT-4o eller nyere modeller - Økt token-forbruk sammenlignet med fritekst-output (marginal) **Eksempel:** ```python class CustomerFeedback(BaseModel): sentiment: str # "positive", "neutral", "negative" product_mentioned: list[str] issues: list[str] satisfaction_score: int # 1-5 completion = client.beta.chat.completions.parse( model="gpt-4o", messages=[ {"role": "system", "content": "Extract feedback details from customer email."}, {"role": "user", "content": email_text} ], response_format=CustomerFeedback, ) ``` ### 2. Multi-Step Workflow Pattern **Bruksområde:** Bygge komplekse workflows der hvert steg produserer strukturert output som input til neste steg. **Fordeler:** - Lettere debugging og logging - Kan cache mellomresultater - Enklere å parallellisere uavhengige steg **Ulemper:** - Flere API-kall (økt latency og kostnad) - Må håndtere feil i hvert steg **Eksempel-workflow (fakta-sjekking):** 1. **Steg 1:** Trekk ut faktiske påstander fra tekst → `list[Claim]` 2. **Steg 2:** Generer søkespørsmål for hver påstand → `list[SearchQuery]` 3. **Steg 3:** Vurder pålitelighet basert på søkeresultater → `FactCheckReport` ### 3. Form-Filling Pattern **Bruksområde:** Chatbots og assistenter som samler strukturert informasjon over flere meldinger. **Fordeler:** - Garanterer at alle påkrevde felter fylles ut - Kan validere input underveis - Enklere å integrere med backend-systemer **Ulemper:** - Kan føles rigid for brukere hvis ikke godt designet - Krever state management på klientsiden --- ## Beslutningsveiledning ### Når bruke Structured Outputs vs JSON Mode | Kriterium | Bruk Structured Outputs | Bruk JSON Mode | Bruk fritekst | |-----------|------------------------|----------------|---------------| | Trenger eksakt schema? | ✅ | ❌ | ❌ | | Kun syntaktisk gyldig JSON? | ✅ | ✅ | ❌ | | Kreativ eller fleksibel output? | ❌ | ❌ | ✅ | | Integreres direkte med database? | ✅ | ⚠️ (må validere) | ❌ | | Eldre modeller (GPT-3.5)? | ❌ | ✅ | ✅ | | GPT-4o eller nyere? | ✅ | ⚠️ (deprecated) | ✅ | ### JSON Schema-begrensninger (strict mode) | Begrensning | Detaljer | |-------------|----------| | **Nestingdybde** | Maks 5 nivåer | | **Totalt antall properties** | Maks 100 properties på tvers av hele schemat | | **Required fields** | Alle fields MÅ være `required` (bruk `["string", "null"]` for optional) | | **additionalProperties** | MÅ være `false` for alle objekter | | **Root type** | Kan ikke være `anyOf` | | **Parallell function calling** | Ikke støttet med `strict: true` | | **Usupporterte keywords** | String: `minLength`, `maxLength`, `pattern`, `format`. Number: `minimum`, `maximum`, `multipleOf`. Objects: `patternProperties`, `unevaluatedProperties`, `propertyNames`, `minProperties`, `maxProperties`. Arrays: `minItems`, `maxItems`, `uniqueItems`, `contains`, `minContains`, `maxContains`, `unevaluatedItems` | **Støttede typer:** String, Number, Boolean, Integer, Object, Array, Enum, anyOf (nested). **Recursive schemas:** Støttes via `$ref` og `#` (root recursion). --- ## Integrasjon med Microsoft-stakken ### Microsoft Foundry / Azure OpenAI **API-versjon:** Structured outputs introdusert i `2024-08-01-preview`, tilgjengelig i GA-versjon `v1`. **Støttede modeller (per 2026-06):** - **GPT-5-serien:** gpt-5, gpt-5.1, gpt-5.1-chat, gpt-5.1-codex, gpt-5-pro, gpt-5-codex, gpt-5-mini, gpt-5-nano (hele serien støtter structured outputs) - **GPT-4-serien:** gpt-4o (2024-08-06, 2024-11-20), gpt-4.1, gpt-4.1-mini, gpt-4.1-nano - **o-serien:** o1, o3-mini, o3-pro, o4-mini - **Codex:** codex-mini (2025-05-16) **Ikke støttet med:** - Assistants API - Foundry Agents Service - "Bring your own data" (Azure AI Search) - Audio-preview modeller (gpt-4o-audio-preview og gpt-4o-mini-audio-preview, versjon 2024-12-17) ### Semantic Kernel **Semantic Kernel** støtter structured outputs via `AzureAssistantAgent.configure_response_format()`: ```python from pydantic import BaseModel class ResponseModel(BaseModel): response: str items: list[str] client, model = AzureAssistantAgent.setup_resources() definition = await client.beta.assistants.create( model=model, name="DataExtractor", instructions="Extract structured data from text.", response_format=AzureAssistantAgent.configure_response_format(ResponseModel), ) ``` **Fordel:** Enklere å integrere med plugins og orchestration-logikk. ### Power Platform / Copilot Studio **Status:** Structured outputs er ikke direkte eksponert i Copilot Studio low-code interface per 2026-02. Må brukes via custom connectors eller Power Automate med HTTP-actions mot Azure OpenAI REST API. **Workaround:** 1. Opprett custom connector med OpenAI-endepunkt 2. Send `response_format` i request body 3. Parse JSON-output i Power Automate --- ## Offentlig sektor (Norge) ### Dataminimering og GDPR Strukturert output kan hjelpe med **dataminimering** (GDPR Art. 5.1c) ved å: - Kun trekke ut spesifikt definerte datafelter - Unngå at modellen returnerer persondata som ikke er nødvendig - Lettere å implementere anonymisering i output-schema **Anbefaling:** Definer schema slik at sensitive felter (personnummer, helseopplysninger) kun inkluderes hvis eksplisitt nødvendig. ### AI Act (EU) Strukturert output kan bidra til **traceability** (Art. 12): - Logg input-schema og output-schema for hver request - Enklere å demonstrere at modellen ikke produserer uventet output - Støtter risikovurdering ved å definere "tillatt" output-format ### Forvaltningsloven og forsvarlighetskrav **§ 6 (Forsvarlighetskravet):** Strukturert output øker forutsigbarheten i automatiserte vedtak: - Reduserer risiko for at LLM-output ikke kan valideres - Gjør det enklere å dokumentere hvordan AI-systemet fungerer - Støtter krav om transparens i automatiserte beslutninger **Eksempel (saksbehandling):** ```python class CaseAssessment(BaseModel): case_id: str decision: str # "approve", "reject", "manual_review" legal_basis: list[str] # Lovparagrafer reasoning: str confidence_score: float # 0.0-1.0 # Output er strukturert og kan logges/auditeres ``` ### Schrems II og datasuverenitet Strukturert output endrer ikke hvor data prosesseres, men: - Kan brukes til å **filtrere ut sensitive data** før de sendes til Azure OpenAI - Gjør det enklere å implementere "privacy-preserving prompts" **Anbefaling:** Kombiner med Azure Private Endpoint og Customer Managed Keys for maksimal kontroll. --- ## Kostnad og lisensiering ### Prismodell Strukturert output medfører **ingen ekstra kostnad** utover standard token-prising for Azure OpenAI. Du betaler for: - Input tokens (prompt + schema-definisjon) - Output tokens (JSON-strukturert output) **Observasjon:** Schema-definisjonen (JSON Schema) legges til som del av system-prompt, så den teller mot input tokens. For komplekse schemas med mange properties, kan dette øke kostnadene marginalt (typisk 50-200 tokens per request). ### Lisensiering Krever Azure OpenAI-ressurs med støttet modell (se over). Ingen spesiell lisens eller feature flag nødvendig. **Microsoft 365 Copilot:** Structured outputs er ikke tilgjengelig via M365 Copilot API per 2026-02. Må bruke Azure OpenAI direkte. --- ## For arkitekten (Cosmo) ### Spørsmål å stille kunden 1. **Datakvalitet og validering** - Hvilke datafelter er kritiske, og hvilke er "nice to have"? - Trenger dere streng validering av output, eller kan dere tolerere noe fleksibilitet? - Finnes det eksisterende JSON schemas dere bruker (OpenAPI, JSON Schema, etc.)? 2. **Workflow-kompleksitet** - Er dette en enkel "input → output"-transformasjon, eller del av en flerstegs pipeline? - Trenger dere å cache eller persistere mellomresultater? - Skal outputen integreres direkte med database, API, eller annet system? 3. **Modenhet og risikotoleranse** - Hva skjer hvis modellen ikke klarer å generere gyldig output? (fallback-strategi) - Har dere logging og monitoring for å oppdage schema-violations? - Trenger dere human-in-the-loop for kritiske beslutninger? 4. **Ytelse og kostnad** - Hva er volumet av requests? (viktig for å estimere kostnader) - Hva er akseptabel latency? (structured outputs kan være noe tregere enn fritekst) - Kan dere cache schemas på klientsiden for å redusere input tokens? 5. **Sikkerhets- og compliance-krav** - Inneholder outputen persondata eller forretningskritisk informasjon? - Må outputen logges for audit-trail (Forvaltningsloven)? - Trenger dere å filtrere ut sensitive data i output-schema? ### Fallgruver å unngå | Fallgruve | Hvorfor det skjer | Hvordan unngå | |-----------|-------------------|---------------| | **For komplekse schemas** | Over 100 properties eller 5 nestingsnivåer → request feiler | Bryt ned i mindre schemas, bruk multi-step workflow | | **Alle fields som required** | Glemmer at JSON Schema strict mode krever alle fields i `required` | Bruk `["string", "null"]` for optional fields | | **Glemmer `additionalProperties: false`** | Strict mode krever dette for alle objekter | Valider schema med tool før prod | | **Parallell function calling** | Kombinerer `strict: true` med `parallel_tool_calls: true` | Sett `parallel_tool_calls: false` eksplisitt | | **JSON Mode vs Structured Outputs** | Bruker deprecated `json_object` for GPT-4o | Migrer til `json_schema` med `strict: true` | | **Manglende feilhåndtering** | Anta at modellen alltid returnerer gyldig output | Sjekk `finish_reason` for "length" eller "content_filter" | ### Anbefalinger per modenhetsnivå #### Nivå 1: Utforsker (PoC) - Start med **enkle schemas** (< 10 properties, flat struktur) - Bruk **Pydantic** i Python for rask prototyping - Test mot **GPT-4o-mini** for kostnadseffektiv utvikling - Eksperimenter med JSON Mode først hvis dere er usikre på schema-design #### Nivå 2: Pilot (Testing i prod-lignende miljø) - Definer **strenge schemas** med alle required fields - Implementer **validering** av output (selv om structured outputs garanterer schema) - Logg **schema-violations** (hvis modellen returnerer `finish_reason: "length"`) - Mål **latency og token-forbruk** for å optimalisere #### Nivå 3: Produksjon (Skala og drift) - Bruk **caching** for schemas som gjenbrukes ofte - Implementer **fallback til JSON Mode** hvis strict mode feiler - Overvåk **error rates** og juster schemas basert på faktisk bruk - Dokumenter **schema-endringer** i API-contract (versjonering) #### Nivå 4: Optimalisert (Kontinuerlig forbedring) - Bruk **recursive schemas** for dynamiske datastrukturer (trær, grafer) - Kombiner med **function calling** for agentic workflows - Implementer **A/B-testing** av ulike schema-designs - Automatiser **schema-generering** fra eksisterende datamodeller (SQL, OpenAPI, etc.) --- ## Kilder og verifisering ### Microsoft Learn (Verified) | URL | Tema | Konfidensnivå | |-----|------|---------------| | [Structured Outputs Guide](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/structured-outputs) | Hovedguide, API-eksempler, schema-begrensninger | **Verified** (2026-02) | | [JSON Mode Guide](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/json-mode) | JSON Mode (legacy), sammenlikning med structured outputs | **Verified** (2026-02) | | [API Reference (v1)](https://learn.microsoft.com/en-us/azure/foundry/openai/latest) | REST API-detaljer, response_format konfigurasjon | **Verified** (2026-02) | | [Prompt Engineering Guide](https://learn.microsoft.com/en-us/azure/foundry/openai/concepts/prompt-engineering) | Output structure best practices | **Verified** (2026-02) | ### Azure OpenAI API-versjon - **Introduced:** `2024-08-01-preview` - **GA:** `v1` (2026-02) ### Konfidensvurdering per seksjon | Seksjon | Konfidens | Kilde | |---------|-----------|-------| | Kjernekomponenter | **Verified** | Microsoft Learn, code samples | | Arkitekturmønstre | **Baseline** | Generalisert fra best practices | | Beslutningsveiledning | **Verified** | Microsoft Learn, API docs | | Microsoft-integrasjon | **Verified** | Microsoft Learn, Semantic Kernel docs | | Offentlig sektor | **Baseline** | GDPR/AI Act-prinsipper, ikke AI-spesifikk guidance | | Kostnad og lisensiering | **Verified** | Azure OpenAI prising (2026-02) | | For arkitekten | **Baseline** | Erfaring og best practices | --- **Oppsummering:** Structured outputs er anbefalt standard for alle nye implementasjoner som krever strukturert data fra Azure OpenAI. JSON Mode bør kun brukes for legacy-støtte eller der strict schema-validering ikke er nødvendig.