每次有人问“知识库怎么搭”,我都会先反问三个问题。不是卖关子,是因为这三个答案会直接决定后面要不要做 RAG。
先问三个问题
- 知识是私有的吗?如果答案在网上能查到,直接让模型答更省事。
- 知识会变吗?如果三年不变且总量很小,直接放进上下文比搭检索便宜。
- 需要给出处吗?制度、合同、医疗这类场景,答案必须能指回原文;这是 RAG 最硬的价值。
三个都偏向“是”,RAG 才值得做。否则先试试更笨的办法:把资料整理好,直接塞进长上下文,或者做成结构化的查询界面。
取舍一:切片——按结构切,还是按长度切
固定长度切片实现最快,但会把一条完整规定劈成两半:前半段说“满足以下条件之一”,后半段才是条件。检索到前半段,模型只能猜。
更稳的做法是先按文档结构切(标题、条款、表格),再对超长段落做二次切分,并且让每个子块带上父级标题。代价是预处理更麻烦,收益是答案不容易断章取义。
表格和图片要单独处理。把表格硬转成文字,行列关系会丢;图片 OCR 出来的文字没有版面,检索效果通常很差。这两类内容值得单独建一条处理链路,而不是塞进通用管道。
判断切片好坏的方法很土:随机抽 20 个问题,看检索出来的块能不能单独读懂。读不懂就说明切错了。
取舍二:检索——向量、关键词,还是混合
纯向量检索擅长语义相近,但对专有名词、编号、缩写很不友好。一个内部系统叫“星图二期”,用户搜“星图”,向量可能给你一堆天文资料。
中文场景里,混合检索通常是默认答案:关键词负责精确命中,向量负责语义召回,再把两路结果融合。代价是要维护两套索引,调参也更麻烦,但省下的调试时间通常值回票价。
还有一个常被忽略的维度:元数据过滤。按部门、时间、文档类型先筛一遍,往往比换更大的模型有效得多。
取舍三:重排——要不要多这一跳
召回 50 条,重排取前 5 条,准确率通常明显提升。代价是延迟和成本:多一次模型调用,响应时间可能翻倍。
我的判断标准是场景:人在等答案(客服、内部问答)值得加重排;机器在批量跑(离线抽取、归档)可以把重排放到批处理里,不占交互时间。
如果预算有限,优先把重排加在“找错了”比例最高的那类问题上,而不是全局开启。
取舍四:生成——引用与拒答
让模型在回答里带上出处,不只是为了好看。它强迫系统在生成前确认“我是从哪段话得出这个结论的”,能显著减少编造。
更重要的是拒答。检索不到、置信度低、来源互相矛盾时,系统应该说“没找到”或“资料之间有冲突”,而不是给一个通顺但错误的答案。这件事要在提示词、阈值和界面三层同时设计:
- 提示词里明确“只依据给定材料回答,找不到就说找不到”;
- 检索分数低于阈值时直接走拒答分支,不调生成;
- 界面上把“未找到”设计成一个正常状态,而不是报错。
上下文预算也是取舍。塞更多材料通常不会更好,噪音会稀释重点。宁可少给几段,也要保证每段都和问题相关。
取舍五:评估——先有题,再谈优化
没有评估集,所有“感觉好多了”都是幻觉。起步不需要复杂工具,50 条真实问题就够,人工标好标准答案和出处。
至少看四个数:检索命中率(正确材料有没有被召回)、引用正确率(引用的段落是否真的支持结论)、拒答率(该说不知道的时候说了没有)、人工可用率(业务人员愿不愿意直接用这个答案)。
每次改动只动一个变量,跑一遍评估集再决定留不留。这条纪律比任何框架都重要。
一张表收束
| 环节 | 常见做法 | 代价 | 什么时候值得 |
|---|---|---|---|
| 切片 | 按结构切 + 父级标题 | 预处理复杂 | 制度、合同、条款类文档 |
| 检索 | 关键词 + 向量混合 | 两套索引 | 有大量专有名词和编号 |
| 重排 | 召回 50 取 5 | 延迟、成本 | 人在等答案的交互场景 |
| 生成 | 强制引用 + 拒答分支 | 答案变“保守” | 需要可信、可追溯 |
| 评估 | 50 题金标准 | 前期投入 | 从第一天就该有 |
什么时候别用 RAG
- 数据量小且稳定。几十页资料直接放上下文,效果稳定、链路更短。
- 问题需要计算或事务。查库存、算价格、下单,应该走工具调用和数据库,不是检索。
- 要求强一致。RAG 的结果是概率性的;对账、合规校验这类场景,规则引擎更合适。
- 资料本身质量差。垃圾进垃圾出,先把文档整理好,比换模型有效。
这三篇是一个系列的开头。后面会补一篇“从能答到敢用”的三个月记录,写评估集怎么长出来、哪些优化最后被证明是白做的。