Files
RAG/docs/09-document-ingestion-indexing-runbook.md
YoVinchen ecdb10c37a
Some checks failed
verify / verify (push) Has been cancelled
Make the governed RAG evidence path executable end to end
Separate local parsing from model indexing, bind review decisions to immutable manifests, persist vectors behind active profiles, and expose retrieval, chat, evaluation, and document workflows through the React workbench.

Constraint: Live Bailian authentication currently fails for all three configured capabilities

Rejected: Direct upload-to-embedding flow | bypasses local review and manifest binding

Confidence: high

Scope-risk: broad

Directive: Keep private-data deployment blocked until authentication, RBAC, and separate database roles land

Tested: make verify; fresh and replay Docker document smoke; worker recovery smoke; frozen synthetic evaluation; migration 0003-0004 roundtrip

Not-tested: Successful live Bailian calls, OCR, real multi-user authorization
2026-07-13 05:58:11 +08:00

11 KiB
Raw Blame History

文档上传、审核、向量化与检索运行手册

本手册用于验证当前已经落地的 synthetic 产品主链:浏览器上传公开虚构文档,经本地安全解析、 人工绑定 outbound manifest 审批、异步向量化和原子激活后,能够被正式 Retrieval API 检索。 这条链路已经在 Docker 中连续两次端到端通过;它证明工程状态机、幂等性和向量写库契约可运行, 但不代替真实百炼授权、真实地质语料质量、PDF/OCR 或最终论文盲测验收。

1. 最短启动与验证

首次克隆后初始化仅存在于本机、已被 Git 忽略的 Secret 文件:

make setup-hooks
bash scripts/init-local-secrets.sh
make up
make status
make seed-offline
make smoke-document

make up 等价于 docker compose up -d --build,会启动数据库、两个 Worker、模型隔离网关、 API、入口 Gateway 和 Web并等待迁移与上传卷初始化成功。make seed-offline 创建 synthetic profile 和公开虚构检索基线;make smoke-document 使用 data/samples/public/upload_demo.md 加入本次运行 nonce 后,自动完成一次全新的上传、解析、审批、 向量化、激活和检索;随后在同一次运行中重放相同声明与内容,验证 ID 不变且不会重复建任务。 smoke 中的 SYNTHETIC_REVIEW_APPROVED 是只针对公开 fixture 的自动契约检查;真实资料必须由 有权限的审核人通过 /documents 检查 exact cloud text 与 manifest不能自动批准。

成功的 smoke 输出只包含不透明 ID、状态、rank、citation、模型名和重排状态不输出正文或 Secret。历史上曾用固定 fixture 连续两次验证相同 document/document-version ID数据库计数均保持

对象 幂等计数
document version 1
chunk 1
vector assignment 1
background job 2解析 1 + 向量化 1
model invocation 1

当前 smoke 每次命令都会创建带随机 nonce 的新文档,避免历史 READY 数据让当前故障误通过; 同一次命令末尾会重放同一幂等键与内容,并要求 upload、document、parse job、active version 身份 保持不变。输出中的 replay_confirmed=true 才表示该双重检查完成。该结果只适用于提交的 synthetic fixture 和当前冻结配置;换文件、切分 profile 或 embedding profile 会生成不同身份。

2. Exited (0) 不是服务暂停

docker compose ps -a 中以下两个容器应当成功运行一次后退出:

  • migrate:执行 alembic upgrade headExited (0) 表示迁移已经应用成功。
  • upload-init:以最小临时权限初始化上传卷属主和目录;Exited (0) 表示初始化成功。

它们不是长期服务,不应保持 Up,也不应配置 restart: always。只有非零退出码才代表启动 失败。长期容器的期望状态如下:

服务 期望状态 说明
db Up (healthy) PostgreSQL + pgvector
model-gateway Up (healthy) 唯一持百炼 Key 与公网出口
api / gateway / web Up (healthy) API、固定上游入口、浏览器页面
worker-local Up 只处理 document_parse,挂载上传卷,无模型网络/Token
worker-model Up 只处理 embedding,可访问模型网,不挂载上传卷

