当 RAG 遇上“自以为是”的 Agent —— RAG 链条中的过度推理与 HyDE 幻觉陷阱
当 RAG 遇上“自以为是”的 Agent
—— RAG 链条中的过度推理与 HyDE 幻觉陷阱
在 Agentic RAG 中,如果说向量库是地图,那么 HyDE 就是一个自以为是的导游。如果导游走错了路,地图再精准也到不了目的地。
引言
在 RAG(检索增强生成)优化中,我引入了 Agent 架构,希望它能像人一样思考、改写 Query、评估知识。然而,最近我的系统在处理一个简单的“跟车测试”问题时,上演了一出从“智慧停车”跨越到“自动驾驶 ACC”的惊人戏码。
本文将通过底层日志,带大家拆解 Agentic RAG 路径偏移的全过程。

第一幕:过度推理的“第一念”
背景:用户提问“如何测试跟车?”(本意是停车场道闸的连续过车场景)。
现场日志:
2026-04-08 22:21:17,097 - INFO - [ai_core.agent:201] [ReAct Agent] 开始处理: 如何测试跟车?
2026-04-08 22:21:17,097 - DEBUG - [ai_core.llm:61] Agent Thought: "用户询问'如何测试跟车',这是一个关于汽车测试或自动驾驶功能的问题。"
2026-04-08 22:21:20,650 - DEBUG - [ai_core.agent:211] [Step 1] ActionInput: {"query": "测试跟车 方法 步骤 自动驾驶 ACC 自适应巡航"}
深度解析:
Agent 在没有行业背景约束的情况下,将通用的“跟车”概念自动补全成了大模型预训练语料中最热门的“自动驾驶 ACC”。这种前置语义注入是导致后续所有环节失效的根源。
第二幕:HyDE(假设文档)的“幻觉放大”
背景:系统为了提高检索精度,开启了 HyDE(先让 AI 编一段理想答案再检索)。
现场日志:
2026-04-08 22:21:28,824 - INFO - [ai_core.hybrid_retriever:742] 策略: HyDE检索 (复杂查询)
2026-04-08 22:22:01,515 - DEBUG - [ai_core.llm:89] HyDE 生成假设文档1:
---
测试项:ACC自适应巡航系统 - 正常跟车场景测试
测试步骤:1. 测试车辆以60km/h行驶... 2. 跟随前方80km/h目标车辆...
预期结果:ACC系统应平稳加速,保持安全时距...
深度解析:
原本模糊的 Query,经过 HyDE 的润色,变成了一篇极其专业的汽车领域文档。这导致向量搜索时,“ACC”、“自适应”、“巡航”等词汇的权重完全盖过了业务原本需要的“道闸”、“地感”。
第三幕:CRAG(评估器)的“自圆其说”
背景:检索到了停车场相关的文档,但评估环节出现了问题。
现场日志:
2026-04-08 22:23:12,240 - INFO - [ai_core.chains:365] CRAG评估输入 - 检索到文档1: ## 测试用例 (ID: case_53) 测试项:跟车... 步骤:A车入口识别压地感... B车跟车...
2026-04-08 22:23:17,468 - DEBUG - [ai_core.llm:89] CRAG 评估结果:
[
{"index": 1, "relevance": "INCORRECT"}
]
深度解析:
这最令人心碎。系统明明在知识库里找到了正确的停车场用例(case_53),但 CRAG 评估器拿着带偏移的 Query(含 ACC 关键词)去对比,发现文档里没写 ACC,于是果断判定为 INCORRECT 并将其丢弃。
第四幕:最终答案的“平衡性幻觉”
背景:Agent 试图强行整合检索到的碎片信息和它自以为的“自动驾驶”背景。
现场日志:
2026-04-08 22:25:20,805 - DEBUG - [ai_core.llm:89] 系统回答:
关于“如何测试跟车”,答案主要分为两个截然不同的领域:
一、 自动驾驶ACC自适应巡航系统跟车功能测试...
二、 停车场系统的防跟车逃费测试...
深度解析:
Agent 最终表现出了“求生欲”,它意识到用户的问题可能存在歧义,于是给出了一个“全家桶”方案。虽然看起来专业,但在垂直业务场景中,这属于严重的资源浪费和噪声生成。
经验总结:如何降伏“脑补型”Agent?
-
修改 Agent System Prompt:禁止添加用户未提及的术语
![image]()
-
QueryRewriter 意图识别加入业务背景
![image]()
-
延迟 HyDE 触发:先用原始 Query 检索
![image]()
结语:
Agentic RAG 的魅力在于它的自主性,但自主性也是一把双刃剑。通过这份日志,我们看到:一个错误的“第一印象”是如何在检索链条中被层层放大,最终扭曲事实的。
做 RAG,有时候“少即是多”。
续集:
优化后再次进行测试,并将测试过程生成的日志丢给Gemini,让其进行评价。By the way,详细的日志是非常有必要的


