Files
SuperBizAgent-java/openspec/changes/archive/2026-07-01-executor-action-memory-relevance/proposal.md
T
zhuyongxin e438df4355 feat(knowledge): Executor 行动记忆 + 归一化质量等级解决 ISS-002 重复检索
- RetrievedDocTracker 升级为域级+文档级双层记录(Map<sessionId, Map<domain, Set<filePath>>>)
- LookupKnowledgeTool 新增 Min-Max 归一化层(BGE-M3 L2 距离→[0,1] similarity)
- 三等级 relevanceLevel:PRECISE / HIGHLY_RELEVANT / REFERENCE + completenessHint 兜底信号
- LookupResult 新增 relevanceLevel、completenessHint、retrievedDomainsThisSession
- Executor prompt 重写:4 条检索约束 + 合法出口不查全不追责,重复检索才惩罚
- 入库可观测性:V010 迁移 + retrieval_details JSON 扩展
- 归档 executor-action-memory-relevance change
2026-07-01 18:24:41 +08:00

90 lines
4.2 KiB
Markdown
Raw 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.
# Proposal: executor-action-memory-relevance
## 问题
ISS-002:Executor 在单次会话中调用 `lookup_knowledge` 20+ 次,大部分是同域换变体的冗余调用。
根因:
1. **行动记忆缺失**:Executor 不知道自己已经检索过哪些域,反复用不同关键词查同一个域
2. **质量信号缺失**:检索结果没有归一化质量等级,LLM 无法判断"结果够不够"
3. **Prompt 约束缺失**:现有 executor prompt 要求"所有需要外部信息的地方都必须调用工具",没有"放弃检索"的合法出口
## 建议方案
### 1. 行动记忆(通过工具返回值传递)
`RetrievedDocTracker` 数据结构升级:`Map<sessionId, Map<domain, Set<filePath>>>`。
每次 `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 迁移