这道题其实在问,怎么给大模型配一个能随时更新的外挂知识库,让它回答时能引用真实资料,而不是全靠训练时记住的那点东西。我理解[[RAG]]的核心是三个环节:离线把文档处理好、在线把相关片段找出来、最后把检索结果喂给模型生成答案。
先说离线阶段。文档进来,得先解析,PDF、Word、网页这些格式不一样,表格和图片还得[[OCR]]。接下来是清洗,去噪、脱敏。最关键的其实是[[Chunk]]分块,怎么切直接决定检索质量。固定按512个字符切,简单但容易把语义切碎。我倾向用语义边界检测,按段落或标题层级来切,同时加一点[[滑动窗口]]重叠,保证上下文连贯。分完块之后做[[Embedding]],把文本转成向量,存到[[Vector Database]]里,比如Milvus或者[[Faiss]]。
在线检索的时候,光靠向量检索不够,因为语义相似不一定能匹配到精确的关键词。所以我一般用**[[Hybrid Search]]**,向量和关键词[[BM25]]两条路并行,再用RRF算法融合排序。但融合完的结果还不够准,我会再加一层[[重排]],用[[Cross-Encoder]]精排Top-K。这里有个坑,重排模型虽然准,但latency高,所以只对召回结果的前几十条做重排,别全量做。另外,用户query有时表达模糊,我还会做query改写,扩展同义词或者澄清指代。
检索到片段之后,怎么喂给生成模型?先按相关性排序拼成上下文,但得控制长度,一般不超过模型上下文窗口的30%到50%,留空间给指令和回答。Prompt设计上,我会明确说「基于以下参考资料回答,如果资料不足请说明」,同时要求模型标注引用来源,就是让它回答时带上「根据第X段」。这样能有效抑制[[Hallucination]]。如果检索分数低于某个阈值,我宁愿让模型说不知道,也不让它瞎编。
举个例子,电商客服场景里,用户问「我退货为什么还要付运费」,如果模型只靠预训练知识,可能答错。但RAG系统可以实时检索最新的运费政策文档,找到「非质量问题退货需用户承担运费」那一条,然后基于它生成答案,还能附上政策原文的链接。
这里有个落地风险:如果知识库里的文档本身质量差,比如有矛盾或者过时,那检索出来的东西就是错的,模型会一本正经地引用错误信息。所以上线前我会特别关注文档的更新机制和版本管理,确保知识库是可信的。另外,检索环节如果召回率低,模型回答就会漏信息,这时候得调分块大小和检索参数。
还有个延伸方向是,当问题需要多步推理时,单次检索不够,我会考虑用[[Agentic RAG]],让模型主动决定要不要再检索,或者拆成子问题逐个查。这个对复杂业务场景挺有用的,但实现起来对模型推理能力要求更高。
所以整体上,我更倾向于把RAG看成一套工程系统,不是简单拼装。离线处理、在线检索、生成集成,每一层都有取舍,真正落地要看业务场景和资源限制,没有银弹。