跳到主要内容

规模化(上)— 成本、体量与数据质量

这一章讲三件事: 一个百万文档级的 RAG 系统到底花多少钱(书里有一笔完整的账); 摄入流在百万文档规模下会怎么坏; 以及「数据天天在变」这件事怎么不让索引变成一潭死水。 这一章全是摄入侧的事;查询侧的规模化(检索质量与护栏)在下一章。

1. 顶层全景:十份文档和百万文档之间的鸿沟

书里的判断开门见山:十份文档的 RAG 谁都搭得起来,几十万到百万级时, 「建索引 + 低延迟检索」本身就是一项工程1。而且文档可能单个就巨大 ——书里举的极端例子:2002 年某一期《Federal Register》(美国联邦公报) 有 5,000 页2

这一章的主走查是书里那笔账的主角:一个客服聊天机器人,背靠 200 万份文档, 每月 15 万次查询。我们先算它的钱(第 2 节),再看它的摄入管线会怎么坏(第 3 节), 脏数据怎么混进来(第 4 节),最后看「数据在变」怎么跟上(第 5 节)。

2. 核心原理(一):一笔完整的钱账

这是全书唯一一次把成本从头算到尾,值得逐项走一遍—— 它就是本章的主走查3:

① 数据量:200 万份文档 × 每份 20 页 = 4,000 万页
② 词元总量:每页约 600 词 × 1.3 词元/词 ≈ 800 词元/页
→ 4,000 万页 × 800 = 32 亿词元
③ 初始嵌入费:embedding-large-3 按 $0.13 / 百万词元
→ 32 亿词元 × $0.13/百万 = $4,160(一次性)
④ 每月查询:15 万次查询的查询嵌入费可忽略,真正贵的是生成
生产级一次问答的输入可达 2,000-4,000 词元
(问题 + 检索到的若干块),按 4,000 输入 + 1,000 输出估
→ 约 $3,000/月
⑤ 基础设施:向量库 $500/月 + 其它算力 $500/月
+ 监控/CI/CD 等 DevOps 工具 $500/月
⑥ 增量嵌入:按月留初始嵌入费的 5-10%,约 $416/月

合计:一次性投入 $4,160;月运营 ≈ $4,916

图说:请注意结构——月度开销里生成占 $3,000(六成),基础设施占 $1,500,
嵌入只占零头。「嵌入很贵」的直觉在运营期是错的;它贵在第一次。

参照物:$4,916/月,大约是一名初级工程师月薪的一小半——一个百万文档级 RAG 系统的月度账单,是「半个不到的人」的量级。这笔账的每个假设 (20 页/文档、4,000 词元输入)都应该换成你自己的数字重算,书里给的是方法。

控成本的三个抓手

书里接着给了压成本的手段4:

  • 多级缓存:最终回答、嵌入、检索块都可以缓存——同一问题第二次来, 一分钱不花(缓存机制留到第 09 章细讲);
  • 动态模型路由:简单请求走便宜快的小模型,只有复杂任务才动用昂贵的 「推理型」模型——一个路由器按问题难度分流;
  • 盯紧每个组件:用量涨上来时,组件会升级(比如从 flash 级模型换到 pro 级),成本和工作量一起涨,要逐组件监控5

3. 核心原理(二):百万文档的摄入管线会怎么坏

书里用 Harvard Caselaw Access Project 压阵:近 700 万份判例文档6。 在这个量级,摄入管线的两大问题是脆弱7:

脆弱。 单脚本跑摄入是单点故障:在第 950,000 份文档上撞见一个坏文件、 一次网络超时、一处内存泄漏——跑了多天的任务从头再来8

慢。 单线程串行处理几百万文档,几小时的活拖成几周; 而数据处理期间源数据还在变,数据永远不新鲜9

书里给的解法分三层,都是成熟的数据工程手段:

① 并行化:Ray/Dask 做分布式嵌入,Spark 备数据,多 GPU 批处理
→ 仅单机并行化文件摄取就能提速 5-10 倍
② 编排:用 Airflow 这类工具把摄入定义成「带依赖关系的任务图」
→ 自动重试、坏文档隔离、告警但不中断;仪表盘盯 docs/sec、
chunks/sec、CPU/GPU 利用率
③ 心态转换:从「避免失败」到「管理失败」——管线必须可重启
→ 两条原则:幂等(idempotency:同一个任务重跑一遍,
结果和跑一遍一样,无副作用)与深度可观测(把「卡住的文档」
和「被逻辑过滤掉的文档」显式暴露出来)

图说:嵌入是整条管线里最吃算力的一步;几百万文档切块后可能是上万亿块,
每块是一个固定长度的向量(如 1024 个 float32 ≈ 4KB)。

作者的建议很干脆:开源框架(Apache Spark、Apache Beam、Airbyte)都是现成的, 别自建10

4. 核心原理(三):脏数据的三种长相

书里把「数据质量不一致」称为生产 RAG 最持久的暗坑之一11。 三种典型,每一种都有具体的「长相」:

