这道题问[[RAG]],其实本质是在问:怎么让大模型在不改变参数的前提下,拥有实时、可信的外部知识。RAG解决的不是模型能力问题,而是知识边界问题。
流程上分三块:索引、检索、生成。我先说索引。离线阶段,我们把文档切碎、[[向量化]]、存进 [[Vector Database]]。这里有个常见的坑:[[分块]]策略。固定长度切分简单,但容易切断语义;语义切分效果好,但计算成本高。我的做法是混合:先用段落级粗切,再对超长块做递归切分,控制块大小在256到512 tokens之间。Embedding模型我倾向用 BGE 或 M3E,兼顾中文效果和推理速度。
检索阶段,用户问题同样转成向量,用 [[ANN]] 算法召回Top-K。但光靠向量不够,比如“退款”和“退货”语义相近但业务不同,所以我会加 [[Hybrid Search]]:向量检索加 [[BM25]] 关键词检索,两路结果合并后再用 [[Cross-Encoder]] [[重排序]]。这一步能显著提升召回相关性,尤其当知识库有大量相似文档时。
生成阶段,把检索到的文本和问题拼成Prompt,让LLM基于证据回答。Prompt结构很关键:先给检索内容,再给问题,明确要求模型引用来源。这里有个风险:如果检索内容有噪声或冲突,模型可能会混淆。所以我会设一个置信度阈值,低于0.6的块直接丢弃,避免污染上下文。
举个例子,电商客服场景。用户问“我买的手机降价了,能退差价吗?”系统先检索知识库,找到“7天价保”政策文档,然后LLM基于这个文档生成回答,并标注来源。如果知识库没更新,比如政策刚改,那RAG就抓不到,所以前提是知识库必须实时同步。常见失败场景是文档版本混乱,比如旧政策和新政策混在一起,检索出矛盾内容,模型会给出模棱两可的回答。
另一个优化方向是查询改写。比如用户问“怎么退款”,系统可以先把它改写成“退款流程和条件”,再检索,能提升召回。这块可以结合 [[ReAct]] 模式,让模型边思考边检索。
最后说一下RAG和微调的边界。微调适合让模型学习特定风格或格式,比如把回答变得幽默;但微调不能注入新知识,而且成本高、更新难。RAG适合知识频繁更新、需要溯源、或者涉及隐私数据的场景。真正落地时,我倾向于RAG为主,微调为辅:用RAG保证知识和溯源,用微调优化输出风格。
所以我会把RAG看成是模型的外挂知识引擎,而不是替代品。它的前提是知识库质量够高、检索够准,否则就是垃圾进垃圾出。