本文是对 AI Agent 智能检索与 RAG 相关知识的学习整理,涵盖检索机制设计、Chunk 切割策略、召回优化、性能优化等核心主题。


一、Agent 检索机制设计

1.1 检索不只是 RAG

很多人一提到 Agent 检索就想到 RAG,但 RAG 只是 Agent 检索中的一部分。Agent 需要检索的场景远不止知识库问答:

  • 摘要压缩后需要召回历史细节
  • 用户说”刚才那个方案”需要检索之前的对话
  • 长任务执行过程中需要重新查找工具结果、中间产物、Checkpoint
  • 查询外部实时数据

核心问题不是”怎么做一个 RAG”,而是怎么设计 Agent 的整个信息检索机制。

1.2 查询什么:Agent 怎么知道自己缺什么

Agent 需要查询的内容包含两个层次:

  1. 开发者层面:在设计 Agent、Action 或业务流程时,决定某一个环节需不需要查询
  2. Agent 自身:在运行过程中思考当前信息够不够、要不要发起查询

基本步骤模板

步骤 说明 示例
明确当前要做出的判断 查询是手段不是目的 判断 LangGraph 是否满足客服 Agent 生产要求
推导所需证据 细化判断标准 生产环境需要支持任务中断和恢复
区分已知和未知 排除已知信息 已知用户技术栈是 Python
判断缺口是否值得查询 降级机制 资源不足时可考虑不查询

1.3 去哪里检索:动态查询空间

查询空间(可查询空间)不只是向量数据库,还包括:

  • 特定 Action
  • ES 索引
  • 业务数据库
  • 历史对话
  • 用户画像
  • 代码仓库、日志、Trace
  • 外部搜索
  • Agent 自己产生的中间结果

关键洞察:可查询空间不是固定的,会随着任务执行不断变化。

1.4 三种固定的检索套路

1. Action 天生提供特定信息

如果某种信息只能由特定 Action 提供,应优先通过规则或业务流程直接绑定,而不是让大模型猜测。

2. ES 检索需要 Index Profile

当 Agent 要在 ES 里面查询时,需要先建立索引说明(Index Registry):

1
2
3
4
5
6
7
8
9
10
{
"index_name": "refund_records",
"description": "存储用户退款申请及支付渠道处理状态",
"suitable_for": ["查询退款是否成功", "查询退款为什么没有到账"],
"not_suitable_for": ["查询商品是否允许退款"],
"fields": ["order_id", "user_id", "refund_status"],
"freshness": "near_real_time",
"authority": "refund_service",
"permissions": ["refund_read"]
}

3. 索引太多放不进上下文

解决方案:先检索索引,再检索数据。可以循环式检索,也可以做成索引树。

二、查询改写

2.1 基本改写规则

规则 描述
保留硬约束 不遗漏用户明确提出的限制
提取软偏好 保留偏好并转换为可查询指标
消除歧义 结合领域和上下文确定具体含义
统一术语表达 转换为标准术语和领域关键词
删除无关信息 去掉情绪表达、重复描述等
从问题转向信息缺口 改写成真正需要补齐的证据
增加过滤条件 补充用户 ID、时间范围等 Metadata
禁止擅自补充事实 不能加入没有证据支持的内容
控制查询粒度 一次查询围绕一个明确的信息缺口

2.2 HyDE:假设文档嵌入

HyDE(Hypothetical Document Embeddings)的核心思路:

  1. 让大模型根据问题生成一份”假想的答案文档”
  2. 将这份文档向量化
  3. 用它去召回真实文档

优势:缩小问题表达与目标文档表达之间的语义差距。

变种

  • 生成多段回答,每段都用于检索,最终重排序
  • 针对初步回答草拟一系列问题和查询语句

适用场景

  • 用户输入含糊,信息量太少
  • 用户表达和存储的数据差异明显

2.3 5W1H:将模糊问题拆成可查询的问题

维度 说明 示例
What 发生了什么 退款当前是什么状态
Who 涉及谁 哪一个用户、订单、支付渠道
When 什么时候发生 退款何时发起、最后一次状态更新
Where 发生在哪里 卡在退款服务还是支付渠道
Why 为什么会发生 是否存在失败码或回调异常
How 怎样执行的 退款链路已执行了哪些步骤

其他拆解方式:MECE、因果链拆解、时间线拆解、实体关系拆解。

三、Chunk 切割策略

3.1 文档入库基本流程

1
文档采集 → 文档解析 → 内容清洗 → Chunk 分片 → 元数据补充 → 向量化 → 入库校验

3.2 三种基本切割方式

方式 优点 缺点
基于长度 实现简单、性能稳定 不理解文档内容,可能切断完整知识单元
基于语义 Chunk 内容更集中 成本高,阈值难统一
基于文档结构 保留文档逻辑关系 依赖文档解析质量

推荐混合方案:文档结构确定大边界,语义判断内部边界,长度限制负责兜底。

3.3 Chunk Size 确定方法

  1. 分析业务中的最小完整知识单元
  2. 结合用户问题的粒度
  3. 通过测试集调参(256、512、800、1200 Token)
  4. 与 Overlap、Top-K、父子文档及上下文窗口一起考虑

3.4 特殊内容处理

类型 处理方式
图片 提取周围文本描述 / 视觉模型生成摘要 / 同时保存原图和描述
长列表 保留共同标题按项分组 / 按语义分类 / 建立父子关系
表格 整表为一个 Chunk / 表头+行组合 / 按业务实体切割

