Files
SuperBizAgent-java/mvp/issues/archived/ISS-002-executor-unconstrained-lookup.md

88 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ISS-002 Executor 无约束重复调用 lookup_knowledge
**状态**:已修复
**严重程度**:中(工具层去重已拦截重复文档,但调用本身仍浪费 token 和耗时)
**发现时间**:2026-07-01
**修复时间**:2026-07-01
**关联**:ISS-001(Part A 已修,Part B 注入范围不足)
---
## 现象
ISS-001 修复后,session 级去重(RetrievedDocTracker)生效,同一文档不再重复召回内容。但 Executor 在单次会话中仍调用 `lookup_knowledge` 20+ 次,大部分被去重拦截返回"已检索过"。
实测日志(session `7c517329`,2026-07-01 13:53):
```
Executor 调用 lookup_knowledge ~20 次
去重拦截 11 次:
- infrastructure/mysql-connection-pool.md × 6
- api/payment-errors.md × 5
有效检索仅 2-3 次(首次命中各域时)
```
Executor 用不同的 query 变体反复查同一个域,因为 LLM 觉得"需要更多细节"。
---
## 根本原因
**knowledge map 和检索约束只注入了 Planner prompt,未注入 Executor prompt。**
当前注入范围:
| 组件 | knowledge map | 每域最多一次约束 |
|------|:---:|:---:|
| Planner prompt | 已注入 | 已注入 |
| Executor prompt | **未注入** | **未注入** |
调用链路:
```
Supervisor → Planner:规划一次,输出"查 infrastructure 域 + api 域"
Supervisor → Executor:执行步骤(ReactAgent,自主决定调用工具)
Executor step 1:lookup("MySQL 连接池配置") → 命中 infrastructure 域 ✓
Executor step 2:lookup("HikariCP 参数调优") → 去重拦截 ✗
Executor step 3:lookup("连接池耗尽排查步骤") → 去重拦截 ✗
Executor step 4:lookup("支付超时排查") → 命中 api 域 ✓
Executor step 5:lookup("ERR_TIMEOUT 错误码") → 去重拦截 ✗
...(反复用不同变体查同域)
```
Executor 看不到"每个域只查一次"的约束,也不知道已有哪些域被检索过。
---
## 影响
- **Token 浪费**:每次去重拦截仍需走完 L0+L1 检索流程,再返回"已检索过";LLM 也要处理这个返回信息
- **耗时增加**:每次冗余调用约 400-500ms(L0+L1 检索 + 向量查询),20 次冗余调用浪费约 10s
- **LLM 行为低效**:Executor 花大量 step 在重复检索上,而不是基于已有信息推理
---
## 修法方向
### 方案 A:Executor prompt 注入 knowledge map + 检索约束
在 `chat-executor-prompt.md` 或 `buildChatExecutorAgent()` 中:
1. 注入 knowledge map(与 Planner 相同的 YAML)
2. 添加规则:"每个域最多调用一次 lookup_knowledge;已检索过的域不要再用不同关键词重复检索"
优点:与 Planner 对齐,LLM 能理解域级边界
缺点:仍依赖 LLM 遵守指令(但比纯 Prompt 约束强,因为有 knowledge map 做锚点)
### 方案 B:工具层硬限制(session + 域级计数)
在 `RetrievedDocTracker` 中增加域级计数:`ConcurrentHashMap<sessionId, Map<domain, count>>`。
当某域检索次数 > 1 时,直接在 `LookupKnowledgeTool` 入口返回"该域已检索过,不允许再次调用"。
优点:100% 可靠,不依赖 LLM
缺点:需改动 RetrievedDocTracker + LookupKnowledgeTool,需要从 filePath 反查 domain
### 建议
**先做方案 A**(改动小,与已有 knowledge map 注入逻辑一致),观察效果。
如果 LLM 仍不遵守,再升级到方案 B。