RAG 管道包含三个阶段:索引、检索和生成。在索引阶段,你将文档(PDF、网页、数据库记录等)拆分成块,将每个块输入嵌入模型以获得向量,并将这些向量存储在像 Qdrant、Pinecone 或 Weaviate 这样的向量数据库中。在检索阶段,用户的查询使用相同的模型进行嵌入,向量数据库返回最相似的前 k 个块(通常为 3—10 个)。在生成阶段,这些块作为上下文插入模型的提示中,模型基于这些内容生成响应。整个往返过程(嵌入查询、搜索、组装提示、生成)通常需要 1—3 秒。
分块是大多数 RAG 系统成功或失败的关键,而且比看起来更微妙。块太小会丢失上下文;块太大则会浪费宝贵的上下文窗口空间在不相关文本上。一个常见的起点是每个块 500—1000 个 token,相邻块之间有 10—20% 的重叠(这样不会丢失跨越边界的的信息)。但简单的固定大小分块通常会将句子截断或将标题与其内容分开。更先进的方法使用文档结构(按标题、段落换行或语义变化进行分块)来创建自包含且有意义的块。LangChain 的 RecursiveCharacterTextSplitter 和 LlamaIndex 的 SentenceSplitter 都尝试处理这个问题,但最佳结果通常来自理解特定文档并编写自定义分块逻辑。
检索步骤比人们想象的有更多的选择。纯向量相似性搜索(嵌入空间中的最近邻查找)是默认方法,但它在精确关键词匹配、专有名词和代码标识符方面存在困难。这就是为什么混合搜索已成为生产系统中的标准:你同时运行向量搜索和传统关键词搜索(BM25),然后通过倒数排名融合或学习型重排序器合并结果。Qdrant、Weaviate 和 Elasticsearch 都原生支持混合搜索。重排序(从检索结果中取前 20—50 个结果,并使用交叉编码器模型进行评分)会增加延迟,但显著提高相关性。Cohere Rerank 和 Hugging Face 的交叉编码器模型是常见的选择。
一个常见的误解是 RAG 消除了幻觉。它确实显著减少了幻觉,但模型仍可能在检索到的块中没有相关信息时生成幻觉,尤其是当块与查询仅间接相关而非直接回答时。优秀的 RAG 系统通过在提示指令中包含来源引用(“仅根据提供的上下文回答,并引用来源”)、过滤掉低相关性块(设置最低相似度阈值而非总是返回前 k 个)以及当检索到的上下文确实无法回答问题时让模型说“我没有足够的信息”来缓解这一问题。一些团队会添加一个验证步骤,通过第二次模型调用检查响应是否确实由来源支持。
RAG 最初由 Facebook AI Research(现 Meta AI)在 2020 年的一篇论文中提出,但直到 2023 年向量数据库和嵌入 API 成熟到足以实际应用时,它才成为主流生产模式。此后,该模式在多个方向上发展:GraphRAG 使用知识图谱代替(或与)向量搜索,以更好地处理关系性问题。代理式 RAG 赋予模型重新表述查询、搜索多个来源并迭代检索的能力,而非仅进行一次搜索。而上下文窗口扩展(模型现在可以处理 100k+ token)导致一些团队对小型知识库完全跳过 RAG,直接将所有内容塞入提示中。这种方法适用于几百页的文档,但在大规模时会崩溃,因此 RAG 仍然是必不可少的。