Skip to content

RAG 完整工作原理:从文档加载、切片、Embedding、检索到生成

如果你想知道 RAG 为什么能让大模型回答企业私有知识,核心答案是:先把资料变成可检索的证据,再把检索结果交给模型生成答案。这篇文章适合已经会调用大模型 API、准备构建知识库,或需要在面试中讲清 RAG 链路的后端工程师。

RAG 不是把所有文档塞进 Prompt,也不是向量数据库加一个聊天页面。它是一条包含数据处理、检索、上下文组装和生成约束的系统链路。任何一环的输入输出不清晰,线上回答都可能失真。

RAG 解决的三个问题

大模型本身并不知道你的内部文档,也不会自动知道刚刚更新的业务规则。RAG 主要解决三类问题:

  1. 知识范围:把模型训练集之外的内部资料作为运行时上下文提供给模型。
  2. 知识时效:文档更新后重新建立索引,查询时读取当前版本,而不是等待模型重新训练。
  3. 答案依据:要求模型基于检索到的片段回答,并可以返回来源、文档版本和定位信息。

RAG 能减少知识缺失和部分幻觉,但不能保证答案正确。错误的切片、过期的索引、召回不足或模型忽略上下文,都会让最终答案出错。

从文档到答案的完整数据流

text
文档源
  -> 加载与解析
  -> 清洗、切片、保留元数据
  -> Embedding
  -> 向量库/关键词索引

用户问题
  -> 查询改写(可选)
  -> 向量召回与关键词召回
  -> 过滤、去重、重排
  -> 上下文组装
  -> LLM 生成带依据的答案
  -> 返回答案、来源和观测信息

索引阶段通常是异步任务,重点是幂等、可重试和版本管理。查询阶段通常是在线请求,重点是延迟、权限过滤和上下文质量。两阶段不应该因为共用一个“知识库”概念,就混在同一个同步接口里。

索引阶段与查询阶段的输入输出

阶段输入关键处理输出
加载PDF、Markdown、网页、数据库记录解析正文并保留来源文档对象
切片文档对象按结构和长度拆分Chunk + 标题、来源、版本
向量化Chunk 文本调用 Embedding 模型向量和模型版本
存储向量、Chunk、元数据写入索引并记录版本可检索索引
召回用户 Query、权限条件相似度或关键词搜索候选 Chunk
重排候选 Chunk相关性、时效性、权限过滤上下文集合
生成Query、上下文、回答规则约束模型输出答案和引用

切片时不要只保存一段字符串。至少应保留文档 ID、标题路径、来源 URL、更新时间、租户或权限范围,以及切片在原文中的位置。这样才能在回答中给出可追溯来源,也能在权限变化时重新过滤。

一个生产级 RAG 系统的模块边界

一个可维护的实现可以拆成以下模块:

  • Loader:负责不同文档源的读取和解析,不负责向量搜索。
  • Splitter:根据 Markdown 标题、段落、代码块或 FAQ 问答边界切片,具体参数见 Chunk Size 选择指南
  • Indexer:调用 Embedding 服务并写入向量库,记录模型版本和索引版本。
  • Retriever:接收 Query 和过滤条件,返回候选证据;复杂场景可以结合 检索策略
  • Reranker:在候选集上做相关性重排、去重和上下文压缩。
  • Generator:只负责 Prompt、模型调用、输出解析和引用格式化。
  • Evaluation:用固定问题集评估召回与回答质量,参考 RAG 评估方法

使用 Go 构建这些模块时,可以让 HTTP 服务负责在线查询,让队列消费者负责索引任务,并使用 context 传递超时和取消信号。这里的优势不是“Go 天生更懂 AI”,而是它适合把 RAG 作为一个具备并发、重试、监控和部署边界的后端服务。

常见失败位置与排查顺序

遇到“回答不准”时,建议按数据流排查,而不是先更换模型:

  1. 文档是否正确解析:扫描 PDF、表格和代码块是否丢失内容。
  2. 切片是否保留语义:标题、条件、步骤是否被拆到不同 Chunk。
  3. 召回是否命中:检查 Top-K、过滤条件和文档版本,确认候选片段真的包含答案。
  4. 上下文是否被截断:记录最终发送给模型的上下文长度和顺序。
  5. 模型是否遵守规则:要求无证据时明确说不知道,并返回引用。
  6. 评估是否可复现:用固定问题集比较改动前后的检索和生成指标。

如果召回结果本身就没有答案,调 Prompt 通常无效;如果召回正确但答案仍然错误,再检查上下文组装、模型参数和输出解析。

继续学习

🚀 学习遇到瓶颈?想进大厂?

看完这篇技术文章,如果还是觉得不够系统,或者想在实战中快速提升?
王中阳的就业陪跑训练营,提供定制化学习路线 + 企业级实战项目 + 简历优化 + 模拟面试。