Courses
我们的 GPT-Realtime-2 概览文章已覆盖发布信息、基准测试结论,以及 OpenAI 为何将实时语音拆分为一个小型模型家族。本教程从该文的终点开始:连接 API、发送音频,并观察代码中的变化。
这种拆分在实践中很重要。测试 1 使用 gpt-realtime-whisper 进行转写,测试 2 使用 gpt-realtime-translate 进行同声传译,测试 3 使用 gpt-realtime-2 构建语音助手。主模型也能胜任翻译或转写等更简单的任务,但您会为并不必要的推理能力和多种响应模式付费,显得大材小用。
在 Python 中设置 GPT-Realtime-2 API
在开始测试前,先将传输方式、认证方式和音频格式分开考虑。这些细节在各示例中大多保持一致。随着文章从文本输出到翻译语音,再到完整的语音循环,变化的是模型端点和事件名称。
在 WebRTC 与 WebSocket 之间选择
OpenAI 文档给出了一个简单规则:在浏览器和移动端使用 WebRTC,在 WebSockets 上构建服务端应用。WebRTC 负责抖动缓冲和音频传输。当后端已从电话系统或媒体流水线接收原始音频时,WebSocket 更合适。

Realtime API 的两条传输路径。图片由作者提供。
基于上述原因,三项 Python 测试均使用 WebSocket。这一路径能直接看到事件名称,从而在代码中清楚地对比不同模型。若是浏览器构建,请使用临时的客户端密钥,避免将 API Key 暴露到前端。
Python 环境与依赖包
使用 Python 3.9 或更高版本。四个脚本的完整代码可在 github.com/KhalidAbdelaty/gpt-realtime-api 获取。先克隆仓库,再安装依赖:
git clone https://github.com/KhalidAbdelaty/gpt-realtime-api.git
cd gpt-realtime-api
pip install websocket-client sounddevice numpy python-dotenv
websocket-client 用于处理套接字;sounddevice 用于捕获麦克风音频;numpy 用于缓冲区转换; python-dotenv 用于加载 API Key。在 macOS 上,可能需要先运行 brew install portaudio 才能使用 sounddevice;在 Linux 上,请安装 portaudio19-dev。
在项目根目录创建 .env 文件:
OPENAI_API_KEY=sk-...
然后在每个脚本中加载:
import os
from dotenv import load_dotenv
load_dotenv()
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
认证与 WebSocket URL
服务端连接在 WebSocket 握手中使用 Authorization: Bearer 头。若应用跟踪单个用户,则添加 OpenAI-Safety-Identifier。以下是后续测试使用的路径:
# Voice agent
wss://api.openai.com/v1/realtime?model=gpt-realtime-2
# Translation
wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate
# Transcription
wss://api.openai.com/v1/realtime?intent=transcription
该翻译路径在测试 2 中很关键,因为它是唯一不直接使用 /v1/realtime 的端点。
测试 1:使用 GPT-Realtime-Whisper 的实时音频转写
转写是最容易过度设计的场景之一。若输出只是文本,转写模型已足够。
测试目标
gpt-realtime-whisper 接收音频并输出逐步的转写增量。它不会进行推理、调用工具或回话。这一更小的工作范围也是其按音频时长计费、而非按 gpt-realtime-2 所用的同一令牌模型计费的原因。成本章节会再谈价格。
代码讲解
关键字段是 session.type: "transcription"。它告诉 API 跳过助手响应,只发出转写事件。完整脚本还处理麦克风采集与线程。这部分改变了 Realtime 会话的行为:
session_config = {
"type": "session.update",
"session": {
"type": "transcription",
"audio": {
"input": {
"format": {"type": "audio/pcm", "rate": 24000},
"transcription": {
"model": "gpt-realtime-whisper",
"language": "en"
},
"turn_detection": None
}
}
}
}
ws.send(json.dumps(session_config))
ws.send(json.dumps({
"type": "input_audio_buffer.append",
"audio": audio_b64
}))
ws.send(json.dumps({"type": "input_audio_buffer.commit"}))
使用 24 kHz PCM16 单声道音频,base64 编码。与语音助手会话不同,该脚本按计时器手动提交输入缓冲,而不是使用 server_vad 进行轮次检测。空提交会触发 input_audio_buffer_commit_empty,因此完整脚本只会在发送了真实音频后才提交。

转写增量会逐词实时到达。图片由作者提供。
观察到的行为
在本地测试中,转写结果会在提交窗口内出现,大约在讲话开始后 3 至 4 秒。由于此设置依赖手动提交而非 VAD,时延与提交间隔相关。
另外要注意顺序:重叠轮次的完成事件可能乱序到达,如果要在 UI 中呈现流式结果,请按 item_id 对齐。