3.5 父子文档

核心思想:小 Chunk 负责检索,大 Chunk 负责提供给大模型阅读。

流程:

  1. 将原始文档切成较大的父 Chunk
  2. 再将每个父 Chunk 切成多个较小的子 Chunk
  3. 对子 Chunk 生成向量并建立索引
  4. 用户查询时,先召回最相关的子 Chunk
  5. 根据 parent_id 找到父 Chunk
  6. 将父 Chunk 放入上下文窗口

基于 RRF 的父 Chunk 排序

1
Score(P) = Σ 1/(k + rank(c_i))

同时考虑子 Chunk 排名越靠前贡献越大,以及同一个父 Chunk 命中的相关子 Chunk 越多累计得分越高。

3.6 层次文档

从父子文档升级到多层文档:

  • 第一层:整份文档
  • 第二层:章节
  • 第三层:小节
  • 第四层:段落
  • 第五层:句子或独立事实

每一层都可以额外保存摘要,检索时同步检索摘要和原文。

召回层次选择

问题类型 优先召回层次
事实型、参数型 段落级或事实级
解释型、原因型 小节级
总结型、概览型 章节级或文档级摘要
对比型、综合型 多个层次同时召回

四、提高召回准确率

4.1 常见检索方式

方式 擅长 不擅长
向量检索 语义相似匹配 精确匹配(错误码、型号)
关键字检索 精确匹配 同义词、不同表达
图数据库 实体关系查询 构建维护成本高

4.2 混合检索流程

1
多路召回 → 统一结构 → 硬条件过滤 → 结果合并去重 → 混合排序 → 业务规则调整

RRF 排序公式

1
RRF Score = Σ 1/(k + rank)

业务规则调整

  • 官方文档优先于论坛内容
  • 当前版本优先于历史版本
  • 实时数据库结果优先于旧摘要
  • 标题精确命中可以适当加权

4.3 检索效果指标

指标 说明
Recall@K 标准相关内容中有多少出现在前 K 个结果
Precision@K 前 K 个结果中有多少真正相关
Hit Rate@K 前 K 个中至少出现一个正确结果
MRR 第一个正确结果排在什么位置
NDCG 同时考虑相关性等级和排序位置
证据覆盖率 必需证据中有多少被成功召回
重复率 Top-K 中高度相似 Chunk 占比

4.4 迭代式检索

基础流程:

  1. 第一轮检索:从用户原始问题开始,获得基本信息
  2. 判断证据是否充分:评估当前结果能否回答问题
  3. 生成下一轮 Query:根据缺失信息生成新查询
  4. 合并新旧结果:去重、降权、处理冲突
  5. 停止条件:证据充分 / 连续无新信息 / 达到预算上限

与 Agentic RAG 的关系:迭代式检索是具体机制,Agentic RAG 是更完整的系统形态,迭代式检索只是其中一个组成部分。

五、检索性能优化

5.1 性能指标

指标 说明
端到端延迟 整个检索链路的总耗时
P50/P95/P99 关注长尾请求
吞吐量 QPS、最大并发数
成本 模型调用次数、Token、GPU

5.2 基础优化

  1. 中间件和索引优化:设计合理的索引和 Mapping
  2. 查询优化:避免宽泛昂贵的 Query
  3. 消除浪费:避免重复 Embedding、重复查询
  4. 预计算:文档切割、Embedding、关键词等在入库阶段完成

5.3 最小充分检索

核心思想:不要试图一次性解决所有问题,找出当前最小的、可以独立完成的目标。

判断最小目标:完成之后能否给用户一个有意义的结果。

适用场景:探索式、多步骤、弱依赖的任务。

不适用场景:不可拆分的任务、用户要求一次性完整结果、各部分强依赖。

5.4 基于预算的动态检索

给每次检索设置 Retrieval Budget:

  • 剩余时间
  • 最大检索轮次
  • 最大 Query 数量
  • 最大数据源数量
  • 最大召回/Rerank 文档数量
  • 剩余 Token 或上下文窗口

策略:先使用成本最低的检索方案,不够再逐渐升级,同时不断检查剩余预算。

5.5 缓存

缓存类型 适用场景 注意事项
检索结果缓存 同一 Query 短时间内重复出现 原始查询先改写再找缓存
最终答案缓存 FAQ、制度查询等答案稳定的问题 依赖实时数据时容易返回过期答案

推荐策略:优先缓存检索结果,谨慎缓存最终答案。

六、检索方案设计要点

6.1 入库

  • 复杂文档不要一刀切(表格、图片、视频等特殊处理)
  • Chunk 不要只会固定长度(父子文档、层次文档、动态 Chunk)

6.2 检索

  • 多路召回 + 动态权重
  • RRF 在父子文档中的应用
  • 迭代式检索 + 最小充分检索
  • 动态控制迭代退出条件
  • 根据结果动态调整检索策略
  • 设置 Budget(时间、轮次、Token 等)

6.3 评估

  • 数据驱动迭代,不是一次性评估
  • 建立固定测试集,每次修改策略后重新验证
  • Bad Case 归因到具体环节
  • 可以考虑自定义评价方法(如编辑距离变种)

总结:入库有创新,检索有创意,评估有闭环。

站内搜索

没有找到内容!