两个 Worker 的信任边界、Secret、网络和卷约束见 ADR-0007

排查时使用:

make status
docker compose logs --tail=200 migrate upload-init api worker-local worker-model
curl -sS http://127.0.0.1:8000/health/ready

不要因为 Alembic 日志最后停在 Will assume transactional DDL 就判断服务挂起;先查看容器 退出码、API readiness 和依赖服务状态。

3. 浏览器操作

访问 http://127.0.0.1:8000/documents。页面按以下顺序工作:

  1. 在浏览器本地校验扩展名、MIME 和 100 MiB 上限,并计算 SHA-256。
  2. 创建带随机 Idempotency-Key 的上传声明,随后流式写入隔离上传卷。
  3. 完成上传并轮询 PARSE_DOCUMENT 任务;本地 Worker 不调用任何云模型。
  4. 展示 display_text、拟出域的 cloud_text、来源锚点和 outbound manifest。
  5. 审核人确认 exact manifest 后批准,或选择稳定原因码拒绝。
  6. 批准后轮询 EMBED_DOCUMENT;向量完整性通过后文档才显示 READY
  7. 转到 http://127.0.0.1:8000/retrieval 检索刚刚激活的内容,或到 http://127.0.0.1:8000/chat 验证带引用的单轮问答。

当前页面的“停止”只会停止浏览器上传请求或任务轮询。后台任务一旦提交,不会因关闭页面而 被强制取消Worker 依靠租约、心跳、fencing token 和 reaper 恢复。

4. 状态机与不可绕过的门禁

upload CREATED
  -> STORED
  -> COMPLETED
  -> document QUARANTINED_LOCAL_REVIEW
  -> PARSE_DOCUMENT / worker-local
       -> LOCAL_PARSED_PENDING_CLOUD_REVIEW
       -> OCR_REQUIRED 或 FAILED禁止继续
  -> 人工审核 exact outbound manifest
       -> REJECTED终止
       -> CLOUD_APPROVED
  -> EMBED_DOCUMENT / worker-model
       -> PENDING -> EMBEDDING -> READY
  -> version READY + document.active_version_id 原子切换
  -> document READY + chunks searchable
  -> 正式 Retrieval 候选

上传成功、解析成功和审批通过都不等于“已可检索”。正式 Retrieval 的 SQL 在 LIMIT 前要求 知识库、服务端授权 scope、active version、CLOUD_APPROVED、正确 profile、READY assignment 和 searchable=true 同时成立。审批使用 review_revision 乐观并发控制,并绑定 exact outbound manifest hash旧页面、变化后的正文或变化后的 profile 不能复用审批。

当前 TXT、Markdown、DOCX 走确定性本地解析PDF 会 fail closed 为 OCR_REQUIRED。这表示系统 没有把 PDF/OCR 或地质图空间理解伪装成已完成能力。

5. API 级手工检查

Swagger 位于 http://127.0.0.1:8000/docs。入库主链使用以下接口:

方法与路径 用途
POST /api/v1/document-uploads 声明文件名、MIME、大小和 SHA-256要求 Idempotency-Key
PUT /api/v1/document-uploads/{id}/content 上传原始字节,入口上限 100 MiB
POST /api/v1/document-uploads/{id}/complete 校验摘要并创建文档/解析任务
GET /api/v1/document-jobs/{id} 轮询解析或向量化任务
GET /api/v1/documents 查看文档状态
GET /api/v1/documents/{id}/review-bundle 分页查看解析结果与 manifest
POST /api/v1/documents/{id}/review-decisions 使用 revision + manifest 批准或拒绝
POST /api/v1/retrieval/search 验证 READY 文档可检索

推荐用 make smoke-document 作为可重复验收;手工拼装请求时不要把文件正文、数据库 DSN、 内部 Token 或百炼 Key 写进 shell 历史、截图或工单。

6. 常见错误排查

