引子:90%的RAG,都"简"在了错误的地方
如果你在网上搜索"如何搭建RAG",大概率会看到这样一个流程:
上传文档 -> 文本分块 -> Embedding向量化 -> 存入向量库 -> 用户提问时做相似度搜索 -> 把结果塞给大模型
这个流程没有错,但它简掉了决定RAG效果的关键环节。结果就是:你上传了100份产品文档,用户问"标准版支持多少并发",系统返回的却是另一份文档里关于"标准版外观尺寸"的段落--向量距离很近,但答非所问。
RAG的效果上限,由检索质量决定,而非模型能力决定。再强的模型,喂进去的上下文是垃圾,出来的回答也是垃圾。
这正是"文档上传 + 向量检索"远远不够的原因。
云行Agent平台的检索管线,在"用户提问"和"大模型回答"之间,插入了5个关键环节。每一个都解决一类具体的检索质量问题。

环节一:查询改写(Query Rewriting)
问题:用户不会像文档那样说话
用户提问往往是口语化、模糊、带有上下文指代的。比如在一个客服Agent的对话中,用户说"那个多少钱"--"那个"指的是什么?向量检索拿到"那个多少钱"这几个字去匹配文档,结果可想而知。
解法:让LLM先"翻译"一遍
平台在检索前,先调用LLM对原始查询进行改写。LLM会结合当前对话的上下文历史,将模糊、省略的提问补全为一段完整的、与文档表述风格匹配的检索查询。
原始提问:"那个产品多少钱"
改写后:"云行Agent平台标准版的价格是多少"
改写后的查询去掉了指代歧义,补充了实体名称,向量匹配的准确率立刻提升一个档次。这一步的额外成本只是一次轻量级LLM调用,但带来的检索质量提升远超这个成本。
环节二:HyDE -- 假设文档嵌入
问题:query和document的"语言鸿沟"
即使查询改写后,用户提问(短句、疑问句)和文档内容(长段、陈述句)在语言风格上仍然存在差异。直接用query的向量和document的向量算相似度,相当于拿"问题"和"答案"做匹配--语义空间不完全对齐。
解法:先编一个"假答案"再去匹配
HyDE(Hypothetical Document Embeddings)的核心思想非常巧妙:让LLM先根据用户提问生成一个"假设性答案文档",然后用这个假设答案的向量去检索真实文档。
为什么有效?因为假设答案虽然内容不一定准确,但它的语言风格、表述方式更接近真实文档。用"答案"去匹配"答案",比用"问题"去匹配"答案",语义相似度的信号更强。
比如用户问"平台支持哪些向量数据库",LLM可能生成一个假设答案:"平台支持Qdrant作为向量数据库,用于存储和检索……"这段话的向量,与真实文档中关于向量数据库的段落,在向量空间中的距离会比原始提问更近。
环节三:双路并行检索
问题:向量检索和关键词检索各有盲区
向量检索擅长语义匹配--"差旅标准"能匹配到"报销政策",因为语义相近。但它有个致命弱点:精确匹配能力差。用户搜一个产品型号"CL-2000-Pro",如果文档里写的是"CL-2000Pro"(少个连字符),向量检索可能完全捞不到。
关键词检索恰好相反--它精确匹配能力极强,但语义理解能力为零。"差旅标准"绝对搜不到只写了"报销政策"的文档。
解法:两路并行,互补短板
平台在检索阶段同时启动两条路径,并行执行:
两路并行执行,互不阻塞,各自返回TopK候选结果。向量路负责"广撒网"召回语义相关的内容,关键词路负责"精准锁定"那些向量检索容易遗漏的精确匹配项。

环节四:RRF融合 -- 让两路结果"公平"排序
问题:两路分数不在一个量纲上
向量检索返回的是余弦相似度(0到1的小数),关键词检索返回的是全文索引的相关性得分(可能是几十甚至上百)。两路结果混在一起,怎么排序?直接比分数大小显然不行--向量路的0.85和关键词路的85完全不是一个概念。
一种做法是对两路分数做归一化,但归一化方法的选择本身就充满争议,不同分布的数据用同一种归一化往往会引入偏差。
解法:只看排名,不看分数
RRF(Reciprocal Rank Fusion,倒数排名融合)用了一个极其优雅的思路:抛弃分数,只用排名。
RRF 公式:score = 1 / (K + rank),其中 K = 60,rank 是文档在该路检索结果中的排名(从1开始)。
排第1名的文档得分 1/61,排第2名得分 1/62,排第60名得分 1/120……排名越靠前,得分越高,但衰减速度逐渐放缓。
两路结果分别计算RRF得分后相加,就是文档的最终融合得分。这个方法的妙处在于:
- 无需校准分数尺度
--只用了排名信息,天然回避了不同检索引擎分数不可比的问题; - 两路都召回的文档自动加权
--如果一篇文章同时被向量检索和关键词检索召回,它的RRF得分就是两路之和,天然排在前面; - 实现简单、效果稳定
--K=60是经过大量实验验证的经验值,几乎不需要调参。
环节五:Rerank重排 -- 精筛最后一道关
问题:召回不等于相关
经过前4个环节,我们拿到了一批排序后的候选文档。但"被检索到"和"真正相关"之间还有距离。双路检索用的是Bi-encoder模型(query和doc分别编码再算相似度),速度快但精度有限--有些文档恰好和query在向量空间距离近,但深入看内容并不直接回答用户问题。
解法:Cross-encoder精排
Rerank阶段使用Cross-encoder重排模型,将query和每个候选doc拼接在一起送入模型,让模型同时"看到"问题和文档,输出一个精确的相关性分数。
Bi-encoder vs Cross-encoder 的区别:前者是"各自打分再比较",后者是"放在一起综合判断"。Cross-encoder精度更高但计算开销更大,所以只对前序环节筛选出的少量候选(通常TopK=20到50)做重排,而非对全库做。
重排后,按相关性分数从高到低截取最终的TopK(由知识库的 retrieval_top_k 配置决定,通常5到10条),作为注入大模型的上下文。这几条文档,就是整个检索管线最终交付给LLM的"弹药"--它们的质量,直接决定了回答的质量。

补充:LLM语义切片 -- 检索质量从"切块"开始
前面5个环节都在讲检索,但检索质量还有一个前置决定因素:文档怎么切。
传统做法是固定长度切割--每500字切一块。这种方式简单粗暴,但会从中间截断一个完整的语义单元。比如一个条款的前半句在Chunk A,后半句在Chunk B,检索时可能只捞到A,大模型看到的是残缺信息。
云行Agent平台采用 LLM语义切片策略:由大模型理解文档结构,按照语义边界(段落、条款、章节)进行切分,保证每个Chunk是一个完整的语义单元。
同时,平台支持 PDF / Word / Excel / PPT 四种格式的原生解析,能正确识别表格、列表、标题层级等结构化信息,而非把所有内容当成纯文本处理。每个切片都保留溯源信息(来源文档、页码、位置),大模型回答时可标注引用来源,让用户能追溯到原始文档验证。
结语:检索质量,是RAG的"地基"
5个环节,从查询改写到Rerank重排,加上前置的LLM语义切片,构成了云行Agent平台知识库检索的完整管线。每一个环节都解决一个具体的质量问题,缺一不可。
如果你正在做RAG但效果不理想,不妨对照这5个环节检查:你的query和文档表述是否对齐?是否只用了单路检索?两路结果是否做了融合?是否做了重排?切片是否破坏了语义完整性?
大多数"RAG效果差"的问题,都能在这5个环节中找到答案。
夜雨聆风