RAG 系统实现:组件与流程
检索增强生成的核心组件与工作流程详解
原题:请详细说明RAG(Retrieval-Augmented Generation)系统的具体实现方式,包括主要组件和工作流程。
重排与优化 · 字节真题
30 秒回答
- 清晰描述RAG的两大核心阶段(检索+生成)及数据流向
- 说明索引构建的关键步骤(文档切分、向量化、存储)
- 列举至少2种检索策略(如混合检索、重排序)及适用场景
- 提及RAG的典型优化方向(查询改写、上下文压缩、多路召回)
回答与解析
答案要点
- 清晰描述RAG的两大核心阶段(检索+生成)及数据流向
- 说明索引构建的关键步骤(文档切分、向量化、存储)
- 列举至少2种检索策略(如混合检索、重排序)及适用场景
- 提及RAG的典型优化方向(查询改写、上下文压缩、多路召回)
- 能指出实现中的常见陷阱(如切分粒度、语义漂移)
RAG核心架构:两阶段流水线
索引阶段(离线)
- 文档处理:按语义/固定长度切分chunk,控制256-512 tokens,保留上下文重叠
- 向量化:用Embedding模型(如BGE、M3E、OpenAI text-embedding-3)编码为稠密向量
- 存储:写入向量数据库(Milvus、Faiss、Elasticsearch),可搭配稀疏索引(BM25)做混合检索
查询阶段(在线)
用户Query → 查询改写(可选)→ 向量检索(Top-K)→ 重排序(可选)→ 上下文拼接 → LLM生成
关键组件详解
| 组件 | 作用 | 典型选择 |
|---|---|---|
| Embedding模型 | 语义编码 | BGE-large、GTE、E5 |
| 向量数据库 | 近似最近邻搜索 | Milvus、Weaviate、pgvector |
| 检索策略 | 提升召回质量 | 稠密+稀疏混合、多路召回 |
| 重排序模型 | 精排优化 | Cross-Encoder、ColBERT |
| 生成模型 | 最终答案生成 | GPT-4、Claude、本地LLM |
进阶优化手段
- 查询改写:用LLM扩展同义问法,解决语义gap
- 上下文压缩:检索后先用小模型过滤无关片段,减少噪声
- Self-RAG:让模型判断是否需要检索,避免过度依赖
落地注意点
- 切分粒度:太细丢上下文,太粗检索不精准,建议按段落/语义边界
- 元数据过滤:结合时间、来源等标签预过滤,减少搜索空间
- 缓存策略:热门query结果缓存,降低向量检索延迟
口语版讲法(约4分钟)
- 一句话定位RAG本质
- 索引阶段:切分与向量化
- 查询阶段:检索与生成
- 优化手段与边界
- 落地风险与取舍
我觉得RAG这道题,其实核心在问一个工程问题:怎么让大模型在不知道答案的时候,能自己去找答案,而不是瞎编。说白了就是给LLM配一个外挂知识库,让它只回答知识库里有的东西。
先说离线索引阶段。第一步是文档切分,这里有个常见的坑:切太细,比如一句话一段,上下文就断了,模型看不懂;切太粗,比如整篇文章一段,检索回来一堆噪声,答案也不准。我一般会按语义段落来切,控制256到512个token,前后保留一点重叠,保证上下文连贯。
切完之后用 Embedding 模型转成向量,比如BGE或者M3E。然后存到 Vector Database 里,像Milvus或者Faiss。不过纯向量检索有个问题,它只认语义相似,不认关键词精确匹配。比如说用户问“订单号12345”,向量检索可能找不到,因为订单号是精确字符串。所以实际落地我往往会做 Hybrid Search,把向量和 BM25 关键词检索结合起来,这样语义和精确匹配都能覆盖。
在线查询阶段,用户来了一个query。这里我会先做一步查询改写,因为用户问得可能不准确。比如客服场景,用户说“我上次买的那个杯子退不了款”,系统可以改写成“退款政策 订单状态 杯子”,这样检索更准。然后去向量库取Top-K,比如取20条。取回来之后,我会加一道 重排,用一个 Cross-Encoder 模型重新算一遍相关性,把最相关的3到5条挑出来拼到prompt里,最后丢给LLM生成答案。
说到优化,我比较常用的是上下文压缩。检索回来的片段里可能有噪声,直接拼进去会干扰模型。我会先用一个小模型过滤一遍,只保留确实相关的句子。还有一个方向是 Self-RAG,让模型自己判断要不要检索,如果知识库里没有就直接说不知道,避免 Hallucination。
举个例子,企业SOP合规场景。员工问“报销餐费需要什么附件”,知识库里可能有几十条政策。如果切分粒度不对,可能只找回“餐费标准”而漏了“附件要求”。所以我会按政策条款的语义边界来切,每条政策单独一段,再配上元数据过滤,比如只选最新的版本。这样召回率能高很多。
这里有个延伸点:RAG的召回质量其实高度依赖Embedding模型和切分策略的配合。如果Embedding模型没针对领域微调,比如用通用模型去匹配法律术语,那召回效果会打折扣。我倾向于先做领域适配,或者用 GraphRAG 引入实体关系来补足语义。
最后说落地的风险和取舍。前提是知识库质量要够好,如果文档本身就有错,RAG只会放大错误。常见失败场景是切分破坏了上下文,导致模型答非所问。所以上线前我会特别关注召回率的评估,用一套标准query跑一遍,看Recall@K有没有达标。如果召回率低,我会先调切分策略或者换Embedding模型。
所以我的判断是,RAG不是万能的,它最适合知识库相对静态、答案有明确来源的场景,比如客服、合规、产品文档。如果知识库频繁变动,或者问题需要多步推理,那可能要上 Agent 或者 ReAct 方案。我更倾向把RAG当成一个基础模块,和微调、Agent组合使用,而不是孤立地看。
关键一句:RAG的召回质量高度依赖Embedding模型和切分策略的配合,需要领域适配或引入GraphRAG补足语义。
面试官还可能这样问
- 问法 1 · 场景切入
假设你做一个客服知识库,用户问“怎么退货”,系统得从海量文档里找相关步骤。这个从查文档到生成答案的流程,你怎么设计?关键组件和顺序是什么?
- 问法 2 · 层层追问
你想给大模型外挂知识库,一般流程是怎样的?……那文档怎么切分成块?……检索完怎么把内容和用户问题拼起来喂给大模型?……如果检索结果不相关,有什么优化手段?
- 问法 3 · 直球架构
讲一下 RAG 的完整实现方案,从离线索引构建到在线查询生成,包括文档切分、向量化、检索策略、重排序、以及提示拼接这几个环节,你是怎么设计和落地的?