概述

RAG(Retrieval-Augmented Generation,检索增强生成)通过先从知识库检索相关内容,再让 LLM 基于检索结果生成答案,显著降低幻觉并让回答有据可依。它是 Agent 接入私域知识、让答案「可溯源」的核心手段。

1. 为什么需要 RAG

直接让 LLM 凭记忆回答存在三类问题:

问题 表现 RAG 的解决
幻觉 编造不存在的事实 提供真实检索片段作为依据
知识滞后 训练数据过期 随时可检索到最新文档
私域知识 LLM 看不见内部资料 检索内部知识库/文档

2. 标准 RAG 流程

一条典型的 RAG 链路包含「离线索引」与「在线检索」两部分:

1
2
【离线】文档 → 切分(chunk) → 嵌入(embedding) → 存入向量库 + 元数据索引
【在线】问题 → 嵌入 → 向量检索(召回 Top-K) → 重排序 → 拼装上下文 → LLM 生成
1
2
3
4
5
6
7
# 伪代码:在线检索
def retrieve_and_generate(question, index):
q_emb = embed(question)
hits = index.search(q_emb, top_k=5) # 向量检索召回
hits = rerank(question, hits) # 重排序精排
context = format_context(hits) # 拼装检索片段
return llm.generate(question, context) # 基于上下文生成

3. 关键环节:切分(Chunking)

切片质量直接决定召回效果。核心权衡是在「语义完整」与「检索粒度」之间取平衡:

  • 按语义单元切分:标题/段落/表格边界优先,避免截断语义
  • 控制切片长度:按 embedding 模型的窗口与预期收敛设置大小
  • 父子切片:小片段检索、父级片段供生成,兼顾召回与上下文
  • 结构化保留:表格、代码块单独处理,避免语义污染

4. 检索与重排序

向量检索擅长「语义相关」,但召回结果可能有噪声,需要精排:

召回策略 说明
向量检索 语义相近,跨语言友好
关键词检索(BM25) 精确术语命中,补充向量盲区
混合检索 向量 + 关键词 + 全文融合,召回更全
重排序(Rerank) 用交叉编码器对 Top-K 精排,提升相关性

经验:先用召回(向量/BM25)拉宽候选,再用 Rerank 精排压缩到 Top-K,能显著提升最终答案质量。

5. 上下文工程(Prompt Assembly)

检索到的片段如何进入上下文,会极大影响输出:

  • 注入引用:为每个片段附带来源与序号([1][2]),便于溯源
  • 去重与截断:合并重复内容,控制注入的 Token 总量
  • 优先序:最相关内容紧邻指令位置,降低重要性衰减
  • 无关过滤:用相关性阈值过滤低分片段,减少噪音干扰

6. 高级 RAG 变体

变体 打法 适用场景
Hybrid-Search 混合检索+重排 通用问答基线
Query Rewriting 检索前改写/扩展问题 提问含糊
Self-RAG 反思是否需要检索、依据是否充分 答案要求高质量
Graph RAG 建成知识图谱,多跳理解实体关系 跨文档逻辑关联
Agentic RAG 逐级漏斗/按需检索,与 Agent 决策结合 复杂多步提问

7. 评估与迭代

RAG 的优化是持续过程,需建立离线评估体系:

  • 检索评估:Recall、Precision @K — 评判召回质量
  • 生成评估:忠实度(是否忠于检索内容)、相关性、答案有用性
  • 反例集:沉淀易错问题,回归验证迭代效果
  • 线上反馈:收集用户点赞/踩,定位失败类型(检索 miss / 生成 drift)

8. 设计小结

  1. 切分是源头,切片语义完整比追求数量更重要
  2. 召回 + 精排组合:混合检索拉宽、Rerank 精排
  3. 引用可溯源:注入来源,让用户和 Agent 都可核查
  4. 与记忆协同:记忆存「事实偏好」,RAG 供「领域知识」
  5. 持续评估迭代:没有离线评估的 RAG 是无底洞
  6. 按需检索:不是每个问题都要检索,可先判断是否需要外部知识(Agentic RAG)