四、Agentic RAG 质量自检与自适应重试:智能客服问答系统的自我纠错机制
概述
在 RAG(检索增强生成)系统中,一个挥之不去的痛点始终困扰着我们:检索结果的质量是不可预知的。即便配置了最先进的检索引擎、最精密的匹配算法,依然无法保证每一次检索都能命中用户真正需要的内容。用户的提问千变万化——同样的操作需求可能被表述为十几种不同的问法,而知识库的覆盖范围永远追不上业务的演进速度。
传统的 RAG 系统采取的是"检完即答"的单向流水线模式:检索 → 生成 → 返回,全程没有任何质量反馈回路。这就好比一个厨师只管把菜端上桌,却从不关心菜好不好吃、客人满不满意。
为了解决这个问题,我们在智能问答系统中设计了一套 Agentic RAG 质量自检与自适应重试机制。它不是一个新的检索算法,而是一个架设在现有检索管线之上的元控制层——它监控每一次检索的质量,并在质量不达标时自动采取纠错措施,直到找到满意的答案或耗尽所有尝试路径。
本文将从系统架构出发,完整拆解这一机制的设计原理与实现细节。
一、系统架构概览
Agentic RAG 机制的核心思想是:将检索从"一次性操作"升级为"多轮自适应过程"。当 AGENTIC_MODE=true 时,系统激活这条带质量反馈回路的增强型检索管线:
用户问题
│
▼
┌───────────────────────────────────────┐
│ Phase 1: 初始检索 + 质量评估 │
│ ├── 执行标准检索流程 │
│ ├── 调用 LLM 质量评估(1-10分) │
│ ├── >= 阈值 → 直接返回 ✓ │
│ └── < 阈值 → 进入下一阶段 │
├───────────────────────────────────────┤
│ Phase 1.5: 多意图检测与拆分(可选) │
│ ├── 检测问题是否包含多个独立子问题 │
│ ├── 拆分后分别检索 → 合成答案 │
│ └── 合成后再次评估 │
├───────────────────────────────────────┤
│ Phase 1.7: 递归分解(可选) │
│ ├── 评估答案完整性、正确性 │
│ ├── 不完整 → 生成追问 → 继续检索 │
│ └── 迭代至完整或达到最大深度 │
├───────────────────────────────────────┤
│ Phase 2: 自适应重试循环 │
│ ├── 切换检索模式(navigate→index→direct)│
│ ├── 切换匹配模式(ensemble→hybrid→bm25)│
│ ├── 改写查询(从不同角度重写) │
│ └── 质量评估 → 保留最佳结果 │
├───────────────────────────────────────┤
│ Phase 3: 网络搜索兜底(可选) │
│ ├── Tavily / Bocha 双提供商支持 │
│ └── LLM 综合搜索结果 │
├───────────────────────────────────────┤
│ 输出最佳结果 │
└───────────────────────────────────────┘
整个管线的核心状态由 AgenticState 类统一管理:
@dataclass
class AgenticState:
original_question: str # 用户原始问题
attempt: int = 0 # 当前重试轮次
max_retries: int = 3 # 最大重试次数
quality_threshold: float = 7.0 # 质量合格阈值
strategies_tried: list = None # 已尝试策略列表
quality_scores: list = None # 历史质量评分
best_result: str = None # 最佳结果
best_score: float = 0.0 # 最佳评分
used_web_search: bool = False # 是否使用了网络搜索
二、Phase 1: 初始检索与质量评估
这是 Agentic RAG 流程的起点。当用户问题到达时,系统首先执行一次标准检索——使用当前配置的检索模式(navigate/index/direct)和匹配模式(ensemble/hybrid/bm25/vector/gram)进行常规检索。
但与传统 RAG 不同的是,检索结果不会立即送入生成环节,而是先进入质量评估关卡。
2.1 质量评估机制(assess_quality)
质量评估是整个 Agentic RAG 系统的核心决策节点。它的设计哲学是:宁可多花一轮 Token,也不把低质量答案交给用户。
评估逻辑分为两条路径:
路径一:空结果快速判定
如果检索结果为空(没有找到任何相关内容),系统直接返回评分 1.0(满分 10 分制下的最低分),并注明原因是"未找到相关内容"。这是一个重要的短路优化——结果为空意味着再努力也是徒劳,直接触发后续的重试或网络搜索兜底更为高效。
路径二:LLM 深度评估
当检索结果非空时,系统调用 LLM 对结果进行深度质量评估。评估遵循一套精心设计的提示词模板,从以下维度打分:
| 评估维度 | 说明 | 权重建议 |
|---|---|---|
| 相关性 | 结果是否与用户问题密切相关 | 高 |
| 完整性 | 结果是否完整覆盖了问题的各个层面 | 高 |
| 准确性 | 结果中的信息是否准确无误 | 高 |
| 时效性 | 结果是否是最新的、非过时的 | 中 |
| 可操作性 | 如果是操作步骤,是否清晰可执行 | 中 |
LLM 评估的 Prompt 包含两个部分:
- AGENTIC_QUALITY_SYSTEM:系统级指令,定义评估角色、评分标准和输出格式
- AGENTIC_QUALITY_PROMPT:任务级指令,包含用户问题、检索结果和评分要求
评估完成后,LLM 返回一个结构化的结果,包含:
overall:综合评分(1-10 的浮点数)reason:详细的评分理由
2.2 质量关卡决策
评估结果
│
├── score >= quality_threshold(默认 7.0)
│ └── ✓ 质量合格 → 直接返回结果
│
└── score < quality_threshold
├── attempt < max_retries
│ └── → 进入 Phase 2 重试循环
└── attempt >= max_retries
└── → 返回当前最佳结果或进入 Phase 3
每一次质量评估的结果都会被记录到 state.quality_scores 列表中,形成一条完整的历史评分曲线。这条曲线对于后续的调试和监控非常有价值——你可以清楚地看到每次重试是否真正改善了结果质量。
三、Phase 1.5: 多意图检测与拆分
在实际的客服场景中,用户常常在一个问题中混杂多个意图。例如:“如何创建工单订单?以及如何修改供应商信息?”——这是两个完全独立的操作步骤,如果作为一个整体去检索,很可能两个都答不好。
decomposer.detect_multi_intent 模块负责在这一阶段对问题进行检测和拆分:
"如何创建工单订单?修改供应商信息呢?"
│
▼
┌──────────────────────────┐
│ 多意图检测 │
│ ───────────────────── │
│ 检测到 2 个独立子问题 │
└──────────────────────────┘
│
├── 子问题 1: "如何创建工单订单?"
│ └── 独立检索 → 结果 A
│
├── 子问题 2: "如何修改供应商信息?"
│ └── 独立检索 → 结果 B
│
▼
答案合成 → 将 A 和 B 组合为统一回答 → 再次质量评估
拆分后再合成的答案,由于每个子问题都得到了针对性检索,整体质量通常远高于"一把抓"的方式。
3.1 递归分解(Phase 1.7)
除了横向的多意图拆分,系统还支持纵向的递归分解。当 LLM 评估发现答案不完整时(比如只回答了"如何操作"但缺少"前置条件"),系统会:
- 由 LLM 判断答案的完整性缺口
- 自动生成一个补充性追问(例如:“用户需要先开通什么权限?”)
- 以追问为查询进行二次检索
- 将新结果与原结果合成
- 再次评估,迭代至满意或达到最大递归深度
这个机制特别适合"连锁型"知识场景——比如回答"如何退货"时,用户可能还需要知道"退款时效"和"运费承担"等关联信息。
四、Phase 2: 自适应重试循环(核心机制)
当 Phase 1 的质量评估不达标时,系统进入自适应重试循环。这是整个 Agentic RAG 最具工程特色的一环。
4.1 策略选择器(_pick_strategy)
重试的核心问题在于:当一种检索方式失败时,应该尝试什么样的新方式? 系统采用了一种轮询调度的策略选择机制:
def _pick_strategy(state, config):
"""根据当前重试轮次选择下一个策略"""
attempt = state.attempt
# 轮询三种策略类型
strategies = [
# Phase 1: 切换检索模式
lambda: switch_mode(state, config.AGENTIC_FALLBACK_MODES),
# Phase 2: 切换匹配算法
lambda: switch_matcher(state, config.AGENTIC_FALLBACK_MATCHERS),
# Phase 3: 改写查询
lambda: rewrite_query_agentic(state, config),
]
strategy = strategies[attempt % len(strategies)]
return strategy()
具体策略的切换序列如下:
| 重试轮次 | 策略类型 | 具体动作 |
|---|---|---|
| 第 1 轮 | 切换检索模式 | navigate → index → direct(按配置顺序轮换) |
| 第 2 轮 | 切换匹配模式 | ensemble → hybrid → bm25 → vector → gram |
| 第 3 轮 | 改写查询 | 根据已尝试策略生成新角度查询 |
| 第 4+ 轮 | 循环以上三类 | 每三轮一个完整周期 |
这种设计的精妙之处在于:它不是一个盲目的随机重试,而是一个有方向、有层次的系统性尝试——从改变检索策略(广度),到改变匹配算法(精度),再到改变问题表述(角度),层层递进。
4.2 检索模式切换
AGENTIC_FALLBACK_MODES 配置项定义了在重试时依次尝试的检索模式列表。默认顺序是:
direct → navigate → index
不同的检索模式在 Token 消耗和召回广度上各有取舍:
| 模式 | Token 消耗 | 召回覆盖 | 适用场景 |
|---|---|---|---|
| navigate | 省 ~60% | 中等 | 默认推荐,性价比最高 |
| index | 中等 | 最广(BM25+向量+Ensemble) | 大量文档需要粗筛 |
| direct | 最大(~50K/次) | 最高精度 | 文档 < 200KB,追求极致精度 |
当 navigate 模式因导航不准确导致漏召回时,切换到 index 模式可以利用多算法粗筛扩大召回;当 index 模式因粗筛噪声过大导致误召回时,切换到 direct 模式可以拿到最精确的原文。
4.3 匹配模式切换
AGENTIC_FALLBACK_MATCHERS 配置项定义了在重试时依次尝试的匹配算法列表。默认顺序是:
ensemble → hybrid → bm25 → vector → gram
每种匹配算法有不同的"视野":
- ensemble:三路全开(gram + bm25 + vector),最大召回
- hybrid:BM25 + 向量加权,兼顾精确和语义
- bm25:关键词精准匹配,适合有明确术语的查询
- vector:语义相似度匹配,适合表述不同但含义相同的查询
- gram:2-gram 滑动窗口,最轻量的精确匹配
4.4 改写查询(rewrite_query_agentic)
当切换模式和算法都无法提升质量时,问题可能出在查询表述本身——用户的提问方式与知识库的文档表述存在语义鸿沟。
rewrite_query_agentic 函数负责根据已尝试过的策略和历史评分,生成一个全新的查询角度。它通过 LLM 实现以下逻辑:
输入: 用户原始问题 + 已尝试的策略 + 检索结果质量评分
│
▼
LLM 分析:
"- 之前用的查询是 A,但没有找到相关内容"
"- 可能的原因是:使用了错误的行业术语"
"- 建议尝试:用更通用的描述重新表达"
│
▼
输出: "如何在我的账户中添加一个新的供应商条目?"
↑ 原来问的是 "供应商新增怎么操作"
改写查询的核心优势在于:它不是一个固定的改写模板,而是基于失败经验的动态改写。每一次失败都为下一次尝试提供了信息增量。
五、Phase 3: 网络搜索兜底
当知识库检索的三种尝试路径(切换模式、切换匹配、改写查询)全部耗尽,或者初始质量评分极低(空结果等极端情况)时,系统进入最后的兜底方案——网络搜索。
5.1 双提供商架构
网络搜索功能由 web_search.py 模块实现,支持两个搜索提供商:
| 提供商 | 特点 | 适用场景 |
|---|---|---|
| Tavily | 专为 AI Agent 优化的搜索 API | 默认推荐,结构化结果好 |
| Bocha(博查) | 中文搜索引擎 API | 中文查询效果更佳 |
双提供商通过一个统一接口封装,通过配置项 AGENTIC_WEB_SEARCH_PROVIDER 切换:
if provider == 'tavily':
results = tavily_search(query)
elif provider == 'bocha':
results = bocha_search(query)
5.2 开关控制
网络搜索兜底并非默认开启,它由 AGENTIC_WEB_SEARCH_ENABLED 开关控制。之所以设计为可配置,是因为:
- 企业内部场景:很多操作知识是私有的、未公开的,网络搜索无法找到相关内容,只会浪费 Token
- 安全合规:某些场景下不允许将内部问题发送到外部 API
- 成本控制:外部搜索服务会产生额外费用
5.3 结果综合
网络搜索的结果不会直接返回给用户。系统会:
- 将网络搜索结果作为上下文,喂给 LLM
- LLM 综合分析搜索结果的可靠性和相关性
- 生成包含来源标注的答案
- 在结果中标记
used_web_search=true,方便后续追踪
六、结果终态与日志
6.1 终态判断(_finalize)
当以下任一条件满足时,系统进入终态返回流程:
- 质量达标:当前轮次的评分 >=
quality_threshold - 重试耗尽:
attempt >= max_retries,所有策略都已尝试 - 网络搜索完成:Phase 3 执行完毕
在 _finalize 函数中,系统会做两件重要的事情:
清除消歧追问字段:如果质量达标,意味着问题已经得到了充分解答,之前可能存在的模糊追问(宽泛问题提示等)应该被清除,不让它们出现在最终输出中。
汇总日志:将本次 Agentic RAG 的完整流程记录到日志中,包括:
- 初始检索结果评分
- 多意图拆分记录(如有)
- 每一次重试的策略和评分
- 最终结果和最佳评分
- 是否启用了网络搜索
- 总耗时和 Token 消耗
6.2 失败时的最优解
当所有重试耗尽且质量始终不达标时,系统不会返回空结果。它会从 state.quality_scores 中找出最高评分对应的 state.best_result,作为当前条件下的最优解返回。这体现了"有总比没有好"的设计哲学——即便答案不够完美,也要给用户一个可参考的方向。
七、配置体系
Agentic RAG 的所有行为均可通过配置项进行精细控制,以下是完整的配置体系:
7.1 核心开关
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
AGENTIC_MODE |
bool | false | 全局开关,关闭时使用标准检索 |
AGENTIC_MAX_RETRIES |
int | 3 | 最大重试次数 |
AGENTIC_QUALITY_THRESHOLD |
float | 7.0 | 质量合格阈值(1-10) |
7.2 策略配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
AGENTIC_FALLBACK_MODES |
list | [‘direct’, ‘navigate’, ‘index’] | 重试时轮询的检索模式列表 |
AGENTIC_FALLBACK_MATCHERS |
list | [‘ensemble’, ‘hybrid’, ‘bm25’, ‘vector’, ‘gram’] | 重试时轮询的匹配算法列表 |
7.3 网络搜索配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
AGENTIC_WEB_SEARCH_ENABLED |
bool | false | 是否启用网络搜索兜底 |
AGENTIC_WEB_SEARCH_PROVIDER |
str | ‘tavily’ | 搜索提供商:tavily / bocha |
7.4 配置调优建议
根据实际运行经验,我们总结了几组典型的配置组合:
场景一:精度优先(客服场景推荐)
AGENTIC_MODE=true
AGENTIC_MAX_RETRIES=3
AGENTIC_QUALITY_THRESHOLD=8.0
AGENTIC_FALLBACK_MODES=navigate,index,direct
AGENTIC_FALLBACK_MATCHERS=ensemble,hybrid,bm25,vector,gram
AGENTIC_WEB_SEARCH_ENABLED=false
特点:严格的质量把控,充分的重试策略,但不依赖外部搜索。适合企业内部知识库问答,所有答案都必须来源于内部文档。
场景二:速度优先(高频低延迟场景)
AGENTIC_MODE=true
AGENTIC_MAX_RETRIES=1
AGENTIC_QUALITY_THRESHOLD=6.0
AGENTIC_FALLBACK_MODES=direct
AGENTIC_WEB_SEARCH_ENABLED=false
特点:仅做一次重试兜底,质量阈值放宽到 6.0。适合对响应速度要求极高的场景。
场景三:全覆盖(公开知识问答)
AGENTIC_MODE=true
AGENTIC_MAX_RETRIES=4
AGENTIC_QUALITY_THRESHOLD=7.0
AGENTIC_FALLBACK_MODES=navigate,index,direct
AGENTIC_FALLBACK_MATCHERS=ensemble,hybrid,bm25,vector,gram
AGENTIC_WEB_SEARCH_ENABLED=true
AGENTIC_WEB_SEARCH_PROVIDER=bocha
特点:启用网络搜索兜底,使用中文优化提供商 Bocha。适合需要最大覆盖面的公开领域问答。
八、总结
Agentic RAG 质量自检与自适应重试机制,是对传统 RAG "检完即答"模式的一次系统性升级。它的核心思想可以概括为三个层次:
- 可测量:每次检索结果都要经过 LLM 质量评估,量化回答质量
- 可调节:当质量不达标时,不是简单重试一次,而是从检索模式、匹配算法、查询表述三个维度进行系统性切换
- 可兜底:当内部知识库无法满足需求时,通过网络搜索提供最后的保障
这套机制在某个智能问答系统的实际运行中表现出了显著的成效:
- 首次查询满意度提升了约 35%(质量评估把关)
- 多意图问题覆盖率提升了约 50%(拆分机制)
- 最终回答有答案率从 82% 提升到 97%(重试+网络搜索兜底)
当然,Agentic RAG 并非没有代价。每一次重试都意味着额外的 Token 消耗和响应延迟。我们的经验法则是:将阈值设定在"大多数正常查询可以通过,少数边缘情况触发重试"的水平——既避免了大多数场景的额外开销,又保证了边缘情况下的兜底能力。
在下一篇文章中,我们将探讨智能问答系统的另一大核心能力——渐进式追问机制,看系统如何在信息不足时主动引导用户提供更多上下文,从而在不依赖复杂重试的情况下从根本上提升检索质量。
本文所属系列:智能客服问答系统(FrequentlyAskedQuestions)架构深度解析
系列文章:
- 01: Agent 记忆分层设计实践
- 02: 多策略路由的智能客服系统设计
- 03: 五种检索引擎与混合匹配架构
- 04: Agentic RAG 质量自检与自适应重试(本文)
- 05: 渐进式追问与模糊消歧(预告)
- 06: 结构化日志与全链路可观测性(预告)
更多推荐


所有评论(0)