OpenAI 实时对话接口
OpenAI 实时对话接口
📝 概述
简介
1.
2.
使用场景
主要特性
🔐 认证与安全
认证方式
1.
2.
临时令牌
安全建议
🔌 连接建立
WebRTC 连接
https://yibuapi.com/v1/realtime
model
Authorization: Bearer EPHEMERAL_KEY
Content-Type: application/sdp
WebSocket 连接
wss://yibuapi.com/v1/realtime
model
Authorization: Bearer YOUR_API_KEY
OpenAI-Beta: realtime=v1
连接流程
数据通道
oai-events
音频流
addTrack()
ontrack
事件💬 对话交互
对话模式
1.
2.
3.
会话管理
事件类型
⚙️ 配置选项
音频配置
pcm16
g711_ulaw
g711_alaw
pcm16
g711_ulaw
g711_alaw
alloy
echo
shimmer
模型配置
VAD 配置
💡 请求示例
WebRTC 连接 ❌
客户端实现 (浏览器)
服务器端实现 (Node.js)
WebRTC 事件收发示例
WebSocket 连接 ✅
Node.js (ws模块)
Python (websocket-client)
浏览器 (标准WebSocket)
消息收发示例
Node.js/浏览器
Python
⚠️ 错误处理
常见错误
1.
2.
3.
错误恢复
1.
2.
3.
4.
📝 事件参考
通用请求头
请求头 | 类型 | 说明 | 示例值 |
---|---|---|---|
Authorization | 字符串 | 认证令牌 | Bearer $NEW_API_KEY |
OpenAI-Beta | 字符串 | API 版本 | realtime=v1 |
客户端事件
session.update
参数 | 类型 | 必需 | 说明 | 示例值/可选值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_123 |
type | 字符串 | 否 | 事件类型 | session.update |
modalities | 字符串数组 | 否 | 模型可以响应的模态类型 | ["text", "audio"] |
instructions | 字符串 | 否 | 预置到模型调用前的系统指令 | "Your knowledge cutoff is 2023-10..." |
voice | 字符串 | 否 | 模型使用的语音类型 | alloy、echo、shimmer |
input_audio_format | 字符串 | 否 | 输入音频格式 | pcm16、g711_ulaw、g711_alaw |
output_audio_format | 字符串 | 否 | 输出音频格式 | pcm16、g711_ulaw、g711_alaw |
input_audio_transcription.model | 字符串 | 否 | 用于转写的模型 | whisper-1 |
turn_detection.type | 字符串 | 否 | 语音检测类型 | server_vad |
turn_detection.threshold | 数字 | 否 | VAD 激活阈值(0.0-1.0) | 0.8 |
turn_detection.prefix_padding_ms | 整数 | 否 | 语音开始前包含的音频时长 | 500 |
turn_detection.silence_duration_ms | 整数 | 否 | 检测语音停止的静音持续时间 | 1000 |
tools | 数组 | 否 | 模型可用的工具列表 | [] |
tool_choice | 字符串 | 否 | 模型选择工具的方式 | auto/none/required |
temperature | 数字 | 否 | 模型采样温度 | 0.8 |
max_output_tokens | 字符串/整数 | 否 | 单次响应最大token数 | "inf"/4096 |
input_audio_buffer.append
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_456 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.append |
audio | 字符串 | 否 | Base64编码的音频数据 | Base64EncodedAudioData |
input_audio_buffer.commit
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_789 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.commit |
input_audio_buffer.clear
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_012 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.clear |
conversation.item.create
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_345 |
type | 字符串 | 否 | 事件类型 | conversation.item.create |
previous_item_id | 字符串 | 否 | 新对话项将插入在此ID之后 | null |
item.id | 字符串 | 否 | 对话项的唯一标识符 | msg_001 |
item.type | 字符串 | 否 | 对话项类型 | message/function_call/function_call_output |
item.status | 字符串 | 否 | 对话项状态 | completed/in_progress/incomplete |
item.role | 字符串 | 否 | 消息发送者的角色 | user/assistant/system |
item.content | 数组 | 否 | 消息内容 | [text/audio/transcript] |
item.call_id | 字符串 | 否 | 函数调用的ID | call_001 |
item.name | 字符串 | 否 | 被调用的函数名称 | function_name |
item.arguments | 字符串 | 否 | 函数调用的参数 | {"param": "value"} |
item.output | 字符串 | 否 | 函数调用的输出结果 | {"result": "value"} |
conversation.item.truncate
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_678 |
type | 字符串 | 否 | 事件类型 | conversation.item.truncate |
item_id | 字符串 | 否 | 要截断的助手消息项的ID | msg_002 |
content_index | 整数 | 否 | 要截断的内容部分的索引 | 0 |
audio_end_ms | 整数 | 否 | 音频截断的结束时间点 | 1500 |
conversation.item.delete
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_901 |
type | 字符串 | 否 | 事件类型 | conversation.item.delete |
item_id | 字符串 | 否 | 要删除的对话项的ID | msg_003 |
response.create
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_234 |
type | 字符串 | 否 | 事件类型 | response.create |
response.modalities | 字符串数组 | 否 | 响应的模态类型 | ["text", "audio"] |
response.instructions | 字符串 | 否 | 给模型的指令 | "Please assist the user." |
response.voice | 字符串 | 否 | 模型使用的语音类型 | alloy/echo/shimmer |
response.output_audio_format | 字符串 | 否 | 输出音频格式 | pcm16 |
response.tools | 数组 | 否 | 模型可用的工具列表 | ["type", "name", "description"] |
response.tool_choice | 字符串 | 否 | 模型选择工具的方式 | auto |
response.temperature | 数字 | 否 | 采样温度 | 0.7 |
response.max_output_tokens | 整数/字符串 | 否 | 最大输出token数 | 150/"inf" |
response.cancel
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 客户端生成的事件标识符 | event_567 |
type | 字符串 | 否 | 事件类型 | response.cancel |
服务端事件
error
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串数组 | 否 | 服务端事件的唯一标识符 | ["event_890"] |
type | 字符串 | 否 | 事件类型 | error |
error.type | 字符串 | 否 | 错误类型 | invalid_request_error/server_error |
error.code | 字符串 | 否 | 错误代码 | invalid_event |
error.message | 字符串 | 否 | 人类可读的错误消息 | "The 'type' field is missing." |
error.param | 字符串 | 否 | 与错误相关的参数 | null |
error.event_id | 字符串 | 否 | 相关事件的ID | event_567 |
conversation.item.input_audio_transcription.completed
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_2122 |
type | 字符串 | 否 | 事件类型 | conversation.item.input_audio_transcription.completed |
item_id | 字符串 | 否 | 用户消息项的ID | msg_003 |
content_index | 整数 | 否 | 包含音频的内容部分的索引 | 0 |
transcript | 字符串 | 否 | 转写的文本内容 | "Hello, how are you?" |
conversation.item.input_audio_transcription.failed
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_2324 |
type | 字符串数组 | 否 | 事件类型 | ["conversation.item.input_audio_transcription.failed"] |
item_id | 字符串 | 否 | 用户消息项的ID | msg_003 |
content_index | 整数 | 否 | 包含音频的内容部分的索引 | 0 |
error.type | 字符串 | 否 | 错误类型 | transcription_error |
error.code | 字符串 | 否 | 错误代码 | audio_unintelligible |
error.message | 字符串 | 否 | 人类可读的错误消息 | "The audio could not be transcribed." |
error.param | 字符串 | 否 | 与错误相关的参数 | null |
conversation.item.truncated
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_2526 |
type | 字符串 | 否 | 事件类型 | conversation.item.truncated |
item_id | 字符串 | 否 | 被截断的助手消息项的ID | msg_004 |
content_index | 整数 | 否 | 被截断的内容部分的索引 | 0 |
audio_end_ms | 整数 | 否 | 音频被截断的时间点(毫秒) | 1500 |
conversation.item.deleted
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_2728 |
type | 字符串 | 否 | 事件类型 | conversation.item.deleted |
item_id | 字符串 | 否 | 被删除的对话项的ID | msg_005 |
input_audio_buffer.committed
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_1121 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.committed |
previous_item_id | 字符串 | 否 | 新对话项将插入在此ID对应的对话项之后 | msg_001 |
item_id | 字符串 | 否 | 将要创建的用户消息项的ID | msg_002 |
input_audio_buffer.cleared
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_1314 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.cleared |
input_audio_buffer.speech_started
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_1516 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.speech_started |
audio_start_ms | 整数 | 否 | 从会话开始到检测到语音的毫秒数 | 1000 |
item_id | 字符串 | 否 | 语音停止时将创建的用户消息项的ID | msg_003 |
input_audio_buffer.speech_stopped
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_1718 |
type | 字符串 | 否 | 事件类型 | input_audio_buffer.speech_stopped |
audio_start_ms | 整数 | 否 | 从会话开始到检测到语音停止的毫秒数 | 2000 |
item_id | 字符串 | 否 | 将要创建的用户消息项的ID | msg_003 |
response.created
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_2930 |
type | 字符串 | 否 | 事件类型 | response.created |
response.id | 字符串 | 否 | 响应的唯一标识符 | resp_001 |
response.object | 字符串 | 否 | 对象类型 | realtime.response |
response.status | 字符串 | 否 | 响应的状态 | in_progress |
response.status_details | 对象 | 否 | 状态的附加详细信息 | null |
response.output | 字符串数组 | 否 | 响应生成的输出项列表 | ["[]"] |
response.usage | 对象 | 否 | 响应的使用统计信息 | null |
response.done
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_3132 |
type | 字符串 | 否 | 事件类型 | response.done |
response.id | 字符串 | 否 | 响应的唯一标识符 | resp_001 |
response.object | 字符串 | 否 | 对象类型 | realtime.response |
response.status | 字符串 | 否 | 响应的最终状态 | completed/cancelled/failed/incomplete |
response.status_details | 对象 | 否 | 状态的附加详细信息 | null |
response.output | 字符串数组 | 否 | 响应生成的输出项列表 | ["[...]"] |
response.usage.total_tokens | 整数 | 否 | 总token数 | 50 |
response.usage.input_tokens | 整数 | 否 | 输入token数 | 20 |
response.usage.output_tokens | 整数 | 否 | 输出token数 | 30 |
response.output_item.added
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_3334 |
type | 字符串 | 否 | 事件类型 | response.output_item.added |
response_id | 字符串 | 否 | 输出项所属的响应ID | resp_001 |
output_index | 字符串 | 否 | 输出项在响应中的索引 | 0 |
item.id | 字符串 | 否 | 输出项的唯一标识符 | msg_007 |
item.object | 字符串 | 否 | 对象类型 | realtime.item |
item.type | 字符串 | 否 | 输出项类型 | message/function_call/function_call_output |
item.status | 字符串 | 否 | 输出项状态 | in_progress/completed |
item.role | 字符串 | 否 | 与输出项关联的角色 | assistant |
item.content | 数组 | 否 | 输出项的内容 | ["type", "text", "audio", "transcript"] |
response.output_item.done
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_3536 |
type | 字符串 | 否 | 事件类型 | response.output_item.done |
response_id | 字符串 | 否 | 输出项所属的响应ID | resp_001 |
output_index | 字符串 | 否 | 输出项在响应中的索引 | 0 |
item.id | 字符串 | 否 | 输出项的唯一标识符 | msg_007 |
item.object | 字符串 | 否 | 对象类型 | realtime.item |
item.type | 字符串 | 否 | 输出项类型 | message/function_call/function_call_output |
item.status | 字符串 | 否 | 输出项的最终状态 | completed/incomplete |
item.role | 字符串 | 否 | 与输出项关联的角色 | assistant |
item.content | 数组 | 否 | 输出项的内容 | ["type", "text", "audio", "transcript"] |
response.content_part.added
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_3738 |
type | 字符串 | 否 | 事件类型 | response.content_part.added |
response_id | 字符串 | 否 | 响应的ID | resp_001 |
item_id | 字符串 | 否 | 添加内容部分的消息项ID | msg_007 |
output_index | 整数 | 否 | 输出项在响应中的索引 | 0 |
content_index | 整数 | 否 | 内容部分在消息项内容数组中的索引 | 0 |
part.type | 字符串 | 否 | 内容类型 | text/audio |
part.text | 字符串 | 否 | 文本内容 | "Hello" |
part.audio | 字符串 | 否 | Base64编码的音频数据 | "base64_encoded_audio_data" |
part.transcript | 字符串 | 否 | 音频的转写文本 | "Hello" |
response.content_part.done
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_3940 |
type | 字符串 | 否 | 事件类型 | response.content_part.done |
response_id | 字符串 | 否 | 响应的ID | resp_001 |
item_id | 字符串 | 否 | 添加内容部分的消息项ID | msg_007 |
output_index | 整数 | 否 | 输出项在响应中的索引 | 0 |
content_index | 整数 | 否 | 内容部分在消息项内容数组中的索引 | 0 |
part.type | 字符串 | 否 | 内容类型 | text/audio |
part.text | 字符串 | 否 | 文本内容 | "Hello" |
part.audio | 字符串 | 否 | Base64编码的音频数据 | "base64_encoded_audio_data" |
part.transcript | 字符串 | 否 | 音频的转写文本 | "Hello" |
response.text.delta
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_4142 |
type | 字符串 | 否 | 事件类型 | response.text.delta |
response_id | 字符串 | 否 | 响应 的ID | resp_001 |
item_id | 字符串 | 否 | 消息项的ID | msg_007 |
output_index | 整数 | 否 | 输出项在响应中的索引 | 0 |
content_index | 整数 | 否 | 内容部分在消息项内容数组中的索引 | 0 |
delta | 字符串 | 否 | 文本增量更新内容 | "Sure, I can h" |
response.text.done
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_4344 |
type | 字符串 | 否 | 事件类型 | response.text.done |
response_id | 字符串 | 否 | 响应的ID | resp_001 |
item_id | 字符串 | 否 | 消息项的ID | msg_007 |
output_index | 整数 | 否 | 输出项在响应中的索引 | 0 |
content_index | 整数 | 否 | 内容部分在消息项内容数组中的索引 | 0 |
delta | 字符串 | 否 | 最终的完整文本内容 | "Sure, I can help with that." |
response.audio_transcript.delta
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_4546 |
type | 字符串 | 否 | 事件类型 | response.audio_transcript.delta |
response_id | 字符串 | 否 | 响应的ID | resp_001 |
item_id | 字符串 | 否 | 消息项的ID | msg_008 |
output_index | 整数 | 否 | 输出项在响应中的索引 | 0 |
content_index | 整数 | 否 | 内容部分在消息项内容数组中的索引 | 0 |
delta | 字符串 | 否 | 转写文本的增量更新内容 | "Hello, how can I a" |
response.audio_transcript.done
参数 | 类型 | 必需 | 说明 | 示例值 |
---|---|---|---|---|
event_id | 字符串 | 否 | 服务端事件的唯一标识符 | event_4748 |
type | 字符串 | 否 | 事件类型 | response.audio_transcript.done |
response_id | 字符串 | 否 | 响应的ID | resp_001 |
item_id | 字符串 | 否 | 消息项的ID | msg_008 |
output_index | 整数 | 否 |