From e3f20b1f06c1e4865a5e236a2809b7e084cdf12a Mon Sep 17 00:00:00 2001 From: zhuyongxin Date: Fri, 26 Jun 2026 17:33:56 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=BD=92=E6=A1=A3=20session-storage?= =?UTF-8?q?=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 devflow 项目档案(brief/evidence/decisions/acceptance) - 更新 devflow/index.md 索引 - 移动 OpenSpec 到 archive --- devflow/index.md | 1 + .../2026-06-26-session-storage/acceptance.md | 28 +++++++++++++++++++ .../2026-06-26-session-storage/brief.md | 21 ++++++++++++++ .../2026-06-26-session-storage/decisions.md | 22 +++++++++++++++ .../2026-06-26-session-storage/evidence.md | 23 +++++++++++++++ .../.archive-ready} | 0 .../2026-06-26-session-storage/.committed | 0 .../2026-06-26-session-storage}/decisions.md | 0 .../2026-06-26-session-storage}/design.md | 0 .../2026-06-26-session-storage}/proposal.md | 0 .../specs/functional-spec.md | 0 .../2026-06-26-session-storage}/tasks.md | 0 12 files changed, 95 insertions(+) create mode 100644 devflow/projects/2026-06-26-session-storage/acceptance.md create mode 100644 devflow/projects/2026-06-26-session-storage/brief.md create mode 100644 devflow/projects/2026-06-26-session-storage/decisions.md create mode 100644 devflow/projects/2026-06-26-session-storage/evidence.md rename openspec/changes/{session-storage/.committed => archive/2026-06-26-session-storage/.archive-ready} (100%) create mode 100644 openspec/changes/archive/2026-06-26-session-storage/.committed rename openspec/changes/{session-storage => archive/2026-06-26-session-storage}/decisions.md (100%) rename openspec/changes/{session-storage => archive/2026-06-26-session-storage}/design.md (100%) rename openspec/changes/{session-storage => archive/2026-06-26-session-storage}/proposal.md (100%) rename openspec/changes/{session-storage => archive/2026-06-26-session-storage}/specs/functional-spec.md (100%) rename openspec/changes/{session-storage => archive/2026-06-26-session-storage}/tasks.md (100%) diff --git a/devflow/index.md b/devflow/index.md index e127456..d6aec8d 100644 --- a/devflow/index.md +++ b/devflow/index.md @@ -7,3 +7,4 @@ | 2026-05-29 | chatmodel-abstraction | 解耦/多模型路由 | ChatModel, EmbeddingModel, DeepSeek, BGE-M3, SiliconFlow, Spring AI | archived | | 2026-06-23 | phase1-infrastructure | 基础设施/文档管理 | MySQL, Redis, Milvus, Flyway, JPA, 向量检索, 类别过滤 | archived | | 2026-06-24 | lookup-knowledge-integration | 知识库检索 | L0精确匹配, L1语义检索, frontmatter, 混合检索 | openspec/changes/lookup-knowledge-integration | archived | +| 2026-06-26 | session-storage | 会话存储/可观测 | diagnosis_session, agent_step, tool_invocation, token追踪, 多Agent路由 | openspec/changes/session-storage | archived | diff --git a/devflow/projects/2026-06-26-session-storage/acceptance.md b/devflow/projects/2026-06-26-session-storage/acceptance.md new file mode 100644 index 0000000..87046af --- /dev/null +++ b/devflow/projects/2026-06-26-session-storage/acceptance.md @@ -0,0 +1,28 @@ +# 验收记录 + +## 验证情况 + +### 静态验证 +- [x] 编译通过(`mvn compile`) +- [x] 42 个测试全部通过(DocumentChunkService / LookupKnowledgeTool / Repository) +- [x] 三张新表通过 Flyway 成功创建 + +### 脚本验证 +- [x] `/api/chat` — 单 Agent 正常响应,agent_step 记录正确 +- [x] `/api/chat` — 复杂问题路由到多 Agent(Planner + Executor) +- [x] `/api/ai_ops` — 多 Agent 流程正常,planner 步骤写入 agent_step +- [x] Tool_invocation L0/L1 检索质量明细正确 +- [x] diagnosis_session 汇总指标(total_token_count / step_count / tool_call_count)正确 +- [x] TokenTrackingChatModel 捕获实际 token 数(已验证 total=827) +- [x] 旧 diagnosis_record 表删除成功 + +### 未验证 +- `/api/chat_stream`(SSE 流式)— 未接入 session 存储,不在本次范围,后续覆盖 +- `self_evaluation` / `feedback` — 无前端交互入口 + +## 剩余风险 + +| 风险 | 说明 | +|------|------| +| Token 累加 | 当前每步独立记录,汇总在 `backfillSessionMetrics`,未在 Hook 层累加 | +| Async 优化 | 同步写 DB 在低并发下无问题,后续可引入 @Async | diff --git a/devflow/projects/2026-06-26-session-storage/brief.md b/devflow/projects/2026-06-26-session-storage/brief.md new file mode 100644 index 0000000..9d88c74 --- /dev/null +++ b/devflow/projects/2026-06-26-session-storage/brief.md @@ -0,0 +1,21 @@ +# 会话存储体系 + +## 背景 +当前 `diagnosis_record` 单表字段耦合在"告警分析"领域,无法支撑通用会话存储。缺少 Agent 决策链维度、检索质量明细、Token 消耗等可观测指标。 + +## 目标 +将单表拆分为三表体系,覆盖 ChatService 和 AiOpsService 两个 Agent 的完整决策链记录,支撑可观测和评估。 + +## 范围 +- 新建 3 张表(diagnosis_session / agent_step / tool_invocation) +- Flyway 迁移 + JPA Entity + Repository +- 改造 AgentLoggingHook 持久化 agent_step +- 改造 LookupKnowledgeTool 写入 tool_invocation +- ChatService / AiOpsService 支持 diagnosis_session 生命周期 +- Token 用量追踪(TokenTrackingChatModel) +- 意图识别路由(单 Agent / 多 Agent) +- 删除旧 diagnosis_record 表 + +## 非目标 +- 不涉及 UI 层面的会话展示 +- 不涉及历史数据迁移 diff --git a/devflow/projects/2026-06-26-session-storage/decisions.md b/devflow/projects/2026-06-26-session-storage/decisions.md new file mode 100644 index 0000000..d39d577 --- /dev/null +++ b/devflow/projects/2026-06-26-session-storage/decisions.md @@ -0,0 +1,22 @@ +# 会话存储 — 决策记录 + +## 关键决策 + +| 决策 | 选择 | 理由 | +|------|------|------| +| AgentLoggingHook 创建方式 | POJO(构造注入),非 @Component | 需为 ChatService/AiOpsService 创建多个实例(不同 agentName) | +| AiOpsService 记录粒度 | 只记子 Agent(Planner/Executor),不记 Supervisor | Supervisor 编排日志已有体现,单独记录增加噪音 | +| sessionId 传递 | RunnableConfig.metadata(优先)+ ThreadLocal(兜底) | RunnableConfig 线程安全,异步兼容 | +| Tool 获取 sessionId | SessionContextHolder(ThreadLocal) | Tool 不在调用链中,无法通过 RunnableConfig 获取 | +| Token 追踪 | TokenTrackingChatModel 包装器拦截 ChatModel.call() | 框架 _TOKEN_USAGE_ 仅 stream 路径可用 | +| Chat 复杂度路由 | 关键词 + 长度判断 | MVP 简化实现 | +| 多 Agent Planner 无工具 | 不注入 methodTools/tools | 防止 Planner 自己执行,强制通过 Executor 执行 | +| 旧表处理 | V007 Flyway 迁移删除 diagnosis_record | 被三表替代,不再使用 | + +## 风险 + +| 风险 | 等级 | 说明 | +|------|:----:|------| +| Hook 同步写 DB | 低 | MVP 阶段数据量小,后续可异步化 | +| token_count 依赖 ChatResponse.usage | 低 | DeepSeek 已确认返回实际用量 | +| stream 路径 session 记录 | 低 | 当前 call 路径正常,stream 需确认 RunnableConfig 传播 | diff --git a/devflow/projects/2026-06-26-session-storage/evidence.md b/devflow/projects/2026-06-26-session-storage/evidence.md new file mode 100644 index 0000000..6dde618 --- /dev/null +++ b/devflow/projects/2026-06-26-session-storage/evidence.md @@ -0,0 +1,23 @@ +# 证据记录 + +## Evidence-Driven 查证 + +### E1: AgentLoggingHook 创建方式 +- **发现**: ChatService 通过 `new AgentLoggingHook()` 创建,非 Spring 管理,无法注入 Repository +- **结论**: 需要改造为可注入的 POJO(构造注入) +- **影响**: Hook 重构为构造注入 Repository + agentName + +### E2: AiOpsService 未使用 Hook +- **发现**: AiOpsService 的 Planner / Executor / Supervisor 均未配置 AgentLoggingHook +- **结论**: 需要补齐,每个子 Agent 加 Hook +- **影响**: Planner 和 Executor 各加 Hook,Supervisor 不加 + +### E3: 项目无异步基础设施 +- **发现**: 全局搜索 `@Async` / `@EnableAsync` 均无匹配 +- **结论**: MVP 阶段同步写 DB,后续优化 +- **影响**: 标记为技术债 + +### E4: RunnableConfig 支持 metadata +- **发现**: `RunnableConfig` 的 `metadata` 为 `ConcurrentMap`,可在构建时设置 +- **结论**: sessionId 通过 `config.addMetadata("sessionId", id)` 传递,线程安全 +- **影响**: 取代 ThreadLocal 方案 diff --git a/openspec/changes/session-storage/.committed b/openspec/changes/archive/2026-06-26-session-storage/.archive-ready similarity index 100% rename from openspec/changes/session-storage/.committed rename to openspec/changes/archive/2026-06-26-session-storage/.archive-ready diff --git a/openspec/changes/archive/2026-06-26-session-storage/.committed b/openspec/changes/archive/2026-06-26-session-storage/.committed new file mode 100644 index 0000000..e69de29 diff --git a/openspec/changes/session-storage/decisions.md b/openspec/changes/archive/2026-06-26-session-storage/decisions.md similarity index 100% rename from openspec/changes/session-storage/decisions.md rename to openspec/changes/archive/2026-06-26-session-storage/decisions.md diff --git a/openspec/changes/session-storage/design.md b/openspec/changes/archive/2026-06-26-session-storage/design.md similarity index 100% rename from openspec/changes/session-storage/design.md rename to openspec/changes/archive/2026-06-26-session-storage/design.md diff --git a/openspec/changes/session-storage/proposal.md b/openspec/changes/archive/2026-06-26-session-storage/proposal.md similarity index 100% rename from openspec/changes/session-storage/proposal.md rename to openspec/changes/archive/2026-06-26-session-storage/proposal.md diff --git a/openspec/changes/session-storage/specs/functional-spec.md b/openspec/changes/archive/2026-06-26-session-storage/specs/functional-spec.md similarity index 100% rename from openspec/changes/session-storage/specs/functional-spec.md rename to openspec/changes/archive/2026-06-26-session-storage/specs/functional-spec.md diff --git a/openspec/changes/session-storage/tasks.md b/openspec/changes/archive/2026-06-26-session-storage/tasks.md similarity index 100% rename from openspec/changes/session-storage/tasks.md rename to openspec/changes/archive/2026-06-26-session-storage/tasks.md