RAG 做对了还是做砸了?一个生产环境的踩坑记录
生产环境 RAG 系统踩坑记录:检索质量远比模型重要,分块策略、混合检索、查询改写等实用优化技巧。
# RAG 做对了还是做砸了?一个生产环境的踩坑记录
做 RAG(检索增强生成)已经一年多了,从最开始的概念验证到现在的生产系统,踩过不少坑。今天聊几个真实的教训。
第一个坑:检索质量比模型质量重要得多
我刚入行 RAG 的时候,觉得模型选型是关键。GPT-4 还是 Claude,谁强谁弱,影响很大。
后来我做了个实验:把同一个检索结果,分别喂给 GPT-3.5 和 GPT-4,发现质量差异几乎可以忽略不计。
但换一个检索策略,结果天差地别。
这说明一个很反直觉的事实:在 RAG 系统里,检索的质量权重远远高于生成模型的质量权重。你把检索做好,哪怕用个 7B 的小模型做生成,效果也比我之前用 GPT-4 配个烂检索要好得多。
第二个坑:分块策略不是越细越好
很多人一上来就把文本切成很小很细的 chunk,觉得这样检索更精准。
实际上不是。我见过一个项目,chunk 切到 200 字一段,检索精度确实高了,但上下文完整性差得离谱。
比如用户问"这个功能的实现原理是什么",检索回来的是第 3 段的后半部分——前面讲设计思路的段落根本没被检索到,因为那一段的关键词跟问题对不上。
后来我们改成了自适应分块:先按段落切,再按语义相似度合并相近的 chunk。效果明显好于固定长度切分。
几个实用的优化技巧
1. 用混合检索,别只依赖向量
纯向量检索有个致命问题:它对精确关键词不敏感。
比如用户搜"ERROR_CODE_404",向量检索可能找不到最相关的文档,因为"ERROR_CODE_404"这个字符串的向量可能跟"未找到错误"的向量更相近。
解决方式很简单:把向量检索和 BM25 关键词检索结合起来。我们用 Elasticsearch 做关键词检索,用 Milvus 做向量检索,最后用 RRF 融合排序。效果提升很明显。
2. 不要忽略查询改写
用户的问题往往是模糊的、不完整的。直接拿去检索,效果通常很一般。
一个常见的做法是在检索前先做查询改写:把用户的问题扩展成更完整的表述,或者拆成多个子问题分别检索。
比如用户问"怎么部署 Redis",改写系统可以把它扩展成"Redis 在 Linux 服务器上的安装部署步骤和配置方法",这样检索出来的结果会更有针对性。
3. 控制上下文长度,别贪多
RAG 最常见的错误就是把检索回来的所有内容都塞进 prompt。
我们之前有一个项目,检索回来 10 个 chunk,每个 chunk 500 字,总共 5000 字塞进 GPT-4。结果模型回复质量反而下降了——因为它被太多无关信息干扰了。
后来我们加了个重排序步骤:用一个小模型对检索回来的 chunk 做相关性打分,只取前 3-5 个最相关的。上下文从 5000 字降到 1500 字,回答质量反而提升了。
关于评估:别只看准确率
做 RAG 系统,评估是个大难题。
很多团队只看"检索结果中有没有包含正确答案",这个指标太粗糙了。更靠谱的做法是端到端评估:用真实用户问题做测试集,人工打分回答质量。
我们团队的做法是:每个月抽 100 个真实用户问题,让两个工程师独立打分(1-5 分),取平均。连续三个月跟踪这个分数,比看任何自动化指标都有意义。
最后说句实话
RAG 不是银弹。它适合的场景是:你有大量结构化文档需要查询,而且这些文档内容相对稳定。
如果你的数据是高度动态的、或者需要复杂推理能力的场景,RAG 的效果可能不如你预期的好。这时候与其折腾 RAG,不如考虑微调一个专用模型,或者直接上 Agent 架构。
工具没有好坏,只有适不适合。搞清楚自己的需求,比追新更重要。