转写由周期性的手动提交触发,而非由静音检测触发。图片由作者提供。
结论:通过。 对于服务端实时转写,gpt-realtime-whisper 满足了本测试需求。但在设定时延目标前,仍建议用真实麦克风、口音和房间噪声进行测试。
测试 2:使用 GPT-Realtime-Translate 的实时翻译
实时语音翻译乍看与转写相似,但会话生命周期不同。翻译端点移除了助手响应循环,使示例更简洁。
测试目标
翻译会话没有助手轮次循环,也不使用 response.create。该模型充当同声传译,而非对话代理。若需要问答、工具或对话状态,测试 3 将切换至 gpt-realtime-2。

翻译会话使用专用且独立的端点。图片由作者提供。
该模型支持 70 多种输入语言和 13 种输出语言。您通过 session.audio.output.language 设置目标语言;源语言自动检测。限制也很明确:不支持自定义提示、不可选配音、也不支持领域词汇表。
代码讲解
前文已提到,翻译使用 /translations WebSocket URL。还有两处变化:session.audio.output.language 目标字段,以及 session.input_audio_buffer.append 事件名称。请注意 session. 前缀。翻译会话在此处使用它。
url = "wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate"
session_config = {
"type": "session.update",
"session": {
"audio": {
"output": {"language": "es"},
"input": {
"transcription": {"model": "gpt-realtime-whisper"},
"noise_reduction": {"type": "near_field"}
}
}
}
}
ws.send(json.dumps(session_config))
ws.send(json.dumps({
"type": "session.input_audio_buffer.append",
"audio": audio_b64
}))
译后音频通过 session.output_audio.delta 到达,其音频字节位于 event["delta"],而非 event["audio"]。源转写与译文转写分别到达:
if event_type == "session.output_audio.delta":
audio_out_queue.put(base64.b64decode(event["delta"]))
elif event_type == "session.input_transcript.delta":
print("[EN]", event.get("delta", ""), end="")
elif event_type == "session.output_transcript.delta":
print("[ES]", event.get("delta", ""), end="")
一个边缘情况:如果源音频本就是目标语言,模型可能会输出静音而不是原样透传。
观察到的行为
对于简短的英译西短语,译后音频会在源语句结束前开始播放。终端会随着流式增量交织显示 [EN] 与 [ES] 行。语言差异更大的组合可能会为上下文等待更久。我能顺畅地跟随译后语音,但不支持自定义声音。
结论:通过,但有注意事项。 gpt-realtime-translate 适合直接的实时翻译。当需要术语管控或品牌化语音时,实用性会降低。
测试 3:构建支持轮流发言与插话的语音助手
这是一项 gpt-realtime-2 测试:构建一个能聆听、发声、保持上下文并可调用工具的语音代理。此处客户端代码的重要性也提升,因为播放与轮次状态可能不同步。
测试目标
gpt-realtime-2 是一个语音到语音的推理模型。它避免了单独的 STT-LLM-TTS 流水线,其 128K 上下文窗口也为长会话提供了空间。通过 reasoning.effort 控制推理强度;除非任务需要更强推理,否则从 low 开始,因为更高设置会增加时延。
代码讲解
下面的设置使用 semantic_vad,它基于语音线索而不只是静音。eagerness 控制模型多快判定用户已说完。需要关注的部分包括模型名称、音频输出设置、手动 response.create,以及助手音频事件名称:
session_config = {
"type": "session.update",
"session": {
"type": "realtime",
"model": "gpt-realtime-2",
"output_modalities": ["audio"],
"audio": {
"input": {
"format": {"type": "audio/pcm", "rate": 24000},
"transcription": {"model": "gpt-realtime-whisper", "language": "en"},
"turn_detection": {
"type": "semantic_vad",
"eagerness": "medium",
"create_response": False,
"interrupt_response": True
}
},
"output": {
"format": {"type": "audio/pcm", "rate": 24000},
"voice": "marin"
}
},
"instructions": "You are a helpful voice assistant. Keep answers short.",
"reasoning": {"effort": "low"}
}
}
当用户转写完成后,客户端创建助手响应。随后助手音频以 response.output_audio.delta 到达,而不是 response.audio.delta。
if event_type == "conversation.item.input_audio_transcription.completed":
ws.send(json.dumps({"type": "response.create"}))
elif event_type == "response.output_audio.delta":
audio_out_queue.put(base64.b64decode(event["delta"]))
处理插话(Barge-In)
中断序列很容易出错。当用户打断助手说话时,服务器会发送 input_audio_buffer.speech_started。客户端应停止播放,记录已播放的时长,并发送带有 audio_end_ms 的 conversation.item.truncate,以标记被截断的位置。否则,服务器会继续转写用户未曾听到的文本,下一轮会感觉不对劲。
if current_response_item_id and playback_position_ms > 0:
ws.send(json.dumps({
"type": "conversation.item.truncate",
"item_id": current_response_item_id,
"content_index": 0,
"audio_end_ms": playback_position_ms
}))
使用笔记本扬声器的一个实际问题是:麦克风可能会拾取助手的音频输出并回传给模型。示例脚本使用 MUTE_MIC_DURING_ASSISTANT = True 在助手说话期间以及短暂冷却期内静音输入流。仅当使用耳机且需要中断支持时,才将其设为 False。

