ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-engineering/references/rag-architecture/streaming-rag-responses.md
Kjell Tore Guttormsen 6a7632146e feat(ms-ai-architect): add plugin to open marketplace (v1.5.0 baseline)
Initial addition of ms-ai-architect plugin to the open-source marketplace.
Private content excluded: orchestrator/ (Linear tooling), docs/utredning/
(client investigation), generated test reports and PDF export script.
skill-gen tooling moved from orchestrator/ to scripts/skill-gen/.

Security scan: WARNING (risk 20/100) — no secrets, no injection found.
False positive fixed: added gitleaks:allow to Python variable reference
in output-validation-grounding-verification.md line 109.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 17:17:17 +02:00

17 KiB

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:

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:

# 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:

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 headersConnection: keep-alive, Transfer-Encoding: chunked

Konfigurasjon:

{
  "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):

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 regionsaria-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:

<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)

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.