WebSocket API 参考
WebSocket API 使用 Bridge 协议 infini.bridge.v1,把自有消息系统连接到 WebSocket 渠道账号。本文说明连接、鉴权、消息、流式回复、中断、心跳和错误处理。创建渠道账号、签发 Token 和验证接入的步骤参见通过 WebSocket 接入智能体。
连接和编码
客户端需要按照目标部署的地址、协议版本和 JSON 字段约定建立连接。
- 连接地址:使用目标部署为 WebSocket 渠道账号提供的地址,端点路径为
/ws/v1。 - 协议版本:
infini.bridge.v1。 - 帧类型:WebSocket 文本帧。
- 消息编码:Protocol Buffers JSON 字段约定。
- JSON 字段名:snake_case。
生产环境应使用目标部署提供的 wss:// 地址。不要根据控制台站点地址自行拼接 WebSocket 主机名。
所有业务帧使用同一种信封:外层 type 指定消息类型,并由同名字段承载数据。例如:
{
"type": "message",
"message": {
"meta": {
"msg_id": "3eeec74d-a4d4-4517-89ec-ef8aeb676666",
"user_id": "user-001"
},
"content": "帮我查询订单状态"
}
}支持的帧类型:
| 方向 | type | 数据字段 | 用途 |
|---|---|---|---|
| 客户端到平台 | auth | auth | 在连接建立后完成鉴权 |
| 客户端到平台 | message | message | 发送用户文本或斜杠指令 |
| 客户端到平台 | interrupt_response | interrupt_response | 响应确认或用户工具中断 |
| 双向 | PING | 无 | 请求业务层心跳响应 |
| 双向 | PONG | 无 | 响应业务层心跳 |
| 平台到客户端 | auth_ok | auth_ok | 确认帧内鉴权成功 |
| 平台到客户端 | message_reply | message_reply | 返回一条完整文本 |
| 平台到客户端 | message_stream_reply | message_stream_reply | 返回流式增量、工具事件或中断 |
| 平台到客户端 | error | error | 返回连接或运行错误 |
完成鉴权
wst_ Token 鉴权一个 WebSocket 渠道账号,不直接鉴权智能体模板或智能体实例。渠道账号的绑定模式和绑定对象决定消息进入哪个智能体。
使用 Subprotocol 鉴权
推荐在 HTTP Upgrade 请求中传递 Token:
Sec-WebSocket-Protocol: infini.bridge.v1, bearer.<base64url_token>base64url_token 是 wst_ Token 的无填充 Base64URL 编码。连接成功后,服务端只回显:
Sec-WebSocket-Protocol: infini.bridge.v1这种方式在连接建立前完成鉴权,不发送 auth 或接收 auth_ok 帧。
使用帧内鉴权
无法在 Upgrade 请求中附加 Token 时,以 infini.bridge.v1 建立连接,并在目标部署规定的鉴权超时内发送:
{
"type": "auth",
"auth": {
"token": "wst_xxxxxxxxxxxxxxxxxxxx"
}
}鉴权成功后收到:
{
"type": "auth_ok",
"auth_ok": {
"connection_id": "550e8400-e29b-41d4-a716-446655440000",
"server_time": "1784685600000000000"
}
}| 字段 | 类型 | 说明 |
|---|---|---|
connection_id | string | 当前连接的标识,可用于客户端日志关联 |
server_time | string | Unix 纳秒时间;按字符串或 BigInt 处理 |
每次重连都必须重新鉴权。不要在日志、错误消息或客户端页面中输出 wst_ 明文。
设置消息元数据
message、message_reply、message_stream_reply 和 interrupt_response 使用 meta 关联用户、对话和回复。
| 字段 | 必填 | 说明 |
|---|---|---|
msg_id | 是 | 由客户端为每条输入生成的全局唯一 ID,推荐使用 UUID;平台不会用该字段阻止重复请求 |
user_id | 客户端消息必填 | 业务系统中的稳定用户标识,用于用户绑定和单聊会话隔离 |
user_name | 否 | 用于显示的用户名称 |
chat_type | 否 | p2p 或 group;省略时按 p2p 处理 |
chat_id | 群聊必填 | 稳定的业务对话标识;单聊省略时使用 user_id 维持对话连续性 |
不要为一次重试重复使用 msg_id 并假设平台会自动去重。会产生业务副作用的工具仍应在业务系统中使用幂等键。
同一个 WebSocket 渠道账号可以有多个客户端连接。客户端应使用 msg_id、chat_id 和自身连接上下文筛选并关联回复,不要假设账号上的每条回复只会发送给发起请求的连接。
发送用户消息
{
"type": "message",
"message": {
"meta": {
"msg_id": "3eeec74d-a4d4-4517-89ec-ef8aeb676666",
"user_id": "user-001",
"user_name": "Alice",
"chat_type": "p2p",
"chat_id": "chat-001"
},
"content": "帮我查询订单状态"
}
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
message.meta | object | 是 | 消息元数据 |
message.content | string | 是 | 用户文本或斜杠指令 |
模板绑定需要按用户创建专属实例时,使用稳定的 user_id 发送 /init。实例绑定可以直接发送普通消息。
WebSocket 接入以文本消息为受支持的输入路径。需要上传文件并把文件作为智能体输入时,使用 Invoke API 的文件上传接口,除非目标部署另行提供 WebSocket 文件输入约定。
接收回复
接收完整文本
message_reply 返回一条完整文本,常用于斜杠指令等非流式回复:
{
"type": "message_reply",
"message_reply": {
"meta": {
"msg_id": "3eeec74d-a4d4-4517-89ec-ef8aeb676666",
"chat_type": "p2p",
"chat_id": "chat-001"
},
"content": "已创建智能体实例"
}
}接收流式事件
message_stream_reply 返回智能体运行中的增量事件:
{
"type": "message_stream_reply",
"message_stream_reply": {
"meta": {
"msg_id": "3eeec74d-a4d4-4517-89ec-ef8aeb676666",
"chat_type": "p2p",
"chat_id": "chat-001"
},
"content": {
"content": "订单正在处理中"
},
"done": false
}
}| 字段 | 类型 | 说明 |
|---|---|---|
thinking.content | string | 思考文本增量 |
content.content | string | 最终回答文本增量 |
tool_call | object | 工具调用;包含 id、name 和 JSON 字符串 arguments |
tool_call_result | object | 工具结果;包含 id、result 和 status |
interrupt | object | 中断;包含 type、id 和 JSON 字符串 data |
done | boolean | true 表示本次智能体运行结束 |
同一帧最多包含一个增量字段;done 可以单独出现,也可以与最后一个文本增量同时出现。客户端应分别累积 thinking 和 content,按工具调用 ID 关联工具事件,并在收到 done: true 后结束本次运行。
响应中断
中断出现在 message_stream_reply.interrupt。客户端应保存该帧的 meta 和中断 ID,完成用户确认或业务工具执行后发送:
{
"type": "interrupt_response",
"interrupt_response": {
"meta": {
"msg_id": "3eeec74d-a4d4-4517-89ec-ef8aeb676666",
"user_id": "user-001",
"chat_type": "p2p",
"chat_id": "chat-001"
},
"payload": {
"interrupt_id": "interrupt-001",
"action": "RESPOND",
"response_data": "{\"ticket_id\":\"INC-1024\",\"status\":\"处理中\"}"
}
}
}| 动作 | 用途 | response_data |
|---|---|---|
APPROVE | 批准确认型中断 | 通常为空 |
REJECT | 拒绝确认型中断 | 通常为空 |
RESPOND | 返回用户输入或用户工具包执行结果 | 使用中断所需的 JSON 字符串 |
ERROR | 表示调用方无法返回有效结果 | 提供可供智能体处理的错误数据 |
interrupt_response.meta 应与原中断的消息上下文一致。用户工具包的执行和参数校验参见定义用户工具包。
处理心跳和重连
Bridge 使用 JSON 文本帧实现业务层心跳,不使用 WebSocket 协议控制帧:
{"type":"PING"}收到 PING 后发送:
{"type":"PONG"}客户端也可以发送 PING 并等待 PONG。心跳间隔、允许丢失次数、鉴权超时和连接数限制由目标部署配置。
断线恢复时:
- 使用带抖动的指数退避建立新连接。
- 重新鉴权。
- 恢复客户端自己的消息关联状态。
- 只重试能够安全重复执行的业务请求。
处理错误
HTTP Upgrade 错误
连接建立前的错误使用 HTTP 状态和 JSON 响应:
{
"code": "unauthorized",
"message": "token invalid"
}| HTTP 状态 | code | 处理 |
|---|---|---|
| 400 | missing_protocol_version | 添加 infini.bridge.v1 子协议 |
| 400 | invalid_token_encoding | 使用无填充 Base64URL 重新编码 wst_ Token |
| 401 | unauthorized | 检查、轮换或重新启用 Token |
| 401 | account_mismatch | 使用绑定到目标 WebSocket 渠道账号的 Token |
| 502 或 503 | gateway_unavailable | 按退避策略重试,并检查目标部署状态 |
| 503 | pre_auth_pool_full | 延迟后重试帧内鉴权,或改用 Subprotocol 鉴权 |
WebSocket 错误帧
连接建立后的错误使用:
{
"type": "error",
"error": {
"code": "invalid_message",
"message": "message parse error"
}
}code | 连接影响 | 处理 |
|---|---|---|
duplicate_auth | 关闭 | 建立新连接并只鉴权一次 |
auth_required | 可能保持或关闭 | 完成鉴权;连接已关闭时重新连接 |
auth_error、unauthorized、account_mismatch | 关闭 | 修正 Token 或渠道账号后重新连接 |
auth_timeout | 关闭 | 在目标部署的时限内发送 auth,或使用 Subprotocol 鉴权 |
max_connections_exceeded | 关闭 | 复用或关闭闲置连接,再按退避策略重试 |
server_restart | 关闭 | 按退避策略重新连接和鉴权 |
invalid_message | 保持 | 修正 JSON 信封或字段后发送新请求 |
meta_user_id_required | 保持 | 添加稳定且非空的 meta.user_id |
agent_error | 保持 | 将当前运行标记为失败,并结合 Trace 排查智能体实例 |
连接还可能以标准 WebSocket Close Code 结束:1000 表示正常结束或心跳超时,1001 表示服务端关闭,1003 表示鉴权或帧类型不可接受,1008 表示策略限制。客户端应同时记录最后一个 error 帧和 Close Code,但不要记录 Token 明文。
鉴权和账号错误在配置修正前不应无界重试。连接暂时不可用、服务重启和网络中断可以按有上限的退避策略恢复。