截断操作让服务器与客户端保持同步。图片由作者提供。
WebRTC 与 SIP 会处理更多缓冲。在本教程使用的 WebSocket 路径下,责任在客户端。示例脚本中的计数器足够支撑演示;生产代码应基于音频输出流的时间戳进行跟踪。
为推理时延配置开场语
当 reasoning.effort 高于 low 时,静默会更明显。可以在系统提示中加入简短的开场口播:
# Preambles
Use a short spoken update before longer tasks.
Keep preambles under five seconds.
Skip preambles for short factual questions.
此行为在 gpt-realtime-2 文档中有所说明。
观察到的行为
在安静环境中,默认设置下的轮流发言表现良好。使用笔记本扬声器时,我需要开启麦克风静音;否则模型会听到自己的输出并形成回声循环。
在更嘈杂的房间里,VAD 设置与麦克风摆放更为关键。十分钟测试中对话记忆保持一致,但若要发布更长时长的应用,我不会忽略重连方案。
结论:核心语音循环通过。 在测试中,gpt-realtime-2 能胜任低推理强度的助手。额外工作主要在客户端:播放、插话处理、重连,以及需要时的工具调用。
Streamlit 演示:一个界面集成三种模型
该 Streamlit 应用将测试置于选项卡选择器后。您可以录制音频、选择目标语言,并在不修改脚本的情况下对比不同模型路径。我将其保留为演示应用而非主要教学路径,因为终端脚本能更直观地展示事件。

三种模型,一套分栏界面。图片由作者提供。
下方演示视频展示了在有效 API Key 下的各个标签页。每个标签都使用真实的 Realtime WebSocket 调用。
从脚本所在的同一文件夹运行应用:
streamlit run demo_app.py
您的 API Key 填写在侧边栏中,且不会被存储。若公开发布应用,请将其放入 Streamlit Secrets。
GPT-Realtime-2 的实际成本与时延
如测试 1 所述,定价分为两组:gpt-realtime-2 按令牌计费,而翻译与转写按分钟计费。

不同模型的按令牌与按分钟计费。图片由作者提供。
对于转写与翻译,成本随时长线性增长。撰写本文时,30 分钟在 gpt-realtime-whisper 上约为 $0.51,在 gpt-realtime-translate 上约为 $1.02。
语音代理的估算更难,因为会话双方都会累积音频令牌。会话长度、说话比例、推理强度以及上下文大小都会影响成本。若早期对话轮次较稳定,提示缓存可降低费用。
除非必须实时交互,否则将 REST 转写调用与 TTS 进行比较是另一回事。对于文件,whisper-1 更便宜,但它不是同类 API。
GPT-Realtime-2 API 限制、音频要求与故障排查
以下是影响我首次测试运行的限制。大多数失败源于音频格式或会话生命周期错误,而非模型本身。
传输与音频约束
如第一项测试所述,WebSocket 音频应为 24 kHz 的 PCM16、单声道并以 base64 编码。每个 input_audio_buffer.append 事件上限为 15 MB,因此 50 毫秒分片可远低于限制。也支持用于电话的 G.711。
Realtime 会话在 OpenAI 上 60 分钟结束,在 Azure OpenAI 上为 30 分钟。更长的应用需要重连方案以及重建状态的方式。语音也必须在首次音频输出前选定;会话中途不可切换。
速率限制与配额
速率限制基于级别并与项目相关。当前第 1 级针对 gpt-realtime-2 列出了每分钟 200 次请求与每分钟 40,000 个令牌。不支持免费层。
常见错误与毛刺
我最常遇到的错误是空缓冲提交和错误的音频格式。对于语音代理,还要注意麦克风拾取助手扬声器输出引发的回授环路。请使用耳机、回声消除或麦克风静音。
对于长会话,请在约第 55 分钟进行重连,而不是等到过期。还有一处文档细节:gpt-realtime-2 模型页有一行通用的“Streaming: Not supported”,而 Realtime 指南则记录了对 /v1/realtime 的使用。该行指的是 Chat Completions 的流式,不是 Realtime API 的行为。
最终结论
三项测试呈现出相同的模式:每个任务都有对应的模型与端点。这样的拆分会影响模型能力、计费方式,以及您需要承担的客户端代码量。
如上所示,gpt-realtime-whisper 负责实时文本,gpt-realtime-translate 负责直接语音翻译,gpt-realtime-2 负责带语音、推理与上下文的助手行为。
代码并未展示某个模型可取代其他模型;它表明实时语音应用依赖会话设计。我的起点会是与任务最匹配的最小模型,其余工程时间则花在音频质量、轮流发言、重连与客户端状态上。
如需更多背景,我们的教程涵盖相关的音频与 Realtime API 主题: