The realtime recipe in the Agora Conversational AI recipes family. Voice-to-voice conversation using a single OpenAI Realtime MLLM — no separate STT, LLM, or TTS. Speak, and hear the model respond directly.
Not zero-key — OPENAI_API_KEY with Realtime API access is required.
Pipeline: OpenAIRealtime MLLM via .with_mllm() (server_vad turn detection)
- Python 3.10+
- Bun
- Agora CLI — makes generating an App ID + App Certificate easy
- OpenAI API key with Realtime API access — set as
OPENAI_API_KEYinserver/.env.local
The same commands work on macOS, Linux, and Windows. On macOS/Linux, setup uses
python3; on Windows, it uses the Python launcher (py) or python. WSL and
virtualenv activation are not required.
# 1. Install web deps + create the Python venv
bun run setup
# 2. Add Agora credentials (CLI), or edit server/.env.local by hand
agora login
agora project use <your-project> # select which project to use
agora project env write server/.env.local # writes App ID + Certificate
# 3. Add your OpenAI Realtime API key to server/.env.local
# OPENAI_API_KEY=sk-... (required — OpenAI Realtime access)
# OPENAI_MODEL=gpt-4o-realtime-preview (optional, this is the default)
# 4. Run backend + web
bun run devOpen http://localhost:3000 → Start Conversation → speak.
If you cloned this repo (rather than scaffolding via the Agora CLI), the steps
above are complete as written: bun run setup creates the Python venv and
installs web dependencies, then bun run dev brings up both services. You
still need Agora credentials and OPENAI_API_KEY in server/.env.local before
a conversation can connect.
Services:
- Frontend — http://localhost:3000
- Backend — http://localhost:8000
- Mock LLM — N/A (the realtime MLLM handles voice end-to-end)
- API docs — http://localhost:8000/docs
Deploy web (Next.js) and server (a reachable FastAPI backend). Set
AGENT_BACKEND_URL in the web deployment so the Next rewrites reach the backend.
A backend-only Docker image is published to
ghcr.io/AgoraIO-Conversational-AI/recipe-agent-realtime on v* tags.
It exposes BACKEND-ONLY (:8000). No separate service is needed.
Backend env file: server/.env.example.
| Variable | Required | Default | Notes |
|---|---|---|---|
AGORA_APP_ID |
✅ | — | Agora Console → Project → App ID |
AGORA_APP_CERTIFICATE |
✅ | — | Agora Console → Project → App Certificate |
OPENAI_API_KEY |
✅ | — | BYO OpenAI key with Realtime API access. Validated at agent start. |
OPENAI_MODEL |
gpt-4o-realtime-preview |
OpenAI Realtime model name | |
AGENT_GREETING |
built-in | Optional opening line override |
bun run setup # install web deps + create server/ venv
bun run dev # run backend (:8000) + web (:3000)
bun run doctor # prerequisite check (no creds needed)
bun run doctor:local # + .env.local + credentials checks
bun run verify # web-only gate (no Agora creds needed)
bun run verify:local # full local gate: backend compile + smoke tests + web build
bun run clean # remove venvs and build artifactsTests run standalone (no Agora cloud needed): pytest in server/, plus
bun run verify in web/. CI runs them on Linux/macOS/Windows × Python 3.10 & 3.13.
Browser (localhost:3000)
│ fetch /api/*
▼
Next.js ──rewrite──▶ Agent backend (server/, localhost:8000)
│ starts agent session (OpenAIRealtime MLLM)
▼
Agora ConvoAI Cloud
│ OpenAI Realtime (voice-to-voice, server_vad)
▼
User hears realtime voice response
No cascading STT/LLM/TTS vendors. No llm/ service.
See ARCHITECTURE.md.
- A Next.js web client (:3000) that drives the RTC/RTM lifecycle and only ever calls
/api/*. - A FastAPI agent backend (:8000) that owns Agora token generation and the agent session lifecycle.
- The
/api/get_config·/api/startAgent·/api/stopAgentcontract between the web client and the backend (Next rewrites, no Route Handlers). - OpenAI Realtime MLLM attached via
.with_mllm()— replaces the cascading STT→LLM→TTS with a single voice-to-voice model. - Server-side VAD (
server_vad) turn detection — owned by the MLLM, no top-level cascading VAD config needed. - BYO key —
OPENAI_API_KEYis required; validated at agent start.
- The browser calls
/api/get_config, which Next rewrites to the backend; the backend mints an Agora token fromAGORA_APP_ID+AGORA_APP_CERTIFICATE. - The browser joins the RTC channel, then calls
/api/startAgent; the backend validatesOPENAI_API_KEYand starts an agent session usingOpenAIRealtime. - The user speaks. Agora routes audio to the OpenAI Realtime endpoint.
- OpenAI Realtime processes voice-to-voice and streams the response audio back.
- The agent's voice plays in the channel. RTM transcript + metrics arrive in the web UI.
/api/stopAgentends the session.
web/— Next.js frontend (:3000); RTC/RTM lifecycle and UI.server/— FastAPI agent backend (:8000); Agora tokens + agent lifecycle, OpenAI Realtime MLLM.ARCHITECTURE.md— system shape and component boundaries.AGENTS.md— guide for coding agents working in this repo.
| Problem | Fix |
|---|---|
/startAgent returns 400 |
Check OPENAI_API_KEY is set and has OpenAI Realtime API access. |
| Agent starts but no audio | Ensure the model (OPENAI_MODEL) supports realtime voice. |
| Local calls fail under a global proxy (Clash, etc.) | Configure your proxy to send 127.0.0.1, localhost, and RFC-1918 ranges DIRECT. |
Released under the MIT License.