Files
zhuyongxin e3f20b1f06 chore: 归档 session-storage change
- 创建 devflow 项目档案(brief/evidence/decisions/acceptance)
- 更新 devflow/index.md 索引
- 移动 OpenSpec 到 archive
2026-06-26 17:33:56 +08:00

5.7 KiB
Raw Permalink Blame History

会话存储 — 功能规格

Requirement 1:三张新表的 DDL

路径:src/main/resources/db/migration/V005__create_session_storage.sql

内容:

  • 创建 diagnosis_session 表(DDL 见 design.md)
  • 创建 agent_step 表(DDL 见 design.md)
  • 创建 tool_invocation 表(DDL 见 design.md)
  • 三条 DDL 写在同一个迁移文件中

验收标准:

  • Flyway migrate 后三张表均存在
  • 表结构字段类型、索引与设计一致
  • JSON 列使用 JSON 类型(MySQL 8+)

Requirement 2:JPA Entity + Repository

2.1 实体类

路径:

  • src/main/java/com/superbiz/agent/domain/entity/DiagnosisSession.java
  • src/main/java/com/superbiz/agent/domain/entity/AgentStep.java
  • src/main/java/com/superbiz/agent/domain/entity/ToolInvocation.java

要求:

  • 使用 @Entity + @Table(name = "...") 映射
  • JSON 字段使用 @JdbcTypeCode(SqlTypes.JSON)(同现有 DiagnosisRecord.toolCalls)
  • @PrePersist 自动填充 createdAt
  • 使用 Lombok @Data @Builder @NoArgsConstructor @AllArgsConstructor

2.2 Repository 接口

路径:

  • src/main/java/com/superbiz/agent/repository/DiagnosisSessionRepository.java
  • src/main/java/com/superbiz/agent/repository/AgentStepRepository.java
  • src/main/java/com/superbiz/agent/repository/ToolInvocationRepository.java

要求:

  • 继承 JpaRepository
  • DiagnosisSessionRepository:findBySessionId(String sessionId)
  • AgentStepRepository:findBySessionIdOrderByStepIndex(String sessionId)、countBySessionId(String sessionId)
  • ToolInvocationRepository:findBySessionId(String sessionId)、findByToolName(String toolName)

验收标准:

  • 3 个 Entity 编译通过
  • 3 个 Repository 编译通过
  • 自定义查询方法命名符合 Spring Data JPA 规范

Requirement 3:AgentLoggingHook 改造为 Spring Bean

路径:src/main/java/com/superbiz/agent/hook/AgentLoggingHook.java

变更:

  • 类上加 @Component 注解
  • 不再通过 new 创建实例
  • 构造注入 AgentStepRepository
  • beforeModel:创建 AgentStep 记录,设置 modelInput,记录开始时间到 RunnableConfig
  • afterModel:更新对应 AgentStep,设置 modelOutput、thought、hasToolCall、durationMs、tokenCount
  • modelInput 和 modelOutput 只存摘要(前 500 字符),不存完整消息体

session_id 传递机制:

  • 调用方(ChatService/AiOpsService)通过 RunnableConfig.metadata() 传入 sessionId
  • Hook 从 config.getMetadata("sessionId") 读取

验收标准:

  • Hook 可注入 AgentStepRepository
  • beforeModel 创建 agent_step 记录并写入 DB
  • afterModel 更新对应 agent_step 记录
  • model_input/output 摘要不超过 500 字符
  • 从 RunnableConfig 正确读取 sessionId
  • 原日志输出行为保持不变

Requirement 4:ChatService 集成

路径:src/main/java/com/superbiz/agent/service/ChatService.java

变更:

  • 注入 DiagnosisSessionRepository
  • executeChat() 中:
    • 执行前:创建 DiagnosisSession(status=RUNNING),生成 sessionId,生成 agent_flow=CHAT
    • 通过 RunnableConfig 将 sessionId 传给 Hook
    • 执行后:更新 DiagnosisSession(status=SUCCESS/FAILED,汇总 step_count、tool_call_count、total_duration_ms)
  • 不再通过 new AgentLoggingHook() 创建 Hook,改为注入 Bean 的 Hook

验收标准:

  • executeChat 执行前后分别创建和更新 diagnosis_session
  • sessionId 通过 RunnableConfig 正确传递给 Hook
  • 汇总指标(duration、step_count)正确写入
  • 异常路径正确设置 status=FAILED

Requirement 5:AiOpsService 集成

路径:src/main/java/com/superbiz/agent/service/AiOpsService.java

变更:

  • 注入 DiagnosisSessionRepository 和 AgentLoggingHook
  • executeAiOpsAnalysis() 中:
    • 执行前:创建 DiagnosisSession(status=RUNNING, agent_flow=AI_OPS)
    • 构建 Planner 和 Executor 时传入 AgentLoggingHook 实例(使用注入的 Bean)
    • 通过 RunnableConfig 将 sessionId 传给 Hook
    • 执行后:更新 DiagnosisSession(汇总指标)
  • Supervisor 不加 Hook

验收标准:

  • AiOpsService 执行前后分别创建和更新 diagnosis_session
  • Planner 和 Executor 各带 AgentLoggingHook
  • 两个 Hook 使用相同的 sessionId
  • Supervisor 不产生 agent_step 记录

Requirement 6:LookupKnowledgeTool 写入 tool_invocation

路径:src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java

变更:

  • 注入 ToolInvocationRepository
  • lookupKnowledge() 执行后:
    • 创建 ToolInvocation 记录
    • 写入 toolName=lookup_knowledge、inputParams(query)、outputPreview(前 500 字符)
    • 写入检索质量:retrievalLayer、l0MatchCount、l1MatchCount、isTruncated、retrievalDetails
    • 写入 durationMs、success
  • sessionId 和 stepId 如何获取需要方案设计(见开放问题)

验收标准:

  • lookup_knowledge 每次调用后创建 tool_invocation 记录
  • 检索质量字段(L0/L1 明细)正确写入
  • 工具执行失败的场景正确记录

Requirement 7:构造注入适配(无 @Async)

路径:所有涉及新增 Repository 注入的类

要求:

  • 所有新注入使用构造注入(@RequiredArgsConstructor 或显式构造器)
  • 不在 MV 阶段引入 @Async 异步基础设施
  • Hook 中的 DB 写入是同步的,作为已知的技术债记录

验收标准:

  • 没有使用 @Autowired 字段注入新 Repository(保持项目已有风格)
  • 没有引入 @Async / @EnableAsync