feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command
Add /ultraresearch-local for structured research combining local codebase analysis with external knowledge via parallel agent swarms. Produces research briefs with triangulation, confidence ratings, and source quality assessment. New command: /ultraresearch-local with modes --quick, --local, --external, --fg. New agents: research-orchestrator (opus), docs-researcher, community-researcher, security-researcher, contrarian-researcher, gemini-bridge (all sonnet). New template: research-brief-template.md. Integration: --research flag in /ultraplan-local accepts pre-built research briefs (up to 3), enriches the interview and exploration phases. Planning orchestrator cross-references brief findings during synthesis. Design principle: Context Engineering — right information to right agent at right time. Research briefs are structured artifacts in the pipeline: ultraresearch → brief → ultraplan --research → plan → ultraexecute. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
baa2d0220b
488 changed files with 213221 additions and 0 deletions
|
|
@ -0,0 +1,446 @@
|
|||
# Structured Output and JSON Mode
|
||||
|
||||
**Last updated:** 2026-02
|
||||
**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** | `minLength`, `maxLength`, `pattern`, `minimum`, `maximum`, `patternProperties`, m.fl. |
|
||||
|
||||
**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
|
||||
|
||||
### Azure AI Foundry / Azure OpenAI
|
||||
|
||||
**API-versjon:** Structured outputs introdusert i `2024-08-01-preview`, tilgjengelig i GA-versjon `v1`.
|
||||
|
||||
**Støttede modeller (per 2026-02):**
|
||||
- **GPT-5-serien:** gpt-5.1, gpt-5.1-codex, gpt-5-pro, gpt-5-mini, gpt-5-nano
|
||||
- **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)
|
||||
|
||||
### 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/ai-foundry/openai/how-to/structured-outputs) | Hovedguide, API-eksempler, schema-begrensninger | **Verified** (2026-02) |
|
||||
| [JSON Mode Guide](https://learn.microsoft.com/en-us/azure/ai-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/ai-foundry/openai/latest) | REST API-detaljer, response_format konfigurasjon | **Verified** (2026-02) |
|
||||
| [Prompt Engineering Guide](https://learn.microsoft.com/en-us/azure/ai-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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue