# 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 结构**: ```java { "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 新增**: ```yaml 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 默认