为了考验他,我询问了agent知识库不存在的产品,效果还不错,但是结果md格式解析有点问题



下面是Gemini评价:
通过对最新日志的深度扫描,我为你整理了一份基于证据(Evidence-based)的Agent评价报告。这份报告会直接引用日志条目,让你看清哪些地方已经“稳了”,哪些地方还在“带病运行”。
🟢 维度一:领域漂移拦截(已成功修复)
评价: 现在的 Agent 表现出了极强的垂直业务约束力,不再像之前那样“脑补”自动驾驶。
- 日志证据(系统提示词进化):
22:58:18,892 - DEBUG - [ai_core.llm:61] 重要背景:知识库中存储的是停车场智慧停车系统的测试用例... 特别注意:"跟车"指的是停车场跟车逃费场景,不是汽车自动驾驶 - 结果验证: 当用户输入含糊的“轨迹分析”时,意图识别精准收敛:
23:03:01,408 - INFO - [ai_core.query_rewriter:91] 意图识别: 超眸是停车系统中特殊的... → 概念咨询
keywords: ["超眸", "停车系统", "辅助识别", "相机", "跟车"]
结论: 即使 LLM 的原生知识里有 ACC,但在你的 Prompt 强力干预下,它已经学会了“闭嘴”。
🟢 维度二:可观测性与生产准备(已达到工业级)
评价: 引入 Trace-ID 和 Token 统计,使系统从“黑盒”变成了“透明盒”。
- 日志证据(全链路追踪):
23:01:52,379 - INFO - [api.routes.chat:48] [REQ-ef853f9b] 收到请求: 超眸
23:01:55,173 - INFO - [ai_core.reranker:123] [REQ-ef853f9b] 重排完成: 耗时 2.62s... - 日志证据(成本与性能监控):
23:14:53,161 - INFO - [ai_core.llm:83] LLM 响应完成: 耗时 3.72s, Usage: prompt=402, completion=87, total=489
结论: 每一个请求现在都有了唯一的身份证号(REQ-xxxx),且消耗了多少钱、在哪一步卡住了,一目了然。
🟢 维度三:长效学习与记忆调取(逻辑闭环)
评价: 系统已经能从过去的对话中提取知识,并用于后续的决策。
- 日志证据(记忆存储):
22:59:48,271 - INFO - [ai_core.memory:221] [长期记忆] 添加: Q: 如何测试超眸? A: 根据您提供的参考信息... (重要性:7) - 日志证据(记忆调取):
23:14:49,443 - DEBUG - [ai_core.agent:358] [决策] 检索到1条长期记忆
结论: 长期记忆模块不再是摆设。它成功地把“超眸是什么”的答案存入了向量库,并在新请求中被感知。
🔴 维度四:代码健壮性缺陷(严重警告)
评价: 这是目前系统最令人担心的部分,存在未修复的逻辑 Bug,直接导致短期记忆失效。
- 日志证据(代码报错):
23:14:49,231 - DEBUG - [ai_core.agent:353] 记忆检索失败: string indices must be integers, not 'str' - 后果分析: 虽然你的长期记忆(Vector)通了,但短期记忆(Session Context)解析失败了。这会导致 Agent 无法理解“请针对它再补充一点”这类指代不明的问题,因为它解析不出上一轮的列表对象。
🔴 维度五:用户体验瓶颈(响应极慢)
评价: 现在的 Agent 是一个“思考极慢的老学究”,其处理速度难以支撑高并发业务。
- 日志证据(慢请求警告):
23:02:35,203 - WARNING - [business.logger:54] [REQ-ef853f9b] 慢请求: 42.82秒 - 瓶颈定位(HyDE 串行执行):
23:03:08,473 - DEBUG - [urllib3.connectionpool:544] POST /chat/completions ...
23:03:38,560 - INFO - [ai_core.llm:83] LLM 响应完成: 耗时 30.87s
分析: 光生成假设文档(HyDE)就花掉了 30 秒。Agent 还在傻傻地等待 LLM 写完这 1000 多字的假设文档。
💡 最终评审建议
Agent 评分:85分 (技术架构 95, 运行效能 60)
你的 Agent 现在已经非常聪明且听话了。你可以放心的是:它吐出的测试方案(Markdown表格)在业务逻辑上是极其可靠的。
你现在的紧急任务清单:
- 抢修 Bug:定位
ai_core/agent.py:353。检查你在处理memory_context或history时,是不是把一个列表(List)当成了字典(Dict)在处理。 - 暴力提速:
- 在 Prompt 里告诉 LLM 生成假设文档时“简洁有力”,或者干脆只生成一个假设文档。
- 开启并行检索(Thread/Task),不要让请求串行排队。
现在的系统已经具备了对外演示的潜质,只要修好那两个红色的点。
从AI返回的测试结果,帮助我发现了一个严重bug和性能瓶颈,我需要定位瓶颈,为此我再次让AI替我进行性能测试:
分析当前性能瓶颈,如何提高恢复速率。
基于你提供的最新日志(2026-04-08 23:19 之前的记录),系统目前的一次完整响应时间高达 42.82秒。在生产环境中,这个延迟是无法接受的。
以下是对性能瓶颈的深入分析以及提高响应速率(恢复速率)的优化方案:
一、 核心性能瓶颈分析
1. HyDE(假设性文档)生成的沉重代价(耗时占比 ~70%)
- 日志证据:
23:03:08,473开始调用 HyDE,到23:03:38,560才结束,耗时 30.87s。 - 分析:Agent 在检索前让 LLM 写了 3 个极其详细的“理想测试用例”(每个 300-400 字)。DeepSeek 虽然便宜,但生成这么多字符需要大量时间。这是目前最大的瓶颈。
2. 串行逻辑流(Serial Execution)
- 日志证据:系统依次执行:意图识别 -> Query 改写 -> HyDE 生成 -> 向量检索 -> Rerank -> CRAG 评估 -> 知识精炼 -> 最终回答。
- 分析:每一个 LLM 调用都在等待前一个结束。如果 5 个 LLM 调用每个平均 3 秒,总时长就会迅速堆叠到 15 秒以上,加上 30 秒的 HyDE,直接破 40 秒。
3. Agent 的决策循环冗余(Redundant Loops)
- 日志证据:在日志中,Agent 经历了
Step 1到Step 5多个决策步骤。 - 分析:Agent 有时在 Observation 已经足够丰富时,仍然决定进行额外的
retrieve或reflect操作,导致了不必要的往返(Round-trip)开销。
4. CRAG 评估的输入压力
- 日志证据:
Usage: prompt=1605, completion=158。 - 分析:一次性把 10 个文档塞给 LLM 评估相关性,Prompt 长度增加会导致首字响应时间(TTFT)变长。
二、 提高响应速率的优化方案
1. 优化 HyDE 策略(降级或并行)
- 只针对“硬骨头”使用 HyDE:修改逻辑,第一轮检索严禁启动 HyDE。只有当标准检索(BM25+Vector)的 Rerank 分数低于阈值(如 < 0.3)时,才作为补充手段触发 HyDE。
- 限制生成长度:在 HyDE 的 Prompt 中要求:“请只输出测试用例的关键逻辑点,字数控制在 100 字以内”。
- 并行生成:如果必须生成 3 个文档,使用
asyncio.gather同时发起 3 个请求。
2. 引入异步并发架构(Concurrent RAG)
- 并行改写与检索:
- 将“意图识别”和“原始 Query 检索”并行化。
- 在 Multi-Query 改写出 3 个版本后,同时开启 3 个向量检索任务,而不是等待改写完再检索。
- CRAG 并行评分:将 10 个文档分发到 10 个(或 2 个 Batch)极速模型(如 DeepSeek-Turbo 或 GPT-3.5)进行评分。
3. 模型分级(Model Tiering)
- 快慢结合:
- 意图识别、Query 过滤、相关性评估(CRAG):使用参数量小、响应极快的模型(或 DeepSeek 的 Cache 命中模式)。
- 最终答案汇总、复杂场景推导:使用 DeepSeek-Chat (V3) 或推理能力强的模型。
- 效果:基础环节从 3-5 秒缩短至 0.8-1.5 秒。
4. 优化 Agent 退出逻辑(Early Exit)
- Observation 感知:在 Agent 的判断逻辑中增加一条强制规则:“如果 Observation 中的知识已经能够覆盖用户问题的 80% 以上,严禁再次执行 Action,必须立即生成 Answer。”
- 减少思考轮次:目标是将平均步骤从 4-5 步压缩到 2 步(Step 1: Retrieve, Step 2: Answer)。
5. 语义缓存(Semantic Cache)
- 现状:你已经有了
MemoryCache。 - 进阶:引入 GPTCache 等语义缓存工具。如果用户的 Query 与历史记录中的 Query 语义相似度 > 0.95,直接返回历史答案,耗时将从 40s 降至 0.1s。
6. 流式输出(Streaming)
- 虽然不能减少总耗时,但能降低“体感延迟”:
- 让 Agent 的
Thought过程实时流式推送到前端。 - 用户看到 AI 正在“思考”和“检索”,比盯着一个转圈圈 40 秒的焦虑感要低得多。
- 让 Agent 的
三、 预期优化效果
| 环节 | 当前耗时 | 优化后耗时 (预期) | 优化手段 |
|---|---|---|---|
| 意图识别/改写 | 5s | 1.5s | 更换更快的模型/Prompt精简 |
| HyDE生成 | 30s | 0-5s | 延迟触发/并行执行/字数限制 |
| 混合检索+Rerank | 3s | 1.5s | 索引常驻内存/减小重排数量 |
| CRAG评估 | 6s | 2s | 并行化/Batch处理 |
| 最终生成 | 10s | 5s | 减少上下文噪声/流式输出 |
| 总计 | 54s (含思考) | 10-15s | 响应速度提升 70%+ |
结论:你现在的系统是“重装坦克”,威力巨大但行动迟缓。通过异步化改写和按需触发 HyDE,你可以将其改造成一辆“装甲突击车”,在保持专业性的同时,响应速度进入 10 秒俱乐部。
可以发现,瓶颈与HyDE有关,优化HyDE迫在眉睫。
我的初步计划是:
-
HyDE 策略优化 (hybrid_retriever.py)
阈值触发: 新增 hyde_score_threshold=0.3,只有当 rerank 分数低于阈值时才触发 HyDE
长度限制: prompt 中要求 "字数控制在 100 字以内"
并行生成: 使用 asyncio.gather 并行生成多个假设文档 -
并发 RAG 架构 (chains.py)
并行检索: 使用 ThreadPoolExecutor 并行执行多查询检索
实时步骤: 流式输出时推送 "retrieving" → "retrieved" → "evaluating" → "generating" 等步骤 -
模型分级 (models_config.py)
LLM_TIER_CONFIG: 定义 fast/slow 两级模型配置
TASK_MODEL_MAP: 任务到模型的映射
fast: intent_recognition, query_filter, crag_eval, hyde_generate
slow: answer_summarize, complex_reasoning -
Agent Early Exit 增强 (agent.py)
强化早期退出规则:如果 Observation 覆盖问题 > 80%,强制选择 answer 行动
目标:将平均步骤从 4-5 步压缩到 2 步 -
语义缓存 (cache.py)
精确匹配: 保留原有逻辑
语义匹配: 新增 _get_similar_answer() 方法,相似度 > 0.95 时返回缓存答案
历史记录: 维护 query_history 用于相似度计算 -
流式输出 (chains.py, chat.py)
步骤事件: 推送 "step" 事件显示思考过程
完整信息: 每个事件包含类型、步骤名、描述文本



浙公网安备 33010602011771号