跳转至

部署与运维

生产入口

推荐使用仓库启动器:

cd backend
bash src/run_cg_rag_http.sh

Python 服务入口是 src.live_retriever_service。默认监听 0.0.0.0:8864,HTTP 前缀为 /cg-rag,MCP 路径为 /cg-rag/mcp/。生产环境应由 systemd、容器编排或等价进程管理器托管,并在前方配置访问控制和 TLS 终止。

Secret 与配置

  • API key 只进入服务端环境变量或权限为 0600 的 secrets YAML;
  • 非敏感配置放普通 YAML 或部署系统环境变量;
  • 不把 key 写进命令行、镜像层、日志、MkDocs 或 Git;
  • 启动后通过 /health 的脱敏摘要确认生效配置,不输出原始 secret。

CG_RAG 优先读取 CG_RAG_*,部分字段兼容 QUESTION_GENERATED_APP_*。完整优先级和字段见配置

启动前检查

  1. 目标 scope 的 corpus、dense index、BM25 index 可读且版本一致。
  2. 本地 embedding/rerank 模型存在,或远端 endpoint 在部署网络中可达。
  3. generation endpoint/model/key 成组配置;只部署检索能力时可留空。
  4. hydration sidecar 路径可写,并位于持久 cache 目录。
  5. 并发限制符合 CPU、GPU、远端配额和请求超时。
  6. 非标准 HTTPS 端口或私有域名已加入出口防火墙与证书信任策略。

Hydration 离线门禁

正式部署必须先为 fullusualusual_plus_law 三个 profile 中实际配置的全部 corpus 构建 hydration sidecar:

python scripts/build_hydration_sidecar.py \
  --env-file /path/to/question_generated_app.env \
  --resource-root /path/to/backend \
  --output /path/to/backend/src/.question_generated_app_cache/cg_rag_hydration.sqlite3

脚本从各 profile 的 topks_by_stem 推导 corpus,不依赖固定数量。它会在目标目录中构建临时 SQLite,严格检查 JSON、文档 ID、文件签名和 PRAGMA quick_check;全部来源通过后才原子替换正式 sidecar。构建失败、磁盘空间不足或目标路径与运行配置不一致时,旧库保持不变,部署必须失败。

仓库的 release 部署器会在服务切换前强制执行该门禁,并比较运行中 CG_RAG health 的 sidecar path hash、plan fingerprint、configured corpus 数和 indexed corpus 数。后续 health 或 smoke 失败时会恢复上一份独立校验过的 sidecar;成功后只保留一个可回滚版本。

Retriever Warmup

服务支持启动 warmup,也支持显式 HTTP warmup:

curl --noproxy '*' -sS \
  -X POST http://127.0.0.1:8864/cg-rag/warmup \
  -H 'Content-Type: application/json' \
  -d '{"scopes":["full","usual","usual_plus_law"]}'

只 warmup 首批真实流量会使用的 scope。manager 当前只常驻最后一个 active scope;依次预热多个 scope 会产生重复加载时间,但不会让它们全部长期驻留。

上线 Smoke

按顺序验证:

curl --noproxy '*' -fsS http://127.0.0.1:8864/cg-rag/health
curl --noproxy '*' -fsS http://127.0.0.1:8864/cg-rag/profiles
curl --noproxy '*' -fsS \
  -X POST http://127.0.0.1:8864/cg-rag/retrieve-rerank \
  -H 'Content-Type: application/json' \
  -d '{"query":"脚手架验收要求","scope":"full","topk":5}'

启用生成时再验证 /constrained-generate/rag/rag/stream。真实 provider smoke 必须通过显式环境开关在 staging 或受控发布流程运行,常规 CI 使用 mock,不依赖生产模型服务。

启用视觉识别时,先确认能力已就绪,再用一张真实现场图片验证两种模式:

curl --noproxy '*' -fsS http://127.0.0.1:8864/cg-rag/health \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["vision"])'

