RAG 不是技术问题,是工程方法论问题

这页不教你从零入门,而是回答”为什么 Demo 跑通了系统还是不好用”。重点是评估、badcase、实验设计、边界判断和项目落地顺序。

标签:评估优先 | Golden Dataset | 实验记录 | 方案边界

这页负责项目落地、评估和边界判断,不负责概念入门。


Page Summary

  • 这页解决什么:把”能跑 Demo”升级成”能评估、能迭代、能讲边界”的工程化方法。
  • 必须记住的结论:没有黄金数据集和指标,就没有有效优化;没有边界判断,就没有可信方案。
  • 读完后的动作:先整理 20-30 条真实 badcase,再建立 Golden Dataset 和实验记录表。

01 五步工程方法论

先有标准,再有系统,再有优化

核心原则: 不要在没有评估标准的情况下开始构建系统。“感觉还不错”不是工程结论。黄金数据集要在写第一行检索代码之前就存在。


步骤 0 · 定义 MVP 边界(先于一切)

不要盲目开始写代码。三个核心问题必须先回答清楚,否则你在为一个模糊的目标优化。

  • 用户是谁? → 内部员工 / 外部客户 / 特定角色(如销售、客服)
  • 具体用例? → 一个用例,不是三个。“企业知识问答”太宽,“销售合同条款查询”才对。
  • 数据源清单? → 1~2 个高质量数据源,不要上来就接十个系统。
  • 成功标准? → 6 周内,用什么指标判断系统”可用”?先写下来。

⚠️ 避免过度扩张:每增加一个数据源,系统复杂度非线性增加。


步骤 1 · 构建黄金数据集(在建系统前)

这是整个项目的”尺子”。没有它,后续一切优化都是直觉驱动,而不是数据驱动。

  • 来源优先级: 真实用户 query(最好)> 手工标注 > LLM 合成(最快但质量最低)
  • 最小规模: 20 条可以起步,50~100 条才有统计意义
  • 覆盖维度: 难度(简单/中等/困难)× 类型(事实性/概念性/流程性)
  • 必须做: 8:2 拆分为开发集和测试集。测试集封存,不参与任何调参。

⚠️ 用测试集调参 = 在为特定数据集过拟合 = 指标虚高 = 上生产后打脸。


步骤 2 · 构建初始检索系统 + 量化评估

用最简单的方法建立基线,然后立刻量化。不要在没有基线数字的情况下开始优化。

  • 起点: 向量检索(Dense)作为基线,不要上来就上混合检索
  • 核心指标: Recall@K(有没有找到)/ MRR(找到的排在第几位)
  • 分块策略: 先用固定大小+overlap(200~500字,10%~20%重叠),记录基线分数
  • Embedding: 先用 text-embedding-3-small,有瓶颈再换

✓ 基线分数是后续所有优化的参照点。“比基线高”才是有效优化。


步骤 3 · 构建回复系统 + 手动错误分析

先接 LLM 生成回答,然后手动读 30~100 条失败案例。这一步不能跳过。

  • 为什么要手动读? 自动化评估需要你先知道”要检查什么”。手动读是发现失败模式的唯一方法。
  • 记录格式: query → 检索到的 chunks → 最终回答 → 失败类型 → 根因
  • 自动化时机: 找到规律后,用关键词检查或 LLM-as-judge 自动化高频失败模式的检测

步骤 4 · 运行受控实验 + 迭代

每次只改一个变量。改了两个变量,你不知道是哪个起作用的。

  • 实验优先级: 先优化检索(数据质量、分块),再优化生成(Prompt)
  • 为什么检索先于生成? 检索决定天花板,Prompt 只能在这个天花板内发挥。
  • 何时进入生产? 开发集指标稳定后,用测试集做最终评估。测试集只用一次。

步骤 ∞ · 生产监控 + 持续迭代

