# Real-Time Audio API for Conversational AI

**Last updated:** 2026-02
**Status:** GA
**Category:** Multi-Modal AI

---

## 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
- **Direktoratetet**: Talebasert rettleiing for førarkort og køyretøytenester

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

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