RAG 实战方法:切分、召回、重排与可验证引用

RAG(Retrieval-Augmented Generation)不是“把文档切块放进向量库”这么简单。它是一条数据与检索链路:内容解析、切分、索引、召回、重排、上下文组装、回答和评测。任何一层丢失信息,模型都无法靠提示词补回来。

先定义可回答范围

列出用户真实问题和权威数据源,例如文章详情、需求状态、友链地址。每类问题需要哪些字段、是否公开、多久更新、能否引用,都应先确定。把权限数据与公共内容混入同一无过滤索引,会制造越权风险。

按语义结构切分

固定每 500 字切一块简单但容易截断标题、代码和表格。更好的顺序是:

  1. 按 Markdown 标题、段落、列表和代码块解析。
  2. 保留父标题路径,例如“Docker > 构建缓存 > CI”。
  3. 小段落按 Token 合并,超长段落再递归拆分。
  4. 为相邻块保留少量重叠,但不要重复整页。
  5. 保存文档 ID、版本、URL、作者、时间和权限标签。

页面标题和关键元数据可以作为每块的上下文前缀,提升脱离原文后的可理解性。

混合召回比单一向量更稳

向量检索擅长语义相近,但对精确 ID、错误码、版本号和专有名词未必稳定;关键词检索恰好擅长这些。将 BM25 与向量结果归一化合并,再用轻量 Reranker 排序,通常比只调 Embedding 阈值可靠。

查询前可做意图识别和改写,但必须保留原始 Query。对于“上一篇文章里的第二种方案”,还需要会话上下文解析出目标文档,而不是直接对这句话做全库向量搜索。

上下文组装要控制冗余

  • 优先不同证据,去掉高度重复 Chunk。
  • 保留标题、URL 和文档更新时间。
  • 代码块与解释尽量一起送入。
  • 总 Token 超限时按相关性和权威性截取。
  • 明确要求模型仅基于证据回答,证据不足就说明不知道。

引用必须能回到原始页面和具体片段。不要让模型凭空生成 URL;链接来自检索元数据,由应用层渲染。

建立评测集

准备几十到几百条真实问题,标注期望文档与可接受答案。至少评估:

  • Recall@K:正确证据是否被召回。
  • 排名:正确证据是否靠前。
  • Faithfulness:回答是否受证据支持。
  • Citation correctness:引用是否指向真正支持结论的内容。
  • 无答案问题:系统是否拒绝编造。

每次改切分、Embedding、索引或 Prompt 都跑同一评测集,避免只凭几个演示问题判断。

数据更新与删除

索引记录内容版本和更新时间。文章修改后应替换旧 Chunk;删除或权限变化要立即从可检索集合移除;失败任务进入可重试队列并可观测。向量库不是事实源,数据库仍负责状态与权限。

参考资料