ms-ai-architect/skills/ms-ai-engineering/references/rag-architecture/streaming-rag-responses.md
Kjell Tore Guttormsen baa2d0220b 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>
2026-04-08 08:58:35 +02:00

435 lines
17 KiB
Markdown

# Streaming and Real-Time RAG Responses
**Last updated:** 2026-02
**Status:** GA
**Category:** RAG Architecture & Semantic Search
---
## Introduksjon
Streaming av RAG-responser innebærer å returnere generert innhold token-for-token eller i små chunks mens modellen prosesserer, fremfor å vente på hele svaret. Dette gir dramatisk redusert opplevd latency og bedre brukeropplevelse ved at tekst vises progressivt på samme måte som ChatGPT og andre moderne AI-grensesnitt.
I tradisjonelle RAG-implementeringer sender klienten en forespørsel, systemet søker i vektordatabasen, augmenterer prompten med kontekst, og LLM-en genererer et komplett svar før noe returneres. Dette kan ta flere sekunder eller minutter for komplekse spørsmål. Med streaming begynner teksten å vises umiddelbart etter første token er generert, noe som gir brukeren tilbakemelding om at systemet arbeider og lar dem begynne å lese svaret mens resten genereres.
Azure OpenAI Service støtter streaming via Server-Sent Events (SSE) i både Chat Completions API og den nyere Responses API. SSE er en HTTP-basert protokoll som holder en langvarig forbindelse åpen og sender datachunks til klienten etterhvert som de blir tilgjengelige. For RAG-applikasjoner betyr dette at retrieval-fasen skjer først (vanligvis ikke-streamet), deretter starter streaming av generert tekst umiddelbart når LLM-en begynner å produsere output.
## Kjernekomponenter
### Server-Sent Events (SSE)
SSE er den primære teknologien for streaming fra Azure OpenAI:
| Komponent | Beskrivelse |
|-----------|-------------|
| **Protokoll** | Enveiskommunikasjon over HTTP (server → klient) |
| **Content-Type** | `text/event-stream` |
| **Event format** | `data: <JSON>\n\n` per event |
| **Avslutning** | `data: [DONE]` signal når streaming er ferdig |
| **Forbindelse** | Langvarig HTTP-tilkobling med `Connection: keep-alive` |
| **Chunk-kodning** | `Transfer-Encoding: chunked` uten Content-Length |
### Azure OpenAI Streaming API
**Chat Completions API** (`stream: true`):
- Enkleste implementasjon for streaming
- Returnerer `ChatCompletionChunk` objekter
- Hver chunk inneholder delta med ny tekst (`choices[0].delta.content`)
- Støtter function calling (argumenter streams også)
- Eksempel response: `{"choices":[{"delta":{"content":"Hello"},"index":0}]}`
**Responses API** (`stream: true`):
- Nyere API som kombinerer Chat Completions og Assistants
- Støtter både synkron og asynkron (background) streaming
- Event-basert format: `response.output_text.delta`
- Kan gjenoppta streaming fra en `sequence_number` ved avbrudd
- Støtter stateful conversations med `previous_response_id`
### Streaming Content Types
I Semantic Kernel Agent Framework brukes spesialiserte content-typer:
| Type | Formål |
|------|--------|
| `StreamingChatMessageContent` | Container for streaming-meldinger |
| `StreamingTextContent` | Token-by-token tekstchunks |
| `StreamingFileReferenceContent` | Filreferanser under streaming |
| `StreamingAnnotationContent` | Metadata og citations i stream |
### Client-side Buffering
Progressive rendering krever håndtering av:
- **Partial tokens** — inkomplette ord eller JSON-strukturer
- **UI updates** — effektiv re-render av chunks uten flimmering
- **Function calls** — pause i streaming når modellen kaller en funksjon
- **Error handling** — reconnect-logikk ved avbrudd
## Arkitekturmønstre
### Mønster 1: Standard RAG med Chat Completions Streaming
**Bruk når:** Enkel RAG-applikasjon med Azure Cognitive Search eller annen vektordb.
**Fordeler:**
- Enklest å implementere (én API-kall med `stream=true`)
- Lavest latency fra første token til bruker
- Kompatibel med alle Azure OpenAI modeller
**Ulemper:**
- Retrieval-fasen er ikke streambar (må vente på søkeresultater før streaming starter)
- Ingen innebygd støtte for gjenopptagelse ved avbrudd
**Arkitektur:**
```
User Query → Azure Cognitive Search (vector search)
→ Prompt augmentation (inject context)
→ Azure OpenAI Chat Completions (stream=true)
→ SSE stream → Client (progressive display)
```
**Implementering:**
```python
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
# 1. Retrieval phase (ikke streamet)
search_results = azure_search_client.search(query, top=5)
context = "\n".join([doc['content'] for doc in search_results])
# 2. Augmentation + streaming generation
messages = [
{"role": "system", "content": f"Answer based on: {context}"},
{"role": "user", "content": query}
]
stream = client.chat.completions.create(
model="gpt-4o",
messages=messages,
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end='', flush=True)
```
### Mønster 2: Responses API med Background Streaming
**Bruk når:** Lange prosesser (reasoning modeller, kompleks research) som kan ta minutter.
**Fordeler:**
- Unngår timeouts på langvarige operasjoner
- Kan gjenoppta streaming fra `sequence_number` ved avbrudd
- Støtter async workflows (brukeren kan komme tilbake senere)
**Ulemper:**
- Høyere time-to-first-token latency enn synkron streaming
- Krever polling-logikk eller WebSocket for status-oppdateringer
**Arkitektur:**
```
User Query → RAG retrieval → Responses API (background=true, stream=true)
→ Poll status (in_progress) → Resume stream fra sequence_number
→ Display chunks progressivt → Final status (completed)
```
**Implementering:**
```python
# Start background streaming response
response = client.responses.create(
model="o3",
input=augmented_prompt,
background=True,
stream=True
)
cursor = None
for event in response:
if event.type == 'response.output_text.delta':
print(event.delta, end='', flush=True)
cursor = event["sequence_number"]
# Ved avbrudd: gjenoppta fra cursor
# GET /responses/{response_id}?stream=true&starting_after={cursor}
```
### Mønster 3: Semantic Kernel Agent med Callback
**Bruk når:** RAG med function calling, multi-turn conversations, behov for å håndtere intermediate steps.
**Fordeler:**
- Håndterer function call results i streaming-flyten
- Callback for intermediate messages (tool calls, partial results)
- Innebygd support i Semantic Kernel Agent Framework
**Ulemper:**
- Mer kompleks setup (krever agent framework)
- Overhead fra framework kan øke latency marginalt
**Arkitektur:**
```
User → Agent (invoke_stream) → RAG retrieval (via function)
→ Streaming response + callback for function results
→ Progressive display + intermediate step logging
```
**Implementering:**
```python
from semantic_kernel.agents import AzureResponsesAgent
async def handle_intermediate(message: ChatMessageContent) -> None:
for item in message.items:
if isinstance(item, FunctionResultContent):
print(f"Retrieved: {item.result[:100]}...")
async for response in agent.invoke_stream(
messages=user_input,
thread=thread,
on_intermediate_message=handle_intermediate
):
print(response.content, end='', flush=True)
```
## Beslutningsveiledning
### Velg Streaming-mønster
| Scenario | Anbefalt mønster | Begrunnelse |
|----------|------------------|-------------|
| RAG med Azure Cognitive Search, < 10s responstid | Chat Completions streaming | Enklest, lavest latency |
| RAG med reasoning modeller (o3, o1-pro), > 1 min | Responses API background streaming | Unngår timeouts |
| Agentic RAG med function calling | Semantic Kernel Agent | Callback-støtte for intermediate steps |
| RAG med flere søk (multi-hop) | Responses API stateful | Reuse context med `previous_response_id` |
| Real-time RAG med WebSocket | Custom med SSE → WebSocket bridge | Bedre browser-support, bidireksjonell kommunikasjon |
### Vanlige feil
| Feil | Symptom | Løsning |
|------|---------|---------|
| **Buffer timeout** | Stream stopper midt i token | Sett `request_timeout > 120s` i backend settings |
| **UI flimmering** | Tekst hopper eller blinker | Bruk React/Vue streaming-biblioteker (react-markdown streaming) |
| **Connection drop** | Stream mister forbindelse | Implementer reconnect med `sequence_number` resume |
| **Partial JSON** | Function call argumenter er inkomplette | Buffer chunks til `finish_reason == "function_call"` |
| **Cache interference** | CDN cacher SSE-responser | Sett `Cache-Control: no-cache` header |
### Røde flagg
- **Streaming før retrieval er ferdig** — vises som tomme eller irrelevante første tokens
- **Ingen progress indicator** — brukeren tror systemet har hengt seg
- **Manglende error streaming** — errors bør også vises progressivt (ikke bare status 500)
- **Synkron retrieval i async context** — blokkerer streaming-start
## Integrasjon med Microsoft-stakken
### Azure OpenAI Service
| Feature | Support | Notes |
|---------|---------|-------|
| **Chat Completions streaming** | GA | `stream=true` parameter |
| **Responses API streaming** | GA | Event-based format |
| **Background streaming** | GA | For o3, o1-pro modeller |
| **Resume streaming** | GA | Via `sequence_number` |
| **Function calling streaming** | GA | Arguments streams token-by-token |
### Azure Application Gateway
For SSE-trafikk gjennom Application Gateway:
**Kritiske innstillinger:**
- **Response buffers** — må være `disabled` (ellers bufres hele responsen)
- **Request timeout** — sett > streaming-forventet tid (f.eks. 300s)
- **Backend headers** — `Connection: keep-alive`, `Transfer-Encoding: chunked`
**Konfigurasjon:**
```json
{
"backendHttpSettings": {
"requestTimeout": 300,
"responseBuffering": false
}
}
```
### Azure API Management
SSE-konfigurasjon krever:
- **Route timeout** — øk fra standard 30s til 300s+
- **No caching** — disable cache policies for SSE endpoints
- **Passthrough mode** — ikke transformer SSE events
### Semantic Kernel
**Agent Framework** (C#, Python):
```python
from semantic_kernel.agents import ChatCompletionAgent
agent = ChatCompletionAgent(...)
async for response in agent.invoke_stream(message, thread):
# response er StreamingChatMessageContent
print(response.content, end='', flush=True)
```
**ChatHistory oppdateres** kun etter full response er mottatt (ikke per chunk).
### Power Platform
**Power Automate** støtter ikke native SSE-streaming. Workaround:
- Bruk polling-flow (sjekk status hver 2s)
- Eller WebSocket via Azure Functions bridge
**Copilot Studio** støtter streaming via SSE for custom connectors (preview).
## Offentlig sektor (Norge)
### Network Policies
SSE krever langvarige HTTP-forbindelser som kan trigge firewall-regler:
| Policy | Anbefaling |
|--------|------------|
| **Idle timeout** | Min. 300s for SSE-forbindelser |
| **Connection limits** | Whitelist Azure OpenAI FQDN for lengre forbindelser |
| **Proxy compatibility** | Test med organisasjonens proxy (noen buffer SSE) |
| **TLS requirements** | TLS 1.2+ (SSE over HTTPS) |
**Kompetanse Norges nettverk:** Hvis proxy buffer disabler SSE, bruk Azure API Management som mellommann med custom buffering.
### Tilgjengelighet (WCAG)
Streaming text må være skjermleser-vennlig:
- **ARIA live regions** — `aria-live="polite"` på streaming-container
- **Focus management** — ikke flytt focus mens tekst streams
- **Pause/resume** — brukeren må kunne pause streaming (tilgjengelighetskrav)
- **Skip to end** — shortcut for å hoppe til ferdig svar
**Eksempel:**
```html
<div role="log" aria-live="polite" aria-atomic="false">
<!-- Streaming text appends here -->
</div>
```
### Personvern (GDPR)
Streaming påvirker logging:
- **Ikke logg partial responses** — vent til `[DONE]` før logging
- **Redaction** — PII-filtrering må skje server-side før streaming starter
- **Audit trail** — logg `sequence_number` for replay-evne
## Kostnad og lisensiering
### Prismodell
Streaming koster **det samme per token** som ikke-streaming:
| Modell | Input (NOK/1K tokens) | Output (NOK/1K tokens) |
|--------|----------------------|------------------------|
| **gpt-4o** | ~0.28 | ~1.12 |
| **gpt-4o-mini** | ~0.014 | ~0.056 |
| **o3** (reasoning) | ~1.68 | ~6.72 |
**Kostnadsoptimalisering:**
- Stream kun når bruker venter (ikke for background jobs)
- Bruk `max_tokens` for å begrense lange responses
- Cache retrieval-resultater (reduserer total tokens ved re-prompts)
### Code Interpreter (Responses API)
Ved bruk av streaming med `code_interpreter` tool:
- **Tilleggskostnad:** 0.28 NOK/session (utover tokens)
- **Session lifetime:** 1 time (idle timeout 20 min)
- **Simultane sessions:** Hver parallel streaming med code_interpreter = ny session
### Lisenskrav
| Tjeneste | Lisenskrav |
|----------|------------|
| **Azure OpenAI** | Azure subscription + OpenAI resource |
| **Semantic Kernel** | Open source (MIT) — ingen lisenskostnad |
| **Application Gateway** | Azure-kostnad (per gateway-time) |
| **API Management** | Per call/måned tier (Consumption for lavt volum) |
## For arkitekten (Cosmo)
### Spørsmål å stille kunden
1. **Forventet responstid?** — Hvis > 30s, vurder background streaming.
2. **Brukerkontekst?** — Chatbot (streaming obligatorisk) vs. batch report (streaming unødvendig).
3. **Network environment?** — Proxy, firewall, idle timeouts kan blokkere SSE.
4. **Function calling?** — Krever callback-logikk for å håndtere intermediate steps.
5. **Mobile vs. web?** — Mobile app kan ha ustabil forbindelse → trenger resume-logikk.
6. **WCAG-krav?** — Streaming må være pause-bar og skjermleser-kompatibel.
7. **Error handling?** — Hvordan skal partial failures vises? (stream error chunks vs. abort)
8. **Token budget?** — Streaming gjør det vanskelig å stoppe ved token-limit (pre-calculate max_tokens).
### Fallgruver
| Fallgruve | Konsekvens | Unngå ved |
|-----------|------------|-----------|
| **Stream før retrieval** | Tomme/irrelevante første tokens | Buffer retrieval-resultater før streaming starter |
| **Ingen reconnect-logikk** | Brukeren ser halvferdig svar | Implementer `sequence_number` resume |
| **Synkron I/O i async context** | Blokkerer streaming | Bruk `asyncio` i Python, `async/await` i C# |
| **Manglende `Cache-Control`** | CDN cacher SSE | Sett `no-cache` header på backend |
| **Ingen progress feedback** | Brukeren venter uten tilbakemelding | Vis spinner til første chunk arrives |
### Anbefalinger per modenhetsnivå
**Nivå 1 (POC):**
- Bruk Chat Completions API med `stream=true`
- Ignorer error handling (fail fast)
- Bruk `print()` for debugging (console output)
**Nivå 2 (Pilot):**
- Implementer reconnect-logikk med timeout
- Legg til ARIA live regions for tilgjengelighet
- Test med organisasjonens proxy/firewall
**Nivå 3 (Produksjon):**
- Bruk Responses API med background streaming for lange prosesser
- Implementer full observability (logg sequence_number, latency per chunk)
- A/B-test streaming vs. ikke-streaming for UX-gevinst
- Set opp Application Gateway med optimale SSE-innstillinger
**Nivå 4 (Skalering):**
- Implementer custom WebSocket-bridge for bedre mobile support
- Bruk Azure SignalR for multi-region streaming med fallback
- Implementer adaptive streaming (juster chunk-størrelse basert på nettverkshastighet)
## Kilder og verifisering
### Verified (fra MCP microsoft-learn)
- Azure OpenAI Responses API streaming: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/responses (Verified: 2026-02)
- Semantic Kernel Agent streaming: https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/agent-streaming (Verified: 2026-02)
- SSE med Application Gateway: https://learn.microsoft.com/en-us/azure/application-gateway/use-server-sent-events (Verified: 2026-02)
- Azure OpenAI REST API reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference (Verified: 2026-02)
- Chat Completions API streaming: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference#chat-completions (Verified: 2026-02)
### Baseline (modellkunnskap)
- SSE standard (W3C EventSource): Baseline (standard protocol knowledge)
- WebSocket vs. SSE tradeoffs: Baseline (industry best practices)
- React streaming patterns: Baseline (frontend framework knowledge)
- WCAG streaming requirements: Baseline (accessibility standards)
**Konfidensnivå per seksjon:**
- Introduksjon: High (Verified via Responses API docs)
- Kjernekomponenter: High (Verified via REST API reference + Semantic Kernel docs)
- Arkitekturmønstre: High (Verified code samples from microsoft-learn)
- Beslutningsveiledning: Medium (Kombinasjon av verified patterns + experience-based)
- Integrasjon med Microsoft-stakken: High (Verified via Application Gateway + API Management docs)
- Offentlig sektor: Medium (Verified network policies + baseline tilgjengelighet)
- Kostnad: High (Verified via Azure OpenAI pricing 2026-02)
- For arkitekten: Medium (Experience-based best practices)
---
*Denne kunnskapsreferansen er generert med MCP microsoft-learn search/fetch (2026-02) og representerer siste tilgjengelige dokumentasjon fra Microsoft Learn.*