这道题其实是在问,怎么让大模型知道它训练时没见过的东西,同时还能控制答案的准确性和时效性。[[RAG]] 的思路很简单,就是给模型配一个外挂知识库,用的时候先查库,再把查到的内容塞进提示词里让模型回答。
具体说一下链路。离线阶段,先要把文档切成块,块的大小很讲究,太小了上下文不够,太大了噪声多,通常 256 到 512 tokens 之间。然后用 [[Embedding]] 模型转成向量,存到 [[Vector Database]] 里。这里有个取舍:纯向量检索语义好,但对精确匹配比如订单号、错误码很弱,所以落地时我一般会加上 [[BM25]] 做 [[Hybrid Search]],两条路并行再合并结果。
在线检索时,用户问题来了,先做查询改写,比如把“上个月的退款”扩展成“2025年3月的退款申请”,提升召回率。然后算相似度,取 Top-K,再用 [[Cross-Encoder]] 做 [[Rerank]],把真正相关的排前面。最后组装成提示词,交给大模型生成答案,同时要求它引用来源。
举个例子,客服系统里用户问“我买的东西降价了,能退差价吗?”如果只靠大模型,它可能瞎编一个政策。用 RAG,我们会先检索知识库中“价保政策”的文档,找到满减规则和申请条件,然后让模型基于这个片段回答,并给出原文链接。这样答案可信,用户也服气。
但 RAG 不是万能的。检索质量直接决定了回答的上限,如果知识库里本身就没存对的信息,或者切分把关键句子切断了,模型再强也白搭。常见失败场景是用户问“为什么昨天能退今天不能退”,这需要跨文档推理,RAG 就很难,因为每段上下文是独立的。另外,检索结果太多会稀释注意力,模型反而抓不住重点。
所以上线前我会特别关注几个前提:一是知识库更新频率,如果每天变,得做好增量索引,避免全量重建;二是查询改写和重排的召回率,至少用一批历史 query 回测,Recall@K 低于 90% 要调参;三是安全过滤,防止检索到涉敏内容。
说到这,其实还有一个进阶方向叫 [[Agentic RAG]],就是让模型自己决定什么时候检索、检索什么,甚至能调用多个工具,比如先查订单系统再查知识库。但这也带来了新问题,比如工具调用的稳定性和延迟,目前还在探索阶段。
总的来说,我会把 RAG 看作大模型落地的标配能力,但不是银弹。真正复杂的场景,我倾向于 RAG 加微调混合用:RAG 管时效性知识,微调管模型固有的能力。