切换日光/暗黑模式
OpenAI 兼容层
实时语音
WebSocket 长连接,双向实时语音:你说它听、它说你听,不用等一轮请求结束。模型是 grok-voice-latest。
WSS
/wss:/api.wxiai.com/v1/realtime端点
WSS /v1/realtime?model=grok-voice-latest
POST /v1/realtime/client_secrets # 换临时凭证(不计费)这是 OpenAI 兼容路径。事件协议就跟 OpenAI Realtime 那一套:session.update 配置会话,input_audio_buffer.append 送音频,response.output_audio.delta 收音频。你现有的 OpenAI Realtime 客户端改个 base_url 基本就能连。
同一能力在原生透传层的写法见 实时语音(原生透传)。
什么情况该用它
| 你要做的 | 用哪个 |
|---|---|
| 语音对话助手(像打电话一样) | 用这个 |
| 一次性的「录音 → 转文字」 | 音生文 STT,更简单 |
| 普通的文本流式输出 | 对话补全 就够,不用上 WebSocket |
建连
javascript
import WebSocket from 'ws'
const ws = new WebSocket(
'wss://api.wxiai.com/v1/realtime?model=grok-voice-latest',
{ headers: { Authorization: 'Bearer YOUR_API_KEY' } },
)
ws.on('open', () => {
ws.send(JSON.stringify({
type: 'session.update',
session: {
voice: 'eve',
instructions: '你是一个耐心的中文客服助手。',
turn_detection: { type: 'server_vad' },
},
}))
})model 是 URL 查询参数,不是 session.update 里的字段。不传默认 grok-voice-latest。
浏览器怎么连
浏览器原生的 WebSocket 构造函数不支持自定义请求头,没法带 Authorization——这是硬限制。xAI 的做法是两步走:
- 你的后端用 API Key 调
POST /v1/realtime/client_secrets,换一个短期临时凭证 - 前端拿这个凭证,用子协议字段建连
bash
curl -X POST https://api.wxiai.com/v1/realtime/client_secrets \
-H "Authorization: Bearer $WXIAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "expires_after": { "seconds": 300 } }'javascript
// 浏览器端
const ws = new WebSocket('wss://api.wxiai.com/v1/realtime', [
`xai-client-secret.${ephemeralToken}`,
])网关同时支持两种子协议前缀:
| 前缀 | 用途 |
|---|---|
xai-client-secret.<临时凭证> | xAI 官方风格,配合 client_secrets 使用 |
openai-insecure-api-key.<密钥> | OpenAI 风格 |
不要把长期 API Key 写进前端
那样任何访问者都能从源码里拿走它。client_secrets 这个端点存在的唯一目的就是避免这件事,而且它本身不计费。
会话配置
建连后第一件事就是发 session.update:
javascript
ws.send(JSON.stringify({
type: 'session.update',
session: {
voice: 'eve',
instructions: '你是一个耐心的中文客服助手。',
turn_detection: {
type: 'server_vad',
threshold: 0.85,
silence_duration_ms: 600,
prefix_padding_ms: 333,
},
audio: {
input: { format: { type: 'audio/pcm', rate: 24000 } },
output: { format: { type: 'audio/pcm', rate: 24000 } },
},
},
}))全部可配字段(turn_detection.*、audio.*、tools、resumption、replace 等 20 多项)见实时语音总览。 可用的 voice 取值与 TTS 共用同一套音色 ID,见音频处理总览。
事件流
你发过去:session.update、input_audio_buffer.append、input_audio_buffer.commit(仅手动模式)、input_audio_buffer.clear、conversation.item.create / .delete / .truncate、response.create、response.cancel。
服务端发回来:session.created / session.updated、conversation.created、input_audio_buffer.*、conversation.item.*、response.created、response.output_audio.delta / .done、response.output_audio_transcript.delta / .done、response.output_text.delta、response.done、error。
完整事件表、字段说明与工具调用流程见实时语音总览。
结束事件是 response.done
不是 OpenAI 的 response.completed。另外文本分片会以 response.text.delta 和 response.output_text.delta 两个名字出现,客户端两个都要处理。
这一层的注意点
model放错地方:它是 URL 查询参数,不是session.update字段。- 在 server VAD 模式下自己发
commit:只有turn_detection为null时才需要手动提交。 - 等
response.completed:Grok 用的是response.done。 - 断线不重连:120 分钟上限 + 网络抖动,断开是常态不是异常。
相关页
- 实时语音总览 —— 完整会话参数、事件表、5 类工具、
force_message、20+ 语言 - 实时语音(原生透传) —— 同一能力的另一条路径
- 音频处理总览 —— 音色清单、TTS / STT
- 对话补全 —— 只需要文本时用这个
