跳转至

故障排查

供调用方及值班人员参考,按现象查明原因。

首先明确一点:CG_RAG 的 HTTP 200 不等于业务成功。 检索成功但生成失败时,HTTP 状态仍为 200,失败信息位于 body 中。SSE 响应不可将最后一个 token 视为成功标志,应检查 final.generation.ok(视觉接口检查 final.ok)。

初步检查

# 服务活着吗?配置齐吗?
curl --noproxy '*' -sS http://127.0.0.1:8864/cg-rag/health

# 有哪些检索范围可用?
curl --noproxy '*' -sS http://127.0.0.1:8864/cg-rag/profiles

health 中需关注的字段:

字段 期望 不对时说明
ok true 服务整体不健康,查看 config_issues
config_issues [] 有内容则表示配置缺失,按提示修正
available_scopes 含你要用的 scope 语料或索引路径未正确配置
generation.configured true 文本生成未配置,rag / constrained-generate 将失败
vision.configured true 视觉未配置,仅影响 vision/*

按错误码查

generation_not_configured

生成端点未配置。检索接口不受影响,但 rag、constrained-generate 不可用。

需配置生成上游。YAML:

cg_rag:
  provider: deepseek   # 或 poly / openai_compatible
  generation_endpoint: https://example.com/v1/chat/completions
  generation_model: your-model

密钥写入 question_app.secrets.yaml 的 cg_rag.api_key。等价环境变量:

export CG_RAG_GENERATION_ENDPOINT='https://example.com/v1/chat/completions'
export CG_RAG_GENERATION_MODEL='your-model'
export CG_RAG_API_KEY='server-side-secret'
export CG_RAG_LLM_PROVIDER='deepseek'   # 或 poly / openai_compatible

修改后重启服务,再通过 health 确认 generation.configured 已变为 true。字段细则见 CG 字段手册。

vision_not_configured

视觉上游未配置。检索与文本生成均正常,仅 vision/* 会失败。

YAML 配置位于 cg_rag.vision(endpoint / model,密钥 cg_rag.vision.api_key),或通过环境变量配置:

export CG_RAG_VISION_ENDPOINT='https://example.com/v1/chat/completions'
export CG_RAG_VISION_MODEL='your-vlm'
export CG_RAG_VISION_API_KEY='server-side-secret'

部署顺序

如果有上层应用依赖 CG_RAG 的视觉能力,先重启 CG_RAG 并确认 health 里 vision.configured=true,再重启上层应用。反过来会让上层在一段时间内对所有图片请求返回失败。

no_stable_article

检索到了候选,但模型未能稳定选出条文。此情况并非服务异常,而是「当前候选集中无法确定回答该问题的条文」。

常见原因及处理方式:

  • 问题过于宽泛(如「安全怎么做」)→ 细化问题描述。
  • scope 选取过窄 → 由 usual 改为 full。
  • topk 过小 → 调大至 10~20,为模型提供更多候选。

generation_timeout / generation_request_failed

至上游模型的请求超时或失败。请先确认上游本身可用:

curl -sS -o /dev/null -w '%{http_code}\n' \
  -X POST "$CG_RAG_GENERATION_ENDPOINT" \
  -H "Authorization: Bearer $CG_RAG_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"model":"'"$CG_RAG_GENERATION_MODEL"'","messages":[{"role":"user","content":"ping"}],"max_tokens":1}'

若上游正常而 CG_RAG 仍报超时,可调大 CG_RAG_TIMEOUT_SECONDS(默认 120 秒),并同步调大客户端超时时限。当前生效值见 health 的 generation.timeout_seconds。

generation_response_invalid

上游已返回内容,但格式无法解析——通常为模型未按要求输出 JSON。多见于 CG_RAG_LLM_PROVIDER 配置有误(例如上游为 OpenAI-compatible 却配置为 deepseek),导致 thinking 参数注入方式不匹配。

vision_upstream_error

视觉上游调用失败。图片过大、格式不支持、上游过载均会触发此错误。建议先将图片压缩至 2 MB 以内并转换为标准 JPEG/PNG 后重试。

invalid_image

base64 无法解码,或图片格式不受支持。请检查:

  • data 字段为纯 base64,不含 data:image/jpeg;base64, 前缀。
  • mime_type 与实际内容一致。
import base64
encoded = base64.b64encode(open("site.jpg", "rb").read()).decode("ascii")
payload = {"images": [{"data": encoded, "mime_type": "image/jpeg"}]}

invalid_request

请求体未通过校验。常见问题:

  • include_debug 与 generation_enable_thinking 必须为 JSON boolean。"true"、1、0 均会被拒绝。
  • retrieval_docs 不可为空数组。

capacity.exceeded(HTTP 429)

并发量超出服务端限流阈值。检索与生成分别独立限流,因此两类请求可能先后触及上限。

  • 非流式请求:等待超时后返回 HTTP 429。
  • /rag/stream:若响应已开始,容量错误通过 SSE 的 error + final 表达,HTTP 状态仍为 200。

客户端应退避后重试,不得立即重发。

按现象查

首次请求明显慢于后续请求

属正常现象。首次访问某个 scope 时需加载索引。上线前建议执行 warmup。

更换索引或语料后结果未更新

检索缓存的 key 中包含 profile_fingerprint,配置确实发生变更时不会命中旧缓存。若结果未变,通常是配置未真正生效——对比 health 中的 profile_fingerprint_summary 与预期值。

pred_indices 与调用方文档序号不一致

pred_indices 为 1-based,对应 retrieval.retrieval_docs 的位置。取文档时应使用 docs[i - 1]。

SSE 卡住不动 / 收不到 token

按以下顺序排查:

  1. 请求头是否包含 Accept: text/event-stream?
  2. 中间层是否存在反向代理缓冲?Nginx 需配置 proxy_buffering off;。
  3. 视觉智能生成必须处理 answer_reset,否则页面将拼接出两份回答。协议详见 HTTP 参考 · SSE。
  4. 受约束生成本质上不是真流式——答案在服务端组装完成后才分段重放,因此「长时间无输出、随后内容一次性到达」属于正常行为。如需真正的边生成边到达,请使用视觉接口或自由生成。

视觉智能生成耗时一至两分钟

属正常现象。该流程会进行多轮法规检索后再作答。如需降低延迟,可改用 vision/answer(自由生成),代价是不含法规引用。

已配置代理后无法连接本机服务

curl 会读取 http_proxy / https_proxy 环境变量,将发往 127.0.0.1 的请求也转发至代理。示例中的 --noproxy '*' 即为此目的。Python 的 requests 同样受此影响,可通过以下方式规避:

session = requests.Session()
session.trust_env = False   # 忽略环境里的代理设置

仍无法定位

携带以下信息查阅日志,可大幅缩短定位时间:

  • 响应头中的 X-Request-ID(或 body 中的 request_id)。
  • 完整请求体(去除图片 base64)。
  • health 的完整输出。

请求 ID 会串联服务端日志,可直接定位至对应调用。也可自行指定:

curl --noproxy '*' -sS -H 'X-Request-ID: my-trace-001' \
  http://127.0.0.1:8864/cg-rag/health

服务端不会在响应中返回 API key、完整本地路径或上游响应正文;日志同样已做脱敏处理。

inbound_token / path_ids(2026-09-29)

  • cg_rag.inbound_token(secrets)/ CG_RAG_INBOUND_TOKEN:入站 Bearer。
  • cg_rag.expose_docs / CG_RAG_EXPOSE_DOCS:默认 false。
  • CG_RAG_REQUIRE_INBOUND_AUTH、CG_RAG_STRICT_CONFIG_CONFLICTS:严格启动开关,默认关。
  • health/profiles 的 path_ids:sha256(os.path.realpath(path))[:16];测试向量 compute_path_id("/data/x") == "e220a107e93688b1"。