上线不是终点。生产流量会暴露测试集没有覆盖的问题。

  • 必须监控: 每次检索的 Recall(在线代理指标)/ 用户满意度 / 响应延迟
  • 持续更新数据集: 把生产中的 badcase 手工标注后加入黄金数据集
  • 知识库更新策略: 增量入库(只算新文档的 embedding)/ 不重算全库
  • 定期重评估: 每月用最新黄金数据集跑一次完整评估,防止指标悄悄退化

02 失败模式分类手册

读完 30~100 条 badcase 后的规律总结

这里的失败模式来自实践归纳。遇到新的 badcase 时,先对照这个分类找根因,不要上来就换模型——80% 的问题出在数据和检索上,不在生成上。


检索层 · F-01 召回缺失(Miss)

症状:相关内容明明在知识库里,但就是没被检索到。模型要么说不知道,要么用训练数据凑答案。

根因:

  • ① 分块太小,关键信息被切断
  • ② Embedding 模型不适配领域语言
  • ③ 专有名词、缩写、产品型号被泛化
  • ④ top-k 设置太小

修复方向:

  • → 加大 chunk_size / 增加 overlap
  • → 换领域适配的 Embedding 模型
  • → 引入 BM25 混合检索(补关键词)
  • → 增加 top-k,配合 Reranker 精排

检索层 · F-02 噪声命中(Noise)

症状:检索到了内容,但返回的 chunk 大量不相关,稀释了真正有用的信息。模型被噪声干扰,答案跑偏。

根因:

  • ① 分块太大,一个 chunk 包含多个主题
  • ② top-k 设置太大
  • ③ 相似度阈值太低,不相关 chunk 也被召回

修复方向:

  • → 减小 chunk_size,使每块主题单一
  • → 加入相似度阈值过滤(< 0.7 直接丢弃)
  • → 引入 Reranker 做二次精排
  • → 使用 Parent-Child 分块策略

检索层 · F-03 排序错误(Misrank)

症状:正确答案被召回了,但没排在前面(排在 Top-3 以外)。LLM 处理上下文时更关注靠前的内容,答案质量因此下降。

根因:

  • ① Bi-encoder 语义相似度打分不精准
  • ② 查询和正确答案表达方式差异大
  • ③ 关键词命中率影响了排序

修复方向:

  • → 引入 Cross-encoder Reranker(精排专用)
  • → 查询改写(让 query 更贴近文档表达)
  • → 实验 HyDE(先生成假设答案再检索)

生成层 · F-04 上下文幻觉(Hallucination)

症状:检索到了正确内容,但 LLM 没有完全基于它回答,混入了训练数据里的”记忆”,造成细节错误。

根因:

  • ① System Prompt 约束不够强
  • ② 参考资料与训练数据有矛盾
  • ③ 模型倾向于”补全”而非”引用”

修复方向:

  • → 强化 Prompt:“只能基于以下资料回答,不得添加资料外的内容”
  • → 要求模型引用来源 [1][2]
  • → 用 Faithfulness 指标自动检测幻觉

生成层 · F-05 答非所问(Irrelevance)

症状:技术上检索和生成都”成功”了,但回答没有切中用户真正的问题。用户说”有帮助”但”不是我要的”。

根因:

  • ① 用户意图模糊,没有做查询理解
  • ② Prompt 没有引导模型聚焦核心问题
  • ③ 回答过于发散

修复方向:

  • → 澄清模糊 query(让模型先确认理解)
  • → 加强 Prompt 中的”聚焦”指令
  • → 用 Answer Relevancy 指标检测

系统层 · F-06 知识库过时(Staleness)

症状:回答内容在技术上是准确的,但基于的是旧版本的文档。产品已更新,文档没更新,导致误导用户。

根因:

  • ① 没有文档版本管理机制
  • ② 增量更新流程缺失
  • ③ 旧文档没有被标记或删除

修复方向:

  • → 为每个 chunk 附加 metadata:version, updated_at
  • → 检索时过滤旧版本文档
  • → 建立文档变更触发的自动重入库流程

系统层 · F-07 多跳缺失(Multi-hop Failure)

症状:问题需要综合两份不同文档的信息才能回答,但单次检索只拿到了其中一份,答案不完整。

