Files
SuperBizAgent-java/devflow/projects/2026-07-01-executor-action-memory-relevance/decisions.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

84 lines
5.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.
# Decisions: executor-action-memory-relevance
## 过程日志
### Clarify 阶段
**入口摘要**:ISS-002 Executor 无约束重复调用 lookup_knowledge(单会话 20+ 次),需要行动记忆 + 归一化质量等级 + prompt 约束来解决。
**slug**: `executor-action-memory-relevance`
**规模分档**: `standard`(涉及 7 个文件,跨 DTO/工具层/持久化/Prompt,有设计决策需澄清)
### Context 阶段
**devflow/index.md 使用状态**: 已命中。前序 change `session-dedup-knowledge-map`(archived)提供了 RetrievedDocTracker、KnowledgeDomainService、ISS-002 文档。
**相关 ADR**: 无直接 ADR,但 `session-dedup-knowledge-map` 的 decisions.md 和 evidence.md 记录了文档级去重和 knowledge map 注入的决策。
**不能违反的历史决策**:
1. RetrievedDocTracker 的文档级去重必须保留
2. knowledge map 只注入 Planner,不注入 Executor(本次讨论确认)
3. L0/L1 原始分数不暴露给 LLM,只在归一化层内部使用(本次讨论确认)
**需进入 OpenSpec 的上下文点**:
1. L1 score 是 L2 距离(值域 [0,+∞)),不是归一化分数——阈值设计需基于实际分布
2. L0 的 category 可从 KnowledgeEntry.getCategory() 直接获取;L1 需解析 metadata JSON
3. ReactAgent 是自主决策工具调用的 Agent,Prompt 约束是软约束
### Grill 阶段 — Question Pool
**维度:术语**
1. [evidence-driven] `relevanceLevel` 三个等级(PRECISE/HIGHLY_RELEVANT/REFERENCE)的边界是否清晰,是否存在 LLM 误解的可能? → **已查证**:三个等级语义明确,PRECISE=唯一匹配、HIGHLY_RELEVANT=高分命中、REFERENCE=低置信度参考。LLM 理解风险低。
**维度:边界**
2. [evidence-driven] L1 score 是 L2 距离(值域 [0,+∞)),当前代码无阈值判断。归一化阈值如何设计? → **已查证**:L2 距离典型范围取决于 BGE-M3 1024 维 embedding 的尺度,需从 `tool_invocation.retrieval_details` 中查询实际 `l1_scores` 分布才能定阈值。当前先以常量定义,标记为"需实测校准"。
3. [evidence-driven] L1 结果的 category 提取需要解析 metadata JSON 字符串,当前 `SearchResult.metadata` 是 `toString()` 的结果。归一化层是否需要 L1 的 domain? → **已查证**:L1 的 domain 主要用于 RetrievedDocTracker 的域级记录。如果 L0 已命中且包含 category,可直接用 L0 的 category;如果仅 L1 命中,需解析 metadata 提取 category。当前知识库中 L0 大概率先命中,L1 domain 提取作为兜底路径。
4. [user-interview] 归一化阈值(L1 score 分界线)在实测数据不足时,是否接受先用保守初始值 + 后续调优的策略? → **用户待确认**
**维度:验收**
5. [evidence-driven] 现有 `tool_invocation` 表 `retrieval_details` JSON 中 `l1_scores` 存的是 L2 距离原始值,新增的 `relevance_level` 和 `completeness_hint` 入库后是否需要回填历史数据? → **已查证**:不需要回填历史数据,新列 nullable 即可,历史记录 relevance_level=null。
### Grill 结论
**evidence-driven 汇报**:
- E1: relevanceLevel 三等级语义清晰,LLM 误解风险低
- E2: L1 score 是 L2 距离,值域不固定,阈值需实测校准
- E3: L0 category 直接可用,L1 category 需解析 metadata(兜底路径)
- E4: 历史数据不回填,新列 nullable
**user-interview 已确认**:
- Q4: 归一化阈值先用保守初始值 + 后续调优 → **用户已确认**,并建议用 Min-Max 归一化到 [0,1]
### Specify 阶段补充
**BGE-M3 L2 归一化实测验证**:
- FullPipelineSmokeTest.embeddingBgeM3Works() 新增 L2 范数断言
- 结果:范数=1.00000002,误差 < 0.01,测试通过
- 结论:BGE-M3 输出为 L2 归一化单位向量,L2 距离数学硬上界 = 2.0
- Min-Max 归一化公式:`similarity = 1 - min(l2Score, 2.0) / 2.0`
**Cross-artifact 对齐检查**:
| 对齐项 | 状态 |
|--------|------|
| brief 目标/范围/非目标 → proposal 覆盖 | 已对齐 |
| proposal 范围/约束 → design 覆盖 | 已对齐 |
| design 归一化/行动记忆/接口影响 → specs 覆盖 | 已对齐 |
| specs 可观察行为 → tasks 覆盖 | 已对齐 |
**接口影响分级**:
- RetrievedDocTracker 数据结构升级 → L2(内部接口,消费者只有 LookupKnowledgeTool)
- LookupResult 新增 3 字段 → L2(工具返回值,无跨模块调用方)
- tool_invocation 新增 2 列 → L2(Flyway nullable,不影响现有查询)
- chat-executor-prompt.md 更新 → L1(Prompt 文本变更)
### Audit 阶段
**架构风险评估**(5 句以内):
1. 归一化层嵌入 LookupKnowledgeTool 内部(静态方法),无跨模块耦合风险。
2. RetrievedDocTracker 升级为双层结构,数据量级不变(文档数 × session 数),内存无风险。
3. L1 metadata 解析 category 是兜底路径,如果 JSON 格式不一致可能解析失败——已有 try-catch 兜底。
4. 归一化阈值 yml 配置化,运行时调优不需要改代码和重启——运维友好。
5. Prompt 约束仍依赖 LLM 遵守——如果 Phase 1 效果不足,Phase 2 域级硬限制的 isDomainRetrieved 已就绪,无需额外改造。