跳转至

SSE、取消与错误

SSE 事件协议

POST /cg-rag/rag/streamPOST /cg-rag/vision/*/stream 返回 text/event-stream。每个事件均为:

event: <event-name>
data: <JSON object>

事件类型:

事件 含义 关键字段
progress 阶段开始或结束 stagelabelstatus
retrieval 完整 retrieve-rerank 结果 retrieval_docscachepipeline
token 已校验答案的显示分块 channel: "answer"text
error 当前业务阶段失败 error.codeerror.message;生成业务错误通常还带 ok: false
final 权威终态 queryretrievalgeneration(视觉接口为 answercitations

视觉流式接口额外使用以下事件:

事件 出现于 含义 关键字段
trace 视觉智能生成 流水线节点状态 namestatussummary
agent 视觉智能生成 agent 事件状态流转 event_idkindstatuslabel
answer_reset 视觉智能生成 作废此前已发送的全部 answer 文本

answer_reset 必须处理。智能生成先校验最终回答是否满足公开协议与引用契约,不满足则重试并重发答案;客户端收到该事件时要清空已渲染的 answer 缓冲,否则会显示两份拼接的回答。/cg-rag/rag/stream 不会发送该事件。

成功顺序通常是:

progress(retrieval/running)
retrieval
progress(generation/running)
token × N
progress(generation/done)
final

没有稳定候选、上游生成失败或容量不足时,服务会发送 error,然后尽量发送结构完整的 final。客户端不要把最后一个 token 当作成功,应以 final.generation.ok(视觉接口为 final.ok)判断业务结果。

视觉接口的响应头在生成开始前就已发出,因此 vision_not_configuredinvalid_image 等失败在流式调用中只能表现为 error 事件,HTTP 状态仍为 200;非流式调用才会返回对应的 503 / 400

CG_RAG_STREAM_ANSWER_TOKEN_DELAY_SECONDS 只控制 answer 分块之间的展示节奏;设为 0 可立即发送。它不会改变模型生成速度。

Request ID

服务安装统一 request ID middleware。调用方可以发送 X-Request-ID;服务会校验并在响应 header、普通 JSON、SSE data 和安全日志上下文中传播。不要把用户文本、候选全文、API key 或上游响应正文塞进 request ID。

HTTP 状态与业务状态

场景 HTTP 业务表示
请求字段无效 400 error.code=invalid_request
Pydantic body 无法解析 400 invalid_requestdetails.errors 含安全字段错误
非流式请求在取得容量前耗尽等待窗口 429 capacity.exceeded,包含 limiter 和等待摘要
/rag/stream 开始后容量耗尽 200 SSE error 后跟结构完整的 final,两者均带 capacity.exceeded
调用被取消 499 generation.cancelled
未捕获服务异常 500 service_error,正文不暴露异常细节
HTTP 成功但生成业务失败 200 generation.ok=false 与稳定错误码

常见生成错误:

  • generation_not_configured:endpoint 或 model 未配置;
  • no_stable_article:检索未得到可用候选;
  • generation_timeout:上游请求超时;
  • generation_request_failed:上游网络、鉴权或服务请求失败;
  • generation_failed:未被上述类型覆盖的生成阶段异常;
  • generation_response_invalid:上游响应或 JSON 索引协议无效;
  • stream_failed:SSE 已开始后发生未分类异常;
  • capacity.exceeded:检索或生成 limiter 未在等待窗口内取得容量。

断连与主动取消

CG_RAG 没有单独的“按 request ID 取消”HTTP 路由。取消来源是:

  • HTTP/SSE 客户端断开;
  • MCP session/task 被取消;
  • 内部调用方传入 cancellation token。

取消信号会向 retriever、constrained generation 和上游 streaming reader 传播。客户端重试时应使用新的 request ID,并根据操作是否幂等决定是否自动重试:retrieve-rerank 可安全重试;generation 可能已经消耗上游 token,但不会改变服务端持久状态。

推荐重试策略

  • invalid_request:修正请求,不自动重试;
  • capacity.exceeded:指数退避并加入 jitter,优先遵循错误详情中的等待信息;
  • generation_not_configured:运维修复配置,不重试;
  • generation_timeoutgeneration_request_failedgeneration_failedservice_error:有限次数退避重试;
  • generation_response_invalid:记录 request ID 后有限重试,持续出现时检查 provider 输出协议;
  • no_stable_article:调整 query、scope 或 topk,而不是原样重试。

日志安全

日志只保留 request ID、错误类型、阶段和脱敏配置摘要。不得记录 API key、Authorization header、完整 prompt、候选全文、上游原始响应或本地敏感绝对路径。普通错误响应同样不得返回这些内容。