Reference files, test fixtures, the playground demo project and one design document now use generic, fictitious examples (buildings, energy, water, grants, municipal services). The playground demo (17 fixtures plus the embedded demo state) tells one consistent story: a municipal customer chatbot that pre-screens housing-benefit applications, classified under Annex III point 5(a). The embedded demo copies were edited in place rather than regenerated, because they already carry newer AI Act dates than the fixture files. Legal text is unchanged. Test semantics are unchanged. Four dark-theme onboarding screenshots with outdated placeholder text are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
14 KiB
Real-Time Audio API for Conversational AI
Last updated: 2026-02 Status: GA Category: Multi-Modal AI Type: reference
Innhold
- Introduksjon
- Kjernekomponentar
- Støtta modellar
- Session Management og State Tracking
- Audio Codec-val og bandbreiddeoptimalisering
- Interruption og Turn-Taking
- Deployment og Scaling Patterns
- Norsk offentleg sektor
- Beslutningsrammeverk
- For arkitekten
Introduksjon
Azure OpenAI GPT Realtime API er ein del av GPT-4o-modellfamilien som støttar låg-latency "speech in, speech out" samtaleinteraksjonar. API-et er designa for sanntids bruksscenario som kundeserviceagentar, taleassistentar og sanntidstolkar, der rask respons er kritisk for brukaropplevinga.
Realtime API tilbyr tre transportmekanismar: WebRTC for klientside-applikasjonar med minimal latency, WebSocket for server-til-server-scenario, og SIP for integrasjon med telefonisystem. For dei fleste bruksscenario tilrår Microsoft WebRTC, som er designa spesifikt for låg-latency sanntids audiostreaming.
For norsk offentleg sektor opnar Realtime API moglegheiter for talebaserte borgartenester, tilgjengelege grensesnitt for personar med funksjonshemmingar, og automatiserte telefontenester. API-et støttar norsk via GPT-4o sin fleirspråklege kapabilitet, noko som gjer det relevant for NAV sin telefoniteneste, kommunale servicesentra og andre offentlege kontaktpunkt.
Kjernekomponentar
| Komponent | Formål | Teknologi |
|---|---|---|
| GPT Realtime API | Låg-latency tale-til-tale interaksjon | Azure OpenAI GPT-4o Realtime |
| WebRTC Transport | Klientside audiostreaming | WebRTC Protocol |
| WebSocket Transport | Server-til-server kommunikasjon | WebSocket Protocol |
| SIP Transport | Telefoniintegrasjon | Session Initiation Protocol |
| Voice Activity Detection | Automatisk taledeteksjon | Innebygd VAD |
| Session Management | Tilstandshandtering per samtale | Realtime API Sessions |
Støtta modellar
| Modell | Versjon | Tilgjengelegheit |
|---|---|---|
gpt-4o-realtime-preview |
2024-12-17 | Global Deployment |
gpt-4o-mini-realtime-preview |
2024-12-17 | Global Deployment |
gpt-realtime |
2025-08-28 | Global Deployment |
gpt-realtime-mini |
2025-10-06 | Global Deployment |
gpt-realtime-mini-2025-12-15 |
2025-12-15 | Global Deployment |
Session Management og State Tracking
Sesjonsarkitektur
Kvar sesjon har ein aktiv samtale (conversation) som akkumulerer input-signal til ein respons blir trigga — enten via eksplisitt event frå klienten eller automatisk via Voice Activity Detection (VAD).
Samtalesekvens
Klient Server
| |
| session.create |
|------------------------------>|
| session.created |
|<------------------------------|
| conversation.created |
|<------------------------------|
| |
| conversation.item.create |
|------------------------------>|
| conversation.item.created |
|<------------------------------|
| |
| response.create |
|------------------------------>|
| response.audio.delta |
|<------------------------------|
| response.audio.delta |
|<------------------------------|
| response.done |
|<------------------------------|
Python WebSocket-implementering
import asyncio
import json
import websockets
from azure.identity import DefaultAzureCredential
async def realtime_conversation():
"""Etabler ein Realtime API-sesjon via WebSocket."""
credential = DefaultAzureCredential()
token = credential.get_token(
"https://cognitiveservices.azure.com/.default"
)
url = (
"wss://<resource>.openai.azure.com/openai/realtime"
"?api-version=2025-04-01-preview"
"&deployment=gpt-4o-realtime-preview"
)
headers = {
"Authorization": f"Bearer {token.token}"
}
async with websockets.connect(url, extra_headers=headers) as ws:
# Konfigurer sesjon
await ws.send(json.dumps({
"type": "session.update",
"session": {
"modalities": ["text", "audio"],
"instructions": (
"Du er ein norsk kundeserviceagent for Direktoratet for digital tjenesteutvikling. "
"Svar på norsk. Ver høfleg og presis."
),
"voice": "alloy",
"input_audio_format": "pcm16",
"output_audio_format": "pcm16",
"turn_detection": {
"type": "server_vad",
"threshold": 0.5,
"prefix_padding_ms": 300,
"silence_duration_ms": 500
}
}
}))
# Lytt etter responsar
async for message in ws:
event = json.loads(message)
if event["type"] == "response.audio.delta":
# Spel av audio-chunk
audio_data = event["delta"]
await play_audio(audio_data)
elif event["type"] == "response.audio_transcript.delta":
# Vis transkripsjon i sanntid
print(event["delta"], end="", flush=True)
elif event["type"] == "response.done":
print("\n[Respons ferdig]")
JavaScript WebRTC-implementering
import { RTClient } from "rt-client";
import { DefaultAzureCredential } from "@azure/identity";
async function startRealtimeSession() {
const credential = new DefaultAzureCredential();
const client = new RTClient(
new URL("https://<resource>.openai.azure.com/"),
credential,
{ deployment: "gpt-4o-realtime-preview" }
);
// Konfigurer sesjon
await client.configure({
modalities: ["text", "audio"],
instructions: "Du er ein norsk serviceagent. Svar på norsk.",
voice: "alloy",
turn_detection: {
type: "server_vad",
threshold: 0.5,
silence_duration_ms: 500
}
});
// Start mikrofon-streaming
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioTrack = stream.getAudioTracks()[0];
client.sendAudio(audioTrack);
// Handter responsar
client.on("response.audio.delta", (event) => {
// Spel av mottatt audio
audioPlayer.appendBuffer(event.delta);
});
client.on("response.audio_transcript.done", (event) => {
console.log("Agent sa:", event.transcript);
});
}
Audio Codec-val og bandbreiddeoptimalisering
Støtta audioformat
| Format | Retning | Eigenskapar |
|---|---|---|
| PCM16 | Input/Output | 24kHz, 16-bit, mono. Lågast latency |
| G.711 u-law | Input/Output | 8kHz. Telefonikompatibelt |
| G.711 A-law | Input/Output | 8kHz. Europeisk telefonistandard |
Bandbreiddeestimering
| Format | Bitrate | Bruksscenario |
|---|---|---|
| PCM16 24kHz | ~384 kbps | Høgkvalitets samtale |
| G.711 8kHz | ~64 kbps | Telefoni, låg bandbreidde |
Optimalisering for norske forhold
def select_audio_config(network_conditions):
"""Vel audioformat basert på nettverkstilhøve."""
if network_conditions["bandwidth_kbps"] > 500:
return {
"input_audio_format": "pcm16",
"output_audio_format": "pcm16",
"sample_rate": 24000,
"quality": "high"
}
elif network_conditions["bandwidth_kbps"] > 100:
return {
"input_audio_format": "g711_ulaw",
"output_audio_format": "g711_ulaw",
"sample_rate": 8000,
"quality": "telephony"
}
else:
return {
"input_audio_format": "g711_alaw",
"output_audio_format": "g711_alaw",
"sample_rate": 8000,
"quality": "low_bandwidth"
}
Interruption og Turn-Taking
Voice Activity Detection (VAD)
Server-side VAD handterer automatisk turskifte i samtalen:
# VAD-konfigurasjon
vad_config = {
"type": "server_vad",
"threshold": 0.5, # Sensitivitet (0.0-1.0)
"prefix_padding_ms": 300, # Audio før talestart
"silence_duration_ms": 500 # Pauselengde for turskifte
}
Avbrytingshandtering
Når brukaren avbryt agenten, må systemet:
- Stoppe pågåande audioavspeling — Trunkere assistenten sin respons
- Synkronisere samtaletilstand — Klient og server må vere i sync
- Starte ny respons — Basert på brukarens avbryting
# Trunkering av pågåande respons
await ws.send(json.dumps({
"type": "conversation.item.truncate",
"item_id": current_response_item_id,
"content_index": 0,
"audio_end_ms": current_playback_position_ms
}))
# Vente på server-bekreftelse
# Server sender conversation.item.truncated
Manuell Turn Management
For scenario der automatisk VAD ikkje er tilstrekkeleg:
# Deaktiver VAD for manuell kontroll
session_config = {
"turn_detection": None # Manuell turskifte
}
# Klient kontrollerer turskifte eksplisitt
await ws.send(json.dumps({
"type": "input_audio_buffer.commit"
}))
# Be om respons eksplisitt
await ws.send(json.dumps({
"type": "response.create"
}))
Deployment og Scaling Patterns
Arkitekturmønster for produksjon
Brukarar
|
v
Azure Front Door (Global Load Balancing)
|
v
Azure API Management (Rate limiting, Auth)
|
v
WebRTC/WebSocket Gateway
|
├── GPT-4o Realtime (Region: Norway East)
├── GPT-4o Realtime (Region: Sweden Central)
└── GPT-4o Realtime (Region: West Europe)
Scaling-strategi
| Dimensjon | Tilnærming |
|---|---|
| Concurrent sessions | Global deployment med automatisk lastfordeling |
| Geographic distribution | Multi-region for låg latency |
| Session stickiness | WebSocket connections bound til region |
| Failover | Automatisk rerouting ved regionsfeil |
Kostnadsoversikt
def estimate_realtime_cost(sessions_per_day, avg_duration_minutes):
"""Estimerer kostnader for Realtime API."""
# Prisar per 1M tokens (estimat, sjekk aktuell prisliste)
input_cost_per_1m = 100 # USD per 1M audio input tokens
output_cost_per_1m = 200 # USD per 1M audio output tokens
# Ca. 1500 tokens per minutt tale
tokens_per_minute = 1500
daily_input_tokens = sessions_per_day * avg_duration_minutes * tokens_per_minute * 0.6
daily_output_tokens = sessions_per_day * avg_duration_minutes * tokens_per_minute * 0.4
daily_cost_usd = (
(daily_input_tokens / 1_000_000) * input_cost_per_1m +
(daily_output_tokens / 1_000_000) * output_cost_per_1m
)
return {
"dagleg_kostnad_usd": daily_cost_usd,
"dagleg_kostnad_nok": daily_cost_usd * 11, # Ca. valutakurs
"månadleg_kostnad_nok": daily_cost_usd * 11 * 30
}
Norsk offentleg sektor
Bruksscenario
- NAV kontaktsenter: Automatisert talebasert rettleiing for ytingar og søknader
- Kommunale servicesentra: 24/7 talebasert borgarservice
- Helsevesenet: Triageringssamtalar med automatisk dokumentasjon
- Skatteetaten: Talebasert rettleiing for skattekort og skattemelding
Regulatoriske krav
| Krav | Tiltak |
|---|---|
| GDPR artikkel 22 | Informer brukar om automatisert avgjerd |
| Forvaltingslova § 11a | Brukar har rett til å snakke med eit menneske |
| Språklova | Støtt både bokmål og nynorsk |
| Samisk språklov | Vurder samisk støtte for relevante tenester |
| Content filtering | Innhaldsfiltrering er aktivert for tekst, men ikkje for audio |
Viktig avgrensing
Innhaldsfiltreringssystemet i Azure OpenAI blir ikkje brukt på prompts og completions prosessert av audiomodellar som Whisper og Realtime API. Dette betyr at organisasjonen må implementere eigne innhaldsfilter for audiopipelines.
Beslutningsrammeverk
| Scenario | Anbefaling | Begrunnelse |
|---|---|---|
| Web-app med sanntidstale | WebRTC transport | Lågast latency, klient-optimalisert |
| Server-til-server integrasjon | WebSocket transport | Full kontroll, server-side logikk |
| Telefoniintegrasjon | SIP transport | Direkte integrasjon med PBX |
| Høg-volum kundesenter | gpt-realtime-mini | Lågare kostnad, tilstrekkeleg kvalitet |
| Komplekse rådgivingssamtalar | gpt-realtime | Betre resonnering og kontekst |
| Sensitive samtalar (helse) | WebSocket + manuell VAD | Full kontroll over dataflyt |
For arkitekten
- GPT Realtime API er designa for låg-latency "speech in, speech out" — bruk WebRTC for klient-applikasjonar (lågast latency) og WebSocket for server-til-server (meir kontroll)
- SIP-transport muliggjer direkte integrasjon med eksisterande telefonisystem — relevant for NAV, kommunale servicesentra og andre offentlege kontaktpunkt med telefonibasert borgarservice
- Voice Activity Detection (VAD) med konfigurerbar sensitivitet handterer turskifte automatisk — juster
silence_duration_ms(500ms standard) for norsk taleflyt - Innhaldsfiltrering gjeld IKKJE for audio — implementer eigne filter for sensitive bruksscenario i offentleg sektor, spesielt helse og rettsvesen
- gpt-realtime-mini gir 60-70% lågare kostnad enn full gpt-realtime — evaluer om kvaliteten er tilstrekkeleg for enklare bruksscenario som FAQ og rettleiing