这道题其实本质在问一件事:专业领域里,知识库和模型能力之间的边界怎么划分。[[RAG]]不是简单的检索加生成,它要解决的是模型不知道、知道但不准、知道但过时这三个问题。我下面从架构、检索、生成、更新四个维度讲一下我的设计思路。
先说整体架构。我一般会分四层:数据层、检索层、生成层、应用层。数据层不只是存文档,还包括用户交互日志,用来做后续的反馈闭环。检索层我坚持[[混合检索]],不只用向量。生成层核心是让模型学会说「我不知道」,而不是瞎编。应用层负责权限、审核、对话管理。
检索模块我重点讲。很多人一上来就用 Hybrid Search,但它的前提是你的标注数据够好,不然权重调不准。我的做法是:先做多路召回,向量检索和 [[BM25]] 关键词检索并行,再加结构化查询。举个例子,法律场景里查《民法典》第几条,关键词检索比向量准得多;但医疗场景里查「罕见病用药」,语义相似度更重要。所以我会根据领域调权重。召回之后做 [[重排]],用 [[Cross-Encoder]] 精排,这一步很关键,能把 Top-100 压到 Top-10,而且能过滤掉时效性不符的。比如法律条文,我会优先选现行有效的,失效的虽然向量相似度高,但精排直接砍掉。这里有个常见失败场景:如果领域词表没建好,同义词映射不准,关键词召回会漏掉大量相关结果。比如医疗里「心肌梗死」和「心梗」,向量能处理,但 BM25 就不行,所以必须维护一个领域同义词词典。
生成模块相对简单,但坑也不少。我主要做两件事:一是 Prompt 约束,二是引用溯源。Prompt 里我会明确说:基于以下参考资料回答,不确定就说不知道,必须引用具体条款或文献编号。然后生成的结果必须带上检索片段的 ID,方便审核时追溯。这样能大幅降低 [[Hallucination]]。但有个前提:基座模型本身得有一定领域理解能力,如果模型完全不理解法律逻辑,光靠 Prompt 约束是不够的。这时候我可能会考虑做一点 [[SFT]] 微调,但那是另一回事。
知识更新是落地最头疼的部分。我把它分成四种场景:增量新增、修改、失效、全量重建。新增最简单,新文档直接[[向量化]]入库。修改我把它拆成「旧版软删除+新版新增」,不原地动索引,否则图索引的局部性会被破坏,召回质量下降。失效也是软删除,打一个失效时间戳,检索时过滤掉。全量重建一般季度做一次,比如 Embedding 模型升级了,就离线重建索引。这里有个关键风险:如果你做的是医疗系统,新指南发布后旧版必须立刻失效,软删除的异步重建可能来不及。所以我会加一个实时修正通道,运营后台可以人工标记某条知识紧急下架,检索时直接从内存黑名单过滤,不依赖索引重建。
另外,我最近在关注 [[Self-RAG]] 的思路,让模型在生成过程中自己判断要不要去检索,而不是每次固定检索。这个对专业领域很有价值,因为有些问题模型本身就知道,不需要检索,能省不少延迟。但它的可靠性还需要验证,比如模型误判了该检索却没检怎么办。
所以整体上,我会把 RAG 看成一种 「知识库在前、模型在后」的协作模式,核心是让模型做它擅长的事,理解和生成,而把事实性交给检索。前提是检索质量要足够高,否则模型再强也是白搭。我更倾向在检索层多下功夫,而不是在生成层硬约束。