Realtime WebSocket
双向音频、文本、事件与会话关闭
WebSocket 连接
wss://www.yunqiai.chat/v1/realtime?model={model}
模型 ID 为 gpt-realtime-2.1 或 gpt-realtime-2.1-mini。服务端 WebSocket 客户端在握手时发送 Authorization: Bearer <API_KEY>。Realtime 使用持续会话,与 Chat、TTS 和录音转写 HTTP 接口不同。
浏览器原生 WebSocket 无法任意设置 Authorization 请求头,因此浏览器应用需通过自己的后端中继连接。长期 API Key 保存在后端,不放入前端 URL、子协议或构建产物。本页方案不依赖临时令牌端点。
会话配置
连接后等待 session.created,再发送 GA 格式的 session.update。音频采用下例的嵌套字段,不使用旧版顶层 modalities、input_audio_format。
{
"type":"session.update",
"session":{
"type":"realtime",
"output_modalities":["audio"],
"instructions":"用中文简短回答。",
"audio":{
"input":{"format":{"type":"audio/pcm","rate":24000},"turn_detection":null},
"output":{"format":{"type":"audio/pcm","rate":24000},"voice":"marin"}
}
}
}收到 session.updated 后即可提交输入。声音和格式需在型号支持范围内,部分渠道可能不支持所有官方语音名。
文本输入
{"type":"conversation.item.create","item":{"type":"message","role":"user","content":[{"type":"input_text","text":"仅回复 READY"}]}}随后发送 {"type":"response.create","response":{"output_modalities":["text"]}} 请求纯文本回复。读取 response.output_text.delta 增量,并在 response.done 中检查 response.status。
音频输入与输出
手动轮次模式使用 turn_detection:null:
- 读取 24 kHz、单声道、16 位有符号 little-endian PCM。发送原始 PCM,不把 WAV 文件头一起当成采样。
- 分块 Base64 编码,发送
{"type":"input_audio_buffer.append","audio":"<BASE64>"}。 - 发送
input_audio_buffer.commit,等到提交确认。 - 发送
response.create。自动 VAD 模式与手动提交使用不同的轮次逻辑,不要重复触发回复。 - 将
response.output_audio.delta的 delta 解码、按顺序拼接,最终按已协商音频格式封装 WAV。
转录文字来自 response.output_audio_transcript.delta,音频需另行读取和保存。语音请求在 response.done 成功后还应检查音频数据;只有转录文字时,音频结果仍不完整。
图片与工具
图片通过 user 消息中的独立 input_image 内容块传入,不写入 input_text。工具执行前校验名称、参数和权限,执行后用 function_call_output 回传结果并保留 call_id,再创建后续 response。
生命周期与错误
记录 event_id、response_id 和结束状态,并处理 error、握手 HTTP 错误、close code / reason、超时及中断。response.done 返回 failed、cancelled、incomplete 时按相应异常处理。关闭前保存已完成输出,重连不会自动恢复旧会话。
重放音频或工具调用前需确认不会重复执行。用户打断时取消当前 response,并按实际播放进度更新服务端对话项,排除尚未播放的音频。
Node.js 程序见 realtime.mjs,依赖 ws 并从环境变量读取 Key,无需 Bun。WebSocket 事件见本页,不包含在 HTTP OpenAPI 中。