06. RAG 工程
六、RAG 工程¶
RAG 不是”把文档喂给模型”,而是把文档处理、索引构建、检索、排序、上下文装配和生成接成一条证据链。系统面对私有知识、频繁更新制度和带权限边界的资料时,先把可靠材料找出来,再在其上组织答案。RAG 解决的不是”模型记住更多”,而是”系统怎样把证据稳定地送到回答里”。
这个判断确立后,各技术会自然落位。MinerU、OCR、切块和元数据补全解决”原始资料怎样变成可信索引对象”。BM25、dense retrieval、hybrid search、rerank 和 ANN 索引解决”候选证据怎样被召回和排序”。版本、权限、缓存、增量更新和多模态检索解决”这条链能不能真正上线”。评测回答”到底是哪一层变好了”。RAG 的难点大多在资料处理、过滤、召回和排序。
总判断:RAG 是一套证据系统¶
普通问答可以直接把问题和上下文交给模型。RAG 场景中,模型不知道公司最新制度、私有知识和当前有效版本,系统必须先查再答。”查”不是把整本手册塞进上下文,而是围绕问题做一轮受控检索,筛出最值得信任的材料。RAG 因此会遇到一系列传统后端问题:文档生命周期管理、版本切换、权限收束、引用可追溯、索引重建、时延和成本控制。
RAG 包含四个模块:离线建库(解析、清洗、切块、向量化、写入索引),在线检索(过滤、召回、hybrid、rerank、证据装配),线上治理(版本、权限、缓存、延迟、引用一致性),评测闭环(证明哪一段在变好)。先把这四段装进脑子,后面学 BM25、HNSW、GraphRAG 或 Ragas 才不会变成热词记忆。
离线建库:先把原始资料变成可检索资产¶
离线建库决定线上答案是否有证据底座。demo 通常只喂干净的 Markdown 或 FAQ 文本,真实企业资料则是 PDF、扫描件、网页、长表格、图文混排、制度附件和截图混合。前处理粗糙,检索几乎一定失真。离线链路推荐拆成:摄取、版面解析、OCR、结构抽取、清洗、切块、元数据补全、embedding、索引写入。标题层级、表格关系、页码和生效状态必须保住,否则 BM25、向量召回、引用定位和版本切换都会变脆。
工业文档处理不是”OCR 识别率越高越好”。传统 OCR 把图像里的字读出来,适合票据和纯文本截图。版面理解回答阅读顺序、栏位关系、标题层级和表格边界,适合多栏和图文混排。结构抽取更进一步,把表格、字段、标题树和引用位置变成后续检索可用的对象。MinerU 代表将这些能力串成”文档智能”链路。默认起步可从 OCR 加轻量结构化开始,但需要跨页表格、稳定引用、字段级 BM25 或版本定位时,应切到结构保真路线。
MinerU 先识别标题、正文、表格、图片、脚注和阅读顺序,再做结构抽取和块级归一化。跨页长表格不能在翻页处直接切断,否则表头、列语义、备注和单位一起断掉。需补行延续识别、表头继承、跨页语义合并和结构归一化。
切块是信息组织,不是字符串截断。固定长度切块简单、吞吐稳定,但对标题、段落、列表、代码块和表格边界无感知。递归字符切片更适合作为默认方案,先尊重语义边界,不够放时再退到细粒度。文档类型别混着切:FAQ 按问答对,制度按标题和条款,代码保持完整,表格先做结构化抽取。
overlap 补的是切块边界造成的语义断裂。太小,跨段条件和引用范围被切坏。太大,制造重复候选,放大 rerank 和上下文装配成本。按文档类型和平均块长来定。
元数据补全决定在线检索的能力边界。文档标题、章节位置、页码、租户、部门、版本、生效状态、更新时间、文档类型,这些字段决定能否做强过滤、回跳引用、以及在旧版和新版并存时给出正确答案。
在线检索:分层缩小证据集¶
在线检索是分层缩小证据集,而非一次相似度计算。推荐顺序:问题理解、标量过滤、第一轮召回、hybrid 合并、第二轮 rerank、上下文装配、引用准备。过滤层排掉不该看的内容。召回层保证不漏关键证据。精排层把”有点相关”压到”真正能回答问题”的段落后面。上下文装配把最值得看的证据组织成模型吃得下的材料。
BM25 在企业检索中依然重要,因为企业问题大量存在编号、术语、岗位等级、产品名、错误码、接口名这类强关键词信号。它比 TF-IDF 更稳定的原因是词频饱和和长度归一化。最小公式:
score(q, D) = Σ IDF(t) * TF_sat(t, D)
TF_sat(t, D) =
f(t, D) * (k1 + 1)
-----------------------------------------
f(t, D) + k1 * (1 - b + b * |D| / avgdl)
IDF(t) = log((N - n(t) + 0.5) / (n(t) + 0.5) + 1)
f(t, D) 是词 t 在文档 D 中出现次数,|D| 是文档长度,avgdl 是全库平均文档长度,N 是文档总数,n(t) 是包含词 t 的文档数。公式回答三件事:词越稀有 IDF 越高;词频通过 TF_sat 饱和,重复十次不比重复两次重要五倍;长文被长度归一化轻度惩罚。
k1 调词频饱和速度:越大,边际收益越慢饱和,适合词重复次数有区分度的场景;越小,重复几次后不再加分,适合短字段。b 调长度归一化强度:b = 0 不看长度,b = 1 最强。字段化检索和 FAQ 不希望长度惩罚太强。Lucene 默认值只是通用起点,文档长度分布、字段形态和分词策略一变,最优区间跟着变。
BM25 落地时,公式只是最后一层,倒排索引和分析器更关键。倒排索引最小对象:term -> posting list(docID, term_freq, positions...)。分析器决定哪些 token 进入索引。企业场景小心过度清洗——错误码、岗位等级、型号、版本号被停用词误伤,BM25 参数怎么调都救不回。字段级 BM25 与全文 BM25 要分清,按字段建索引和权重:
这不是固定公式,但标题命中和正文命中不该同权处理。
稀疏召回、稠密召回、Hybrid search、GraphRAG 和长上下文直接塞全文的选型:编号、术语、错误码明显的问题先靠稀疏召回。用户说法和文档写法差异大时,稠密召回更有价值。多数企业系统从 Hybrid 起步,兼顾成本、复杂度和稳健性。GraphRAG 只在实体关系密集时更值得。材料规模小、边界清楚时,直接塞长上下文。
embedding 模型选型看六件事:语义质量、维度、吞吐、价格、时延、领域适配。维度越高,存储、网络和索引成本越高。吞吐越低,离线建库越容易拖慢。内存直觉:
1000 万 条 1024 维向量,每维 4 字节,原始向量接近 40 GB,未算索引和元数据。embedding 维度直接影响索引类型、缓存策略和部署成本。
query rewrite 解决用户表述不完整。多 query 扩展解决单个 query 难以覆盖多个语义面。HyDE 先生成”假想答案”再向量召回,适合用户问题模糊的场景。共同风险是 query drift——重写漂离原意。对改写链单独做评测,验证 Recall@K 提升是否覆盖 drift 风险。
Hybrid search 把稀疏和稠密两类信号组织成召回系统。先标量过滤,再并行跑关键词和向量召回,去重和分数对齐后交给 rerank。分数对齐可用 rank fusion、RRF、分位归一化或通道内标准化。两路分数不是同一量纲。RRF:
它不关心原始分数能否比较,只关心候选在各通道里的名次是否稳定靠前。工业系统偏爱先做 rank fusion 再 rerank。
rerank 用更精细的匹配判断把有限上下文预算花在最值得的候选上。调优抓手:候选集大小、batch size、序列截断长度。候选集太小无发挥空间,太大会增加时延和成本。rerank 解决排序,不解决过滤、权限或索引问题。
ANN 索引:HNSW 是多层近邻图,从高层跳到低层再局部扩展。M 控制连边数,efConstruction 影响建图质量,efSearch 影响查询探索宽度。图边数 ≈ 向量数 × M。IVF 先分中心簇再簇内查,nlist 控制倒排簇数,nprobe 控制查询探针数。PQ 压缩向量表示,子空间数 m 和 bit 数决定精度。三者不是替代关系,是不同规模、内存预算和更新需求下的取舍。
标量过滤在线上 RAG 中是主路径能力。时间范围、租户、部门、版本、生效状态、文档类型应在召回前进入查询计划,否则旧版、越权或无关资料先被召回,rerank 和模型白花钱纠错。
Precision 和 Recall 按层权衡:召回层目标是别漏,精排层目标是别乱。
Agent 里的检索按证据缺口触发¶
Agent 不要把向量检索当成每轮固定动作。触发条件分三类:问题依赖外部证据(制度问答、工单状态),在生成前触发建立证据边界;工具或状态暴露事实缺口(缺 claim_id 或时间范围),检索作为受控 read-only tool;回答阶段需补引用,只查特定证据。是否触发检索,取决于当前状态是否有证据缺口。
知识库查询工具的输入输出契约¶
检索接进 Agent 后,成为正式工具。输入至少包含:query、intent、tenant_scope、filters、top_k、rerank_k、need_citations。输出为结构化证据列表,带 chunk_id、doc_id、score、source_title、page、version、freshness、snippet、evidence_type。rerank、引用、冲突仲裁和长期记忆写入才有正式对象可接。
线上治理:权限、版本、更新、缓存和多模态¶
检索能力是及格线,治理决定能否上线。权限和版本最先浮现。企业系统在当前用户有权看到的资料里找最相关内容。检索阶段保留 chunk ID、文档标题、章节位置、页码、版本号和文档状态,后端兜底返回引用。版本切换有明确依据,不靠 prompt。
Milvus 的 Collection 是强隔离单元,适合生命周期、索引策略、权限边界独立的数据集。Partition 适合同一 schema 下按分类、租户、时间分组。选型先看过滤边界强度、更新频率、数据规模、是否需要独立生命周期。默认顺序:能用 metadata filter 先不拆库,分组长期稳定再考虑 Partition,隔离边界强到需独立生命周期才上多 Collection。
增量索引意味着解析结果、切块结果、倒排索引、向量索引、rerank 缓存、引用映射和线上缓存一起切换。三种常见缓存:query cache 挡重复问题,embedding cache 挡重复向量化,result cache 挡全链路重复计算。key 设计和版本、租户、时间窗口绑定。
多模态检索分通道处理:文本语义、视觉特征、OCR 结果、结构字段分别处理,召回或精排阶段权重组合。排查顺序:OCR 是否保住关键字段 → embedding 与检索通道配置 → 通道权重 → 精排与回答。
多模态接入链:原件落对象存储,媒体元数据入库,分发到 OCR/版面解析/CV 组件,抽结构化字段、区域框和可检索文本。
GraphRAG 适合关系密集、实体关联强的场景(组织架构、事故因果链)。收益是实体与关系显式化;成本是实体抽取、对齐、图谱更新复杂度上升。制度问答和 FAQ 用普通 chunk 检索加 rerank 即可。
评测闭环:先分问题类型,再看指标,再做优化¶
评测先按问题类型拆。编号与术语型、规则例外型、权限敏感型、版本更新型、多模态、关系密集型问题打在检索链的不同位置。评测分三层:检索层(正确材料是否进入候选集、过滤是否生效、排序是否把关键证据放前),答案层(是否忠于证据、是否漏掉限制条件、引用是否可核验),业务层(追问率、人工接管率、引用点击率、延迟、单位问题成本)。
Ragas 的 Faithfulness 看答案判断能否在上下文找到支持;Answer Relevance 看是否真正回应用户问题;Context Precision 衡量上下文里真正相关的内容比例。
排序指标:Recall@K 看召回层,MRR 看首个正确结果排位,nDCG 看整体排序质量。先用 Recall@K 看召回层,再用 MRR 或 nDCG 看 rerank 层,最后和 Context Precision、Faithfulness、业务指标对照。
优化顺序:源文档和结构保真 → 切块与元数据 → 过滤和召回 → hybrid 与 rerank → 上下文装配和回答约束。每次改动能说清修的是哪一段。