这道题问[[RAG]]的架构和流程,其实本质是问你怎么把外部知识可靠地注入到大模型生成里,同时控制[[幻觉]]和成本。我理解RAG的核心就三个环节:先把知识切成块并[[向量化]]存起来,然后根据用户问题把相关的块捞回来,最后让模型基于这些块来回答。但真正落地的时候,每个环节都有很多坑要踩。
先说索引模块。[[分块]]这一步很多人随便按固定长度切,但实际业务里,比如客服退款场景,用户问的是“我退货了但没收到退款”,相关文档可能是一整段流程说明,如果切碎了,模型只拿到半截,答案就会断章取义。我倾向于用语义分块,比如检测段落边界或者Embedding相似度变化点来切,保证每个块语义完整。向量化用Embedding模型,像BGE或者OpenAI的ada,选型前提是看你的领域和语言,中英文混合场景我偏向BGE,因为它对中文支持好。存储用[[向量数据库]],Milvus适合大规模,Elasticsearch适合已经有ES基础设施的团队,这个选择没有绝对好坏,取决于你的运维能力和规模。
再来看检索。这里有个常见误区:只做向量检索。其实很多业务场景,比如搜订单号、错误码,精确匹配比语义更重要。所以我会用**[[混合检索]]**,把[[BM25]]关键词检索和向量检索结合起来,两条路都走,然后合并结果。检索完还有一个关键步骤是[[重排序]],用[[Cross-Encoder]]模型对Top-K结果精排,这一步能大幅提升召回质量。我见过一个失败案例:只靠向量检索,用户问“满减和折扣能叠加吗”,结果召回了一堆满减规则,但没召回折扣规则,因为“折扣”这个词在向量空间里被稀释了。加上BM25就能直接命中折扣相关文档。
生成环节其实最容易被忽视。把检索到的文档一股脑塞进Prompt,模型很容易被无关信息干扰。我会做两件事:一是按相关性排序,截断到模型上下文窗口的合理比例,比如70%;二是在Prompt里明确指令,要求模型“仅基于提供的文档回答,如果找不到答案就说不知道”,并且输出时带上引用来源。这能有效降低幻觉。
说到幻觉,这里有个延伸点:即使检索做得好,模型也可能自己编。我会在生成后加一层验证,比如用另一个轻量模型检查答案是否忠实于检索文档,或者用[[Self-RAG]]让模型自己反思。但这就涉及成本和延迟的权衡了,不是所有场景都需要。
最后说说我的判断。RAG落地的前提是知识库质量够高,如果文档本身错误百出,再好的RAG也没用。所以我会把RAG看作一个系统工程,检索是上限,生成是下限,检索质量决定了你能拿到多好的信息,而生成只是把这些信息组织好。我更倾向于在检索和重排序上多花功夫,而不是在Prompt上雕花。