脏法长什么样后果
OCR 错零件号「PO-001A4-LIMA」被认成「PO-OO1A4-1IMA」(0→O、L→1)精确检索零件号时永远找不到
样板文字每页的「Confidential—Do Not Distribute」、页眉页脚混进正文每个块都掺着同一堆噪声,稀释语义
编码错UTF-8 文件按 ISO-8859-1 读,「The user's query」变成「The user’s query」关键词变形,匹配断裂

脏数据不洗,照样被切块、嵌入、入库——污染就此进了向量空间(全部嵌入向量构成的「位置空间」),检索精度整体下滑12

书里的解法是分诊式预处理:先给每份文档做「triage」(分诊——判断这份是 原生 PDF 还是图片型 PDF、HTML 要不要去样板),再按类型路由到对应的清洗管线; 清洗规则可以按领域定制13

5. 核心原理(四):大文件与「数据在变」

单个文档就放不下怎么办

Texas Instruments 的一份技术参考手册有 17,000+ 页——整个读进内存几乎 必然 OOM(out of memory,内存耗尽)14。两条策略:

  • 流式处理:逐页读、逐页出块,峰值内存大降,还能尽早开始产出;
  • 按页区间并行:把页码分给多个 worker 各处理一段——注意别把一个 跨页表格从中间劈开15

书里的代码例拿一本 352 页的公开教科书,按每 50 页切成子 PDF 再分头处理16

索引新鲜度:从批处理到秒级

数据天天变,全量重建索引对几百万文档来说太慢太贵17。书里的路径分三层:

  1. 增量更新:只处理新增/修改/删除的文档;检测变更用 CDC (change data capture,变更数据捕获——监听数据库的日志(数据库对每次数据增删改的记录))。

    事务(一批要么全做要么全不做的数据库操作)的每一步都记在这份日志上,每行变更都会变成一个事件18;

  2. 秒级可检索:客服知识库里一篇新修法文章发布后,聊天机器人必须立刻能答 ——否则它还在给过时方案。手段:更快的解析与嵌入、异步处理 (「确认收到」与「后台索引」解耦)、选为低延迟更新设计的向量库19;

  3. 选型对照:书里按写作时点评了各向量库的即时索引适配度—— Qdrant 最高(Rust 实现、为实时更新设计),Pinecone 与 Weaviate 次之, Milvus 对索引类型敏感,Elasticsearch/OpenSearch 的向量索引延迟略高20

6. 作者的判断与证据

  • 成本算例是作者构造的演示算例,每个假设都明写(20 页/文档、600 词/页、 150K 查询/月),数字前后一致、可复算——作为「算账方法」的示范价值高于具体数字
  • 「5-10 倍提速」「两条原则」是工程经验陈述,方向可靠,倍数因场景而异。
  • 向量库适配度表是 2026 年时点的快照,半年内就可能过时。

7. 边界与局限

  • 本章没有讨论合规驱动的删除(GDPR「被遗忘权」要求把某人的数据从所有 衍生块里移除)——这个更硬的问题第 16 章才回来。
  • 脏数据一节给了分类与分诊思路,没给「清洗到什么程度算干净」的验收标准—— 第 11 章的检索评测是唯一诚实的裁判。
  • 编排一节假设你能用云/内部集群(多台机器联合干活的一组服务器);air-gapped 环境的编排没有展开。
  • 「嵌入只占成本零头」依赖 OpenAI 的嵌入定价;自部署 GPU 嵌入时账会重排。

8. 可带走的

  1. RAG 的钱账结构:一次性嵌入费 + 月度(生成费 ≈ 六成 + 基础设施 + 增量嵌入);运营期的大头是生成,不是嵌入;
  2. 百万文档摄入的两大病是脆弱与慢:解法是并行化 + 编排 + 「管理失败」的心态;
  3. 幂等与深度可观测是摄入管线的两条设计原则:任务可安全重跑;卡住的和被丢弃的都要显式可见;
  4. 脏数据三长相:OCR 错、样板文字、编码错——分诊式预处理,按文档类型路由;
  5. 17,000 页的单文件靠流式 + 按页区间并行,别劈开跨页表;
  6. 新鲜度三件套:CDC 检测变更、异步解耦摄入、选实时友好的向量库;
  7. 别自建摄入框架:Spark/Beam/Airbyte 已经存在。

9. 原文地图