curl --noproxy '*' -fsS \
  -X POST http://127.0.0.1:8864/cg-rag/vision/answer \
  -H 'Content-Type: application/json' \
  -d "{\"images\":[{\"data\":\"$(base64 -w0 smoke.jpg)\",\"mime_type\":\"image/jpeg\"}]}"

自由生成通过后再验证 /cg-rag/vision/agentic:它同时覆盖 VLM 上游、进程内检索回调和引用校验,是视觉链路最有价值的单条 smoke。检查返回的 citations 非空且 retrieval_docs 与之对应——citations 为空说明引用契约或检索没有正常工作。

关键观测项

GET /cg-rag/health 应持续观测:

  • 顶层 active_scope
  • retriever.resident_scopesretriever.load_countretriever.last_load_time_msretriever.last_loaded_scope
  • retrieve cache 的 entries/hits/misses/max_entries/ttl;
  • profile fingerprint id 与脱敏 summary;
  • hydration 的 enabled、path hash、plan fingerprint、configured/indexed corpora、lookup hit/miss/failure、build count 和 last error;
  • rerank 是否走远端 API、当前公开模型名;
  • generation 是否 configured、provider/model、thinking、streaming;
  • vision 是否 configured、model、图片与轮数上限(vision.configuredfalse 时视觉接口全部返回 vision_not_configured);
  • retrieval/generation capacity 的 max、active、queued、peak、rejected 和等待上限。

应用日志应按 request ID 聚合,重点告警 capacity.exceededservice_errorstream_failed、hydration lookup failure、retriever 重复加载和 generation response invalid。启用视觉识别后还应关注 vision_upstream_errorvision_response_invalidinvalid_image 的比例:前两者指向 VLM 上游,后者通常是调用方的图片处理有问题。

视觉与文本生成共用同一个 generation 容量限制器。视觉请求耗时远高于文本 constrained generation,因此 capacity.generation 的 queued/rejected 上升时,先看是否有批量视觉流量在挤占配额。

发布与回滚

生产环境是一个 Git 检出目录,代码、依赖与运行数据同处一处。发布流程为:拉取目标提交、按需重建前端产物、重启受影响的服务窗口,再完成 health/retrieve/generation smoke。secret、SQLite、hydration sidecar 与语料软链接都不受 Git 跟踪,拉取不会覆盖它们。

服务各自有独立的启动脚本,重启时只启动受改动影响的那一个:src/run_cg_rag_http.sh(CG_RAG)、src/run_question_generated_api.sh(Question API)、src/run_question_generated_web.sh(Web)。三者都会先关闭同名 tmux 窗口再重建,不要在正在运行的目录上手工覆盖 Python 文件。

视觉识别只依赖配置和代码,不引入新的持久化资产:图片随请求传入并在内存中处理,回滚代码即可回退该能力,无需还原任何数据文件。

回滚条件至少包括:

  • health 不通过或目标 scope 不可用;
  • 相同基准 query 的召回为空或来源字段明显退化;
  • generation 错误率、invalid response 或 timeout 显著上升;
  • SSE 无 final、取消后仍持续占用上游连接;
  • cache fingerprint、hydration 或 rerank 配置与发布预期不一致。

回滚即检出上一个已知良好的提交并重启对应服务,同时保留失败发布的脱敏日志与 request ID。索引或 sidecar 发生 schema/内容变更时,要把它们作为独立版本化资产处理,不能只回滚代码——它们不在 Git 中,需要在回滚代码前单独备份并还原。

文档发布

CG_RAG MkDocs 使用严格构建:

cd backend
mkdocs build --strict

Cloudflare Pages 发布脚本为:

CG_RAG_DOCS_WRANGLER_ENV_FILE=/path/to/cg-rag-docs.env \
  bash scripts/deploy_cg_rag_docs_pages.sh

凭据文件必须留在仓库外或被精确 ignore;发布完成后复核自定义域名、sitemap 与搜索索引。