Skip to content

AgentHub 会话运行面协议(仅调用方 · 单页)

读者:只调用 AgentHub 会话能力(多轮流式对话 / 语音 / 附件 / 文生图)的开发者——Agent 的建模与发布由平台方或租户管理员完成,你拿到的是「地址 + API-Key + 已发布的 Agent ID」。 交付方式:本页随凭证一并交付,自包含;不需要访问 AgentHub 仓库。 契约事实源openapi.yaml(SSOT)——冲突时以 openapi 为准。深度接入(自建 Agent / 建模 / 计费对账全链)另见 SaaS 接入 Cookbook。 状态基准:2026-08-27。


1. 认证(两个请求头,全程不变)

X-AgentHub-Api-Key: ahk_...            # 租户级 API-Key(服务端凭据)
X-AgentHub-On-Behalf-Of: <uuid>        # 影子用户 ID(你的终端用户在平台侧的映射)
  • API-Key 是服务端到服务端凭据——不要放进浏览器 / 小程序等终端代码;
  • 所有响应为 Envelope{"code": "...", "message": "...", "data": {...}}code != "SUCCESS" 即业务错误(SSE 流除外,见 §4);
  • 凭据丢失只能轮转(POST /api/v1/delivery/api-keys/{id}:rotate),旧 Key 即时失效。

2. 端点总览(运行面)

