共计 2762 个字符,预计需要花费 7 分钟才能阅读完成。
为什么我们需要重新理解RAG?
2026年的今天,大语言模型(LLM)几乎成了每个技术团队的标配。可在实际落地时,绝大多数团队都卡在了同一个地方上——记忆。无论模型训练得多大,知识截止日期永远停留在几个月前;无论参数量多庞大,它依然会对着专有文档胡编乱造。于是检索增强生成(RAG)从一种“可选方案”逐渐演变成了生产环境的必须组件。
但我在最近一年帮多个团队做技术咨询时发现,很多从业者对RAG的理解还停留在“把文档切碎,塞进向量库,然后问问题”这个层面。一旦遇到召回率不高、答案质量不稳定的情况,就直接祭出“换个更强的embedding模型”这种粗暴解法。这让我觉得有必要重新把RAG的核心原理拆开揉碎讲一遍,特别是那些容易忽略但又至关重要的细节。
RAG的本质:不是检索加生成,而是检索与生成的协同
很多人把RAG看作两条独立的管线——一条是检索管道,一条是生成管道,最后用prompt粘起来。这种理解会漏掉一个关键点:检索的结果直接影响生成的质量,而生成的需求也反向决定了检索的策略。这不是简单的“拼装”,而是一种协同优化。
检索阶段:分块是门艺术,不是技术
最常见的错误是使用固定长度的chunk(比如每段512 token)按顺序切割。我在一个金融文档项目中亲眼看到,合同中的“免责条款”被切成了两半,前半段在chunk A,后半段在chunk B。用户询问“什么情况下免责?”时,系统只召回了一个不完整的段落,LLM被迫脑补了后半段,直接捏造了一条免责条件。
正确的做法是语义化分块:先识别文档的结构化元素(标题、段落、列表、表格),然后以语意完整为单位切片。对于markdown或HTML文档,可以保留层级标签(如h2、li),让chunk在向量化时天然包含结构信息。2025年底我团队测试过一种基于LLM的递归分块器,先用小模型识别段落边界,再根据语义相似度合并相邻片段,召回率比固定分块高了17%。
检索策略:混合检索才是现实世界的答案
纯向量检索在语义匹配上很强,但遇到精确匹配(比如设备型号“Q7-2026”或产品批号“A1B2”)时,向量相似度常常败给字符匹配。这里就要引出混合检索——把稠密向量检索(dense retrieval)和稀疏词汇检索(如BM25)结合起来,再通过一个重排序模型(cross-encoder)做最终选拔。
我常用的方案是:用两个独立的检索器分别取top-30,合并去重后交给一个轻量级的reranker(比如BGE-Reranker-v2-m3,2026年初发布的版本),最终返回top-5作为context。成本方面,reranker每次推理大约0.5ms(在A100上),对于大多数业务场景完全可以接受。
生成阶段:不是喂chunk就完事了
拿到top-5的检索结果后,很多人直接把它们拼成一段长文本塞进system prompt。但LLM对输入序列中不同位置的信息敏感度差异很大——开头和结尾的注意力更高,中间容易被“淹没”。所以我建议遵循两点:
- 排序优化:把relevance score最高的chunk放在最前面和最后面,次高的放在中间。这个简单的“三明治结构”能让LLM更关注关键信息。
- 源标注与去噪声:在每个chunk前加上文档名称和段落编号(如“来源:《2026设备手册》第三章第2节”),不仅帮助LLM区分不同来源,还能在最终答案中生成引用。另外,如果检索结果中存在重复内容或高度相似片段,用简单的去重算法(如阈值过滤相似度>0.95的chunk)可以减少context冗余。
一个实战案例:医疗报告问答系统
2025年第四季度,我帮一家三甲医院搭建了病历QA系统。一开始采用标准RAG流程(OpenAI embedding + ChatGPT),患者问“我上次的血糖值是多少?”时,系统总是回答“根据您的病历,血糖值在正常范围内”,但患者要的是具体数值。问题出在:检索时没有精确匹配。
我们做了两处改动:
- 对数值和日期字段建立独立的倒排索引,在检索query中检测到数值关键词(如“血糖”、“120mg/dL”)时,优先用精确匹配锁定包含该数值的chunk。
- 在prompt中增加一个强制输出格式要求:“如果检索到的信息包含具体数字,请原样输出,不要概括”。
改动后,数值类问题的准确率从63%提升到了94%,而且没有增加额外的推理延迟。
评估RAG:跳出人工打分的天坑
很多团队在评估RAG系统时还在靠人工看几十条结果——不仅效率低,而且主观偏差大。更系统的方法是建立分维度自动化评估:
- 检索质量:用召回率(Context Recall)和命中率(Hit Rate)衡量检索器是否能够覆盖真实答案所需的片段。可以用一个“黄金chunk集合”预先标注,然后跑离线测试。
- 生成质量:用LLM-as-Judge的方法,让一个专门的评估模型(如GPT-4o或者Claude-4)对回答进行忠实度(faithfulness)和有用性(helpfulness)打分。忠实度尤其重要——如果模型生成的答案包含检索context中不存在的信息,直接记为失败。
- 端到端成本:包括embedding向量化成本、向量库存储费、LLM推理token消耗。我见过一个电商问答系统,为了堆高top-k数量,每轮查询消耗5000+ token,一个月API费用破万。合理设置top-k和chunk长度(我通常用256-512 token),能省下30%-50%的成本。
2026年的新趋势:RAG与Agent的融合
写这篇文章时,我和同行们交流发现,大家不再满足于单次检索的RAG了。一种常见的进阶用法是多跳RAG——当初始检索无法覆盖问题时,自动拆解成多个子问题,分别检索后合并推理。比如用户问“去年销量最高的产品跌价了多少?”,系统先检索“去年销量最高的产品”,得到产品名“Alpha-X3”,再检索“Alpha-X3价格变化”,最后计算跌幅。
这本质上已经从“检索+生成”变成了“推理+检索+生成+验证”的循环,再结合工具调用,就变成了一个RAG驱动的Agent。2026年初的LangGraph和Dify都提供了现成的多跳编排能力,门槛正在降低。
最后想说的话
RAG不是银弹,但它是在不微调模型的前提下,让LLM处理私有知识最务实的方案。从我经手的十几个项目来看,大部分效果问题都出在“细节”上——分块方式、检索策略、context组织、评估方法。与其盲目更换更贵的模型,不如先把这些基本功打扎实。毕竟,好的RAG系统,是用巧劲而不是蛮力解决问题的。
希望这篇文章能给正在搭建或优化RAG系统的你一些直接可用的思路。如果你在落地过程中遇到具体卡点,也欢迎在评论区留言交流——赛义德的日常这个账号一直主张“实战派”交流,不在乎争论对错,只在乎能不能解决问题。