- 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
4.2 KiB
4.2 KiB
Proposal: executor-action-memory-relevance
问题
ISS-002:Executor 在单次会话中调用 lookup_knowledge 20+ 次,大部分是同域换变体的冗余调用。
根因:
- 行动记忆缺失:Executor 不知道自己已经检索过哪些域,反复用不同关键词查同一个域
- 质量信号缺失:检索结果没有归一化质量等级,LLM 无法判断"结果够不够"
- 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、retrievedDomainsThisSessionchat-executor-prompt.md:检索约束重写ToolInvocation实体 + V010 迁移:新增列LookupKnowledgeTool.saveToolInvocation():扩展入库字段
非目标
- 不给 Executor 注入 knowledge map(保持 Agent 边界)
- 不修改 Planner prompt 或 Planner 逻辑
- 不修改
PrimaryResult/SupplementResult的字段(不暴露原始分数给 LLM) - Phase 2 域级硬限制暂不实施,先观察 prompt 约束效果
风险
- L1 score 阈值(0.3/0.7)需要根据实际 embedding 分布调优,当前为初始值
- 归一化等级可能让 LLM 过早停止检索——需实测观察 REFERENCE 场景下的行为
- 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 迁移