主题原书章原文位置
百万文档的难、Federal RegisterVolume and Complexity of Documentstext/30-fm-volume-and-complexity-of-documents.txt:4(搜「hundreds of thousands」) · :7(搜「Federal Register」)
成本算例Cost Management and Optimizationtext/32-fm-cost-management-and-optimization.txt:10(搜「2M documents」) · :16(搜「$4160」) · :25(搜「$4916」)
缓存与动态路由Cost Management and Optimizationtext/32-fm-cost-management-and-optimization.txt:37(搜「dynamic model routing」) · :37(搜「cache」)
Caselaw、脆弱与慢Handling a Large Volume of Documentstext/33-fm-handling-a-large-volume-of-documents.txt:4(搜「Caselaw」) · :25(搜「950,000」) · :31(搜「single-threaded」)
并行/编排/幂等Handling a Large Volume of Documentstext/33-fm-handling-a-large-volume-of-documents.txt:64(搜「Airflow」) · :79(搜「restartable」) · :83(搜「idempotency」) · :96(搜「5–10× speedup」)
脏数据三类、分诊Dealing with Inconsistent Data Qualitytext/34-fm-dealing-with-inconsistent-data-quality.txt:13(搜「PO-001A4」) · :36(搜「triage」)
17,000 页手册Handling Large Documentstext/35-fm-handling-large-documents.txt:4(搜「Texas Instruments」)
按 50 页切分例Example: Splitting a Large PDF Filetext/36-fm-example-splitting-a-large-pdf-file.txt:4(搜「Sutton」)
CDC、实时索引Managing Document Updates and Refreshtext/37-fm-managing-document-updates-and-refresh.txt:16(搜「change data capture」) · :7(搜「real-time indexing」)
向量库适配度表Managing Document Updates and Refreshtext/37-fm-managing-document-updates-and-refresh.txt:43(搜「Qdrant」)

Footnotes

  1. 出处:「Volume and Complexity of Documents」第 4 段(text/30-fm-volume-and-complexity-of-documents.txt:4,搜「hundreds of thousands」)。

  2. 出处:「Volume and Complexity of Documents」第 7 段(text/30-fm-volume-and-complexity-of-documents.txt:7,搜「Federal Register」)。

  3. 出处:「Cost Management and Optimization」第 10-25 段(text/32-fm-cost-management-and-optimization.txt:10,搜「2M documents」;:16,搜「$4160」;:25,搜「$4916」)。

  4. 出处:「Cost Management and Optimization」第 37 段(text/32-fm-cost-management-and-optimization.txt:37,搜「dynamic model routing」)。

  5. 出处:「Cost Management and Optimization」第 43 段(text/32-fm-cost-management-and-optimization.txt:43,搜「gemini-2.5-flash」)。

  6. 出处:「Handling a Large Volume of Documents」第 4 段(text/33-fm-handling-a-large-volume-of-documents.txt:4,搜「Caselaw」)。

  7. 出处:「Handling a Large Volume of Documents」第 19 段(text/33-fm-handling-a-large-volume-of-documents.txt:19,搜「brittleness」)。

  8. 出处:「Handling a Large Volume of Documents」第 25 段(text/33-fm-handling-a-large-volume-of-documents.txt:25,搜「950,000」)。

  9. 出处:「Handling a Large Volume of Documents」第 31 段(text/33-fm-handling-a-large-volume-of-documents.txt:31,搜「single-threaded」)。

  10. 出处:「Handling a Large Volume of Documents」第 96 段(text/33-fm-handling-a-large-volume-of-documents.txt:96,搜「5–10× speedup」)与第 99 段(同文件,搜「Apache Spark」)。

  11. 出处:「Dealing with Inconsistent Data Quality」第 4 段(text/34-fm-dealing-with-inconsistent-data-quality.txt:4,搜「gotcha」)。

  12. 出处:「Dealing with Inconsistent Data Quality」第 30 段(text/34-fm-dealing-with-inconsistent-data-quality.txt:30,搜「polluting」)。

  13. 出处:「Dealing with Inconsistent Data Quality」第 36 段(text/34-fm-dealing-with-inconsistent-data-quality.txt:36,搜「triage」)。

  14. 出处:「Handling Large Documents」第 4 段(text/35-fm-handling-large-documents.txt:4,搜「Texas Instruments」)。

  15. 出处:「Handling Large Documents」第 7 段(text/35-fm-handling-large-documents.txt:7,搜「incremental」)与第 10 段(同文件,搜「page ranges」)。

  16. 出处:「Example: Splitting a Large PDF File」第 4 段(text/36-fm-example-splitting-a-large-pdf-file.txt:4,搜「Sutton」)。那本书是 Sutton & Barto 的强化学习教材,我们书架上也收了它(reinforcement-learning-sutton-barto)。

  17. 出处:「Index Freshness」第 7 段(text/31-fm-index-freshness.txt:7,搜「Full re-indexing」)。

  18. 出处:「Managing Document Updates and Refresh」第 16 段(text/37-fm-managing-document-updates-and-refresh.txt:16,搜「change data capture」)。

  19. 出处:「Managing Document Updates and Refresh」第 7 段(text/37-fm-managing-document-updates-and-refresh.txt:7,搜「real-time indexing」)与第 22 段(同文件,搜「asynchronous」)。

  20. 出处:「Managing Document Updates and Refresh」第 32-69 段(text/37-fm-managing-document-updates-and-refresh.txt:43,搜「Qdrant」),原书 Table 3-1。