Skip to main content
Version: Next

RAG 优化策略

RAG 优化应先定位问题所在的环节,再选择策略。一个实用的排查链路是:

知识是否覆盖
→ 文档是否正确解析
→ 切片是否保留语义
→ Embedding 是否适合领域
→ 是否召回正确片段
→ 模型是否正确使用上下文

先建立可观测性​

每次查询至少记录:

  • 原始问题和必要的会话上下文
  • 改写后的查询(如果有)
  • 召回的 Node、来源和相似度分数
  • 最终提示词或其安全摘要
  • 模型答案和评测结果

只看最终答案很难区分检索错误和生成错误。打印或保存 response.source_nodes 是最直接的第一步。

增加召回数量:只作为诊断手段​

将 similarity_top_k 从 2 调大到 5 或 10,可能让遗漏的片段进入上下文:

query_engine = index.as_query_engine(
similarity_top_k=5,
llm=llm,
)

但这不是长期方案。过多片段会增加输入成本、超过上下文限制,并把多个同名员工或无关内容混在一起。应通过评测确定合理范围,而不是无限增大 top_k。

优化文档与切片​

结构清晰的 Markdown 通常比结构被破坏的纯文本更容易检索。建议:

  • 保留标题层级、表格和列表关系;
  • 将一条完整事实尽量放在同一个片段中;
  • 通过 chunk_overlap 保留相邻片段的上下文;
  • 保留文件名、章节、页码和业务标签等元数据;
  • 定期删除过期、重复和与业务无关的知识。

示例:

from llama_index.core.node_parser import SentenceSplitter

splitter = SentenceSplitter(
chunk_size=1000,
chunk_overlap=200,
)
nodes = splitter.get_nodes_from_documents(documents)

chunk_size 和 chunk_overlap 没有通用最优值,应使用业务评测集进行对比。

更换 Embedding 模型​

Embedding 模型决定语义空间的质量。可以比较不同模型在同一数据、同一切片和同一评测集上的 Context Recall 与 Context Precision。升级模型时需要重新建立索引,不能直接将旧向量和新模型生成的向量混用。

检索前优化​

用户问题往往过短或含有歧义,可以在检索前进行:

  • 问题改写:补足省略的主体和上下文;
  • 问题扩写:生成多个相关查询,提高召回覆盖;
  • 用户画像扩展:结合岗位、组织或权限信息;
  • 元数据过滤:先按岗位、时间、部门等标签筛选;
  • 澄清提问:问题无法唯一确定目标时,先向用户确认;
  • 多步检索:将复杂问题拆成多个有依赖关系的子问题。

例如,“张伟是哪个部门的?”在存在多名同名员工时并不充分,系统应列出候选或要求用户补充身份信息,而不是凭相似度猜测。

检索后优化​

  • 重排序(ReRank):先用向量检索快速召回,再用更精确的模型重新排序并过滤;
  • 相似度阈值:过滤低于可信分数的结果;
  • 滑动窗口:命中一个片段后补充其前后相邻片段,恢复被切分的上下文;
  • 混合检索:结合关键词匹配与向量检索,兼顾专有名词和语义表达;
  • 来源去重:避免同一事实的重复片段占满上下文。

知识空间与意图空间​

优化不只是调模型参数,还要持续维护知识库:

  1. 收集真实用户问题,了解意图空间的变化;
  2. 补充知识库中缺失的业务内容;
  3. 优化文档结构和检索算法,减少无关知识;
  4. 由领域专家审核答案和 Ground Truth;
  5. 将结果加入回归评测集,形成持续迭代闭环。

如果知识库根本没有覆盖某个问题,工程和算法优化都无法生成可靠的事实答案;这类问题应明确拒答或进入知识补充流程。