本文是对 AI Agent 智能检索与 RAG 相关知识的学习整理,涵盖检索机制设计、Chunk 切割策略、召回优化、性能优化等核心主题。
一、Agent 检索机制设计
1.1 检索不只是 RAG
很多人一提到 Agent 检索就想到 RAG,但 RAG 只是 Agent 检索中的一部分。Agent 需要检索的场景远不止知识库问答:
- 摘要压缩后需要召回历史细节
- 用户说”刚才那个方案”需要检索之前的对话
- 长任务执行过程中需要重新查找工具结果、中间产物、Checkpoint
- 查询外部实时数据
核心问题不是”怎么做一个 RAG”,而是怎么设计 Agent 的整个信息检索机制。
1.2 查询什么:Agent 怎么知道自己缺什么
Agent 需要查询的内容包含两个层次:
- 开发者层面:在设计 Agent、Action 或业务流程时,决定某一个环节需不需要查询
- Agent 自身:在运行过程中思考当前信息够不够、要不要发起查询
基本步骤模板:
| 步骤 | 说明 | 示例 |
|---|---|---|
| 明确当前要做出的判断 | 查询是手段不是目的 | 判断 LangGraph 是否满足客服 Agent 生产要求 |
| 推导所需证据 | 细化判断标准 | 生产环境需要支持任务中断和恢复 |
| 区分已知和未知 | 排除已知信息 | 已知用户技术栈是 Python |
| 判断缺口是否值得查询 | 降级机制 | 资源不足时可考虑不查询 |
1.3 去哪里检索:动态查询空间
查询空间(可查询空间)不只是向量数据库,还包括:
- 特定 Action
- ES 索引
- 业务数据库
- 历史对话
- 用户画像
- 代码仓库、日志、Trace
- 外部搜索
- Agent 自己产生的中间结果
关键洞察:可查询空间不是固定的,会随着任务执行不断变化。
1.4 三种固定的检索套路
1. Action 天生提供特定信息
如果某种信息只能由特定 Action 提供,应优先通过规则或业务流程直接绑定,而不是让大模型猜测。
2. ES 检索需要 Index Profile
当 Agent 要在 ES 里面查询时,需要先建立索引说明(Index Registry):
1 | { |
3. 索引太多放不进上下文
解决方案:先检索索引,再检索数据。可以循环式检索,也可以做成索引树。
二、查询改写
2.1 基本改写规则
| 规则 | 描述 |
|---|---|
| 保留硬约束 | 不遗漏用户明确提出的限制 |
| 提取软偏好 | 保留偏好并转换为可查询指标 |
| 消除歧义 | 结合领域和上下文确定具体含义 |
| 统一术语表达 | 转换为标准术语和领域关键词 |
| 删除无关信息 | 去掉情绪表达、重复描述等 |
| 从问题转向信息缺口 | 改写成真正需要补齐的证据 |
| 增加过滤条件 | 补充用户 ID、时间范围等 Metadata |
| 禁止擅自补充事实 | 不能加入没有证据支持的内容 |
| 控制查询粒度 | 一次查询围绕一个明确的信息缺口 |
2.2 HyDE:假设文档嵌入
HyDE(Hypothetical Document Embeddings)的核心思路:
- 让大模型根据问题生成一份”假想的答案文档”
- 将这份文档向量化
- 用它去召回真实文档
优势:缩小问题表达与目标文档表达之间的语义差距。
变种:
- 生成多段回答,每段都用于检索,最终重排序
- 针对初步回答草拟一系列问题和查询语句
适用场景:
- 用户输入含糊,信息量太少
- 用户表达和存储的数据差异明显
2.3 5W1H:将模糊问题拆成可查询的问题
| 维度 | 说明 | 示例 |
|---|---|---|
| What | 发生了什么 | 退款当前是什么状态 |
| Who | 涉及谁 | 哪一个用户、订单、支付渠道 |
| When | 什么时候发生 | 退款何时发起、最后一次状态更新 |
| Where | 发生在哪里 | 卡在退款服务还是支付渠道 |
| Why | 为什么会发生 | 是否存在失败码或回调异常 |
| How | 怎样执行的 | 退款链路已执行了哪些步骤 |
其他拆解方式:MECE、因果链拆解、时间线拆解、实体关系拆解。
三、Chunk 切割策略
3.1 文档入库基本流程
1 | 文档采集 → 文档解析 → 内容清洗 → Chunk 分片 → 元数据补充 → 向量化 → 入库校验 |
3.2 三种基本切割方式
| 方式 | 优点 | 缺点 |
|---|---|---|
| 基于长度 | 实现简单、性能稳定 | 不理解文档内容,可能切断完整知识单元 |
| 基于语义 | Chunk 内容更集中 | 成本高,阈值难统一 |
| 基于文档结构 | 保留文档逻辑关系 | 依赖文档解析质量 |
推荐混合方案:文档结构确定大边界,语义判断内部边界,长度限制负责兜底。
3.3 Chunk Size 确定方法
- 分析业务中的最小完整知识单元
- 结合用户问题的粒度
- 通过测试集调参(256、512、800、1200 Token)
- 与 Overlap、Top-K、父子文档及上下文窗口一起考虑
3.4 特殊内容处理
| 类型 | 处理方式 |
|---|---|
| 图片 | 提取周围文本描述 / 视觉模型生成摘要 / 同时保存原图和描述 |
| 长列表 | 保留共同标题按项分组 / 按语义分类 / 建立父子关系 |
| 表格 | 整表为一个 Chunk / 表头+行组合 / 按业务实体切割 |
3.5 父子文档
核心思想:小 Chunk 负责检索,大 Chunk 负责提供给大模型阅读。
流程:
- 将原始文档切成较大的父 Chunk
- 再将每个父 Chunk 切成多个较小的子 Chunk
- 对子 Chunk 生成向量并建立索引
- 用户查询时,先召回最相关的子 Chunk
- 根据 parent_id 找到父 Chunk
- 将父 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 迭代式检索
基础流程:
- 第一轮检索:从用户原始问题开始,获得基本信息
- 判断证据是否充分:评估当前结果能否回答问题
- 生成下一轮 Query:根据缺失信息生成新查询
- 合并新旧结果:去重、降权、处理冲突
- 停止条件:证据充分 / 连续无新信息 / 达到预算上限
与 Agentic RAG 的关系:迭代式检索是具体机制,Agentic RAG 是更完整的系统形态,迭代式检索只是其中一个组成部分。
五、检索性能优化
5.1 性能指标
| 指标 | 说明 |
|---|---|
| 端到端延迟 | 整个检索链路的总耗时 |
| P50/P95/P99 | 关注长尾请求 |
| 吞吐量 | QPS、最大并发数 |
| 成本 | 模型调用次数、Token、GPU |
5.2 基础优化
- 中间件和索引优化:设计合理的索引和 Mapping
- 查询优化:避免宽泛昂贵的 Query
- 消除浪费:避免重复 Embedding、重复查询
- 预计算:文档切割、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 归因到具体环节
- 可以考虑自定义评价方法(如编辑距离变种)
总结:入库有创新,检索有创意,评估有闭环。