Files
zhuyongxin a1c896ebda chore(docs): 归档 ISS-001 session-dedup-knowledge-map + ISS-002 mvp 文档
- 移动 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
2026-07-01 18:27:04 +08:00

61 lines
3.8 KiB
Markdown
Raw Permalink 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.md — session-dedup-knowledge-map
## Question Pool
| # | 问题 | 类型 | 状态 |
|---|---|---|---|
| Q1 | domain.when_to_retrieve 来源(手动/自动聚合/LLM上传时生成) | user-interview | 已确认 |
| Q2 | LLM 生成时机(同步上传 vs 异步补全) | user-interview | 已确认 |
| Q3 | knowledge map 结构(域级平铺 vs 两层) | user-interview | 已确认 |
| Q4 | domain.when_to_retrieve 存储(内存 vs DB) | user-interview | 已确认 |
| Q5 | Executor 文档级细粒度筛选是否进 MVP | user-interview | 已确认 |
| E1 | ThreadLocal 在多 Agent 路径是否安全 | evidence-driven | 已汇报 |
| E2 | 6 个文档是否全部有 category 字段 | evidence-driven | 已汇报 |
| E3 | 去重 key 设计 | evidence-driven | 已汇报 |
| E4 | Planner prompt token 增量是否可接受 | evidence-driven | 已汇报 |
| E5 | EvaluationService.tool_call_count 影响 | evidence-driven | 已汇报 |
## Evidence-Driven 结论
- **E1**:`AsyncConfig` 只启用 `@EnableAsync`,无 TaskDecorator。`SupervisorAgent.invoke()` 是同步阻塞调用,工具调用与主线程同线程,ThreadLocal 当前路径安全。异步扩展时需补 TaskDecorator。
- **E2**:全部 6 个文档均有 `category` 字段:api(1)、domain(1)、infrastructure(3)、troubleshooting(1)。
- **E3**:`KnowledgeEntry.filePath` 在 L0 内唯一,L1 `_source` 字段也是 filePath,统一用 filePath 作去重 key。
- **E4**:当前 planner prompt 21 行,注入 knowledge map 约增加 200-400 字符,可接受。
- **E5**:去重后 `agent_step.has_tool_call` 减少,`tool_call_count` 降低,这是修复效果,`EvaluationService` 评分规则无需改动。
## User-Interview 确认记录
**Q1** — doc.when_to_retrieve 来源
用户原话:选 C(上传时 LLM 自动生成)
确认状态:已确认
**Q2** — LLM 生成时机
用户原话:选 X(同步,上传时当场生成)
确认状态:已确认
**Q3** — knowledge map 结构
用户原话:认可两层结构(domain → documents[])
确认状态:已确认
补充:Planner 只注入域级 when_to_retrieve,文档级 when_to_retrieve 留 Executor 筛选(Phase 2)
**Q4** — domain.when_to_retrieve 存储
用户原话:存 DB,这样每次启动都不用让 LLM 再总结一次
确认状态:已确认 → 新建 knowledge_domain 表,Flyway 迁移脚本
**Q5** — Executor 文档级细粒度筛选
用户原话:留 Phase 2
确认状态:已确认,MVP 不做
## Pre-apply 补充决策
- **P1:KnowledgeIndexService.parseDocumentToEntry 替换为 Jackson**:`extractJsonValue` / `extractJsonArray` 手写解析器遇到含逗号、引号的自然语言字段(whenToRetrieve)会截断。全量替换为 `objectMapper.readValue(metadata, Frontmatter.class)`,影响范围仅 `KnowledgeIndexService`,行为更健壮。(用户确认)
- **P2:LookupResult 新增 message 字段**:去重命中时 `found=false` + `message="文档已在本会话中检索过:xxx"`,不复用 `primary.content`。语义清晰,LLM 能理解原因不会重试。(用户确认)
## 关键设计决策
1. **两级 when_to_retrieve**:文档级(upload 时 LLM 生成,存 metadata)+ 域级(文档变更时 LLM 聚合,存 knowledge_domain 表)
2. **域级重算触发**:文档上传后、文档删除后,只重算受影响的域(不是全量);`loadIndex()` 时如果某域在 DB 没有记录,则触发生成
3. **注入 Planner 只给域级**:knowledge map 只包含域级 when_to_retrieve + documents[](title + covers),不暴露文档级 when_to_retrieve
4. **去重 key**:filePath(L0+L1 统一)
5. **去重状态存储**:JVM 内 `ConcurrentHashMap<sessionId, Set<filePath>>`,`SessionContextHolder.clear()` 时同步清理