Skip to content

Latest commit

 

History

History
271 lines (213 loc) · 8.35 KB

File metadata and controls

271 lines (213 loc) · 8.35 KB

上游 Conversation SSE 协议说明

Conversation SSE 是上游对话链路的流式返回协议。每条 SSE data: 通常是一段 JSON payload,也可能是协议标记或结束标记。客户端需要按顺序消费这些 payload,维护当前会话状态、文本内容、工具调用状态和图片结果指针。

基本形态

常见 payload 示例:

"v1"
{"type":"resume_conversation_token",...}
{"p":"","o":"add","v":{...}}
{"v":{...}}
{"p":"/message/content/parts/0","o":"append","v":"..."}
{"type":"server_ste_metadata","metadata":{...}}
[DONE]

处理建议:

payload 含义 处理方式
"v1" 协议版本标记 可记录,通常不影响业务
[DONE] 当前 SSE 流结束 停止继续读取
JSON object 事件、消息或 patch 按字段更新会话状态
JSON string 短文本 patch 或协议标记 结合上下文处理
非 JSON 内容 原始内容 保留为 raw 事件,避免中断流

常用字段

字段 说明
type 上游事件类型,如 resume_conversation_tokeninput_messagemessage_markertitle_generationserver_ste_metadata
conversation_id 当前会话 ID,可从多个事件中获得
p patch 路径,例如 /message/content/parts/0
o patch 操作,例如 addappendreplacepatch
v patch 值,可能是字符串、数组,也可能包含完整 message
c 消息序号或游标,常见于 add 类事件
message.id 消息 ID
message.author.role 消息角色,常见 systemuserassistanttool
message.content.content_type 内容类型,如 textmultimodal_textmodel_editable_context
message.content.parts 内容片段,可能包含文本、图片指针或多模态对象
message.status 消息状态,如 in_progressfinished_successfully
message.end_turn 是否结束当前轮次
metadata.tool_invoked 本轮是否调用工具
metadata.turn_use_case 本轮用途,如 textmultimodal
metadata.async_task_type 异步工具任务类型,图片生成通常为 image_gen

会话启动事件

上游通常会先返回恢复令牌或会话令牌:

{
  "type": "resume_conversation_token",
  "kind": "topic",
  "token": "...",
  "conversation_id": "..."
}

这个事件主要用于标识会话和恢复上下文。业务层通常只需要保存 conversation_idtoken 不应该暴露给下游用户。

消息 add 场景

完整消息可能通过 add 或带 v.message 的事件出现:

{
  "p": "",
  "o": "add",
  "v": {
    "message": {
      "author": {"role": "assistant"},
      "content": {"content_type": "text", "parts": [""]},
      "status": "in_progress"
    },
    "conversation_id": "..."
  },
  "c": 3
}

此类事件常用于创建一条新消息。若消息角色为 assistant,后续文本通常会通过 patch 继续追加。

文本增量场景

文本输出通常由多条 patch 组成:

{"p":"/message/content/parts/0","o":"append","v":"Hello"}
{"v":" world"}
{"p":"","o":"patch","v":[
  {"p":"/message/content/parts/0","o":"append","v":"!"},
  {"p":"/message/status","o":"replace","v":"finished_successfully"},
  {"p":"/message/end_turn","o":"replace","v":true}
]}

处理要点:

形态 含义
p == "/message/content/parts/0"o == "append" 向当前文本追加内容
o == "replace" 用新值替换目标字段
o == "patch"v 是数组 批量 patch,需要按数组顺序处理
只有 vv 是字符串 可能是省略路径的文本增量,应结合当前文本流处理

输入消息场景

用户输入会以 input_message 或普通 user message 出现。图片编辑请求会包含用户上传的参考图:

{
  "type": "input_message",
  "input_message": {
    "author": {"role": "user"},
    "content": {
      "content_type": "multimodal_text",
      "parts": [
        {"asset_pointer": "sediment://file_input"},
        "编辑提示词"
      ]
    }
  },
  "conversation_id": "..."
}