现象/错误 含义 检查与处理
migrateupload-initExited (0) 正常一次性任务终态 检查长期服务是否 Up/healthy不要反复重启一次性任务
UPLOAD_*、摘要/大小不匹配 声明与实际字节不一致或上传状态冲突 重新选择原文件;不要修改声明后复用 upload ID
OCR_REQUIRED PDF 当前不在可靠解析范围 换用 TXT/Markdown/DOCX 验证;等待 OCR/PDF adapter
REVIEW_REVISION_CONFLICT revision 或 manifest 已变化 刷新 review bundle重新人工复核后提交
文档停在待审核 安全门禁正常工作 /documents 检查 cloud text 和 manifest再批准或拒绝
embedding job FAILED profile、维度、模型调用或完整性校验失败 查看脱敏 error code 和 worker-model 日志;不要直接改 searchable
文档 READY 但检索不到 scope/profile/active version 或 seed 基线不一致 先运行 make seed-offline,再检查 retrieval 的生效 profile 与 trace
百炼三能力返回 401 Key、北京工作空间、端点或模型权限不匹配 按第 7 节重新做 provider smoke401 不自动重试

日志和 API Problem 必须只包含稳定错误码、trace 和不透明 ID。若发现任何 Secret 或受限正文, 立即停止真实调用、轮换凭证并运行 make check-secrets

7. 切换到真实阿里云百炼

synthetic E2E 使用 fake embedding/rerank不需要百炼。切换真实模式前必须完成

  1. 在百炼北京地域控制台撤销任何曾出现在聊天、日志或截图中的旧 Key。
  2. 创建具备 text-embedding-v4qwen3-rerankdeepseek-v4-flash 权限的新 Key。
  3. 只把新 Key 写入已忽略的 secrets/bailian_api_key;真实工作空间 URL 只写本地部署配置。
  4. 确认 Key、专属工作空间域名、北京地域和计费方案属于同一空间。
  5. 重启 model-gateway 及调用方,运行:
docker compose restart model-gateway api worker-model
docker compose --profile tools run --rm provider-smoke

只有 Embedding、Rerank、Chat 三项最小实际调用全部成功,才能运行真实 seed-demo 和真实文档 向量化。当前已验证事实仍是三项请求到达供应商但均返回 401因此真实百炼未验收不能用 synthetic smoke 的成功替代这项外部门禁。

三项探测成功后,先运行 docker compose --profile tools run --rm seed-demo 创建独立的百炼 synthetic 知识库及 active profile再在未提交的 .env 中设置 DOCUMENT_NAMESPACE_MODE=bailian,重建 API 和模型 Worker最后运行 fresh + replay smoke

docker compose --profile tools run --rm seed-demo
docker compose up -d --force-recreate api worker-model
make smoke-document

此时上传声明的知识库/scope 仍由服务端固定选择,请求不能自行越权指定;输出中的 knowledge_base_id 应为百炼 synthetic 命名空间,向量由 text-embedding-v4 生成并写入 pgvector检索经 qwen3-rerank。切回离线回归时把该配置恢复为 fake 并重建 API。 在认证、RBAC 和资料出域审批完成前,这个开关只允许公开虚构资料,不能用于私有或真实报告。

API、浏览器、worker-local、seed/smoke 工具都不持百炼 Key。worker-model 只有内部 Worker Token真正的百炼 Key 始终只存在于 model-gateway。任何真实资料还必须先完成权利、涉密和 云处理审批;有效 Key 不等于有权把资料发送到云端。

8. 当前验证基线与剩余范围

截至 2026-07-13提交前全量门禁记录为 296 项后端测试、53 项前端测试,并完成固定身份重放与 fresh + replay 两类 Docker synthetic 产品链 E2E。正式毕业验收仍需完成真实百炼认证、PDF/OCR、真实 授权语料、多租户/RBAC、至少 300 题正式双审盲测、备份恢复、性能/并发压测、论文定稿和答辩 彩排。这些未完成项不能由本手册的 smoke 结果替代。