RAG 效果不好,团队的第一反应往往是改提示词或者换更强的模型。这个方向大概率是错的——按实际项目的分布,七八成 RAG 问题出在检索侧,只有一两成在生成侧。本文基于 Spring AI 的实战拆解整条链路的四个失败点,以及每个点的定位方法。
一句话定调:检索决定上限,生成只决定表达
论证很朴素:100 个问题里如果检索有 40 次没召回正确片段,这 40 个问题的答案注定是错的——正确信息根本没进模型视野,它只能凭训练知识去猜,猜就是幻觉。反过来,正确片段进了上下文,7B 级别的本地模型也能给出不错的回答。
推论:别用换模型解决"答不对"的问题。 换模型改善的是表达质量(更通顺、更会引用),改善不了"压根没检索到"。
四个失败点,分段验证
一次 RAG 调用链路:解析改写 → 检索(向量+关键词+权限过滤)→ 重排截断 → 生成。四个环节各有典型症状:
| 失败环节 | 表现 |
|---|---|
| 查询改写失效 | 口语提问检索不到书面表述 |
| 召回不足或越权 | 答不出,或泄露不该给的内容 |
| 噪声淹没 | 相关片段被不相关内容挤到后面 |
| 生成侧失控 | 幻觉、假引用 |
排查的铁律是分段验证:把检索出来的片段原样打印出来看。检索结果本身答不了这个问题——去改提示词毫无意义;检索结果里有正确答案但模型没用——才是生成环节的锅。见过太多团队跳过这一步,在提示词里加"请严格按照资料回答",改了半天白费劲。
Embedding 的三个实践点
向量不能跨模型混用。 每个嵌入模型一套坐标系,换模型等于全量重嵌入——RAG 里最贵的一次性操作,选型要一次定准。中文语料质量差异明显,正确做法是拿自己业务的 30~50 条真实问句做小测试集,比较候选模型"正确文档进前 3"的比例,半天的投入省掉几个月调参。
阈值比 top-k 更重要。 用户问的问题知识库里没有答案时,检索照样返回"最接近的 5 条",模型看到 5 段不相关内容,大概率硬编一个答案。设相似度阈值,低于阈值就明确回答"知识库没有相关内容"——一个坦诚的"不知道",比自信的错答安全得多。
分块是第一道关口
三种切法各有代价:固定长度切(每 500 字块间重叠 50 字)实现最简单,但一句话可能被切两半;按标题段落结构切,块内语义完整但长度不均;语义切分质量最好,可每块多一次模型调用。表格必须特殊处理——按行切开等于表头和数据分离,检索到也没法用,正确做法是整表成块外加一行摘要。
什么时候别用 RAG
跨文档聚合统计("今年一共处理了多少起")——检索取的是"最相关的几块",天生不擅长遍历全部,走结构化查询让模型生成 SQL;表格数值计算——数字关系在切块后丢失,入库后精确计算;文档只有几页——直接全塞上下文。用近似的工具做需要精确的事,是架构层面的错误,调参救不了。语义问题走 RAG、数值统计走结构化查询,让模型当路由器,才是可维护的拆法。

评论0