根因:

  • ① 单次检索设计,无法处理跨文档推理
  • ② 用户问题包含隐式依赖关系

修复方向:

  • → 实现 Multi-hop RAG:第一次检索结果作为第二次检索的 query
  • → 引入 Agentic RAG,让模型自主决定检索次数
  • → 构建知识图谱(GraphRAG)

系统层 · F-08 超出知识库(Out of Scope)

症状:用户问的问题知识库里根本没有,但系统没有识别出来,而是用相关度最高但不准确的 chunk 凑了一个答案。

根因:

  • ① 没有相似度阈值判断”是否能回答”
  • ② 没有设计拒答逻辑

修复方向:

  • → 设置相似度阈值:全部 chunk 得分低于阈值 → 触发”超出知识库”回复
  • → Prompt 中明确指示:“如果资料中没有,必须说不知道”
  • → 定期分析”知识盲点”并补充文档

03 实验记录模板

一次只改一个变量

实验的核心纪律: 每次实验只改一个变量。改了两个变量,你不知道哪个起作用,下次就不知道该保留哪个。“感觉更好了”不是结论,数字说话。

实验日志示例(用于记录课程 v1→v10 的迭代过程)

版本变更内容Recall@3 变化MRR 变化结论 / 备注
v3 基线ChromaDB + chunk=200 + overlap=40 + text-embedding-3-small— (基线)— (基线)建立基线数字,后续所有版本与此对比
v4-exp1Embedding 换成 BGE-M3(中文领域模型)+0.08 ↑+0.05 ↑中文专业术语场景显著提升;通用问题基本持平;API成本降低
v4-exp2Embedding 换成 text-embedding-3-large(更大维度)+0.03 ↑+0.01 ↑提升有限,但成本翻倍。不值得,回退到 exp1 的 BGE-M3
v5-exp1加入 BM25 混合检索(alpha=0.5)+0.12 ↑+0.09 ↑专有名词、产品型号 query 命中率大幅提升;通用 query 无明显变化
v5-exp2调整 alpha=0.3(减少 BM25 权重)-0.02 ↓-0.01 ↓alpha=0.5 是更好的配置,保留
v6-exp1加入 bge-reranker(召回 Top-20,精排取 Top-3)+0.06 ↑+0.15 ↑MRR 提升显著,正确答案排名更靠前;p99 延迟增加 300ms
v7-exp1加入 HyDE 查询改写+0.05 ↑+0.04 ↑概念性问题提升明显;事实性问题提升不大;额外增加一次 LLM 调用成本

实验纪律: 每次实验只改一个变量 · 同一数据集(开发集)评估 · 记录延迟和成本变化 · 所有实验结果保留,不删除”失败”记录

评估指标速查

指标公式说明
Recall @ K命中数 / 查询总数前 K 个结果里有没有包含正确答案。最重要的检索指标——天花板由此决定。
MRRavg(1 / rank)相关文档排在第几位。不只看”找到了”,还看”排在哪里”。
FaithfulnessRAGAS 框架生成的答案有没有忠实于检索资料,没有编造内容。反映幻觉程度。
Answer RelevancyRAGAS 框架答案有没有切中用户问题。检索和生成都正确,但答非所问仍算失败。

04 项目启动检查清单

开始写代码之前必须全部过一遍

业务定义(第 0 步)

  • 用户是谁已明确(具体到角色,不是”企业用户”)
  • 具体用例已定义(单一用例,不是”全能助手”)
  • 数据源清单已确认(1~2 个,有访问权限)
  • 6 周成功标准已书面定义(量化指标)
  • 数据安全 / 合规要求已了解(是否涉及敏感数据)

评估准备(在写代码前)

  • 黄金数据集至少 20 条已准备(手标优先)
  • 开发集 / 测试集已拆分(测试集已封存)
  • Recall@K 和 MRR 评估脚本已可运行
  • 基线评估已完成并记录(有数字才能比对)

