Merge branch 'emdash/lemon-shrimps-bake-7q6xl' into refactor/rag-chunking-strategy
# Conflicts: # AGENTS.md # CLAUDE.md # src/main/resources/application.yml
This commit is contained in:
@@ -0,0 +1 @@
|
||||
COMMITTED
|
||||
@@ -0,0 +1,112 @@
|
||||
# Phase 1 Infrastructure - Decisions Log
|
||||
|
||||
## Grill 阶段澄清记录
|
||||
|
||||
### 2026-06-23
|
||||
|
||||
#### Q1: SessionContext 字段设计
|
||||
**问题**: Redis 会话需要存储哪些字段?
|
||||
|
||||
**决策**:
|
||||
```java
|
||||
class SessionContext {
|
||||
String sessionId;
|
||||
String diagnosisId;
|
||||
String currentStep;
|
||||
Map<String, Object> collectedEvidence;
|
||||
List<ToolCall> toolCallHistory;
|
||||
String intentType; // 预留 Phase 2 意图识别
|
||||
LocalDateTime createdAt;
|
||||
LocalDateTime lastAccessAt;
|
||||
}
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- 支持多轮对话恢复上下文
|
||||
- intentType 预留 Phase 2,避免后续修改结构
|
||||
- tool_calls 同时存 Redis(临时)和 MySQL(持久)
|
||||
|
||||
**用户确认**: 已确认
|
||||
|
||||
---
|
||||
|
||||
#### Q2: 包名重构策略
|
||||
**问题**: org.example → com.superbiz.agent 是否需要兼容层?
|
||||
|
||||
**决策**: 直接全量替换,不保留兼容层
|
||||
|
||||
**理由**:
|
||||
- 内部项目,无外部依赖者
|
||||
- 兼容层增加复杂度
|
||||
- MVP 阶段保持简单
|
||||
|
||||
**用户确认**: 已确认
|
||||
|
||||
---
|
||||
|
||||
#### Q3: Redis 降级策略
|
||||
**问题**: Redis 故障时如何处理?
|
||||
|
||||
**决策**: Phase 1 不做降级,Redis 故障直接失败
|
||||
|
||||
**理由**:
|
||||
- MVP 优先跑通核心流程
|
||||
- 降级策略增加复杂度
|
||||
- 单元测试可用内存 Mock
|
||||
|
||||
**备选方案** (Phase 2/3):
|
||||
- 自动降级到内存实现
|
||||
- 返回友好错误提示
|
||||
|
||||
**用户确认**: 已确认(先跑通 MVP)
|
||||
|
||||
---
|
||||
|
||||
## Evidence-Driven 查证结果
|
||||
|
||||
### 诊断记录 vs 案例的边界
|
||||
**查证文件**: docs/tables/diagnosis_record.md, docs/tables/case_library.md
|
||||
|
||||
**结论**:
|
||||
- 诊断记录:每次诊断都记录
|
||||
- 案例:从诊断记录中筛选(成功诊断 + 用户反馈 useful)
|
||||
- 转换触发:diagnosis_record.feedback = 'useful' + confidence >= 80
|
||||
|
||||
**状态**: 已查证,边界清晰
|
||||
|
||||
---
|
||||
|
||||
### 文档范围
|
||||
**查证文件**: docs/tables/api_document.md
|
||||
|
||||
**结论**:
|
||||
- Phase 1: 只处理接口文档(API 文档、错误码说明)
|
||||
- Phase 2/3: 可扩展为其他类型(运维手册、FAQ)
|
||||
|
||||
**状态**: 已查证,范围明确
|
||||
|
||||
---
|
||||
|
||||
### 单元测试覆盖率标准
|
||||
**查证文件**: docs/architecture/implementation-detail.md
|
||||
|
||||
**结论**:
|
||||
- 目标:行覆盖率 70%+
|
||||
- Repository: 100%
|
||||
- Service: 80%+
|
||||
- Tool: 80%+
|
||||
- Controller: 70%+
|
||||
|
||||
**状态**: 已查证,标准明确
|
||||
|
||||
---
|
||||
|
||||
## 待写入 CONTEXT.md 的术语
|
||||
|
||||
无新增术语。现有术语已在 docs/ 中定义清楚。
|
||||
|
||||
---
|
||||
|
||||
## 待创建 ADR
|
||||
|
||||
无。Phase 1 都是标准技术选型,无需 ADR。
|
||||
@@ -0,0 +1,267 @@
|
||||
# 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 默认
|
||||
@@ -0,0 +1,171 @@
|
||||
# Proposal: Phase 1 基础设施搭建
|
||||
|
||||
## 问题
|
||||
|
||||
当前项目是一个 Demo,需要改造为 MVP 诊断 Agent 系统。Phase 1 需要搭建基础设施:
|
||||
- 缺少持久化层(MySQL + JPA)
|
||||
- 缺少分布式会话管理(Redis)
|
||||
- 代码结构需要重构(包名、分层)
|
||||
- 缺少文档管理基础功能
|
||||
|
||||
## 建议方案
|
||||
|
||||
### 1. 数据持久化
|
||||
|
||||
**方案**:Spring Data JPA + MySQL + Flyway
|
||||
|
||||
**理由**:
|
||||
- JPA 是 Spring Boot 标准持久化方案
|
||||
- Flyway 管理数据库版本,团队协作友好
|
||||
- 3 张表设计已完成(docs/tables/)
|
||||
|
||||
**实现**:
|
||||
1. 添加依赖(spring-boot-starter-data-jpa, mysql-connector-j, flyway-core)
|
||||
2. 创建 3 个 Flyway 迁移脚本(V001/V002/V003)
|
||||
3. 创建 JPA 实体类(DiagnosisRecord, CaseLibrary, ApiDocument)
|
||||
4. 创建 Repository 接口(继承 JpaRepository)
|
||||
|
||||
### 2. 会话管理
|
||||
|
||||
**方案**:Redis 替代内存 HashMap
|
||||
|
||||
**理由**:
|
||||
- 支持分布式部署
|
||||
- 自动 TTL(30 分钟)
|
||||
- Spring Data Redis 集成简单
|
||||
|
||||
**实现**:
|
||||
1. 添加 spring-boot-starter-data-redis 依赖
|
||||
2. 创建 SessionManager 接口 + RedisSessionManager 实现
|
||||
3. SessionContext 使用 JSON 序列化
|
||||
|
||||
### 3. 代码结构重构
|
||||
|
||||
**方案**:包名重构 + 分层优化 + DTO 抽离
|
||||
|
||||
**包名重构**:
|
||||
- `org.example` → `com.superbiz.agent`
|
||||
- 工具:IDEA Refactor → Rename Package
|
||||
|
||||
**分层结构**:
|
||||
```
|
||||
com.superbiz.agent/
|
||||
├── controller/ # REST API
|
||||
├── service/ # 业务逻辑
|
||||
├── repository/ # 数据访问
|
||||
├── domain/
|
||||
│ ├── entity/ # JPA 实体
|
||||
│ ├── dto/ # DTO
|
||||
│ └── enums/ # 枚举
|
||||
├── agent/ # Agent 层(Phase 2)
|
||||
├── tool/ # 工具层
|
||||
├── session/ # 会话管理
|
||||
└── config/ # 配置
|
||||
```
|
||||
|
||||
**DTO 抽离**:
|
||||
- Controller 不直接依赖 Entity
|
||||
- 使用 MapStruct 做对象转换
|
||||
|
||||
### 4. 文档管理
|
||||
|
||||
**方案**:CRUD + Milvus 向量同步
|
||||
|
||||
**功能**:
|
||||
1. 上传接口:文件 → 文本提取 → 分块 → 向量化 → MySQL + Milvus
|
||||
2. 查询接口:分页、过滤
|
||||
3. 删除接口:MySQL + Milvus 同步删除
|
||||
4. 检索工具:精确匹配(MySQL)+ 语义检索(Milvus)+ RRF 融合
|
||||
|
||||
## 范围
|
||||
|
||||
**包含**:
|
||||
- Day 1-2: MySQL 表 + JPA + Repository + Redis 会话
|
||||
- Day 3: 包名重构 + 分层优化 + DTO 抽离
|
||||
- Day 4-5: 文档管理 4 个接口 + 混合检索工具
|
||||
|
||||
**不包含**:
|
||||
- Agent 功能(Phase 2)
|
||||
- 意图识别和 RAG(Phase 2)
|
||||
- Verifier 和 Harness(Phase 3)
|
||||
|
||||
## 非目标
|
||||
|
||||
- 性能优化(后续优化)
|
||||
- 完整的权限控制(MVP 不需要)
|
||||
- 前端界面(只做后端 API)
|
||||
|
||||
## 来自 devflow 的上下文约束
|
||||
|
||||
无(这是首个 OpenSpec,devflow 目录为空)
|
||||
|
||||
## 风险
|
||||
|
||||
1. **包名重构影响范围大**
|
||||
- 缓解:先提交当前代码,独立分支重构
|
||||
- 验证:重构后编译通过 + 启动成功
|
||||
|
||||
2. **Flyway 首次运行可能失败**
|
||||
- 缓解:本地 MySQL 先手动测试
|
||||
- 回退:Flyway 支持 repair 修复
|
||||
|
||||
3. **Redis 本地环境依赖**
|
||||
- 缓解:提供 Docker Compose 配置
|
||||
- 回退:可降级为内存实现(测试用)
|
||||
|
||||
## 关键假设
|
||||
|
||||
1. MySQL 8.0+ 和 Redis 6.0+ 可用(本地或 Docker)
|
||||
2. 现有 Milvus 集成不需要改动
|
||||
3. 单元测试覆盖率目标:70%+
|
||||
|
||||
## 成功标准
|
||||
|
||||
1. ✅ 3 张表创建成功,索引完整
|
||||
2. ✅ Repository 层单元测试通过
|
||||
3. ✅ Redis 会话存取正常,TTL 生效
|
||||
4. ✅ 包名重构完成,编译通过
|
||||
5. ✅ 文档上传/查询/删除接口可用
|
||||
6. ✅ 混合检索工具返回正确结果
|
||||
7. ✅ 整体测试覆盖率 ≥ 70%
|
||||
|
||||
## 产出文件(预期)
|
||||
|
||||
**数据库迁移**:
|
||||
- `src/main/resources/db/migration/V001__create_diagnosis_record.sql`
|
||||
- `src/main/resources/db/migration/V002__create_case_library.sql`
|
||||
- `src/main/resources/db/migration/V003__create_api_document.sql`
|
||||
|
||||
**实体类**:
|
||||
- `com.superbiz.agent.domain.entity.DiagnosisRecord`
|
||||
- `com.superbiz.agent.domain.entity.CaseLibrary`
|
||||
- `com.superbiz.agent.domain.entity.ApiDocument`
|
||||
|
||||
**Repository**:
|
||||
- `com.superbiz.agent.repository.DiagnosisRecordRepository`
|
||||
- `com.superbiz.agent.repository.CaseLibraryRepository`
|
||||
- `com.superbiz.agent.repository.ApiDocumentRepository`
|
||||
|
||||
**会话管理**:
|
||||
- `com.superbiz.agent.session.SessionManager`
|
||||
- `com.superbiz.agent.session.RedisSessionManager`
|
||||
- `com.superbiz.agent.session.SessionContext`
|
||||
|
||||
**文档管理**:
|
||||
- `com.superbiz.agent.controller.DocumentController`
|
||||
- `com.superbiz.agent.service.DocumentService`
|
||||
- `com.superbiz.agent.service.TextExtractor`
|
||||
- `com.superbiz.agent.tool.DocumentSearchTool`
|
||||
|
||||
**配置**:
|
||||
- `pom.xml`(增加依赖)
|
||||
- `application.yml`(增加 MySQL + Redis 配置)
|
||||
|
||||
**测试**:
|
||||
- `*RepositoryTest.java`
|
||||
- `*ServiceTest.java`
|
||||
- `*ControllerTest.java`
|
||||
|
||||
## 工期估算
|
||||
|
||||
5 天(按实施计划)
|
||||
@@ -0,0 +1,312 @@
|
||||
# Phase 1 Infrastructure - Specifications
|
||||
|
||||
## 功能规格
|
||||
|
||||
### 1. 数据库表创建
|
||||
|
||||
#### 1.1 diagnosis_record 表
|
||||
**输入**:Flyway 迁移脚本 V001
|
||||
**输出**:MySQL 表创建成功
|
||||
**验收标准**:
|
||||
- ✅ 表结构与 docs/tables/diagnosis_record.md 一致
|
||||
- ✅ 所有索引创建成功
|
||||
- ✅ JSON 字段类型正确
|
||||
- ✅ 默认值和注释完整
|
||||
|
||||
#### 1.2 case_library 表
|
||||
**输入**:Flyway 迁移脚本 V002
|
||||
**输出**:MySQL 表创建成功
|
||||
**验收标准**:
|
||||
- ✅ 表结构与 docs/tables/case_library.md 一致
|
||||
- ✅ 外键约束正确
|
||||
- ✅ 索引覆盖查询场景
|
||||
|
||||
#### 1.3 api_document 表
|
||||
**输入**:Flyway 迁移脚本 V003
|
||||
**输出**:MySQL 表创建成功
|
||||
**验收标准**:
|
||||
- ✅ 表结构与 docs/tables/api_document.md 一致
|
||||
- ✅ province 和 category 索引就绪
|
||||
|
||||
---
|
||||
|
||||
### 2. JPA 实体与 Repository
|
||||
|
||||
#### 2.1 DiagnosisRecord 实体
|
||||
**字段映射**:
|
||||
- `@Id @GeneratedValue` - id
|
||||
- `@Column(unique=true)` - diagnosis_id
|
||||
- `@JdbcTypeCode(SqlTypes.JSON)` - tool_calls
|
||||
- `@Enumerated(EnumType.STRING)` - fault_category, status
|
||||
- `LocalDateTime` - created_at, updated_at
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 所有字段与数据库一致
|
||||
- ✅ JSON 字段序列化正确
|
||||
- ✅ 枚举映射正确
|
||||
- ✅ Lombok 注解完整
|
||||
|
||||
#### 2.2 Repository 查询方法
|
||||
**DiagnosisRecordRepository**:
|
||||
```java
|
||||
Optional<DiagnosisRecord> findByDiagnosisId(String diagnosisId);
|
||||
Optional<DiagnosisRecord> findByBusinessId(String businessId);
|
||||
Optional<DiagnosisRecord> findByTraceId(String traceId);
|
||||
List<DiagnosisRecord> findByFaultCategoryAndErrorCode(
|
||||
FaultCategory category, String errorCode);
|
||||
Page<DiagnosisRecord> findByCreatedAtBetween(
|
||||
LocalDateTime start, LocalDateTime end, Pageable pageable);
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 单元测试通过(@DataJpaTest + H2)
|
||||
- ✅ 分页查询正确
|
||||
- ✅ 复杂查询性能可接受(< 100ms)
|
||||
|
||||
---
|
||||
|
||||
### 3. Redis 会话管理
|
||||
|
||||
#### 3.1 SessionManager 接口
|
||||
```java
|
||||
public interface SessionManager {
|
||||
SessionContext get(String sessionId);
|
||||
void save(SessionContext context);
|
||||
void delete(String sessionId);
|
||||
boolean exists(String sessionId);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 RedisSessionManager 实现
|
||||
**存储格式**:
|
||||
- Key: `session:{sessionId}`
|
||||
- Value: SessionContext 的 JSON 字符串
|
||||
- TTL: 1800 秒(30 分钟)
|
||||
|
||||
**异常处理**:
|
||||
- Redis 连接失败 → 抛出 RedisConnectionException
|
||||
- 序列化失败 → 抛出 SessionSerializationException
|
||||
- Session 不存在 → 返回 null(get 方法)
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 存取删操作成功
|
||||
- ✅ TTL 自动刷新(每次 get/save)
|
||||
- ✅ JSON 序列化/反序列化正确
|
||||
- ✅ 单元测试覆盖(Mock RedisTemplate)
|
||||
|
||||
---
|
||||
|
||||
### 4. 文档管理
|
||||
|
||||
#### 4.1 文档上传接口
|
||||
**接口**:`POST /api/documents/upload`
|
||||
|
||||
**请求**:
|
||||
```json
|
||||
{
|
||||
"file": "multipart/form-data",
|
||||
"province": "广东",
|
||||
"category": "社保接口"
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "上传成功",
|
||||
"data": {
|
||||
"documentId": "uuid",
|
||||
"fileName": "社保接口文档.docx",
|
||||
"chunkCount": 12
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**处理流程**:
|
||||
1. 文件类型校验(.txt, .md, .docx, .pdf)
|
||||
2. 文本提取
|
||||
3. 分块(chunk_size=500, overlap=50)
|
||||
4. DashScope 向量化
|
||||
5. MySQL 存元数据
|
||||
6. Milvus 存向量
|
||||
|
||||
**错误处理**:
|
||||
- 文件类型不支持 → 400 Bad Request
|
||||
- 文件大小超限(10MB) → 413 Payload Too Large
|
||||
- 向量化失败 → 500 Internal Server Error(回滚 MySQL)
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 支持 .txt, .md, .docx, .pdf
|
||||
- ✅ MySQL + Milvus 事务一致
|
||||
- ✅ 单元测试覆盖
|
||||
|
||||
#### 4.2 文档查询接口
|
||||
**接口**:`GET /api/documents?province=广东&category=社保接口&page=0&size=10`
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"content": [
|
||||
{
|
||||
"documentId": "uuid",
|
||||
"fileName": "社保接口文档.docx",
|
||||
"province": "广东",
|
||||
"category": "社保接口",
|
||||
"createdAt": "2026-06-23T10:00:00"
|
||||
}
|
||||
],
|
||||
"totalElements": 1,
|
||||
"totalPages": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 分页正确
|
||||
- ✅ 过滤生效
|
||||
- ✅ 性能可接受(< 100ms)
|
||||
|
||||
#### 4.3 文档删除接口
|
||||
**接口**:`DELETE /api/documents/{documentId}`
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
**处理流程**:
|
||||
1. 删除 MySQL 记录
|
||||
2. 根据 document_id 删除 Milvus 向量
|
||||
|
||||
**事务性**:
|
||||
- MySQL 删除失败 → 不删除 Milvus
|
||||
- Milvus 删除失败 → 记录日志(容忍)
|
||||
|
||||
**验收标准**:
|
||||
- ✅ MySQL 记录删除
|
||||
- ✅ Milvus 向量删除
|
||||
- ✅ 幂等性(重复删除不报错)
|
||||
|
||||
#### 4.4 混合检索工具
|
||||
**接口**:`DocumentSearchTool.search(errorCode, province)`
|
||||
|
||||
**输入**:
|
||||
```java
|
||||
{
|
||||
"errorCode": "40003",
|
||||
"province": "广东"
|
||||
}
|
||||
```
|
||||
|
||||
**输出**:
|
||||
```java
|
||||
List<DocumentChunk> {
|
||||
"documentId": "uuid",
|
||||
"chunkId": "uuid",
|
||||
"content": "错误码 40003 表示...",
|
||||
"score": 0.95
|
||||
}
|
||||
```
|
||||
|
||||
**检索策略**:
|
||||
1. **精确匹配**(MySQL):
|
||||
```sql
|
||||
SELECT * FROM api_document
|
||||
WHERE error_code = '40003' AND province = '广东'
|
||||
```
|
||||
2. **语义检索**(Milvus):
|
||||
- 向量化查询文本
|
||||
- 相似度搜索 Top 10
|
||||
3. **RRF 融合**:
|
||||
- 精确匹配分数 = 1.0
|
||||
- 语义检索分数 = Milvus 相似度
|
||||
- 合并排序,返回 Top 3
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 精确匹配优先
|
||||
- ✅ 语义检索补漏
|
||||
- ✅ 返回 Top 3
|
||||
- ✅ 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
## 接口规格
|
||||
|
||||
### API 设计原则
|
||||
- RESTful 风格
|
||||
- 统一响应格式 `Result<T>`
|
||||
- HTTP 状态码语义化
|
||||
- 异常统一处理
|
||||
|
||||
### 统一响应格式
|
||||
```java
|
||||
class Result<T> {
|
||||
int code; // 业务状态码
|
||||
String message; // 提示信息
|
||||
T data; // 数据
|
||||
long timestamp; // 时间戳
|
||||
}
|
||||
```
|
||||
|
||||
### 错误码约定
|
||||
- 200: 成功
|
||||
- 400: 参数错误
|
||||
- 404: 资源不存在
|
||||
- 500: 服务器错误
|
||||
|
||||
---
|
||||
|
||||
## 性能规格
|
||||
|
||||
### 响应时间要求
|
||||
- 文档上传:< 5s(单文件 < 5MB)
|
||||
- 文档查询:< 100ms
|
||||
- 文档删除:< 200ms
|
||||
- 混合检索:< 500ms
|
||||
- Repository 查询:< 50ms
|
||||
|
||||
### 并发要求
|
||||
- 支持 10 QPS(Phase 1 目标)
|
||||
- 后续扩展至 100 QPS(Phase 2/3)
|
||||
|
||||
---
|
||||
|
||||
## 安全规格
|
||||
|
||||
### 输入校验
|
||||
- 文件类型白名单
|
||||
- 文件大小限制(10MB)
|
||||
- SQL 注入防护(JPA Prepared Statement)
|
||||
- XSS 防护(输入转义)
|
||||
|
||||
### 数据安全
|
||||
- Redis 密码保护
|
||||
- MySQL 用户权限最小化
|
||||
- 敏感日志脱敏
|
||||
|
||||
---
|
||||
|
||||
## 测试规格
|
||||
|
||||
### 单元测试覆盖率
|
||||
- Repository: 100%
|
||||
- Service: 80%+
|
||||
- Tool: 80%+
|
||||
- Controller: 70%+
|
||||
|
||||
### 测试类型
|
||||
- 单元测试(JUnit 5 + Mockito)
|
||||
- 集成测试(@SpringBootTest)
|
||||
- 接口测试(MockMvc)
|
||||
|
||||
### 必须覆盖的场景
|
||||
- 正常流程
|
||||
- 边界条件
|
||||
- 异常处理
|
||||
- 并发安全
|
||||
@@ -0,0 +1,400 @@
|
||||
# Phase 1 Infrastructure - Tasks
|
||||
|
||||
## 任务清单
|
||||
|
||||
### Day 1-2: 数据库 + 实体 + 会话(8 个任务)
|
||||
|
||||
#### Task 1.1: 添加依赖到 pom.xml
|
||||
**优先级**: P0(阻塞后续任务)
|
||||
**预估时间**: 15 分钟
|
||||
**产出**:
|
||||
- 修改 `pom.xml`
|
||||
- 添加:spring-boot-starter-data-jpa, mysql-connector-j, flyway-core, flyway-mysql, spring-boot-starter-data-redis, spring-boot-starter-test, h2
|
||||
**验收**: `mvn clean compile` 成功
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.2: 创建 Flyway 迁移脚本 - diagnosis_record
|
||||
**优先级**: P0
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `src/main/resources/db/migration/V001__create_diagnosis_record.sql`
|
||||
**依据**: `docs/tables/diagnosis_record.md`
|
||||
**验收**:
|
||||
- 表结构与文档一致
|
||||
- 索引完整
|
||||
- 注释完整
|
||||
- 本地 MySQL 执行成功
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.3: 创建 Flyway 迁移脚本 - case_library
|
||||
**优先级**: P0
|
||||
**预估时间**: 20 分钟
|
||||
**产出**:
|
||||
- `src/main/resources/db/migration/V002__create_case_library.sql`
|
||||
**依据**: `docs/tables/case_library.md`
|
||||
**验收**: 同 Task 1.2
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.4: 创建 Flyway 迁移脚本 - api_document
|
||||
**优先级**: P0
|
||||
**预估时间**: 20 分钟
|
||||
**产出**:
|
||||
- `src/main/resources/db/migration/V003__create_api_document.sql`
|
||||
**依据**: `docs/tables/api_document.md`
|
||||
**验收**: 同 Task 1.2
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.5: 配置 MySQL + Redis + Flyway
|
||||
**优先级**: P0
|
||||
**预估时间**: 20 分钟
|
||||
**产出**:
|
||||
- 修改 `src/main/resources/application.yml`
|
||||
- 添加 spring.datasource, spring.jpa, spring.flyway, spring.data.redis 配置
|
||||
**验收**:
|
||||
- 应用启动成功
|
||||
- Flyway 自动执行迁移
|
||||
- 3 张表创建成功
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.6: 创建 JPA 实体类
|
||||
**优先级**: P0
|
||||
**预估时间**: 45 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.domain.entity.DiagnosisRecord`
|
||||
- `com.superbiz.agent.domain.entity.CaseLibrary`
|
||||
- `com.superbiz.agent.domain.entity.ApiDocument`
|
||||
**依赖**: Task 1.2, 1.3, 1.4
|
||||
**验收**:
|
||||
- 字段与数据库一致
|
||||
- Lombok 注解完整
|
||||
- JSON 字段序列化正确
|
||||
- 编译通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.7: 创建 Repository 接口
|
||||
**优先级**: P0
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.repository.DiagnosisRecordRepository`
|
||||
- `com.superbiz.agent.repository.CaseLibraryRepository`
|
||||
- `com.superbiz.agent.repository.ApiDocumentRepository`
|
||||
**依赖**: Task 1.6
|
||||
**验收**:
|
||||
- 继承 JpaRepository
|
||||
- 常用查询方法定义
|
||||
- 编译通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.8: Repository 单元测试
|
||||
**优先级**: P1
|
||||
**预估时间**: 60 分钟
|
||||
**产出**:
|
||||
- `DiagnosisRecordRepositoryTest`
|
||||
- `CaseLibraryRepositoryTest`
|
||||
- `ApiDocumentRepositoryTest`
|
||||
**依赖**: Task 1.7
|
||||
**测试框架**: @DataJpaTest + H2
|
||||
**验收**:
|
||||
- 测试覆盖率 100%
|
||||
- CRUD 测试通过
|
||||
- 自定义查询测试通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.9: 创建会话管理接口
|
||||
**优先级**: P0
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.session.SessionManager` (接口)
|
||||
- `com.superbiz.agent.session.SessionContext` (数据类)
|
||||
- `com.superbiz.agent.session.ToolCall` (数据类)
|
||||
**验收**:
|
||||
- 接口定义清晰
|
||||
- SessionContext 字段完整(含 intentType)
|
||||
- 编译通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.10: Redis 会话管理实现
|
||||
**优先级**: P0
|
||||
**预估时间**: 45 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.session.RedisSessionManager`
|
||||
- `com.superbiz.agent.session.SessionConfiguration`
|
||||
**依赖**: Task 1.9
|
||||
**验收**:
|
||||
- 实现 SessionManager 接口
|
||||
- TTL 设置为 30 分钟
|
||||
- JSON 序列化配置正确
|
||||
- 编译通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.11: Redis 会话管理单元测试
|
||||
**优先级**: P1
|
||||
**预估时间**: 45 分钟
|
||||
**产出**:
|
||||
- `RedisSessionManagerTest`
|
||||
**依赖**: Task 1.10
|
||||
**测试框架**: @SpringBootTest + Mock RedisTemplate
|
||||
**验收**:
|
||||
- 存取删测试通过
|
||||
- TTL 测试通过
|
||||
- 序列化测试通过
|
||||
|
||||
---
|
||||
|
||||
### Day 3: 代码结构重构(3 个任务)
|
||||
|
||||
#### Task 3.1: 包名重构
|
||||
**优先级**: P0
|
||||
**预估时间**: 30 分钟
|
||||
**操作**:
|
||||
1. IDEA Refactor → Rename Package
|
||||
2. `org.example` → `com.superbiz.agent`
|
||||
3. 更新 `pom.xml` 中的 mainClass
|
||||
4. 全局搜索确认无遗漏
|
||||
**验收**:
|
||||
- 编译通过
|
||||
- 启动成功
|
||||
- 无遗漏的 org.example
|
||||
|
||||
---
|
||||
|
||||
#### Task 3.2: 分层结构优化
|
||||
**优先级**: P1
|
||||
**预估时间**: 45 分钟
|
||||
**产出**:
|
||||
- 创建目录结构(controller/service/repository/domain/tool/config/exception)
|
||||
- 移动现有类到对应目录
|
||||
**验收**:
|
||||
- 目录结构符合 design.md
|
||||
- 编译通过
|
||||
- 启动成功
|
||||
|
||||
---
|
||||
|
||||
#### Task 3.3: DTO 抽离
|
||||
**优先级**: P1
|
||||
**预估时间**: 60 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.domain.dto.DiagnosisRequest`
|
||||
- `com.superbiz.agent.domain.dto.DiagnosisResponse`
|
||||
- `com.superbiz.agent.domain.dto.DocumentUploadRequest`
|
||||
- `com.superbiz.agent.domain.dto.DocumentQueryResponse`
|
||||
- `com.superbiz.agent.domain.dto.Result<T>` (统一响应)
|
||||
**验收**:
|
||||
- Controller 不 import Entity
|
||||
- 编译通过
|
||||
|
||||
---
|
||||
|
||||
### Day 4-5: 文档管理(7 个任务)
|
||||
|
||||
#### Task 4.1: 创建 TextExtractor 服务
|
||||
**优先级**: P0
|
||||
**预估时间**: 60 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.service.TextExtractor`
|
||||
**功能**:
|
||||
- 支持 .txt, .md, .docx, .pdf
|
||||
- 提取纯文本
|
||||
**依赖**: 可能需要添加 Apache POI / PDFBox 依赖
|
||||
**验收**:
|
||||
- 4 种格式提取成功
|
||||
- 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.2: 文档分块服务
|
||||
**优先级**: P0
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.service.DocumentChunkService` (可能已存在,重构)
|
||||
**功能**:
|
||||
- chunk_size=500
|
||||
- overlap=50
|
||||
**验收**:
|
||||
- 分块逻辑正确
|
||||
- 单元测试通过
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.3: 文档上传接口
|
||||
**优先级**: P0
|
||||
**预估时间**: 90 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.controller.DocumentController#upload`
|
||||
- `com.superbiz.agent.service.DocumentService#uploadDocument`
|
||||
**依赖**: Task 4.1, 4.2
|
||||
**验收**:
|
||||
- 上传成功返回 documentId
|
||||
- MySQL + Milvus 数据一致
|
||||
- 异常处理完整
|
||||
- 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.4: 文档查询接口
|
||||
**优先级**: P1
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `DocumentController#query`
|
||||
- `DocumentService#queryDocuments`
|
||||
**验收**:
|
||||
- 分页查询正确
|
||||
- 过滤条件生效
|
||||
- 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.5: 文档删除接口
|
||||
**优先级**: P1
|
||||
**预估时间**: 45 分钟
|
||||
**产出**:
|
||||
- `DocumentController#delete`
|
||||
- `DocumentService#deleteDocument`
|
||||
**验收**:
|
||||
- MySQL 删除成功
|
||||
- Milvus 删除成功
|
||||
- 幂等性保证
|
||||
- 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.6: 混合检索工具
|
||||
**优先级**: P0
|
||||
**预估时间**: 90 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.tool.DocumentSearchTool`
|
||||
**功能**:
|
||||
- 精确匹配(MySQL)
|
||||
- 语义检索(Milvus)
|
||||
- RRF 融合
|
||||
**验收**:
|
||||
- 精确匹配优先
|
||||
- 语义检索补漏
|
||||
- 返回 Top 3
|
||||
- 单元测试覆盖
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.7: 集成测试
|
||||
**优先级**: P1
|
||||
**预估时间**: 60 分钟
|
||||
**产出**:
|
||||
- `DocumentIntegrationTest`
|
||||
**测试场景**:
|
||||
- 上传 → 查询 → 检索 → 删除 完整流程
|
||||
**验收**:
|
||||
- 端到端测试通过
|
||||
|
||||
---
|
||||
|
||||
### 全局任务
|
||||
|
||||
#### Task G.1: 统一异常处理
|
||||
**优先级**: P1
|
||||
**预估时间**: 30 分钟
|
||||
**产出**:
|
||||
- `com.superbiz.agent.exception.GlobalExceptionHandler`
|
||||
- `com.superbiz.agent.exception.SessionNotFoundException`
|
||||
- `com.superbiz.agent.exception.DocumentProcessException`
|
||||
**验收**:
|
||||
- 异常统一捕获
|
||||
- 返回格式统一
|
||||
|
||||
---
|
||||
|
||||
#### Task G.2: Docker Compose 配置
|
||||
**优先级**: P2
|
||||
**预估时间**: 20 分钟
|
||||
**产出**:
|
||||
- `docker-compose.yml` (MySQL + Redis + Milvus)
|
||||
**验收**:
|
||||
- `docker-compose up -d` 启动成功
|
||||
- 应用连接成功
|
||||
|
||||
---
|
||||
|
||||
#### Task G.3: README 更新
|
||||
**优先级**: P2
|
||||
**预估时间**: 15 分钟
|
||||
**产出**:
|
||||
- 更新 `README.md`
|
||||
- 添加 Phase 1 安装说明
|
||||
- 添加本地开发指南
|
||||
|
||||
---
|
||||
|
||||
## 任务依赖关系图
|
||||
|
||||
```
|
||||
Day 1-2:
|
||||
Task 1.1 → Task 1.5
|
||||
↓
|
||||
Task 1.2, 1.3, 1.4 → Task 1.6 → Task 1.7 → Task 1.8
|
||||
↓
|
||||
Task 1.5 → Task 1.9 → Task 1.10 → Task 1.11
|
||||
|
||||
Day 3:
|
||||
Task 3.1 (阻塞) → Task 3.2 → Task 3.3
|
||||
|
||||
Day 4-5:
|
||||
Task 4.1, 4.2 → Task 4.3 → Task 4.7
|
||||
↓
|
||||
Task 4.4
|
||||
↓
|
||||
Task 4.5
|
||||
↓
|
||||
Task 4.6 → Task 4.7
|
||||
|
||||
全局:
|
||||
Task G.1 (并行)
|
||||
Task G.2 (并行)
|
||||
Task G.3 (最后)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键路径
|
||||
|
||||
```
|
||||
Task 1.1 → 1.5 → 1.6 → 1.7 → 3.1 → 3.2 → 4.1 → 4.3 → 4.6 → 4.7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 预估总工时
|
||||
|
||||
- Day 1-2: 5.5 小时(11 个任务)
|
||||
- Day 3: 2 小时(3 个任务)
|
||||
- Day 4-5: 6 小时(7 个任务)
|
||||
- 全局: 1 小时(3 个任务)
|
||||
|
||||
**总计**: 14.5 小时(约 2 个完整工作日)
|
||||
|
||||
---
|
||||
|
||||
## 里程碑
|
||||
|
||||
**Milestone 1**: Day 2 结束
|
||||
- ✅ 数据库表就绪
|
||||
- ✅ JPA + Repository 可用
|
||||
- ✅ Redis 会话管理可用
|
||||
|
||||
**Milestone 2**: Day 3 结束
|
||||
- ✅ 包名重构完成
|
||||
- ✅ 代码结构清晰
|
||||
|
||||
**Milestone 3**: Day 5 结束
|
||||
- ✅ 文档管理 CRUD 完整
|
||||
- ✅ 混合检索工具可用
|
||||
- ✅ 单元测试覆盖率达标(70%+)
|
||||
Reference in New Issue
Block a user