- 移动 session-dedup-knowledge-map OpenSpec 到 archive 目录 - 提交 ISS-001 遗留的 devflow 档案文件 - 更新 ISS-002 状态为已修复 - 新增 mvp/architecture/action-memory-relevance.md 设计文档 - 更新 mvp/README.md 文档导航 - 更新 devflow/index.md OpenSpec 链接指向 archive
3.3 KiB
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() 中:
- 注入 knowledge map(与 Planner 相同的 YAML)
- 添加规则:"每个域最多调用一次 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。