教程中心进阶
进阶

用 OpenAI Realtime API 做一个能开口对话的语音智能体

2026.07.13· 7 个步骤 · 24 分钟阅读· 🎙️ OpenAI Realtime

打字太慢,对话才自然。传统语音 AI 是"听(STT)→ 想(LLM)→ 说(TTS)"三段接力,光 glue 就堆了约 600ms 延迟,还容易丢语气。OpenAI Realtime API(GPT-Realtime-2)直接在一个连接里"语音进、语音出",实测首字延迟能压到 1 秒出头。本教程用官方 OpenAI Agents SDK,带你搭一个会开口对话、能调工具、还能被中途打断的语音智能体。

🎙️ 本教程适合:会 JavaScript/Node 或 Python、想做"真语音交互"的开发者。纯零代码用户可先看本中心《用 Coze 做早安资讯 Bot》体验语音类玩法。

先搞懂:Realtime 和普通语音 AI 差在哪?

一句话:它把"听→想→说"合成了一条直通隧道,没有中间的转写再生成环节。对比一下:

方案延迟体验
STT→LLM→TTS 接力~600ms+ 额外 glue机械、容易断语气
Realtime 单连接p50 ~1.1s 往返自然、支持打断

安全红线:浏览器端绝不能直接放你的标准 API Key。Realtime 用"临时密钥(ephemeral key)",由你的后端签发、约一分钟过期,前端只拿临时密钥连。这一步不能省。

Step 1:装好 Agents SDK

1 安装 OpenAI Agents SDK(JS 版)

本教程用浏览器 + WebRTC 跑语音(最省事)。新建项目并安装推荐的包(需要 Zod v4):

# 用 Vite 起个空项目(或直接进你现有前端项目)
npm create vite@latest my-voice-agent -- --template vanilla-ts
cd my-voice-agent

# 安装 Agents SDK 与 Zod
npm install @openai/agents zod
💡 偏好 Python?官方也有 openai-agents Python 包,from agents.realtime import RealtimeAgent 用法类似。本教程以 JS 为主线,思路互通。

Step 2:后端签发临时密钥

2 临时密钥:前端连模型的"一次性门票"

在你的后端(Node/Python 都行)加一个接口,用真实 Key 换一个短命临时密钥:

// 后端示例(Node)
export async function mintEphemeralKey() {
  const res = await fetch("https://api.openai.com/v1/realtime/client_secrets", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      session: { type: "realtime", model: "gpt-realtime-2" },
    }),
  });
  const data = await res.json();
  return data.value; // 以 ek_ 开头,约 1 分钟有效
}

真实 Key 永远只在后端:临时密钥 ek_... 前端才能用,过期即废。千万别把 OPENAI_API_KEY 写进前端代码或提交到仓库。

Step 3:创建你的语音 Agent

3 定义"它是谁、该怎么说"

在前端用 RealtimeAgent 定义人设,和定义普通 Agent 很像,只是它输出的是语音:

import { RealtimeAgent } from "@openai/agents/realtime";

const agent = new RealtimeAgent({
  name: "语音小助手",
  instructions: "你是一个简洁友好的中文语音助手,回答要短、口语化,一次不超过三句话。",
  // voice 可选:alloy / echo / shimmer 等
});
🔑 语音 Agent 的人设要更口语、更短:用户是"听"不是"读",长篇大论体验很差。把"每次不超过三句话"写进 instructions 是关键。

Step 4:建立连接并开口

4 用 WebRTC 连上麦克风,开始对话

RealtimeSession 通过 WebRTC 连接(自动处理麦克风采集和扬声器播放),传入 Step 2 的临时密钥:

import { RealtimeSession } from "@openai/agents/realtime";

const session = new RealtimeSession(agent, {
  model: "gpt-realtime-2",
});

// 用后端换来的临时密钥连接
await session.connect({ apiKey: ephemeralKey });

// 连上后,直接对麦克风说话即可;
// 想用代码触发首句,也可以:
// session.sendMessage("你好,介绍一下你自己");
🚀 WebRTC 模式下,音频输入输出由 SDK 自动接管,你不用自己处理录音和播放。打开页面、授权麦克风,说句话试试,它就会回话。

Step 5:给它"动手能力"(工具调用)

5 让语音助手真能"办事"

纯聊天不够,给它挂个工具(比如查订单),对话中它就能自动调用:

const lookupOrder = {
  name: "lookup_order",
  description: "根据用户说的订单号查询状态",
  parameters: { type: "object", properties: { orderId: { type: "string" } } },
  async execute({ orderId }) {
    // 这里调你自己的后端 / 数据库
    return { orderId, status: "已发货", eta: "今天 18:00 前" };
  },
};

const agent = new RealtimeAgent({
  name: "语音小助手",
  instructions: "你是客服助手,需要查订单时调用 lookup_order 工具。",
  tools: [lookupOrder],
});

工具调用要设审批:涉及"下单、退款、发消息"等写操作,开启 async_tool_calls 并在前端用 session.approve_tool_call() 让用户确认,防止 AI 自作主张。

Step 6:处理"打断"(Barge-in)

6 用户插话时,立刻闭嘴

真人对话会打断。Realtime 原生支持:用户一开口,AI 正在说的语音会自动停止(通过 response.cancel)。WebSocket 模式下你要自己暂停采集;WebRTC 基本自动处理。关键是开启语义级语音活动检测(semantic VAD)让打断更自然:

const session = new RealtimeSession(agent, {
  model: "gpt-realtime-2",
  config: {
    audio: {
      input: { turnDetection: { type: "semantic_vad" } },
      output: { modality: "audio" },
    },
  },
});
🎉 到这一步,你已经有一个"能听、能说、能办事、还能被中途打断"的语音 Agent 了。实测首字延迟 p50 约 1.1 秒,体验已经很接近真人。

Step 7:调延迟与上线加固

7 压延迟、接电话、做生产加固

想接到电话?用 Twilio 媒体流桥接(8kHz μ-law 需重采样到 24kHz PCM16)。上线前加固清单:

加固清单:
✅ 临时密钥只在后端签发,前端绝不出现标准 Key
✅ 写操作工具开启用户审批(approve_tool_call)
✅ 设置推理强度 reasoning.effort,平衡延迟与质量
✅ 监控 Token 用量,设预算上限
✅ 异常处理:断线自动重连 + 静音检测

自己搭还是买托管?若只是做个 Demo,Realtime API 很香;若要大规模接电话、做号码管理、合规录音,Retell / Vapi / Bland 这类托管平台能省很多运维。按团队精力取舍。

常见问题速查

你遇到的现象大概率原因 & 解决
报 401 / 连接被拒前端误用了标准 Key;改用后端签发的临时密钥
说话没反应麦克风权限没授权,或 turnDetection 配置缺失
延迟明显偏高关掉不必要的工具、降低 reasoning.effort、确认 semantic_vad
WebSocket 模式静音失效WS 不自动 mute,需自己暂停 sendAudio()