Files
SuperBizAgent-java/openspec/changes/phase-1-infrastructure/design.md
T
zhuyongxin 3f15778b28 docs: 添加 Phase 1 完整实施计划和 OpenSpec
- 添加项目级 CLAUDE.md 和 AGENTS.md 配置
- 添加完整实施计划(docs/architecture/implementation-detail.md)
- 创建 OpenSpec phase-1-infrastructure:
  - proposal.md: 需求和方案
  - design.md: 架构设计
  - specs/functional-specs.md: 功能规格
  - tasks.md: 21 个任务清单
  - decisions.md: grill 阶段决策记录
  - .commit: 标记为 Committed OpenSpec

OpenSpec 已通过 sm-flow 完整流程(clarify → context → propose → grill → specify → audit → commit)
2026-06-23 10:58:11 +08:00

8.6 KiB
Raw Blame History

Phase 1 Infrastructure - Design

架构设计

1. 数据持久化层

┌─────────────────────────────────────────┐
│           Application Layer             │
│  (Service / Controller / Agent)         │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│         Repository Layer (JPA)          │
│  - DiagnosisRecordRepository            │
│  - CaseLibraryRepository                │
│  - ApiDocumentRepository                │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│            MySQL 8.0+                   │
│  - diagnosis_record (诊断记录)          │
│  - case_library (案例库)                │
│  - api_document (文档元数据)            │
│  - flyway_schema_history (版本管理)     │
└─────────────────────────────────────────┘

Flyway 迁移流程:

  1. 启动时自动扫描 db/migration/V*.sql
  2. 检查 flyway_schema_history 表
  3. 执行未运行的脚本
  4. 记录版本号

2. 会话管理层

┌─────────────────────────────────────────┐
│        Diagnosis Flow                   │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│      SessionManager (Interface)         │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│     RedisSessionManager (Impl)          │
│  - get(sessionId): SessionContext       │
│  - save(context): void                  │
│  - delete(sessionId): void              │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│            Redis 6.0+                   │
│  Key: session:{sessionId}               │
│  Value: SessionContext (JSON)           │
│  TTL: 30 minutes                        │
└─────────────────────────────────────────┘

SessionContext 结构:

{
  "sessionId": "uuid",
  "diagnosisId": "uuid",
  "currentStep": "queryOrder",
  "collectedEvidence": {
    "orderInfo": {...},
    "logs": [...]
  },
  "toolCallHistory": [
    {
      "toolName": "queryOrder",
      "params": {...},
      "result": {...},
      "timestamp": "2026-06-23T10:00:00"
    }
  ],
  "intentType": "诊断",
  "createdAt": "2026-06-23T09:55:00",
  "lastAccessAt": "2026-06-23T10:00:00"
}

3. 包结构设计

com.superbiz.agent/
├── SuperBizAgentApplication.java       # 启动类
│
├── controller/                         # REST 控制器
│   ├── DiagnosisController.java
│   ├── DocumentController.java
│   └── CaseController.java
│
├── service/                            # 业务服务
│   ├── DiagnosisService.java
│   ├── DocumentService.java
│   ├── CaseService.java
│   ├── TextExtractor.java              # 文本提取
│   └── VectorService.java              # 向量化服务
│
├── repository/                         # 数据访问
│   ├── DiagnosisRecordRepository.java
│   ├── CaseLibraryRepository.java
│   └── ApiDocumentRepository.java
│
├── domain/                             # 领域模型
│   ├── entity/                         # JPA 实体
│   │   ├── DiagnosisRecord.java
│   │   ├── CaseLibrary.java
│   │   └── ApiDocument.java
│   ├── dto/                            # 数据传输对象
│   │   ├── DiagnosisRequest.java
│   │   ├── DiagnosisResponse.java
│   │   ├── DocumentUploadRequest.java
│   │   └── DocumentQueryResponse.java
│   └── enums/                          # 枚举
│       ├── FaultCategory.java
│       ├── DiagnosisStatus.java
│       └── SourceType.java
│
├── session/                            # 会话管理
│   ├── SessionManager.java             # 接口
│   ├── RedisSessionManager.java        # Redis 实现
│   ├── SessionContext.java             # 会话上下文
│   └── ToolCall.java                   # 工具调用记录
│
├── tool/                               # 工具层
│   ├── DocumentSearchTool.java         # 混合检索
│   └── (其他 tool 保留 Phase 2)
│
├── config/                             # 配置
│   ├── JpaConfig.java
│   ├── RedisConfig.java
│   ├── MilvusConfig.java               # 保留现有
│   └── DashScopeConfig.java            # 保留现有
│
└── exception/                          # 异常处理
    ├── GlobalExceptionHandler.java
    ├── SessionNotFoundException.java
    └── DocumentProcessException.java

4. 文档管理流程

文档上传流程:
User → POST /api/documents/upload
  ↓
DocumentController.upload()
  ↓
DocumentService.uploadDocument()
  ↓ (并行)
  ├─→ TextExtractor.extract()          # 提取文本
  ├─→ chunkText()                       # 分块
  ├─→ VectorService.embed()             # 向量化
  ├─→ ApiDocumentRepository.save()      # 存 MySQL
  └─→ MilvusClient.insert()             # 存 Milvus
  ↓
返回 document_id
混合检索流程:
Agent → DocumentSearchTool.search(errorCode, province)
  ↓
  ├─→ MySQL 精确匹配
  │   SELECT * FROM api_document
  │   WHERE error_code = ? AND province = ?
  │
  ├─→ Milvus 语义检索
  │   向量化查询 → 相似度搜索 → Top 10
  │
  └─→ RRF 融合排序
      (精确匹配优先 + 语义补漏)
  ↓
返回 Top 3 文档片段

5. 数据库配置

application.yml 新增:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/superbiz_agent?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
    username: ${DB_USERNAME:root}
    password: ${DB_PASSWORD:your-password}
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  jpa:
    hibernate:
      ddl-auto: validate                # 生产用 validate,Flyway 管理表结构
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect
  
  flyway:
    enabled: true
    baseline-on-migrate: true
    locations: classpath:db/migration
  
  data:
    redis:
      host: localhost
      port: 6379
      password: ${REDIS_PASSWORD:}
      database: 0
      timeout: 3000
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0

6. 测试策略

Repository 测试:

  • 使用 @DataJpaTest + H2 内存数据库
  • 测试 CRUD + 自定义查询

Service 测试:

  • 使用 @SpringBootTest + Mockito
  • Mock Repository 和外部依赖

Controller 测试:

  • 使用 @WebMvcTest + MockMvc
  • Mock Service 层

集成测试:

  • 使用 @SpringBootTest + Testcontainers(可选)
  • 测试完整流程

技术决策

Flyway vs Liquibase

选择:Flyway

理由:

  • 更简单,SQL-first
  • Spring Boot 官方推荐
  • 社区活跃

Jackson vs Gson

选择:Jackson(Spring Boot 默认)

理由:

  • Spring Boot 内置
  • 性能更好
  • 与 Spring MVC 集成好

Lettuce vs Jedis

选择:Lettuce(Spring Data Redis 默认)

理由:

  • 异步支持
  • 线程安全
  • Spring Boot 默认