SSE、取消与错误¶
SSE 事件协议¶
POST /cg-rag/rag/stream 与 POST /cg-rag/vision/*/stream 返回 text/event-stream。每个事件均为:
事件类型:
| 事件 | 含义 | 关键字段 |
|---|---|---|
progress |
阶段开始或结束 | stage、label、status |
retrieval |
完整 retrieve-rerank 结果 | retrieval_docs、cache、pipeline |
token |
已校验答案的显示分块 | channel: "answer"、text |
error |
当前业务阶段失败 | error.code、error.message;生成业务错误通常还带 ok: false |
final |
权威终态 | query、retrieval、generation(视觉接口为 answer、citations) |
视觉流式接口额外使用以下事件:
| 事件 | 出现于 | 含义 | 关键字段 |
|---|---|---|---|
trace |
视觉智能生成 | 流水线节点状态 | name、status、summary |
agent |
视觉智能生成 | agent 事件状态流转 | event_id、kind、status、label |
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_configured、invalid_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_request,details.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_timeout、generation_request_failed、generation_failed、service_error:有限次数退避重试;generation_response_invalid:记录 request ID 后有限重试,持续出现时检查 provider 输出协议;no_stable_article:调整 query、scope 或 topk,而不是原样重试。
日志安全¶
日志只保留 request ID、错误类型、阶段和脱敏配置摘要。不得记录 API key、Authorization header、完整 prompt、候选全文、上游原始响应或本地敏感绝对路径。普通错误响应同样不得返回这些内容。