检索系统

  • 分块策略已选定并有数字支撑(对比实验完成)
  • Embedding 模型已选定(中文场景考虑 BGE 系列)
  • 向量数据库已配置(含 metadata schema 设计)
  • 相似度阈值已设定(低于阈值触发拒答逻辑)

生产准备

  • 已完成 30+ 条手动错误分析(找到主要失败模式)
  • 主要失败模式已有自动化检测(代码或 LLM-judge)
  • 延迟 p50/p99 已测量(知道用户实际等待时间)
  • 成本估算完成(每月 embedding + LLM token 费用)
  • 测试集最终评估完成(用且仅用一次)

05 RAG 方案边界

知道什么时候不该用 RAG,和知道什么时候该用同样重要

RAG 不是银弹。向客户推荐方案时,如果你能说出”这个场景用 RAG 反而不合适,因为……”,你的专业度会立刻比只会推 RAG 的人高出一个档次。

场景推荐方案不推荐判断依据
知识库有限(< 50 页),内容稳定,问题类型固定Fine-tuning 或 Prompt EngineeringRAG 过度设计内容少到可以直接放进 System Prompt,RAG 带来的工程复杂度不值得
私有文档频繁更新(每天有新内容),不能有知识截止RAG(增量入库)Fine-tuning(更新成本太高)Fine-tuning 每次更新都要重新训练,成本不可接受;RAG 只需要增量 embedding
问题需要精确数字推理(财务计算、代码执行)Tool Use + 结构化数据库查询纯 RAG(检索文本,无法精确计算)LLM 算数不可靠;结构化数据应该用 SQL/API 查询,不是向量检索
知识库超大(百万级文档),延迟敏感(< 200ms)RAG + 语义缓存 + ANN 优化 + 向量库分级存储朴素 RAG(单节点、无缓存)朴素 RAG 在大规模下延迟不可控;需要工程优化
多文档综合推理(需要跨 5+ 个文档才能回答一个问题)GraphRAG 或 Agentic RAG(多跳)经典单跳 RAG(一次检索搞不定)单次检索只能召回局部信息;需要有状态的多轮检索或知识图谱
高安全合规要求(金融、医疗),不能有任何幻觉RAG + 强 Faithfulness 检测 + 人工审核机制完全自动化无人工节点LLM 幻觉无法完全消除;高风险场景必须有人工审核兜底

06 售前背景的核心差异化

工程能力 + 业务理解 = 稀缺组合

纯工程师知道怎么写代码,但不知道这个系统在业务上解决了什么问题,也不知道怎么向客户解释技术决策。这正是你的优势所在。

能力 01 · 从业务需求推导技术方案

客户说”我们想做知识库问答”,你能问出”用户是谁、问的是什么类型的问题、数据在哪里”——这三个问题比直接写代码更重要,也是方法论第 0 步的核心。这是大多数工程师问不出来的问题。

能力 02 · 量化标准 → 项目提案

黄金数据集的方法论直接对应项目提案的”成功指标”章节。你可以在方案里写:“第 2 周交付 30 条黄金数据集和基线 Recall@3;第 4 周目标 Recall@3 > 0.85”——这是可落地的承诺,不是模糊的”提升效率”。

能力 03 · 向非技术人员解释技术决策

你能用”这个方案的边界在哪里”这张表,向客户解释为什么推荐 RAG 而不是 Fine-tuning,为什么选混合检索而不是纯向量。这不是炫技,是建立信任——客户需要知道你理解他们的场景,不是在卖技术方案。

综合优势 · 最有价值的产出:可复用的工程资产

每个项目积累的东西:黄金数据集(下个项目可参考结构)、失败模式记录(形成 checklist)、实验日志(形成决策依据)、方案边界文档(形成销售材料)。

这些不只是技术文档,也是下一个项目的提案素材——“我们在类似场景做过,Recall@3 从 0.62 提升到 0.89,用的是这套方法论”。这才是售前转型后真正的核心竞争力。


关联阅读

  • 要回到组件全貌:去知识地图看模块关系。
  • 要解释方案边界:去 5D 完全理解看对比、场景和常见误区。
  • 要快速找概念和参数:去文档索引。