# Proposal: executor-action-memory-relevance ## 问题 ISS-002:Executor 在单次会话中调用 `lookup_knowledge` 20+ 次,大部分是同域换变体的冗余调用。 根因: 1. **行动记忆缺失**:Executor 不知道自己已经检索过哪些域,反复用不同关键词查同一个域 2. **质量信号缺失**:检索结果没有归一化质量等级,LLM 无法判断"结果够不够" 3. **Prompt 约束缺失**:现有 executor prompt 要求"所有需要外部信息的地方都必须调用工具",没有"放弃检索"的合法出口 ## 建议方案 ### 1. 行动记忆(通过工具返回值传递) `RetrievedDocTracker` 数据结构升级:`Map>>`。 每次 `lookup_knowledge` 返回值附带 `retrievedDomainsThisSession`,让 Executor 知道自己本次会话已检索过哪些域。 **不给 Executor knowledge map**——保持 Agent 边界清晰:Planner 知道全域(规划查哪个域),Executor 只知道自己做了什么(执行检索 + 基于结果推理)。 ### 2. 归一化质量等级(封装 L0/L1 分数差异) 在 `LookupKnowledgeTool` 内部新增归一化层,将 L0 匹配数和 L1 score 统一为三个等级: | 等级 | 含义 | LLM 应做什么 | |------|------|-------------| | `PRECISE` | 精准命中 | 直接使用,不再检索 | | `HIGHLY_RELEVANT` | 高度相关 | 综合推理,大概率不需要继续查 | | `REFERENCE` | 相关参考 | 可参考,如需更精准请明确缺什么维度 | 归一化逻辑: - L0 唯一匹配 → PRECISE - L0 命中 + L1 高分 → HIGHLY_RELEVANT - L0 多匹配 + L1 中分 → HIGHLY_RELEVANT - L0 多匹配 + 无 L1 → REFERENCE - 仅 L1 命中 → 按 score 分 HIGHLY_RELEVANT / REFERENCE **L0/L1 原始分数不返回给 LLM**,只在归一化层内部使用。原始分数入库(`tool_invocation.retrieval_details`)保留可观测性。 ### 3. 兜底信号(completenessHint) 每次返回附带 `completenessHint`,给 LLM "天花板"信号: | relevanceLevel | completenessHint | |----------------|-----------------| | PRECISE | "知识库中不存在比上述结果更精准的文档" | | HIGHLY_RELEVANT | "当前结果已高度相关,继续检索不太可能找到更精准的文档" | | REFERENCE | "当前结果为相关参考,如需更精准信息请明确缺少的具体维度" | ### 4. Executor prompt 重写检索约束 - 基于 `retrievedDomainsThisSession` 判断重复(不是"不要重复",而是"重复了该怎么办") - 给 LLM 合法出口:"不查全不会被追责,重复检索才会被惩罚" - 利用 `relevanceLevel` + `completenessHint` 判断质量 ### 5. 入库可观测性 `tool_invocation` 表新增 `relevance_level` 和 `dedup_reason` 列。 `retrieval_details` JSON 扩展:加入归一化等级、兜底信号、已检索域、去重原因、L1 top score。 ## 范围 - `LookupKnowledgeTool`:归一化层 + 行动记忆注入 + 域级拦截 - `RetrievedDocTracker`:数据结构升级(域级记录) - `LookupResult`:新增 `relevanceLevel`、`completenessHint`、`retrievedDomainsThisSession` - `chat-executor-prompt.md`:检索约束重写 - `ToolInvocation` 实体 + V010 迁移:新增列 - `LookupKnowledgeTool.saveToolInvocation()`:扩展入库字段 ## 非目标 - 不给 Executor 注入 knowledge map(保持 Agent 边界) - 不修改 Planner prompt 或 Planner 逻辑 - 不修改 `PrimaryResult`/`SupplementResult` 的字段(不暴露原始分数给 LLM) - Phase 2 域级硬限制暂不实施,先观察 prompt 约束效果 ## 风险 1. L1 score 阈值(0.3/0.7)需要根据实际 embedding 分布调优,当前为初始值 2. 归一化等级可能让 LLM 过早停止检索——需实测观察 REFERENCE 场景下的行为 3. Prompt 约束仍依赖 LLM 遵守——如果效果不足,需启用 Phase 2 域级硬限制 ## 来自 devflow 的上下文约束 - 前序 change `session-dedup-knowledge-map`:已实现文档级去重(RetrievedDocTracker + filePath)和 Planner knowledge map 注入 - ISS-001:文档级重复召回已修复 - glossary:ReactAgent 是自主决策工具调用的 Agent,不受外部流程控制 - JPA ddl-auto 使用 validate 模式,表结构修改必须通过 Flyway 迁移