这类 sediment://... 表示输入附件,不是生成结果。即使它可以被下载,也不能当作输出图片返回。

图片工具成功场景

图片生成或图片编辑成功时,上游一般会出现工具消息:

{
  "v": {
    "message": {
      "author": {"role": "tool"},
      "content": {
        "content_type": "multimodal_text",
        "parts": [
          {"asset_pointer": "file-service://file_result"},
          {"asset_pointer": "sediment://file_result"}
        ]
      },
      "metadata": {"async_task_type": "image_gen"}
    }
  },
  "conversation_id": "..."
}

只有同时满足以下条件的图片指针,才应该视为输出结果:

条件 说明
message.author.role == "tool" 来源是工具消息
metadata.async_task_type == "image_gen" 工具任务是图片生成
asset_pointerfile-service://...sediment://... 指向可解析图片资源

图片指针类型

指针 常见来源 说明
file-service://file_xxx 图片工具输出 可通过文件下载接口解析
sediment://file_xxx 输入附件或图片工具输出 需要结合消息角色判断来源
file_upload 上传过程占位 通常不应作为输出

不要只凭字符串里出现 file_sediment:// 就判定为输出图。必须结合消息角色和任务类型。

策略拒绝场景

当上游拒绝请求时,通常不会产生图片工具消息,而是返回普通 assistant 文本:

I can't assist with that request. If you have another type of modification...

常见伴随事件:

{"type":"title_generation","title":"Request Denied","conversation_id":"..."}
{
  "type": "server_ste_metadata",
  "metadata": {
    "tool_invoked": false,
    "turn_use_case": "multimodal",
    "did_prompt_contain_image": true
  },
  "conversation_id": "..."
}

处理要点:

条件 行为
有 assistant 拒绝文本 应返回文本消息
tool_invoked == false 说明没有实际工具结果
没有 role=toolasync_task_type=image_gen 的消息 不应收集输出图片
用户输入消息里有图片指针 仍然只视为输入附件

moderation 场景

部分请求可能返回 moderation 事件:

{
  "type": "moderation",
  "moderation_response": {
    "blocked": true
  },
  "conversation_id": "..."
}

blocked == true,应认为本轮被策略拦截。后续如有 assistant 文本,应优先返回该文本;若没有文本,可返回合适的错误信息。

marker 和 title 事件

上游会返回一些辅助事件:

{"type":"message_marker","marker":"user_visible_token","event":"first"}
{"type":"message_marker","marker":"last_token","event":"last"}
{"type":"title_generation","title":"...","conversation_id":"..."}

这些事件通常用于前端展示、标题生成或流式状态标记,不代表实际文本内容或图片结果。

metadata 事件

server_ste_metadata 用于描述本轮调度和工具状态:

{
  "type": "server_ste_metadata",
  "metadata": {
    "tool_invoked": true,
    "turn_use_case": "multimodal",
    "model_slug": "i-mini-m",
    "did_prompt_contain_image": true
  }
}

常用判断:

字段 说明
tool_invoked == true 上游认为本轮调用过工具
tool_invoked == false 上游未调用工具,常见于拒绝或纯文本响应
turn_use_case == "text" 按文本响应处理
turn_use_case == "multimodal" 多模态请求,不代表一定有图片输出
did_prompt_contain_image == true 输入包含图片,不代表输出包含图片

结束后的结果判断

SSE 结束后可按以下顺序判断结果:

  1. 如果已经收集到图片工具输出指针,解析并下载输出图片。
  2. 如果没有输出图片指针,但有 assistant 文本,并且本轮被拦截或未调用工具,返回文本消息。
  3. 如果没有输出图片指针,但有 conversation_id,可查询完整会话明细,继续寻找图片工具输出。
  4. 查询完整会话时,仍然只读取 role=toolasync_task_type=image_gen 的消息。
  5. 如果没有图片结果也没有文本,返回上游异常或空结果错误。