端点用途
POST /api/v1/app/conversations开会话(body:{"agent_id": "<uuid>", "client_conversation_key": "<可选幂等键>"})→ data.id = 会话 ID;命中幂等键返回 200 原会话
POST /api/v1/app/conversations/{id}/turns跑一轮,响应为 SSE 流(§4)
GET /api/v1/app/conversations/{id}/turns/{turn_id}断连重拉:返回该轮完整结果,幂等不重跑不重复扣费(§5)
GET /api/v1/app/conversations/{id}/messages?limit=&offset=历史分页(MessagePageOut{items, limit, offset}
POST /api/v1/app/conversations/{id}:end显式结束(幂等);闭合后只读。空闲超时也会自动闭合

会话状态机:active → closing → closedclosed 后所有写操作返回 409 CONVERSATION_CLOSED会话钉死打开时的 Agent 版本——Agent 重新发布后需开新会话才生效。

3. 轮次请求体(content_blocks

json
{"content_blocks": [
  {"type": "text", "text": "帮我查退款政策"},
  {"type": "file", "file_id": "<uuid>", "filename": "notes.txt", "excerpt": "<commit 返回的摘录>"},
  {"type": "choice_selection", "card_message_id": "<uuid>", "selected": ["<option_id>"]}
]}
  • text:普通文本轮;
  • file:附件随轮(先走附件三步上传 authorize→直传→commit,excerpt 以 commit 返回为准);
  • choice_selection:回上一轮 turn_card 的选项。

4. SSE 帧目录(核心)

POST .../turns 成功时返回 200 text/event-stream(响应头 Cache-Control: no-cacheX-Accel-Buffering: no)。帧为标准 SSE 三行式:

id: 3:2                      ← 帧号 = {轮次 seq}:{帧序号},单调递增
event: turn_delta
data: {"turn_id": "...", "seq": 2, "text": "退款政策如下"}

(空行 = 帧边界;data 均为单行 JSON)

次数data 负载
turn_started1{"turn_id", "seq", "status": "generating"} —— turn_id 是断连重拉的钥匙,首帧必到
turn_delta0..N{"turn_id", "seq", "text"} —— 增量文本,按序拼接
turn_card0..1{"turn_id", "card": {"type": "choice_card", "card_schema_version": 1, "prompt", "options": [{"id", "label"}], "multi", "fallback_text"}}
turn_file0..N{"turn_id", "file": {"type": "file", "file_id", "filename", "mime_type", "size_bytes"}} —— 文生图/工件产物;取内容走 GET .../files/{file_id}(短 TTL 签名 URL)
turn_completed1{"turn_id", "status": "succeeded", "points_charged": int|null, "message_ids": ["<user_msg_id>", "<assistant_msg_id>"]};低余额时附 "balance_warning": true(仅提示不阻断)

三条协议性质(客户端实现必须知道):

  1. 先完结,后吐帧:服务端把轮次完整执行并落库后才投影为帧流。因此流一旦开始,结果已确定;流中不会再出现业务错误。
  2. 流前错误是普通 Envelope:所有校验失败(404/409/402/422…)发生在流开始之前,以标准 HTTP 状态码 + Envelope JSON 返回——客户端按 Content-Type 区分:application/json = 错误,text/event-stream = 正常。
  3. 帧号支持 Last-Event-ID 记账id{轮次 seq}:{帧序号};但权威的断连恢复路径是 §5 的 GET 重拉(幂等、不重跑、不重复扣费)。

5. 断连重拉(三条命令的协议)

① POST .../turns   → 至少收到首帧 turn_started,记下 turn_id
② (连接断开,丢弃未完成的流)
③ GET .../turns/{turn_id} → TurnOut(该轮全部消息 + 计费,已持久化的最终结果)

TurnOut{"id", "conversation_id", "seq", "status", "operation_id", "points_charged", "messages": [...], "started_at", "ended_at", ...}。重复 GET 幂等。

6. 错误码目录

HTTPcode含义 / 处置
401API_KEY_INVALIDKey 错误/吊销;检查请求头
402POINTS_INSUFFICIENT余额不足;零副作用,充值后原样重试
403AUTH_TENANT_MISMATCHOn-Behalf-Of 用户非本租户或非 active
404CONVERSATION_NOT_FOUND / CONVERSATION_TURN_NOT_FOUND / CONVERSATION_MESSAGE_NOT_FOUND / CONVERSATION_ATTACHMENT_NOT_FOUND资源不存在或跨租户(同形防枚举)
409CONVERSATION_CLOSED会话已闭合;开新会话
409CONVERSATION_ACTIVE_TURN_CONFLICT同会话已有进行中轮次;等它完成或直接 GET 重拉
409CONVERSATION_AGENT_NOT_PUBLISHED / CONVERSATION_AGENT_ARCHIVEDAgent 未发布/已归档;联系发布方
422VALIDATION_ERROR请求形状 / MIME / 字节数不过白名单
422CONVERSATION_SPEECH_NOT_ENABLED该 Agent 快照未启用语音;按「不可用」降级
500CONVERSATION_TURN_FAILED轮次执行异常(message 带 trace_id,找平台方)
504CONVERSATION_GUARDRAIL_VIOLATION护栏拦截(墙钟超时等;message 有具体原因)

7. 计费生命周期(你只需要关心四件事)

  1. 轮次:开轮先冻结 points_per_turn,成功结清(turn_completed.points_charged),失败全额解冻退回——试错成本只有成功轮次;
  2. 语音:转写 / 合成各按次计费(快照价),TTS 缓存命中零扣点(同消息 + 同音色返回同一 URL);
  3. 余额不足:402 POINTS_INSUFFICIENT,零副作用,引导充值后重试;
  4. 低余额提示:结清后可用余额 < 3×单价时 turn_completedbalance_warning: true(仅提示)。

对账键(流水 operation_id 前缀):轮次 turn:{turn_id}、转写 stt:{transcription_id}、合成 tts:{speech_id}、入账 grant:...

8. 可运行示例

最小 Python 客户端(含断连重拉演示,零第三方依赖)+ 本地 mock 服务:AgentHub SDK 包 sdk/python/examples/——mock_conversation_server.py 起本地假服务,conversation_minimal.py 全流程跑通(开会话 → 流式 → 模拟断连 → GET 重拉 → 结束),不接触真实平台即可验证你的接入代码。

9. 事实源与联动

本页是 Cookbook 附录 A/B/C 的外部交付版:端点契约以 openapi.yaml 为准;帧负载 / 错误码与 Cookbook 附录 A/B 双源维护,变更需双改。语音(STT/TTS)、附件上传三步、图片理解、文生图的完整 curl 见 Cookbook §7~§11。