RAG 产品化实战
RAG 产品化实战:从 demo 到可信知识库
demo 级 RAG 与可信产品级 RAG 的差距,集中在四个方面:检索质量(文档一多就答非所问)、知识新鲜度(文档改了索引没跟上)、护栏(引用、拒答、幻觉防控)与评测(上线前后怎么量化好坏)。本文承接 RAG 原理 与 知识库问答设计,技术原理细节见 检索技术 与 高级 RAG,按「产品化路线图 → 索引运营 → 检索质量工程 → 失败模式与兜底 → 成本与性能 → 客服案例」的链路讲产品化决策,关键结论均附权威来源,内容为原创整理。
产品化路线图:从可演示到可扩展
demo 与生产的差距清单
demo 演示时文档量小、测试问题预先知道答案,答错可以换个问法;上线后要面对的真实差距是:
- 检索召回不足:文档量上来后,纯向量检索召回变差,答非所问成为头号问题——PromptingGuide 的 RAG 综述把基础 RAG(naive RAG)的局限总结为低精确率与低召回率
- 幻觉:模型答出资料里没有的内容,且用户很难察觉
- 知识更新滞后:源文档改了,索引没有同步,答案停留在旧版本(见 ai/rag.md 关键环节表 的「知识更新」行)
- 成本:embedding、rerank、LLM 生成每一轮都要花钱,量上来后账单超出预期
- 时延:检索 + 重排 + 长上下文生成层层叠加,交互变慢
- 评测缺失:demo 靠「感觉答得不错」,上线后没有评测集与监控,改动了什么、改好改坏都说不清
demo 为什么显得好
demo 有三重滤镜:文档量小(检索不易失焦)、问题预先知道答案(答错就换个问法)、没有真实用户压力(答错没有代价)。上线 = 同时撤掉这三重滤镜——所以「demo 能答」不是「生产能答」的证据,评测集基线才是。
四个阶段:可演示 → 可信 → 可运营 → 可扩展
| 阶段 | 定位 | 进入条件 | 常见卡点 | 达标信号 |
|---|---|---|---|---|
| 可演示 | 给内部/客户看效果 | 一份种子文档库 + 一条检索问答链路 | 只挑了「预先知道答案」的问题演示 | 30–50 条真实问题的评测集跑通 |
| 可信 | 敢让真实用户用 | 引用溯源 + 拒答 + 权限过滤 + 评测集基线 | 以为「demo 能答 = 生产能答」 | 评测集基线达标,答错有归因路径 |
| 可运营 | 能持续变好 | 错案回流闭环 + 知识更新流水线 + 监控 | 评测集不更新、错案不回流 | 无答案率/采纳率可监控,SLA 有告警 |
| 可扩展 | 能承载规模与多场景 | 成本与延迟预算内、多租户隔离、灰度发布 | 成本失控、权限随租户数爆炸 | 延迟/成本按预算,改动走灰度回归 |
每个阶段的进入条件具体化:
- 进入「可信」:回答必须带可点击核对来源;资料没有就拒答;权限过滤在检索层生效;评测集(30–50 条真实问题,标注答案与应命中文档 id)跑出基线——没有这三样,用户用起来就是「答错了也不知道该怪谁」
- 进入「可运营」:错答案例回流 → 归因(修文档 / 修检索 / 修提示词)→ 修复 → 补进评测集的闭环跑起来;文档变更 → 索引更新有流水线;线上指标(无命中率、top-1 相关率、点踩率)有监控与告警
- 进入「可扩展」:成本与延迟有预算(见「成本与性能」);多租户隔离验证过;换模型、改切块这类改动有灰度流程(先评测集回归,再小流量对比,再全量)
各阶段的典型产出:可演示 → demo 评测集 + 选型记录;可信 → 基线报告 + 护栏清单;可运营 → 监控看板 + 回流 SOP;可扩展 → 成本模型 + 灰度流程。
常见误解是「可运营」必须全量知识库——不是:20–100 条种子集就能进入「可信 → 可运营」的循环,范围扩不扩由评测集与错案密度决定(路径见下文客服案例)。
阶段转换检查清单
| 转换 | 完成前必须验证 |
|---|---|
| 可演示 → 可信 | 引用溯源可用(点击直达原文)/拒答不硬编/低权限账号调 API 检不到高权限内容/评测集基线已记录 |
| 可信 → 可运营 | 错案回流闭环跑通一轮/文档更新流水线有告警/无命中率与 top-1 相关率有监控/检索与回答日志落库 |
| 可运营 → 可扩展 | 成本模型与预算有数/延迟预算达标(p95 在场景预算内)/多租户隔离验证过/灰度流程走完一次 |
「可信」不是一次验收的结果
常见误解是「上线即可信」。可信是这套闭环持续运转的状态:评测集在扩充、错案在回流、指标在监控——一旦停止,系统会悄悄退化(新文档没入库、新问题没人测、旧问题改了又回来)。
索引运营:生产核心
demo 阶段索引是一次性建的;生产阶段索引是持续运营的资产——切块怎么切、文档怎么更新、元数据怎么设计,直接决定检索质量的长期表现。
从源文档到索引:入库流水线
| 环节 | 生产要求 | 常见坑 |
|---|---|---|
| 解析 | 文本型 PDF 直接提取;扫描件先 OCR;表格整表保留 | 表格被拆散、页眉页脚混入正文 |
| 结构化 | 标题层级、条款编号、流程步骤保留;HTML/Markdown/代码用对应解析器 | 条文与正文分离,命中编号看不到内容 |
| 去重 | 同一主题多版本/转载合并,标注唯一来源;来源可信度分级 | 重复文档互相打架,模型随机挑一个 |
| 元数据 | 类型、部门、版本、更新时间、权限标签、来源可信度——入库时打好 | 事后再补等于重跑一遍入库 |
| 切块 | 切法与 embedding 模型匹配,参数可配置 | 在句子中间硬切、列表被拆散 |
| 嵌入 | 语言与领域匹配(中文库别用英文为主的模型) | 语义距离退化,检索命中率崩 |
| 校验 | 每批入库抽样 N 个块人工检查(语义完整、元数据齐全) | 烂块静默入库,线上答错才发现 |
「入库即校验」是索引运营的第一道质量门:抽样检查成本低,但能把「切块碎、元数据缺、内容错」三类问题拦在上线前。
切块策略的迭代:固定长度 vs 语义切块 vs 父子块
切块决定检索单元的大小与边界,是「RAG 的第一工程决策」(原理见 检索技术 的「切块策略」)。产品化视角看三种策略的取舍:
| 策略 | 适合 | 生产注意 | 一句话 |
|---|---|---|---|
| 固定长度 | 长度均匀的日志/条款 | 会在句子中间硬切,中文还要避免切词 | 简单但粗暴 |
| 递归切块 | 大部分文档 | 表格、代码要先用对应解析器提取 | 实用默认 |
| 语义切块 | 连贯叙述型文档 | LlamaIndex 官方 node parser 文档注明其断句正则主要面向英文,中文/多语言要实测 | 质量好、成本高 |
| 父子块 | 需要精确检索 + 完整上下文 | 小块嵌入做精确检索、命中后把父块一起给生成(AutoMergingRetriever 思路) | 窄检索宽上下文 |
- 没有普适最优切法:PromptingGuide 的 RAG 综述指出不同 embedding 模型对块大小偏好不同(如 ada-002 时代 256–512 token 块效果较好),不存在放之四海皆准的切法——
chunk_size/chunk_overlap必须做成可配置参数,在同一评测集上对比后再定 - 块内上下文缺失严重时,还可以考虑上下文化切块:切块后先让模型为每块补一段「上下文说明」(所在文档、主题、与其他块的关系)再嵌入与检索,命中率提升明显,代价是每块多一次模型调用(Anthropic Contextual Retrieval)
- 切块变更 = 索引重建:改切块参数意味着全库重切、重新嵌入——这是成本最高的一次改动,做之前先问:badcase 里「切块问题」的占比够高吗?评测集上有前后对比数据吗?
- 重建的成本与回滚:重建前冻结当前索引(或保留上一版向量库快照),新索引跑评测集 + 小流量灰度,确认无劣化再切换;切块参数是配置,不是代码——回滚 = 切回旧配置重刷,而不是改代码重新发布
- 换策略的判断信号:badcase 归类里「切块问题」占比高(检索命中但块内容残缺、答案被切断在边界);评测集上候选策略的命中率差 > 3–5% 才值得动手——切块迭代是全库成本最高的改动,必须有评测数据支撑,不拍脑袋
- 结构化内容先解析再切:代码、表格、HTML、Markdown 先用对应解析器提取再决定切法——表格可以整表一块、代码按函数切、Markdown 按标题层级切(口径见 检索技术)
- 块大小起点:256–512 token 是常见起点(经验值非铁律),长文档知识库可试 512–1024;overlap 10–20% 起步,答案常跨边界时加大——全部做成配置,评测集对比后定案(口径见 检索技术)
- 切块选型操作步骤:① 用默认递归切块出基线;② badcase 归类——「块内上下文缺失」占比高 → 试父子块或上下文化切块,「句子被切断」占比高 → 换语义切块或调大 overlap;③ 每个候选策略在同一评测集上对比命中率与端到端指标,再定案
文档更新与删除:增量索引、失效条目、版本一致性
- 增量索引:LlamaIndex 官方文档管理页明确索引支持 insert / delete / update / refresh 四种操作,其中
refresh_ref_docs()按文档 id 与内容哈希去重,只更新内容变化的文档、插入新增文档,是「同步经常变化的源目录」的推荐模式;前提是显式设置文档 id(如用文件名当 id) - 失效条目处理:文档下架时同步删除对应块并记录原因,避免「问了一个已下架的流程,答案还是旧的」;「删除」与「更新」分开记录日志,便于排查
- 版本一致性:源文档带版本号与更新时间;知识条目记录「来源版本 + 更新时间」,回答引用时能回溯到具体版本;发布顺序固定为先改源文档、再刷新索引——「文档改了但没刷索引」是线上答案停留在旧版的最常见原因
- 版本差异大的文档(如制度大改)建议整体重建索引,而不是依赖逐块 update——旧块的「幽灵引用」更难排查
- 产品化做法:把「源文档变更 → 刷新索引」做成定时或事件驱动的任务,并暴露「最后同步时间」供监控
- 更新频率分层:高频变更文档(FAQ、价格表)走事件驱动(webhook 或消息队列),低频变更(制度、手册)定时扫描即可——不要对所有文档用同一套同步策略,高频的等不起定时器,低频的用事件驱动是浪费
- 触发方式选型:文档系统有 API/webhook 就事件驱动;只有文件系统就定时扫描(mtime + 哈希);两者都不可靠时靠「人工触发 + 最后同步时间展示」兜底——先有同步,再谈自动化
- 同步失败的可见性:同步任务失败要告警而不是静默重试——「索引没刷」比「刷错了」更隐蔽;每次同步的 diff 摘要(新增 X 篇 / 更新 Y 篇 / 删除 Z 篇)写入日志,供抽查
- 同步延迟 SLA 示例:制度类 24 小时内、FAQ/价格类 1 小时内、事故公告类实时(事件驱动)——SLA 按「答案过时的代价」定,不是一刀切;超时告警进值班流程
- 索引版本管理:索引与源文档集版本一一对应,切换索引像切换代码版本——记录「源文档集版本 + 切块参数 + embedding 模型 + 构建时间」,出问题能定位「这个答案来自哪个索引版本」
- 文档拆分/合并:一篇文档拆成两篇(或反之)时,旧块全部失效——按文档 id 整体删除重建,不要逐块修补;文档改名时保留旧 id 别名,避免引用断裂
元数据与过滤:权限、时间、来源如何落到索引
元数据是索引运营的「第二层结构」:给每个块带上(文档类型、部门、版本、更新时间、权限标签),检索时先按元数据缩小候选集,既提质量又省 rerank 成本。
- 文档级权限:权限标签随元数据入库,检索前按用户权限过滤——权限标签入库时打好,不是查询时临时拼;敏感文档不进公共索引(详见 kb-qa.md 权限控制)
- 时间过滤:知识新鲜度可以靠元数据实现——Qdrant 官方混合查询文档展示了在融合结果后用公式打分叠加按时间衰减的加权,新文档得分更高;也支持硬过滤(只查某个时间窗口内的文档)
- 时间过滤的两种形态:硬过滤(只查某时间窗口,适合「按版本查」)与软加权(时间衰减,适合「默认给最新」)——用哪种取决于产品语义:「要最新版」用软加权,「查历史版」要硬过滤开关
- 来源过滤:按文档类型、来源可信度分级(官方文档 vs 员工上传)过滤或加权,冲突时权威源优先(见 kb-qa.md 知识管理)
- 数据安全:embedding 与向量库的传输和存储加密、日志不落问答全文、API key 按最小权限发放;合规场景(医疗、法律、金融)留存审计记录——谁在什么时间问了什么、检索命中了哪些文档
- 权限标签设计:粒度按「文档级」起步(同一文档同权限),确需细分时再下探到「块级」——块级标签维护成本高;标签命名与组织架构对齐(部门 / 职级 / 项目组),避免一套标签多种含义
- 元数据缺失的后果:权限过滤、时间衰减、引用溯源全部做不了——元数据要入库时打好,事后再补等于重跑一遍入库
知识冲突处理
- 同一问题两份文档结论矛盾时:给文档配优先级/权威级元数据(以最新版本、以权威源为准),检索时按此加权
- 定期扫描「同主题不同结论」的文档对,可以借助评测集里的冲突问题主动暴露
- 无法裁决时,如实列出两种说法并各带来源,而不是让模型自行圆场;PromptingGuide 的 RAG 综述把这类对抗性输入下的表现归入评测的鲁棒性维度
- 冲突处理的优先级顺序:先查版本(旧版压新版?)→ 再查权威级(员工上传 vs 官方制度)→ 最后才是如实并列——把「哪份为准」的决策留给业务方定规则,不要留给模型临场发挥
检索质量工程
检索质量工程的目标,是让「正确的块」稳定地进入模型上下文——OpenAI 官方 Cookbook 的检索问答范例用「开卷考试」类比:模型权重是长期记忆、检索到的上下文是翻开的笔记——检索到什么,决定答案能有多可信;该文还指出,事实性回忆场景检索优于微调,微调更适合风格与任务教学。检索质量 = 产品体验上限:检索不到,生成再好也没用——预算分配上,检索侧的投入(切块、混合、重排、评测集)通常回报最高。线上管线的典型形态是:混合检索取候选 → rerank 收敛 → 元数据与权限过滤 → 生成;下面按「取舍 → 诊断 → 评测」展开。
混合检索(BM25 + embedding + rerank)的产品取舍
- 向量检索擅长语义匹配(「报销流程」命中「差旅费用报销规范」),BM25 擅长精确词匹配(型号、编号、人名、专有名词),两者互补——文档量上来后,混合检索是召回质量最实在的兜底(原理见 检索技术)
- Qdrant 官方混合查询文档给出可落地的融合方案:同一份数据同时建稠密向量(语义)与稀疏向量(词匹配),子查询各自检索后用融合算法合并。融合方式三种:RRF(按名次融合,
k默认 2,官方视为安全默认)、加权 RRF(有评测集时用 train/val 划分调权重)、DBSF(保留原始分数、按分布归一化后相加,适合信任原始分数量级的场景);官方还明确提醒:不要对两种分数做固定比例线性加权——两种分数尺度不同,加权结果不可比 - 选型提示:像 Qdrant 这类原生支持混合查询的数据库,把两路检索与融合收敛在存储层,自己不用拼两个检索器、维护融合逻辑;选型时优先看数据库是否内置混合检索与融合算法
- LangChain 官方 reranker 文档把 rerank 描述为「对 RAG 流水线质量提升最大的单点改进之一」:先便宜检索取大 top-k(如 20),再把「问题」与「文档」两两配对直接打分,重排后只留 top-n(如 3–5)
- 托管方案:Cohere Rerank API按「问题 + 文档列表」返回重排结果,支持 100+ 语言,按 search units 计费,另有 fast 变体降本提速
- 先拿 BM25 出基线再叠加向量检索:BM25 零训练成本、可解释性强——评测集上「BM25 就够」就不要再加向量路,复杂度只出现在评测证明必要的地方(原则见 Building Effective Agents)
- 稀疏向量的实现注意:BM25 路的「分词 + 自定义词典」直接决定精确匹配质量(产品名、型号不能被错误切分)——词典维护是持续成本,把高频新词(新产品名)纳入更新流程(适配细节见 检索技术 的 BM25 领域适配)
产品取舍:不是全都要,而是看评测集。每一层都有代价:
| 组件 | 收益 | 代价 | 什么时候值得上 |
|---|---|---|---|
| BM25 关键词路 | 精确术语召回,几乎零边际成本 | 分词器与词典维护 | 库里有型号/编号/专有名词——几乎总是值得 |
| 混合融合(RRF) | 两路互补,召回兜底 | 融合逻辑(优先选原生支持的向量库) | 评测集显示单路召回不足时 |
| rerank | 「提升最大的单点改进之一」 | 每候选一次模型推理,延迟与成本随 top-k 涨 | 预算允许、badcase 显示「检到了但排得靠后」时 |
工程要点:融合的候选集合要够大(各路各取 top-k 如 50,融合后取前 5–10 进生成),避免「某一路的相关块被另一路挤掉」;融合前先按元数据过滤缩小候选集,省后续精排成本;融合参数(各路权重、RRF 的 k)都是可调参数,一律用评测集定,不拍脑袋。
何时可以不上 rerank:候选集小(单路 top-10 就够)、延迟预算极紧(首 token < 1 秒)、评测集显示 rerank 后命中率提升 < 3%——rerank 是「提升最大的单点改进之一」,但不是每个场景都需要(对比见 检索技术)。
检索失败的诊断方法:查不到 vs 查到错的
两个症状相似但修复手段完全不同,排查第一步先分清楚:
- 查不到(召回不足):该检的块没进 top-k,回答「没有相关资料」——问题在切块、embedding 或查询侧。诊断动作:换个说法搜一下、直接在块里搜关键词——块里有但检索不到,是召回问题;块里根本没有,是知识治理问题(文档没入库/没切对)
- 查到错的(排序/切块问题):检到了但排位靠后,或检到错的块,答非所问——问题在排序侧:rerank 没上、融合权重不对、top-k 太小把相关块挤掉了;也可能是切块把答案切散,相关块存在但内容残缺
诊断顺序(与 ai/rag.md 排查顺序 一致):切块 → 检索 → 生成 → 引用,从前往后。先确认「相关块到底在不在检索结果里」:在 → 排序问题;不在 → 召回问题。方向错了,后面的修复全是白费。
自查三连:同一问题换个说法(「报销」→「差旅费用」)还能检索到吗?精确术语(型号、编号)能检索到吗?top-k 里相关块排第几?——三个问题分别测语义路、关键词路与排序(完整清单见 ai/rag.md 检索质量自检清单)。
检索失败排查清单
① 相关块在块库里搜得到吗?——搜不到是知识治理问题(文档没入库 / 没切对);② 相关块进 top-k 了吗?——没进是召回问题;③ 进 top-k 但排位靠后?——排序问题;④ 块内容残缺(答案被切断)?——切块问题;⑤ 权限 / 时间过滤误杀?——元数据问题。
检索质量的评测:命中率、MRR、RAGAS 的适用与限制
- 第一步是人工评测集:收集或编写 N 个代表性真实问题(常见、长尾、应拒答、跨文档、多轮),标注标准答案与「应命中的文档 id」——这是所有自动评估的地基,也是每次改动的回归基准;每发现一个线上错案就补进去
- 检索层指标:LlamaIndex 官方评测文档的 RetrieverEvaluator 内置 hit rate(该命中的是否命中)与 MRR(命中的排序位置是否靠前);检索评测要批量跑而不是逐条看——单次检索好坏说明不了问题
- 端到端指标:RAGAS 官方指标文档的 faithfulness(回答与检索上下文的事实一致性)与 answer relevancy(是否答所问)覆盖生成侧;context recall / context precision 对应检索侧(上下文覆盖度与噪声比例)
- 适用与限制:RAGAS 是相对评测工具,分数用于对比与回归,不是绝对质量;LLM-as-judge 打分可规模化,但判断器可能偏爱冗长或自带立场,需要定期人工抽检校准(方法论见 评估与评测)
- 标注成本怎么控:检索线标注(应命中文档 id)最贵,按「每类问题先标 5–10 条」起步,覆盖类型比数量重要;回答线标注让领域专家标「要点 + 应拒答」,LLM 生成候选只作参考(口径与 RAG 基础 的评测集构建一致)
- 标注粒度:检索线标注「应命中的文档 id」起步(块 id 太细、标注成本高),命中率不达标再下探到块级定位——先粗后细,别一上来就标块
- 报告分组:评测结果按问题类型分组(常见 / 长尾 / 跨文档 / 多轮),整体数字会掩盖结构性短板——「多轮追问全挂」只有分组才看得到
- 组件级与端到端分开跑、对起来看:检索命中率 100% 不保证回答正确(生成可能无视资料),回答正确也可能检索很烂(答案在常见知识里)——组件级定位「哪一环坏了」,端到端衡量「用户体感」(体系见 高级 RAG 的「RAG 评测体系」)
- 指标速查:
| 指标 | 衡量什么 | 哪条线 | 来源 |
|---|---|---|---|
| hit rate / MRR | 该命中的是否命中、是否排得靠前 | 检索线 | LlamaIndex 官方评测文档 |
| context recall / precision | 检索上下文覆盖度、噪声比例 | 检索线 | RAGAS 官方文档 |
| faithfulness | 回答是否忠实于检索来源 | 回答线 | LlamaIndex / RAGAS |
| answer relevancy | 是否答所问 | 回答线 | RAGAS 官方文档 |
评测与监控:从评测集到线上闭环
- 上线前:评测集覆盖五类问题(常见、长尾、应拒答、冲突文档、多轮追问);来源从真实用户日志收集(冷启动期可从客服工单、FAQ 话题、同事提问中收集),答案与应命中文档由领域专家标注,LLM 生成的候选只作参考;30–50 个问题起步即可暴露主要问题,随后随反馈闭环持续扩充
- 跑通两条指标线并记录基线:检索线(hit rate / MRR / context recall / context precision)+ 回答线(faithfulness / answer relevancy)——用评测集做技术选型(是否上混合检索、是否上 rerank、选哪个 reranker、块大小),Qdrant 官方文档建议用评测集在 RRF / 加权 RRF / DBSF 之间选择,因为「二者没有谁普遍更优」;每次改动(chunk 参数、embedding 模型、rerank 模型、提示词)都重跑评测集,防止「改好了 A 坏掉了 B」
- 上线后监控:检索指标(无命中率、top-1 相关率抽样人工标注)、回答质量(点赞/点踩、人工抽检 faithfulness、LLM-as-judge 抽样评分趋势)、知识新鲜度(索引最后同步时间、源文档更新到答案可见的延迟,超 SLA 报警)
- 反馈闭环:错答案例回流 → 归因(修文档 / 修检索 / 修提示词,与 kb-qa.md 评估标准 一致)→ 修复 → 补进评测集防回归
- 变更走灰度:embedding 模型、rerank 模型、chunk 参数这类改动,先在评测集上回归,再小流量灰度对比线上指标,确认无劣化再全量——避免「上线当天才发现答错率上升」
- 调参纪律:一次只动一个变量(切块 / 融合权重 / rerank top-k),重跑评测集记录前后对比——同时改两个参数,出了问题不知道是谁的错;每次实验留「问题 → 假设 → 实验 → 结论」记录,避免重复踩坑
- 阈值起点示例(示意,按你场景调):faithfulness ≥ 0.85、hit rate ≥ 0.8、无命中率 < 5%——先出基线再定红线,红线是「相对基线下降 X 点就拦截」,不是拍脑袋定绝对值
- 评测集与生产链路隔离:测试用例一旦进入提示词或训练数据就失效(评测集污染)——评测集版本管理、定期轮换新增(见 评估与评测)
检索日志与 badcase 回流
- 日志要打什么:用户问题(脱敏)、改写后查询、检索命中的块 id、各路贡献(向量路 / 关键词路)、融合与 rerank 分数、最终进上下文的块——没有这些字段,错案归因只能靠猜
- 监控指标:无命中率(检索空结果比例)、top-1 相关率(抽样人工标注)、检索延迟分位数(p50 / p95)、检索失败率(向量库超时 / 报错)——上线前定阈值,上线后告警
- 看板口径:一条「无命中率」时间线 + 一张「top-1 相关率」抽检表 + 一张「错案分类」周表,就够运营早期使用——不要一开始就堆十几个指标,先跑通三个
- 回流节奏:每周固定抽检错案归类(召回 / 排序 / 切块 / 生成 / 知识缺),修好后补进评测集——没有日志与回流,检索优化就是盲调;「命中块 id」与「用户是否满意」关联起来,还能发现「检到了但用户不满意」的深层问题
- 日志合规:检索日志含用户问题与命中内容,属于敏感数据——脱敏、限权、留存期按数据合规要求定(见 出海与合规)
失败模式与兜底
生产环境的失败不是「答得不好」一句话,而是可枚举、可检测、可兜底的模式。失败模式之间有因果层级(切块失败 → 检索失败 → 生成失败 → 引用失败),前面环节的失败会传染给后面——排查永远先查上游(见 ai/rag.md 失败模式的层级关系)。四大高频失败模式:
| 失败模式 | 症状 | 检测方法 | 产品兜底 |
|---|---|---|---|
| 幻觉 | 回答里出现资料没有的内容,用户难察觉 | 抽样跑 faithfulness(回答论断能否由引用来源支持) | 提示词约束「只基于资料」;低于阈值的回答标记或拦截;高风险场景人工审核 |
| 引用错配 | 来源并不支持对应论断(张冠李戴) | 引用校验:回答里的编号必须在真实来源集合内 | 生成时强制使用真实块编号;引用正确率单独评估;用户可点开核对 |
| 知识过期 | 文档已更新,答案还是旧的 | 索引最后同步时间、源文档更新到答案可见的延迟 | 增量更新流水线 + 同步延迟 SLA 告警(见「索引运营」) |
| 权限泄漏 | 低权限用户拿到高权限内容 | 上线前用低权限账号直接调 API 验证;审计日志抽查 | 权限过滤在检索前生效,且每一路召回都过滤(见 高级 RAG 的权限放大案例) |
| 多轮失焦 | 追问后回答跑偏 | 多轮样本的检索命中率骤降 | 检索输入带「本轮问题 + 上文摘要 + 上轮命中文档」,话题切换重置状态(见 高级 RAG 的多轮对话检索) |
幻觉护栏的分层
- 提示词约束:只基于检索资料回答,资料不足以回答时声明;模型补充的常识性知识与资料结论分开标注
- 自动化护栏:上线前与抽样监控中跑 faithfulness 评测,低于阈值的回答标记或拦截
- 场景分级:高风险场景(医疗、法律、合规、金融)增加人工审核环节或提高拒答阈值——护栏的严格程度要与场景风险匹配
- 护栏分级决策(按场景风险):
| 场景风险 | 例子 | 护栏强度 |
|---|---|---|
| 低 | 内部知识库、员工自助问答 | 引用 + 拒答 + 抽样 faithfulness 监控 |
| 中 | 客服对外回复 | 引用 + 拒答阈值收紧 + 话术合规 + 转人工兜底 |
| 高 | 医疗 / 法律 / 金融建议 | 上述全部 + 人工审核 + 提高拒答阈值 + 审计留痕 |
- 拒答阈值不是一次定死的:每轮评测后按「误拒率 × 应拒漏答率」的曲线调——阈值调高误拒变多(用户被推走),调低漏答变多(幻觉风险),用评测集找平衡点(口径见 kb-qa.md 拒答正确率)
- 多轮对话是护栏的重灾区:追问时上文丢失,检索失焦,模型容易拿旧上下文硬答——ai/rag.md 关键环节表已列出此坑;产品上建议把「本轮问题 + 上一轮检索命中的文档」一起作为检索输入,并限制轮次内的话题漂移
无答案兜底与转人工
- 资料里没有就明确说「没有相关资料」,不要硬编;拒答不是缺陷,而是可信度的一部分(PromptingGuide 的 RAG 综述把「负面拒答」列为 RAG 鲁棒性评测的一个维度)
- 降级路径设计:检索低置信 → 引导澄清问题 → 给 FAQ 链接 → 转人工;客服等场景下,降级到标准话术比硬答更好
- 转人工要「带着上下文转」:把用户问题、已尝试的检索、低置信原因一并转给人工,人工不用重新问一遍——这是「自动化解决 + 人工兜底」边界上的常见做法(linux.do 客服自动化的工程实现)
- 降级话术示例(示意):「这个问题我暂时没有找到资料,已为你转接人工客服,工单号 XXXX」——给用户下一步,而不是只给「不知道」
- 兜底的衡量:转人工率(自动解决不了的占比)、转人工后的解决率与用户满意度、无答案率按主题归类——兜底不是「失败率」,是「降级质量」:转得准、接得住,用户不会因为转人工而流失
- 无答案率要拆开看:「检索空结果」与「检索到但拒绝回答」是两类问题——前者是知识/召回问题,后者是阈值问题;合并统计会掩盖真实短板(口径见 kb-qa.md 评估标准)
成本与性能
RAG 的成本与延迟是叠加结构:embedding 存储是一次性 + 维护成本,检索与 rerank 是每次查询的边际成本,LLM 生成是每次问答的大头。算账方法见 LLM 成本测算,这里讲 RAG 特有的决策。
预算动作线:写 PRD 前算单次成本(三步法)→ 上线前定延迟预算与成本红线 → 上线后按月回填账单校准 → 每次加组件(rerank、查询改写)前先算增量成本。
成本构成
| 项 | 性质 | 决定因素 | 优化手段 |
|---|---|---|---|
| embedding 存储 | 一次性 + 增量 | 块数量 × 向量维度 × 索引类型 | 维度按数据量选(768/1024 对多数场景够用);HNSW 吃内存、IVF-PQ 省内存 |
| embedding 计算 | 入库与查询时 | 文档量与查询量 | 增量索引只重算变化的文档 |
| 检索(ANN/BM25) | 每次查询 | 候选集大小、索引参数 | 调 efSearch / nprobe 控延迟(见 检索技术) |
| rerank | 每次查询 | top-k 大小 × 候选数 | 只对候选集重排,不对全库重排 |
| LLM 生成 | 每次问答 | 输入(检索块 + 上下文)与输出长度 | 重排后只留 3–5 个块;提示词精简吃缓存折扣 |
非模型成本要单列:存储、向量库、评测与标注人工、人工兜底(客服转人工)——模型 token 费通常只占总成本一半上下(口径见 LLM 成本测算)。
向量维度与存储的直觉账:768 维 × 100 万块约 3 GB(按 float32 计,量化后更低)——维度减半存储减半,效果未必差多少,值得在评测集上测(口径见 检索技术)。
延迟预算
| 场景 | 延迟预算 | 做法 |
|---|---|---|
| 实时助手 / 语音 | 首 token < 1 秒 | 小 top-k、轻 rerank、向量库走内存 |
| 客服问答 | 2–3 秒 | 标准混合检索 + rerank |
| 异步分析报告 | 10 秒+ | 可上多路召回 + 大 top-k + 更强 rerank |
预算怎么用:p95 达标、p50 留余量;「首 token 延迟」与「端到端延迟」分开记——客服场景首 token 快但端到端 2–3 秒是常态。
降本决策原则
- 每次问答成本 = 检索 + rerank + 生成,量上来后按「单次成本 × 调用量」预算(见 LLM 成本测算);AI 客服这类「长输入、短回复」场景输入占大头,优化重点是压上下文与缓存
- rerank 的 top-k 与生成块数是最直接的成本旋钮:top-50 → rerank → top-5,比「直接取 top-5」质量好、比「top-20 全进生成」便宜
- 查询处理(改写、多查询)每多一次 LLM 调用都是钱,先测基线再决定上不上(见 高级 RAG)
- 单次成本预算示例(示意数字,以官方定价为准):客服问答输入 2k token + 输出 300 token 的旗舰模型单次约 1–2 美分,加检索与 rerank 后乘 1.2–1.5 工程系数——日 10 万调用就是每月数千到上万美元量级,必须在写 PRD 前按 LLM 成本测算 的三步法算清
- 优化顺序:先压检索链路(top-k、ANN 参数、rerank 候选数),再考虑生成侧(换快模型、流式、分级路由)——检索侧的优化通常免费且不影响答案质量,生成侧的优化往往要权衡质量
- 上线后按月回填真实账单,校准成本模型——预算不是一次算完,是持续校准
托管 vs 自建:成本与运维的取舍
| 组件 | 托管 API | 自建 | 决策要点 |
|---|---|---|---|
| embedding | 按 token 计费,零运维 | 模型部署 + 显存 | 量小用托管;量大且稳定再自建 |
| rerank | Cohere 等按 search units 计费 | CPU 可跑小模型(如 bge-reranker-v2-m3) | 延迟敏感先本地小模型 |
| 向量库 | 云托管(Qdrant / Milvus 等) | 自部署 | 数据量、运维人力、合规(数据不出域) |
- 模型分级路由:简单问题(FAQ 直答、查数值)走小模型 / 快模型,复杂问题才调旗舰——检索成本固定,生成侧分级是最大的省钱杠杆(分层思路见 LLM API 与供应商)
案例:客服知识库从 20–100 条种子文档起步
为什么用客服举例:客服知识库是「权限、时效、评测、兜底」四件事都占全的场景——对外答错有代价(要求拒答与兜底)、FAQ 高频变更(要求增量索引)、内外权限不同(要求检索层过滤)、自动化比例可度量(要求评测指标)——这套方法可以直接平移到企业知识库等其他场景。
与 AI 产品开发生命周期 的客服工单助手走查口径一致:不要一上来就想「全量知识库」,而是用 20–100 条种子文档/参考数据起步,按代理权阶梯逐步扩展。
- 种子文档(20–100 条):从历史客服工单、FAQ、产品文档里挑高频问题对应的条目,整理成「问题 + 标准答案 + 应命中文档」的参考数据集——规模够暴露主要问题即可,关键是真实问题分布,不是自己出题自己答
- v1 只答高频:只覆盖种子集范围内的主题(对应 ai-lifecycle 走查的 v1 工单路由阶段:先用种子集把「用户 query → 应答/应路由」跑通),答不上来就转人工——先保证不犯错
- v2 建议解决方案:客服界面显示「要点 + 引用来源 + 采纳/修改」,采纳率作为质量指标(ai-lifecycle 走查里 v2 的评测是检索质量,Top-3 命中 ≥ 70%)
- v3 全量知识库 + 自动解决:种子集随反馈闭环扩充(每解决一个错案就补进评测集),逐步放开检索范围;自动解决率与转人工率双达标后才升级代理权
- 持续运营:产品发版 → FAQ 更新 → 增量索引 → 监控无答案率;错案回流归因(修文档 / 修检索 / 修提示词)
种子集怎么选:优先「高频 × 有标准答案」的条目(FAQ 前 50 问、工单高频主题);覆盖问题类型(查询 / 流程 / 比较 / 边界);每条必须能标出应命中文档——标不出应命中文档的问题不要进种子集。
冷启动常见失败:种子集从「文档目录」里随便挑(不是从真实问题分布挑);只标答案不标应命中文档(检索线没法评);一上来就追求「全部文档都能答」(范围失控)——三条都对应同一个定位:「种子集是评测集 + 参考数据集的载体」。
阶段推进的指标与兜底(与 ai-lifecycle 走查口径一致):
| 版本 | 覆盖范围 | 评测指标 | 兜底 | 升级条件 |
|---|---|---|---|---|
| v1 工单路由 | 种子集覆盖的主题 | 路由准确率 | 客服一键改路由,修改写回日志 | 改路由率达标 |
| v2 建议解决方案 | + 知识库检索 | 检索质量(Top-3 命中 ≥ 70%)+ 建议采纳率 | 客服可编辑建议后再发送 | 采纳率达标且无误导客诉 |
| v3 自动解决 | 全量知识库 | 自动解决率、转人工率、投诉率 | 用户可一键转人工 | 转人工率与投诉率双达标 |
客服知识库的特殊权限问题:对外回答要「只答可公开内容」,对内(客服工作台)才能检索内部 SOP——同一个知识库要支持「对外白名单视图」与「对内全量视图」两种权限面,权限标签在检索前过滤(产品决策见 kb-qa.md 权限控制);预算与阈值(延迟 2–3 秒、无答案率阈值、转人工率与自动解决率双指标)在 v1 就要定,不要等 v3。
最小起点
如果只有一周时间:建 30 条评测集 + 一个 BM25 基线 + 引用溯源,先跑通「可信」的最小闭环——比搭全量检索管线更有价值。
这条路径的关键认知:种子文档不是「内容少一点的知识库」,而是「评测集 + 参考数据集的载体」——从第一天就积累「问题 → 应命中文档 → 标准答案」三元组,后面每一步扩展都有回归基准。社区实践的共识也是:先把高频问题答稳、把人工兜底留好,再谈自动化比例(linux.do 客服自动化的工程实现)。
规模演进:30–50 条起步 → 每轮 CC 循环扩充 → 数百条后按类型分层(回归集 + 探索集)——评测集是活的资产,不是一次建完的文档(节奏见 kb-qa.md 评估节奏)。
小结:从 demo 到可信知识库的最小路径
把上面各节收拢成一条可执行的落地顺序:
- 建评测集:30–50 个真实问题,标注答案与应命中文档,记录基线指标
- 上混合检索与 rerank,用评测集在 RRF / 加权 RRF / DBSF 与 reranker 型号之间选型
- 补元数据:类型、版本、更新时间、权限标签,让检索层过滤生效
- 接知识更新链路:源文档变更 → 刷新索引 → 监控同步延迟
- 接护栏:引用溯源、拒答策略、faithfulness 阈值与人工抽检
- 灰度上线,错答案例回流补进评测集,防回归
每一步都有对应的衡量方式(见上文各节),「可信」不是一次验收的结果,而是这套闭环持续运转的状态。
最典型的失败路径
跳过评测集直接上线 → 上线后凭感觉调参 → 越调越乱 → 知识库不更新 → 用户流失。这条路径的每一步都是「省了当天的事,欠了长期的钱」——路线图里每个阶段的卡点,都是前人踩过的坑;回到正轨的办法也只有一条:从建评测集重新开始。
来源说明
本文为原创整理,主要依据以下权威来源(截至 2026-08 均已核实可达):
- LangChain 官方文档:Cross encoder reranker——rerank 原理、用法与模型选型
- Qdrant 官方文档:Hybrid Queries——混合检索与 RRF / DBSF 融合、按时间衰减加权
- Cohere 官方文档:Rerank Overview——托管 rerank 服务与计费
- LlamaIndex 官方文档:Node Parser Modules——chunk 策略与解析器
- LlamaIndex 官方文档:Document Management——增量更新与 refresh 去重
- LlamaIndex 官方文档:Evaluating——检索与回答评测(hit rate / MRR / FaithfulnessEvaluator)
- RAGAS 官方文档:Metrics——端到端评测指标(faithfulness、answer relevancy、context precision、context recall)
- Anthropic 官方文档:Citations——引用溯源与原文段落返回
- OpenAI 官方 Cookbook:Question answering using embeddings-based search——检索问答范式与「检索优于微调」的讨论
- dair-ai Prompt-Engineering-Guide:RAG——RAG 范式演进、块大小研究与鲁棒性评测综述
- linux.do:客服自动化的工程实现——社区实测的客服自动化工程做法(自动化解决 + 人工兜底的边界设计)
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:AI-PM Wiki Team
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用