ms-ai-architect/skills/ms-ai-engineering/references/multi-modal/real-time-audio-api.md
Kjell Tore Guttormsen 3a73eeafdc refactor(ms-ai-architect): R13 del 1 — nøytraliser Cosmo-personaen i ref-korpusets headinger, etter å ha rettet en gate som var målt usann to ganger
Ordre 20260912T193441Z-7358817909. Steg 1 var ikke transformen, men å rette
roadmapens R13-gate og få den ratifisert. Gaten `grep -rl "Cosmo"
skills/*/references -> 0` var usann på to uavhengige måter:

1. Ordren fanget den første: 451 av forekomstene er Azure Cosmos DB, ekte
   produktinnhold. Diskriminatoren er ikke bokstaven «s» — `Cosmos <norsk
   substantiv>` er genitiv av personaen (`### Cosmos tonalitet`), mens
   `Cosmos DB`/`CosmosClient`/`cosmos_ru` er produkt.
2. Denne økten fant den andre: 132 persona-forekomster ligger i prosa,
   tabeller, dialog-replikker og proveniens-linjer. Heading-nøytralisering
   kan ikke nå dem, så «0 persona» er uoppnåelig også under den ratifiserte
   formen. Operatøren ratifiserte alternativ A: gaten speiler formen, og de
   132 bokføres til R13b/R14.

Tre korreksjoner av premisser som sto i ordren og STATE:
  «ca 320 produkt»   -> 451 (case-sensitivt nett manglet 327 lowercase
                        TOC-ankre + 99 identifikatorer; sann nevner 1 638)
  «169 headinger»    -> 401. 169 var `^## For Cosmo`-prefikset (168) og var
                        internt inkonsistent med sin egen topp-variant (204)
  «417 matcher ingen
   populasjon»       -> 417 er cosmo-headinger utenfor kodefences; briefens
                        nevner var reell hele tiden

Fence-bevissthet er målt skadelig, ikke nødvendig: begge toggle-regler er
gale på dette korpuset (naiv toggle skjuler en ekte heading i
chain-of-thought-prompting.md, CommonMark-regelen ubalanserer
service-level-documentation-dr.md). Fence-agnostisk deteksjon finner 401
heading-linjer i nøyaktig de samme 40 variantene som fence-bevisst finner
400 i — ingen kodeblokk-linje er byte-identisk til en persona-heading. Derfor
nøkles transformen på 40 enumererte heading-tekster og ignorerer fences. En
ukjent variant kaster; en slug-kollisjon kaster. Ingenting auto-fikses.

TOC-en regenereres ikke, den rettes kirurgisk: alle 327 persona-lenker hadde
lenketekst lik én av de 40 heading-tekstene og anker lik slugify av den
(327/327, 0 avvik), så heading og TOC-entry skrives i samme operasjon og
ingen mellomtilstand etterlater en død lenke.

Ratifisert målform: `For Cosmo`, `For Cosmo Skyberg` og `For arkitekten
(Cosmo)` konvergerer på `For arkitekten`. To filer kolliderte og er adjudisert
ved å lese dem, ikke ved regel.

Verifisering (alle 7 kriterier fra ordren):
  G1 persona på heading-linjer   401 -> 0
  G2 døde fragmentlenker         1 -> 1 (pre-eksisterende, unntatt)
  G3 produkt-forekomster         451 -> 451; `Cosmos DB|Azure Cosmos` 308 = 308
  de 3 kun-produkt-filene        byte-identiske
  nettet validert begge veier    injisert persona feller G1; genitiv feller G1;
                                 produkt-heading og de 3 filene passerer
  hele diffen                    802 heading-linjer + 654 TOC-linjer, ANNET = 0
  linjeantall                    728 lagt til = 728 slettet
  suite                          1120/1120 (1097 + 23 nye)
  validate-plugin                250 PASS / 0 FAIL
  stikkprøve                     10 filer, alle 5 skills, inkl. de 3 mest
                                 produkt-tunge (26/20/19) — kun heading+TOC

Utenfor scope, urørt: de 4 SKILL.md, de 23 commands, CLAUDE.md, README.md,
NOTICE.md, docs/ (alt R14).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 22:12:28 +02:00

14 KiB

Real-Time Audio API for Conversational AI

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


Innhold

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:

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