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>
415 lines
14 KiB
Markdown
415 lines
14 KiB
Markdown
# Real-Time Audio API for Conversational AI
|
|
|
|
**Last updated:** 2026-02
|
|
**Status:** GA
|
|
**Category:** Multi-Modal AI
|
|
**Type:** reference
|
|
|
|
---
|
|
|
|
## Innhold
|
|
|
|
- [Introduksjon](#introduksjon)
|
|
- [Kjernekomponentar](#kjernekomponentar)
|
|
- [Støtta modellar](#støtta-modellar)
|
|
- [Session Management og State Tracking](#session-management-og-state-tracking)
|
|
- [Audio Codec-val og bandbreiddeoptimalisering](#audio-codec-val-og-bandbreiddeoptimalisering)
|
|
- [Interruption og Turn-Taking](#interruption-og-turn-taking)
|
|
- [Deployment og Scaling Patterns](#deployment-og-scaling-patterns)
|
|
- [Norsk offentleg sektor](#norsk-offentleg-sektor)
|
|
- [Beslutningsrammeverk](#beslutningsrammeverk)
|
|
- [For arkitekten](#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
|
|
|
|
```python
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```python
|
|
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:
|
|
|
|
```python
|
|
# 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:
|
|
|
|
1. **Stoppe pågåande audioavspeling** — Trunkere assistenten sin respons
|
|
2. **Synkronisere samtaletilstand** — Klient og server må vere i sync
|
|
3. **Starte ny respons** — Basert på brukarens avbryting
|
|
|
|
```python
|
|
# 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:
|
|
|
|
```python
|
|
# 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
|
|
|
|
```python
|
|
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
|