docs: 完成 MVP 架构设计文档
- 数据库设计:3张核心表 (diagnosis_record/case_library/api_document) - Agent架构:4 Agent协作 (Supervisor/Planner/Executor/Verifier) - 意图识别:L0正则+L1小模型Agent分层 - RAG两层加载:L1预加载通用知识 + L2按需加载具体文档 - Skill体系:/diagnose-by-orderid 标准化诊断流程 - Harness控制:5 Gates + 中断机制 - 会话管理:Redis临时存储 + 扩展方案 - 闭环机制:用户反馈 → BadCase → 优化 - 实施规划:3阶段13天
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
# 数据库设计文档索引
|
||||||
|
|
||||||
|
## 📂 文档结构
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── README.md # 总览(推荐从这里开始)
|
||||||
|
├── database-design.md # 总览(同 README.md)
|
||||||
|
│
|
||||||
|
├── tables/ # 表设计详细文档
|
||||||
|
│ ├── diagnosis_record.md # 诊断记录表(核心)
|
||||||
|
│ ├── case_library.md # 案例库表
|
||||||
|
│ └── api_document.md # 文档元数据表
|
||||||
|
│
|
||||||
|
└── architecture/ # 架构设计文档
|
||||||
|
├── agent-architecture-mvp.md # ⭐ Agent 架构 MVP 精简版
|
||||||
|
├── agent-architecture.md # Agent 架构完整版(含生产级扩展)
|
||||||
|
├── session-management.md # 会话管理设计
|
||||||
|
└── implementation-plan.md # 实施规划
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速导航
|
||||||
|
|
||||||
|
### 我是开发者
|
||||||
|
1. [总览](README.md) - 了解整体设计
|
||||||
|
2. [diagnosis_record](tables/diagnosis_record.md) - 核心业务表
|
||||||
|
3. [实施规划](architecture/implementation-plan.md) - 开发计划
|
||||||
|
|
||||||
|
### 我是运维
|
||||||
|
1. [总览](README.md) - 了解表结构
|
||||||
|
2. [实施规划](architecture/implementation-plan.md) - 部署检查清单
|
||||||
|
|
||||||
|
### 我是产品
|
||||||
|
1. [总览](README.md) - 了解系统定位
|
||||||
|
2. [会话管理](architecture/session-management.md) - 了解用户交互流程
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 表清单
|
||||||
|
|
||||||
|
| 表名 | 优先级 | 文档 | 说明 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| diagnosis_record | P0 | [查看](tables/diagnosis_record.md) | 诊断记录(核心) |
|
||||||
|
| case_library | P0 | [查看](tables/case_library.md) | 案例库 |
|
||||||
|
| api_document | P0 | [查看](tables/api_document.md) | 文档元数据 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 阅读建议
|
||||||
|
|
||||||
|
### 第一次阅读
|
||||||
|
```
|
||||||
|
1. README.md(10分钟)
|
||||||
|
- 了解设计原则
|
||||||
|
- 了解表关系
|
||||||
|
|
||||||
|
2. diagnosis_record.md(15分钟)
|
||||||
|
- 核心表设计
|
||||||
|
- 字段泛化设计
|
||||||
|
|
||||||
|
3. implementation-plan.md(5分钟)
|
||||||
|
- 分阶段实施计划
|
||||||
|
```
|
||||||
|
|
||||||
|
### 深入理解
|
||||||
|
```
|
||||||
|
- case_library.md - 案例推荐机制
|
||||||
|
- api_document.md - 文档管理设计
|
||||||
|
- session-management.md - 会话管理机制
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 文档维护
|
||||||
|
|
||||||
|
- 原完整文档已备份:`database-design-backup-20240622.md`
|
||||||
|
- 每个表的详细设计在 `tables/` 目录
|
||||||
|
- 架构设计在 `architecture/` 目录
|
||||||
|
- 修改表结构时,同步更新对应 Markdown
|
||||||
+155
@@ -0,0 +1,155 @@
|
|||||||
|
# 数据库设计文档
|
||||||
|
|
||||||
|
## 📚 文档导航
|
||||||
|
|
||||||
|
### 核心表设计
|
||||||
|
- [diagnosis_record](tables/diagnosis_record.md) - 诊断记录表(核心)
|
||||||
|
- [case_library](tables/case_library.md) - 案例库表
|
||||||
|
- [api_document](tables/api_document.md) - 文档元数据表
|
||||||
|
|
||||||
|
### 架构设计
|
||||||
|
- [Agent 架构设计](architecture/agent-architecture.md) - Agent 协作 + Skill + Harness
|
||||||
|
- [会话管理](architecture/session-management.md) - Redis + MySQL 会话管理
|
||||||
|
- [实施规划](architecture/implementation-plan.md) - 分阶段实施计划
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、设计原则
|
||||||
|
|
||||||
|
### 1.1 核心原则
|
||||||
|
- ✅ **简单优先**:满足诊断流程需要,避免过度设计
|
||||||
|
- ✅ **渐进增强**:先实现核心功能,再逐步扩展
|
||||||
|
- ✅ **数据分离**:诊断结果持久化(MySQL),会话上下文临时化(Redis)
|
||||||
|
- ✅ **适度冗余**:避免过度范式化,适当冗余提升查询性能
|
||||||
|
|
||||||
|
### 1.2 系统定位
|
||||||
|
**自动化诊断系统**
|
||||||
|
- 核心:一键诊断 → 返回完整报告
|
||||||
|
- 辅助:支持追问,但不是主要场景
|
||||||
|
- 特点:大部分用户单次诊断即结束,少数用户会追问细节
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、表结构总览
|
||||||
|
|
||||||
|
### 2.1 核心表关系
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ diagnosis_record │ 诊断记录(核心)
|
||||||
|
│ - 每次诊断一条 │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│ 1:1
|
||||||
|
↓
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ case_library │ 案例库(知识沉淀)
|
||||||
|
│ - 诊断成功→案例 │
|
||||||
|
└─────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ api_document │ 文档元数据(管理层)
|
||||||
|
│ - 状态追踪/去重 │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│ doc_id
|
||||||
|
↓
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Milvus │ 文档内容(检索层)
|
||||||
|
│ - 向量检索 │
|
||||||
|
└─────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Redis Session │ 会话管理(临时)
|
||||||
|
│ - 30分钟过期 │
|
||||||
|
│ - 支持追问 │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 表统计
|
||||||
|
|
||||||
|
| 表名 | 类型 | 预估数据量 | 用途 |
|
||||||
|
|------|------|-----------|------|
|
||||||
|
| diagnosis_record | 核心 | 3.6万/年 | 诊断记录 |
|
||||||
|
| case_library | 核心 | 500-1000 | 案例库 |
|
||||||
|
| api_document | 核心 | 100-200 | 文档管理 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、技术栈
|
||||||
|
|
||||||
|
### 3.1 数据存储
|
||||||
|
```
|
||||||
|
MySQL 8.0+
|
||||||
|
├─ 元数据管理
|
||||||
|
├─ 事务支持
|
||||||
|
└─ JSON 字段支持
|
||||||
|
|
||||||
|
Redis 6.0+
|
||||||
|
├─ 会话存储
|
||||||
|
├─ 缓存
|
||||||
|
└─ TTL 自动过期
|
||||||
|
|
||||||
|
Milvus 2.6+
|
||||||
|
├─ 向量存储
|
||||||
|
├─ 语义检索
|
||||||
|
└─ 混合检索
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 开发框架
|
||||||
|
```
|
||||||
|
Spring Boot 3.2
|
||||||
|
Spring AI Alibaba 1.1.0
|
||||||
|
Milvus SDK Java 2.6.10
|
||||||
|
DashScope SDK
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、快速开始
|
||||||
|
|
||||||
|
### 4.1 创建数据库
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 1. 创建数据库
|
||||||
|
CREATE DATABASE diagnosis_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- 2. 执行建表脚本(按顺序)
|
||||||
|
SOURCE tables/diagnosis_record.sql;
|
||||||
|
SOURCE tables/case_library.sql;
|
||||||
|
SOURCE tables/api_document.sql;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 初始化 Milvus
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 创建 Collection
|
||||||
|
MilvusClientFactory.createCollection();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 配置 Redis
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
database: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、版本历史
|
||||||
|
|
||||||
|
| 版本 | 日期 | 变更内容 |
|
||||||
|
|------|------|---------|
|
||||||
|
| v1.0 | 2024-06-15 | 初版,定义核心表结构 |
|
||||||
|
| v2.0 | 2024-06-15 | diagnosis_record 字段泛化,支持多种故障类型 |
|
||||||
|
| v2.1 | 2024-06-22 | 文档拆分,增加 api_document 表 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、维护说明
|
||||||
|
|
||||||
|
- 每个表的详细设计在 `tables/` 目录下
|
||||||
|
- 架构设计文档在 `architecture/` 目录下
|
||||||
|
- 修改表结构时,同步更新对应的 Markdown 文档
|
||||||
|
- 重大变更需记录在版本历史中
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
# Agent 架构设计(MVP 版)
|
||||||
|
|
||||||
|
## 一、MVP 全景
|
||||||
|
|
||||||
|
```
|
||||||
|
用户输入
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ 意图识别(Intent Recognition) 🆕 │
|
||||||
|
│ "用户想干什么?" │
|
||||||
|
│ │
|
||||||
|
│ 诊断意图 → 路由到诊断 Skill │
|
||||||
|
│ 文档意图 → 路由到文档问答 │
|
||||||
|
│ 案例意图 → 路由到案例查询 │
|
||||||
|
│ 闲聊 → 快速响应(不启动 Agent) │
|
||||||
|
│ 模糊/无关 → 提示用户,直接中断 │
|
||||||
|
└──────────────┬───────────────────────────┘
|
||||||
|
│ 诊断意图
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ Supervisor Agent(调度者) │
|
||||||
|
│ "谁来干?什么时候停?" │
|
||||||
|
└──────────────┬───────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ Planner Agent(规划者) │
|
||||||
|
│ 分析问题 → 制定策略 → 生成报告 │
|
||||||
|
└──────────────┬───────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ Executor Agent(执行者) │
|
||||||
|
│ 调用工具收集证据 │
|
||||||
|
└──────────────┬───────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ Verifier Agent(验证者) │
|
||||||
|
│ 事实核查 → 判定通过/修正/驳回 │
|
||||||
|
└──────────────┬───────────────────────────┘
|
||||||
|
↓
|
||||||
|
诊断报告输出
|
||||||
|
↓
|
||||||
|
用户反馈(有用/无用)
|
||||||
|
↓
|
||||||
|
案例沉淀 + BadCase 优化
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、意图识别(入口层)🆕
|
||||||
|
|
||||||
|
### 2.1 设计理念
|
||||||
|
|
||||||
|
```
|
||||||
|
定位:独立模块,不嵌入任何单一 Agent
|
||||||
|
|
||||||
|
分层策略(不是二选一,而是组合):
|
||||||
|
|
||||||
|
L0: 正则规则 —— 0 成本,毫秒级 ✅ MVP
|
||||||
|
├─ 处理 80%+ 的结构化查询
|
||||||
|
├─ 正则匹配订单号/traceId/错误码格式
|
||||||
|
└─ 关键词匹配("报错"/"异常"/"失败")
|
||||||
|
|
||||||
|
L1: 小模型 Agent —— 低成本,百毫秒级 ✅ MVP
|
||||||
|
├─ L0 未命中时触发
|
||||||
|
├─ 处理灵活的模糊表达("系统有点慢"、"怎么查不到了")
|
||||||
|
├─ 不启动全链路 Agent,只做意图分类
|
||||||
|
└─ 判断为诊断意图 → 路由到诊断 Skill
|
||||||
|
|
||||||
|
L2: 兜底策略 —— 极少使用
|
||||||
|
├─ L0+L1 都无法判断 → 意图不明 → 中断
|
||||||
|
└─ Phase 2 增强
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 意图分类与路由
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────────────┐
|
||||||
|
│ 意图 │ 说明 │ 路由 │
|
||||||
|
├────────────────────────────────────────────────────┤
|
||||||
|
│ 诊断意图 │ 包含结构化标识或错误描述 │ → 诊断Skill│
|
||||||
|
│ 文档问答 │ "XX接口的参数有哪些" │ → 直接RAG │
|
||||||
|
│ 案例查询 │ "之前有类似的问题吗" │ → 案例检索 │
|
||||||
|
│ 闲聊 │ "你好"/"谢谢" │ → 快速响应 │
|
||||||
|
│ 意图不明 │ 无法识别 │ → 中断+提示 │
|
||||||
|
└────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
关键原则:
|
||||||
|
- 只有诊断意图才启动 Agent 全链路
|
||||||
|
- 非诊断意图走轻量路径或直接中断
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 L0:正则规则(MVP,处理 80%)
|
||||||
|
|
||||||
|
```
|
||||||
|
为什么先做 L0?
|
||||||
|
→ 0 成本(不调 LLM),毫秒级响应
|
||||||
|
→ 结构化查询占比最大(订单号、traceId、错误码、关键词)
|
||||||
|
→ L0 命中直接路由,不需要走后续逻辑
|
||||||
|
|
||||||
|
规则配置(可扩展):
|
||||||
|
┌────────────────────────────────────────────────┐
|
||||||
|
│ 规则 │ 意图 │ 方式 │
|
||||||
|
├────────────────────────────────────────────────┤
|
||||||
|
│ 匹配 \d{12,} │ 诊断 │ 正则 │
|
||||||
|
│ 匹配 trace[-_]?\w{8,} │ 诊断 │ 正则 │
|
||||||
|
│ 包含"报错‖失败‖异常‖挂了‖超时" │ 诊断 │ 关键词│
|
||||||
|
│ 包含"文档‖接口‖参数‖字段‖API" │ 文档 │ 关键词│
|
||||||
|
│ 包含"案例‖之前‖类似‖历史" │ 案例 │ 关键词│
|
||||||
|
│ 长度 <= 5 字符 │ 闲聊 │ 规则 │
|
||||||
|
└────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
命中 → 直接路由,不调 L1
|
||||||
|
未命中 → 进入 L1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 L1:小模型 Agent(MVP,处理剩余 20%)
|
||||||
|
|
||||||
|
```
|
||||||
|
为什么用小模型 Agent 而非嵌入到 Supervisor?
|
||||||
|
→ 意图识别是独立职责,不应耦合到任何业务 Agent
|
||||||
|
→ 轻量 Agent:单一职责,只分类不执行
|
||||||
|
→ 成本低(~50 token),延迟低(~200ms)
|
||||||
|
|
||||||
|
何时触发:L0 规则未命中
|
||||||
|
|
||||||
|
System Prompt:
|
||||||
|
"你是意图分类器,判断用户想做什么。
|
||||||
|
只返回一个词:[诊断 / 文档查询 / 案例查询 / 闲聊 / 意图不明]
|
||||||
|
|
||||||
|
诊断:用户描述了故障、报错、异常
|
||||||
|
文档查询:用户询问接口文档、字段含义
|
||||||
|
案例查询:用户询问历史案例、类似问题
|
||||||
|
闲聊:简单的问候、感谢
|
||||||
|
意图不明:无法判断用户意图"
|
||||||
|
|
||||||
|
输入:用户原始输入
|
||||||
|
输出:意图类型 + 置信度
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 L2:兜底策略
|
||||||
|
|
||||||
|
```
|
||||||
|
L0+L1 都无法判断 → L2 兜底
|
||||||
|
|
||||||
|
中断规则:
|
||||||
|
├─ 意图不明 → 提示用户 + 中断
|
||||||
|
│ "无法判断您的意图,请提供订单号或错误码"
|
||||||
|
├─ 闲聊 → 快速响应 + 中断
|
||||||
|
│ "我是故障诊断助手,请描述您遇到的问题"
|
||||||
|
└─ 不启动 Agent,直接返回
|
||||||
|
|
||||||
|
路由规则:
|
||||||
|
├─ 诊断意图 → 启动 Supervisor + 4 Agent 全链路
|
||||||
|
├─ 文档意图 → 不启动 Agent,直接 RAG 检索
|
||||||
|
└─ 案例意图 → 不启动 Agent,直接查询 case_library
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 架构位置
|
||||||
|
|
||||||
|
```
|
||||||
|
用户输入
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ 意图识别模块(独立) │
|
||||||
|
│ │
|
||||||
|
│ L1: 小模型 Agent ─→ 诊断意图? │
|
||||||
|
│ │ 文档意图? │
|
||||||
|
│ │ 案例意图? │
|
||||||
|
│ │ 闲聊? │
|
||||||
|
│ ↓ │
|
||||||
|
│ L2: 兜底 ─────────→ 意图不明 → 中断 │
|
||||||
|
│ 闲聊 → 快速响应 │
|
||||||
|
└───────────────┬──────────────────────────┘
|
||||||
|
│ 诊断意图
|
||||||
|
↓
|
||||||
|
Supervisor → Planner → Executor → Verifier
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.6 MVP vs Phase 2
|
||||||
|
|
||||||
|
```
|
||||||
|
MVP L0(正则)+ L1(小模型Agent) 覆盖 95%+ 场景
|
||||||
|
Phase 2 L2(兜底增强) 细化中断提示,支持多轮澄清
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、4 个 Agent 设计
|
||||||
|
|
||||||
|
### 2.1 Supervisor Agent(调度者)
|
||||||
|
|
||||||
|
**职责**:总指挥,协调工作流
|
||||||
|
|
||||||
|
```
|
||||||
|
调度规则:
|
||||||
|
├─ 接收任务 → 发给 Planner 分析
|
||||||
|
├─ Planner 完成 → 发给 Executor 执行
|
||||||
|
├─ Executor 完成 → 发给 Verifier 校验
|
||||||
|
└─ Verifier PASS → 输出报告 / REJECT → 返回 Planner 重新规划
|
||||||
|
|
||||||
|
不做:
|
||||||
|
- 不直接调用工具
|
||||||
|
- 不直接生成报告
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Planner Agent(规划者 + 分诊)
|
||||||
|
|
||||||
|
**职责**:分析问题、制定策略、生成报告草稿
|
||||||
|
|
||||||
|
```
|
||||||
|
分析规则:
|
||||||
|
├─ 有 errorCode + 接口 URL → EXTERNAL_API(外部接口故障)
|
||||||
|
├─ 有堆栈信息 → INTERNAL_ERROR(系统内部错误)
|
||||||
|
├─ 有数据库错误码(如 1213)→ DATABASE(数据库问题)
|
||||||
|
└─ 其他 → 通用排查
|
||||||
|
|
||||||
|
规划流程:
|
||||||
|
1. 确定 fault_category
|
||||||
|
2. 制定排查步骤(每步:工具名 + 参数 + 预期)
|
||||||
|
3. 生成决策:EXECUTE(继续执行)| FINISH(生成报告)
|
||||||
|
|
||||||
|
Replanner 职责:
|
||||||
|
├─ Executor 每次返回结果后 → 评估证据是否充分
|
||||||
|
├─ 需要补充?→ 调整步骤,继续执行
|
||||||
|
├─ 证据齐全?→ FINISH,生成报告草稿
|
||||||
|
└─ 连续 3 次失败?→ 降级
|
||||||
|
|
||||||
|
禁止:
|
||||||
|
- 编造数据
|
||||||
|
- 引用未经工具返回的内容
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Executor Agent(执行者)
|
||||||
|
|
||||||
|
**职责**:调用工具收集证据
|
||||||
|
|
||||||
|
```
|
||||||
|
工具清单:
|
||||||
|
├─ queryOrder:查询订单/业务数据(MySQL 只读)
|
||||||
|
├─ searchDoc:检索接口文档(混合检索 Milvus + MySQL)
|
||||||
|
├─ recommendCase:推荐相似案例(精确匹配 + 语义检索)
|
||||||
|
└─ getCurrentTime:获取当前时间
|
||||||
|
|
||||||
|
执行规则:
|
||||||
|
├─ 每次只执行 Planner 指定的一个步骤
|
||||||
|
├─ 返回结构化的执行结果
|
||||||
|
├─ 失败时返回错误详情(便于 Planner 调整)
|
||||||
|
└─ 禁止编造结果
|
||||||
|
|
||||||
|
扩展预留:
|
||||||
|
// 代码中 Executor 是接口,后续可扩展为 SubAgent
|
||||||
|
public interface Executor {
|
||||||
|
ExecutionResult execute(Step step);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 Verifier Agent(验证者)
|
||||||
|
|
||||||
|
**职责**:验证诊断报告,防止编造
|
||||||
|
|
||||||
|
```
|
||||||
|
验证流程:
|
||||||
|
|
||||||
|
1️⃣ 事实核查(最重要)
|
||||||
|
├─ 报告中的错误码 → 在 tool_calls 中存在?
|
||||||
|
├─ 根因结论 → 有日志/文档证据支撑?
|
||||||
|
├─ 修复方案 → 引用了文档或案例?
|
||||||
|
└─ 发现编造数据 → 直接 REJECT
|
||||||
|
|
||||||
|
2️⃣ 完整性检查
|
||||||
|
├─ 根因分析章节不能为空
|
||||||
|
├─ 证据链章节不能为空
|
||||||
|
└─ 修复方案章节不能为空
|
||||||
|
|
||||||
|
判决结果:
|
||||||
|
├─ PASS:报告成立,直接输出
|
||||||
|
├─ REVISE:小问题可修正,返回 Planner 微调
|
||||||
|
└─ REJECT:编造数据或严重错误,返回 Planner 重新分析
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、RAG 两层加载策略
|
||||||
|
|
||||||
|
### 4.1 设计理念
|
||||||
|
|
||||||
|
```
|
||||||
|
问题:
|
||||||
|
❌ 全前置:启动时把所有文档塞给 Agent → 信息过载,推理变慢
|
||||||
|
❌ 纯被动:等到需要才查 → Planner 没有全局视野,可能跑偏
|
||||||
|
❌ 固定步骤:每次都调 → 内部错误查接口文档浪费
|
||||||
|
|
||||||
|
正确做法:两层互补
|
||||||
|
|
||||||
|
L1 预加载(Planner 启动时)
|
||||||
|
→ 通用领域知识:系统架构、通用错误码、业务流程
|
||||||
|
→ 给 Planner 全局视野,避免方向性错误
|
||||||
|
|
||||||
|
L2 按需加载(Executor 执行中)
|
||||||
|
→ 具体接口文档:字段定义、错误码含义、调用规范
|
||||||
|
→ 给 Executor 精准证据,定位具体问题
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 两层对比
|
||||||
|
|
||||||
|
| | L1 预加载 | L2 按需加载 |
|
||||||
|
|------|---------|-----------|
|
||||||
|
| 触发时机 | 意图识别后,Planner 启动前 | Executor 拿到具体信息后 |
|
||||||
|
| 内容 | 通用知识(架构、流程、高频错误码) | 具体接口文档(字段、错误码含义) |
|
||||||
|
| 目的 | 让 Planner 有全局视野 | 让 Executor 有精准证据 |
|
||||||
|
| 成本 | 固定,每次诊断 1 次 | 按需,最多 2-3 次 |
|
||||||
|
| 谁负责 | Supervisor 注入 | Executor 自主调用 |
|
||||||
|
|
||||||
|
### 4.3 实现方式
|
||||||
|
|
||||||
|
```
|
||||||
|
L1 预加载:
|
||||||
|
Supervisor 在启动 Planner 前:
|
||||||
|
searchDoc(keyword="系统架构 通用错误码 业务流程")
|
||||||
|
→ 注入到 Planner 的 System Prompt 中
|
||||||
|
→ Planner 拥有"领域背景知识"
|
||||||
|
|
||||||
|
L2 按需加载:
|
||||||
|
Executor 执行 Step 2 时:
|
||||||
|
拿到 errorCode=40003, faultSource="广东"
|
||||||
|
→ 自主调用 searchDoc(errorCode="40003", faultSource="广东")
|
||||||
|
→ 获取该接口的具体字段定义和错误码说明
|
||||||
|
→ 作为证据写入诊断报告
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Skill 设计(1 个)
|
||||||
|
|
||||||
|
### /diagnose-by-orderid(按订单号诊断)
|
||||||
|
|
||||||
|
```
|
||||||
|
输入:orderId
|
||||||
|
|
||||||
|
工作流(6 步):
|
||||||
|
|
||||||
|
Step 1: 查询订单信息
|
||||||
|
工具:queryOrder
|
||||||
|
失败:ABORT(订单不存在则终止)
|
||||||
|
|
||||||
|
Step 2: 检索接口文档
|
||||||
|
工具:searchDoc
|
||||||
|
参数:errorCode + faultSource
|
||||||
|
失败:SKIP(标注"文档缺失")
|
||||||
|
|
||||||
|
Step 3: 查询日志
|
||||||
|
工具:queryLogs(Mock)
|
||||||
|
参数:traceId
|
||||||
|
失败:SKIP(标注"日志缺失")
|
||||||
|
|
||||||
|
Step 4: 检索相似案例
|
||||||
|
工具:recommendCase
|
||||||
|
参数:errorCode + faultCategory
|
||||||
|
失败:SKIP(标注"无相似案例")
|
||||||
|
|
||||||
|
Step 5: 生成诊断报告
|
||||||
|
汇总所有证据,按模板生成报告
|
||||||
|
|
||||||
|
Step 6: Verifier 验证
|
||||||
|
事实核查 → 判决
|
||||||
|
|
||||||
|
门禁规则:
|
||||||
|
├─ Step 1 失败 → 终止,返回"订单不存在"
|
||||||
|
├─ Step 2-4 失败 → 跳过,标注缺失信息
|
||||||
|
├─ 任意步骤超时 30s → 终止
|
||||||
|
└─ Verifier REJECT → 返回 Planner 重新规划
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、Harness 控制层(精简版)
|
||||||
|
|
||||||
|
### 4.1 5 个 Quality Gates
|
||||||
|
|
||||||
|
```
|
||||||
|
输入门禁(2 个):
|
||||||
|
├─ Gate 1: 输入参数非空校验
|
||||||
|
└─ Gate 2: 5 分钟内同一订单 → 返回缓存
|
||||||
|
|
||||||
|
执行门禁(1 个):
|
||||||
|
└─ Gate 3: 工具调用超时(10 秒)
|
||||||
|
|
||||||
|
输出门禁(2 个):
|
||||||
|
├─ Gate 4: 报告章节完整性(3 章节不全 → 不通过)
|
||||||
|
└─ Gate 5: 置信度阈值(< 60 → 标记"低置信度")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 中断规则
|
||||||
|
|
||||||
|
```
|
||||||
|
自动中断:
|
||||||
|
├─ 工具连续失败 3 次 → 终止,降级输出
|
||||||
|
└─ 全局超时 30 秒 → 终止
|
||||||
|
|
||||||
|
条件降级:
|
||||||
|
├─ 文档检索为空 → 跳过继续
|
||||||
|
├─ 案例推荐为空 → 跳过继续
|
||||||
|
└─ 日志查询失败 → 跳过继续
|
||||||
|
|
||||||
|
降级输出:
|
||||||
|
"无法自动诊断,请人工介入"
|
||||||
|
+ 已收集的证据(订单信息 + 部分日志 + 已知错误码)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、技术实现
|
||||||
|
|
||||||
|
### 5.1 基于 Spring AI Alibaba
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Supervisor - 框架提供
|
||||||
|
SupervisorAgent supervisor = SupervisorAgent.builder()
|
||||||
|
.name("diagnosis_supervisor")
|
||||||
|
.model(chatModel)
|
||||||
|
.subAgents(List.of(planner, executor, verifier))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Planner
|
||||||
|
ReactAgent planner = ReactAgent.builder()
|
||||||
|
.name("planner_agent")
|
||||||
|
.model(chatModel)
|
||||||
|
.systemPrompt(plannerPrompt)
|
||||||
|
.outputKey("planner_plan")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Executor(代码中预留 SubAgent 扩展接口)
|
||||||
|
ReactAgent executor = ReactAgent.builder()
|
||||||
|
.name("executor_agent")
|
||||||
|
.model(chatModel)
|
||||||
|
.systemPrompt(executorPrompt)
|
||||||
|
.methodTools(diagnosisTools)
|
||||||
|
.tools(new ToolCallback[]{queryOrder, searchDoc, recommendCase, getCurrentTime})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Verifier
|
||||||
|
ReactAgent verifier = ReactAgent.builder()
|
||||||
|
.name("verifier_agent")
|
||||||
|
.model(chatModel)
|
||||||
|
.systemPrompt(verifierPrompt)
|
||||||
|
.outputKey("verifier_result")
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 工具注册
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Component
|
||||||
|
public class DiagnosisTools {
|
||||||
|
|
||||||
|
@Tool(description = "查询订单/业务数据(只读)")
|
||||||
|
public OrderInfo queryOrder(@ToolParam(description = "订单号") String orderId) {
|
||||||
|
// MySQL 只读 + SQL 注入防护
|
||||||
|
}
|
||||||
|
|
||||||
|
@Tool(description = "检索接口文档")
|
||||||
|
public List<DocChunk> searchDoc(
|
||||||
|
@ToolParam(description = "错误码") String errorCode,
|
||||||
|
@ToolParam(description = "省份/服务名") String faultSource
|
||||||
|
) {
|
||||||
|
// 混合检索:精确匹配 + 向量检索
|
||||||
|
}
|
||||||
|
|
||||||
|
@Tool(description = "推荐相似历史案例")
|
||||||
|
public List<CaseResult> recommendCase(
|
||||||
|
@ToolParam(description = "错误码") String errorCode,
|
||||||
|
@ToolParam(description = "故障类别") String faultCategory
|
||||||
|
) {
|
||||||
|
// 精确匹配 MySQL + 语义检索 Milvus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、闭环机制
|
||||||
|
|
||||||
|
```
|
||||||
|
诊断报告输出
|
||||||
|
↓
|
||||||
|
用户反馈(useful / not_useful)
|
||||||
|
↓
|
||||||
|
├─ useful → 自动生成 case_library
|
||||||
|
└─ not_useful → 记录 BadCase
|
||||||
|
↓
|
||||||
|
每周 BadCase 分析
|
||||||
|
↓
|
||||||
|
Prompt / Skill 优化
|
||||||
|
↓
|
||||||
|
准确率验证(测试集重跑)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、MVP vs 扩展方向
|
||||||
|
|
||||||
|
| 维度 | MVP | 扩展方向 |
|
||||||
|
|------|-----|---------|
|
||||||
|
| Agent | 4 个 Agent | SubAgent 模式(专科医生) |
|
||||||
|
| Skill | 1 个 | 渐进式披露(3 层知识) |
|
||||||
|
| 工具 | @Tool 注解 | MCP 独立 Server |
|
||||||
|
| 回退 | 2 级(失败→降级) | 4 级路由 |
|
||||||
|
| Gates | 5 个 | 15 个全流程门禁 |
|
||||||
|
| 隔离 | 单 JVM | K8s Pod 进程隔离 |
|
||||||
|
| 进化 | 案例自动生成 | 模式识别 + Prompt 自优化 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、面试话术(精简版)
|
||||||
|
|
||||||
|
> "我用 Spring AI Alibaba 实现了一个故障诊断 Agent 系统。
|
||||||
|
>
|
||||||
|
> 入口层是**意图识别**:先判断用户想干什么——诊断故障、查文档、查案例还是闲聊。
|
||||||
|
> 非诊断意图直接走轻量路径,只有诊断意图才启动 Agent 全链路,节省资源。
|
||||||
|
>
|
||||||
|
> 4 Agent 协作:Supervisor 调度、Planner 制定策略、
|
||||||
|
> Executor 调用工具收集证据、Verifier 验证报告防止编造。
|
||||||
|
>
|
||||||
|
> 诊断流程封装成了 Skill,标准化 6 个步骤和异常处理。
|
||||||
|
> Harness 层 5 个门禁保证质量——最关键的是输出门禁,
|
||||||
|
> Verifier 会对比报告数据和工具返回数据,发现编造就驳回。
|
||||||
|
>
|
||||||
|
> 闭环机制:用户反馈 → BadCase 分析 → Prompt 优化。
|
||||||
|
> 案例自动沉淀,系统越用越智能。"
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,211 @@
|
|||||||
|
# 实施规划
|
||||||
|
|
||||||
|
## Phase 1:核心功能(第1周)
|
||||||
|
|
||||||
|
### 实现内容
|
||||||
|
```
|
||||||
|
✅ diagnosis_record 表
|
||||||
|
✅ case_library 表
|
||||||
|
✅ api_document 表
|
||||||
|
✅ Redis 会话管理
|
||||||
|
✅ 单次诊断流程
|
||||||
|
```
|
||||||
|
|
||||||
|
### 不实现
|
||||||
|
```
|
||||||
|
❌ conversation_history 表(先不加)
|
||||||
|
❌ 会话同步(先不做)
|
||||||
|
❌ 追问功能(先不支持)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验收标准
|
||||||
|
```
|
||||||
|
- 用户输入订单号 → 返回诊断报告
|
||||||
|
- 诊断记录持久化到 MySQL
|
||||||
|
- 可以查询历史诊断
|
||||||
|
- 可以统计诊断成功率
|
||||||
|
- 文档可以导入、查询、删除
|
||||||
|
- 案例可以推荐
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2:追问功能(第2周)
|
||||||
|
|
||||||
|
### 实现内容
|
||||||
|
```
|
||||||
|
✅ 支持多轮对话(基于 Redis 上下文)
|
||||||
|
✅ conversation_history 表(可选)
|
||||||
|
✅ 会话上下文管理
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验收标准
|
||||||
|
```
|
||||||
|
- 用户可以追问细节
|
||||||
|
- Agent 能基于上下文回答
|
||||||
|
- 追问不创建新的诊断记录
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3:优化分析(第3周)
|
||||||
|
|
||||||
|
### 实现内容
|
||||||
|
```
|
||||||
|
✅ 会话同步(Redis → MySQL)
|
||||||
|
✅ BadCase 分析
|
||||||
|
✅ 追问频率统计
|
||||||
|
✅ 案例质量评分
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验收标准
|
||||||
|
```
|
||||||
|
- 重要会话自动同步到 MySQL
|
||||||
|
- 可以分析用户追问模式
|
||||||
|
- 可以优化 Prompt 和功能
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 技术债务清单
|
||||||
|
|
||||||
|
### 待优化项(Phase 4+)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. api_document 增强
|
||||||
|
- 软删除(archived_at)
|
||||||
|
- 启用开关(enabled)
|
||||||
|
- 批次管理(batch_id)
|
||||||
|
- 状态细化(PARSING/SPLITTING/INDEXING...)
|
||||||
|
|
||||||
|
2. case_library 增强
|
||||||
|
- 复杂评分(useful_count + score)
|
||||||
|
- 标签分类(tags)
|
||||||
|
- 版本管理
|
||||||
|
- 案例合并
|
||||||
|
|
||||||
|
3. 性能优化
|
||||||
|
- Redis 缓存有效文档列表
|
||||||
|
- 分页查询优化
|
||||||
|
- 索引优化
|
||||||
|
|
||||||
|
4. 监控告警
|
||||||
|
- 诊断成功率监控
|
||||||
|
- 诊断耗时监控
|
||||||
|
- 文档索引状态监控
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据迁移计划
|
||||||
|
|
||||||
|
### 如果已有旧数据
|
||||||
|
|
||||||
|
```
|
||||||
|
1. diagnosis_record 迁移
|
||||||
|
- 旧字段 → 新字段映射
|
||||||
|
- order_id → business_id
|
||||||
|
- province → fault_source
|
||||||
|
- api_url → fault_target
|
||||||
|
|
||||||
|
2. 执行迁移脚本
|
||||||
|
UPDATE diagnosis_record SET
|
||||||
|
business_id = order_id,
|
||||||
|
fault_category = 'EXTERNAL_API',
|
||||||
|
fault_source = province,
|
||||||
|
fault_target = api_url
|
||||||
|
WHERE fault_category IS NULL;
|
||||||
|
|
||||||
|
3. 验证数据一致性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 部署检查清单
|
||||||
|
|
||||||
|
### Phase 1 部署前
|
||||||
|
|
||||||
|
```
|
||||||
|
□ MySQL 数据库已创建
|
||||||
|
□ 三张核心表已创建(diagnosis_record/case_library/api_document)
|
||||||
|
□ Redis 已配置并可连接
|
||||||
|
□ Milvus Collection 已创建
|
||||||
|
□ 向量化服务(DashScope)配置正确
|
||||||
|
□ 文件上传目录已创建并有写权限
|
||||||
|
□ 应用配置文件检查完成
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置文件示例
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# application.yml
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://localhost:3306/diagnosis_system
|
||||||
|
username: root
|
||||||
|
password: xxx
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
database: 0
|
||||||
|
|
||||||
|
milvus:
|
||||||
|
host: localhost
|
||||||
|
port: 19530
|
||||||
|
collection-name: api_doc_collection
|
||||||
|
|
||||||
|
dashscope:
|
||||||
|
api-key: sk-xxx
|
||||||
|
|
||||||
|
file:
|
||||||
|
upload:
|
||||||
|
path: /data/uploads
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 回滚方案
|
||||||
|
|
||||||
|
### 数据库回滚
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 保留旧表备份
|
||||||
|
CREATE TABLE diagnosis_record_backup_20240622 AS SELECT * FROM diagnosis_record;
|
||||||
|
|
||||||
|
-- 回滚时恢复
|
||||||
|
DROP TABLE diagnosis_record;
|
||||||
|
RENAME TABLE diagnosis_record_backup_20240622 TO diagnosis_record;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Milvus 回滚
|
||||||
|
|
||||||
|
```
|
||||||
|
- Milvus 数据无法回滚
|
||||||
|
- 建议:重要操作前先备份 Collection
|
||||||
|
- 或者:保留原始文件,可重新索引
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 监控指标
|
||||||
|
|
||||||
|
### 核心指标
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 诊断成功率
|
||||||
|
- 目标:> 85%
|
||||||
|
- 告警:< 80%
|
||||||
|
|
||||||
|
2. 诊断耗时
|
||||||
|
- 目标:P95 < 10s
|
||||||
|
- 告警:P95 > 15s
|
||||||
|
|
||||||
|
3. 文档索引成功率
|
||||||
|
- 目标:> 95%
|
||||||
|
- 告警:< 90%
|
||||||
|
|
||||||
|
4. 案例推荐准确率
|
||||||
|
- 目标:> 70%
|
||||||
|
- 评估:用户反馈
|
||||||
|
```
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
# 会话管理设计
|
||||||
|
|
||||||
|
## 会话存储策略
|
||||||
|
|
||||||
|
### Redis(主)
|
||||||
|
|
||||||
|
**数据结构**:
|
||||||
|
```
|
||||||
|
key: session:{session_id}
|
||||||
|
value: {
|
||||||
|
"sessionId": "sess-abc",
|
||||||
|
"userId": "user-123",
|
||||||
|
"currentDiagnosisId": "diag-001",
|
||||||
|
"messages": [
|
||||||
|
{"role": "user", "content": "诊断订单 A"},
|
||||||
|
{"role": "assistant", "content": "完整报告..."}
|
||||||
|
],
|
||||||
|
"context": {
|
||||||
|
"province": "广东",
|
||||||
|
"apiName": "社保查询",
|
||||||
|
"errorCode": "40003"
|
||||||
|
},
|
||||||
|
"createdAt": "2024-06-15T14:30:00Z",
|
||||||
|
"lastActiveAt": "2024-06-15T14:35:00Z"
|
||||||
|
}
|
||||||
|
ttl: 1800秒(30分钟)
|
||||||
|
```
|
||||||
|
|
||||||
|
**优势**:
|
||||||
|
- ✅ 快速读写
|
||||||
|
- ✅ 自动过期
|
||||||
|
- ✅ 支持追问(保存上下文)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### MySQL(辅助,可选)
|
||||||
|
|
||||||
|
**同步策略**:
|
||||||
|
1. 重要会话同步
|
||||||
|
- 有用户反馈的会话
|
||||||
|
- 诊断失败的会话(BadCase)
|
||||||
|
- 多轮对话 > 3 轮的会话
|
||||||
|
|
||||||
|
2. 同步时机
|
||||||
|
- 会话结束时(30分钟过期)
|
||||||
|
- 用户反馈时(实时)
|
||||||
|
- 定时任务(每小时,可选)
|
||||||
|
|
||||||
|
3. 同步目标
|
||||||
|
- conversation_history 表
|
||||||
|
- 用于长期分析和审计
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据流设计
|
||||||
|
|
||||||
|
### 场景1:单次诊断(主流 80%)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户发起诊断
|
||||||
|
POST /api/diagnosis/start
|
||||||
|
{
|
||||||
|
"orderId": "202406150001"
|
||||||
|
}
|
||||||
|
|
||||||
|
2. 创建会话(Redis)
|
||||||
|
key: session:sess-abc
|
||||||
|
ttl: 1800秒
|
||||||
|
|
||||||
|
3. 创建诊断记录(MySQL)
|
||||||
|
INSERT INTO diagnosis_record
|
||||||
|
- diagnosis_id: diag-001
|
||||||
|
- session_id: sess-abc
|
||||||
|
- status: RUNNING
|
||||||
|
|
||||||
|
4. Agent 执行诊断
|
||||||
|
- 调用工具(queryOrder, queryLogs, searchDoc...)
|
||||||
|
- 生成报告
|
||||||
|
|
||||||
|
5. 更新诊断记录(MySQL)
|
||||||
|
UPDATE diagnosis_record
|
||||||
|
- status: SUCCESS
|
||||||
|
- root_cause: "idCard字段缺失"
|
||||||
|
- report_markdown: "完整报告..."
|
||||||
|
|
||||||
|
6. 返回报告
|
||||||
|
→ 大部分用户到此结束
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 场景2:追问(少数 20%)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户追问
|
||||||
|
POST /api/chat
|
||||||
|
{
|
||||||
|
"sessionId": "sess-abc",
|
||||||
|
"message": "为什么会缺失字段?"
|
||||||
|
}
|
||||||
|
|
||||||
|
2. 从 Redis 获取上下文
|
||||||
|
GET session:sess-abc
|
||||||
|
- 有之前的诊断结果
|
||||||
|
- 有对话历史
|
||||||
|
|
||||||
|
3. Agent 基于上下文回答
|
||||||
|
- 不创建新的 diagnosis_record
|
||||||
|
- 只是普通对话
|
||||||
|
|
||||||
|
4. 更新 Redis 会话
|
||||||
|
- 追加对话历史
|
||||||
|
- 刷新 TTL(重新计时30分钟)
|
||||||
|
|
||||||
|
5. 可选:保存到 conversation_history(MySQL)
|
||||||
|
- 如果需要长期分析
|
||||||
|
- 异步存储
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 场景3:同一会话多次诊断
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户第一次诊断
|
||||||
|
"诊断订单 A"
|
||||||
|
→ diagnosis_record(diag-001, session_id=sess-abc)
|
||||||
|
|
||||||
|
2. 用户第二次诊断
|
||||||
|
"再诊断订单 B"
|
||||||
|
→ diagnosis_record(diag-002, session_id=sess-abc)
|
||||||
|
|
||||||
|
3. 会话关联
|
||||||
|
- 同一个 session_id
|
||||||
|
- 两条 diagnosis_record
|
||||||
|
- Redis 中保存完整对话历史
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 会话生命周期
|
||||||
|
|
||||||
|
```
|
||||||
|
创建
|
||||||
|
↓
|
||||||
|
活跃(每次交互刷新TTL)
|
||||||
|
↓
|
||||||
|
30分钟无活动
|
||||||
|
↓
|
||||||
|
自动过期
|
||||||
|
↓
|
||||||
|
可选:同步到 MySQL(重要会话)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实现示例
|
||||||
|
|
||||||
|
### Java 代码
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class SessionService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
private static final String SESSION_PREFIX = "session:";
|
||||||
|
private static final Duration SESSION_TTL = Duration.ofMinutes(30);
|
||||||
|
|
||||||
|
// 创建会话
|
||||||
|
public String createSession(String userId) {
|
||||||
|
String sessionId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
SessionData session = SessionData.builder()
|
||||||
|
.sessionId(sessionId)
|
||||||
|
.userId(userId)
|
||||||
|
.messages(new ArrayList<>())
|
||||||
|
.context(new HashMap<>())
|
||||||
|
.createdAt(LocalDateTime.now())
|
||||||
|
.lastActiveAt(LocalDateTime.now())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String key = SESSION_PREFIX + sessionId;
|
||||||
|
redisTemplate.opsForValue().set(key, toJson(session), SESSION_TTL);
|
||||||
|
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取会话
|
||||||
|
public SessionData getSession(String sessionId) {
|
||||||
|
String key = SESSION_PREFIX + sessionId;
|
||||||
|
String json = redisTemplate.opsForValue().get(key);
|
||||||
|
return json != null ? fromJson(json) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新会话(刷新TTL)
|
||||||
|
public void updateSession(SessionData session) {
|
||||||
|
session.setLastActiveAt(LocalDateTime.now());
|
||||||
|
String key = SESSION_PREFIX + session.getSessionId();
|
||||||
|
redisTemplate.opsForValue().set(key, toJson(session), SESSION_TTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除会话
|
||||||
|
public void deleteSession(String sessionId) {
|
||||||
|
String key = SESSION_PREFIX + sessionId;
|
||||||
|
redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,155 @@
|
|||||||
|
# 数据库设计文档
|
||||||
|
|
||||||
|
## 📚 文档导航
|
||||||
|
|
||||||
|
### 核心表设计
|
||||||
|
- [diagnosis_record](tables/diagnosis_record.md) - 诊断记录表(核心)
|
||||||
|
- [case_library](tables/case_library.md) - 案例库表
|
||||||
|
- [api_document](tables/api_document.md) - 文档元数据表
|
||||||
|
|
||||||
|
### 架构设计
|
||||||
|
- [Agent 架构设计](architecture/agent-architecture.md) - Agent 协作 + Skill + Harness
|
||||||
|
- [会话管理](architecture/session-management.md) - Redis + MySQL 会话管理
|
||||||
|
- [实施规划](architecture/implementation-plan.md) - 分阶段实施计划
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、设计原则
|
||||||
|
|
||||||
|
### 1.1 核心原则
|
||||||
|
- ✅ **简单优先**:满足诊断流程需要,避免过度设计
|
||||||
|
- ✅ **渐进增强**:先实现核心功能,再逐步扩展
|
||||||
|
- ✅ **数据分离**:诊断结果持久化(MySQL),会话上下文临时化(Redis)
|
||||||
|
- ✅ **适度冗余**:避免过度范式化,适当冗余提升查询性能
|
||||||
|
|
||||||
|
### 1.2 系统定位
|
||||||
|
**自动化诊断系统**
|
||||||
|
- 核心:一键诊断 → 返回完整报告
|
||||||
|
- 辅助:支持追问,但不是主要场景
|
||||||
|
- 特点:大部分用户单次诊断即结束,少数用户会追问细节
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、表结构总览
|
||||||
|
|
||||||
|
### 2.1 核心表关系
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ diagnosis_record │ 诊断记录(核心)
|
||||||
|
│ - 每次诊断一条 │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│ 1:1
|
||||||
|
↓
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ case_library │ 案例库(知识沉淀)
|
||||||
|
│ - 诊断成功→案例 │
|
||||||
|
└─────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ api_document │ 文档元数据(管理层)
|
||||||
|
│ - 状态追踪/去重 │
|
||||||
|
└──────────┬──────────┘
|
||||||
|
│ doc_id
|
||||||
|
↓
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Milvus │ 文档内容(检索层)
|
||||||
|
│ - 向量检索 │
|
||||||
|
└─────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ Redis Session │ 会话管理(临时)
|
||||||
|
│ - 30分钟过期 │
|
||||||
|
│ - 支持追问 │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 表统计
|
||||||
|
|
||||||
|
| 表名 | 类型 | 预估数据量 | 用途 |
|
||||||
|
|------|------|-----------|------|
|
||||||
|
| diagnosis_record | 核心 | 3.6万/年 | 诊断记录 |
|
||||||
|
| case_library | 核心 | 500-1000 | 案例库 |
|
||||||
|
| api_document | 核心 | 100-200 | 文档管理 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、技术栈
|
||||||
|
|
||||||
|
### 3.1 数据存储
|
||||||
|
```
|
||||||
|
MySQL 8.0+
|
||||||
|
├─ 元数据管理
|
||||||
|
├─ 事务支持
|
||||||
|
└─ JSON 字段支持
|
||||||
|
|
||||||
|
Redis 6.0+
|
||||||
|
├─ 会话存储
|
||||||
|
├─ 缓存
|
||||||
|
└─ TTL 自动过期
|
||||||
|
|
||||||
|
Milvus 2.6+
|
||||||
|
├─ 向量存储
|
||||||
|
├─ 语义检索
|
||||||
|
└─ 混合检索
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 开发框架
|
||||||
|
```
|
||||||
|
Spring Boot 3.2
|
||||||
|
Spring AI Alibaba 1.1.0
|
||||||
|
Milvus SDK Java 2.6.10
|
||||||
|
DashScope SDK
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、快速开始
|
||||||
|
|
||||||
|
### 4.1 创建数据库
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 1. 创建数据库
|
||||||
|
CREATE DATABASE diagnosis_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- 2. 执行建表脚本(按顺序)
|
||||||
|
SOURCE tables/diagnosis_record.sql;
|
||||||
|
SOURCE tables/case_library.sql;
|
||||||
|
SOURCE tables/api_document.sql;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 初始化 Milvus
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 创建 Collection
|
||||||
|
MilvusClientFactory.createCollection();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 配置 Redis
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
database: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、版本历史
|
||||||
|
|
||||||
|
| 版本 | 日期 | 变更内容 |
|
||||||
|
|------|------|---------|
|
||||||
|
| v1.0 | 2024-06-15 | 初版,定义核心表结构 |
|
||||||
|
| v2.0 | 2024-06-15 | diagnosis_record 字段泛化,支持多种故障类型 |
|
||||||
|
| v2.1 | 2024-06-22 | 文档拆分,增加 api_document 表 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、维护说明
|
||||||
|
|
||||||
|
- 每个表的详细设计在 `tables/` 目录下
|
||||||
|
- 架构设计文档在 `architecture/` 目录下
|
||||||
|
- 修改表结构时,同步更新对应的 Markdown 文档
|
||||||
|
- 重大变更需记录在版本历史中
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
# api_document - 文档元数据表
|
||||||
|
|
||||||
|
## 表定位
|
||||||
|
|
||||||
|
**文档管理表**:管理接口文档的元信息,不负责文档检索(检索由 Milvus 负责)
|
||||||
|
|
||||||
|
## 设计理念
|
||||||
|
|
||||||
|
### 文档管理,不是文档检索
|
||||||
|
|
||||||
|
**核心定位**:
|
||||||
|
- MySQL 负责文档元数据管理(状态、版本、去重)
|
||||||
|
- Milvus 负责文档内容存储和检索
|
||||||
|
- 通过 doc_id 关联两者
|
||||||
|
|
||||||
|
**MVP版本原则**:
|
||||||
|
- ✅ 最简字段,满足基本管理需求
|
||||||
|
- ✅ 文件去重(基于 file_hash)
|
||||||
|
- ✅ 状态追踪(索引进度)
|
||||||
|
- ✅ 硬删除(同步删除 Milvus 数据)
|
||||||
|
- ❌ 暂不支持:软删除、启用开关、版本管理(Phase 2)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 表结构(MVP版)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE api_document (
|
||||||
|
-- 主键
|
||||||
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
doc_id VARCHAR(64) UNIQUE NOT NULL COMMENT '文档唯一ID(UUID),关联Milvus',
|
||||||
|
|
||||||
|
-- 文档分类
|
||||||
|
fault_category VARCHAR(32) DEFAULT 'EXTERNAL_API' COMMENT '文档类别',
|
||||||
|
fault_source VARCHAR(128) COMMENT '文档归属(省份/服务名)',
|
||||||
|
api_name VARCHAR(128) COMMENT '接口名称',
|
||||||
|
version VARCHAR(32) DEFAULT 'v1.0' COMMENT '文档版本',
|
||||||
|
|
||||||
|
-- 文件信息
|
||||||
|
file_name VARCHAR(256) NOT NULL COMMENT '原始文件名',
|
||||||
|
file_path VARCHAR(512) COMMENT '文件存储路径',
|
||||||
|
file_hash VARCHAR(64) COMMENT '文件MD5 hash(用于去重)',
|
||||||
|
file_size BIGINT COMMENT '文件大小(字节)',
|
||||||
|
|
||||||
|
-- 索引状态
|
||||||
|
status VARCHAR(16) DEFAULT 'PENDING' COMMENT '索引状态(PENDING/PROCESSING/INDEXED/FAILED)',
|
||||||
|
chunk_count INT DEFAULT 0 COMMENT '分块数量',
|
||||||
|
error_message TEXT COMMENT '失败原因',
|
||||||
|
|
||||||
|
-- 时间字段
|
||||||
|
indexed_at DATETIME COMMENT '索引完成时间',
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
UNIQUE INDEX uk_file_hash (file_hash),
|
||||||
|
INDEX idx_doc_id (doc_id),
|
||||||
|
INDEX idx_fault_source (fault_source),
|
||||||
|
INDEX idx_status (status),
|
||||||
|
INDEX idx_created_at (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文档元数据表(MVP版)';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 字段说明
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| doc_id | VARCHAR(64) | 是 | **核心**:文档唯一ID,关联 Milvus |
|
||||||
|
| fault_category | VARCHAR(32) | 否 | 文档类别 |
|
||||||
|
| fault_source | VARCHAR(128) | 否 | 文档归属(省份/服务名)|
|
||||||
|
| api_name | VARCHAR(128) | 否 | 接口名称 |
|
||||||
|
| version | VARCHAR(32) | 否 | 文档版本 |
|
||||||
|
| file_name | VARCHAR(256) | 是 | 原始文件名 |
|
||||||
|
| file_path | VARCHAR(512) | 否 | 文件存储路径 |
|
||||||
|
| file_hash | VARCHAR(64) | 否 | **去重关键**:文件MD5 |
|
||||||
|
| file_size | BIGINT | 否 | 文件大小 |
|
||||||
|
| status | VARCHAR(16) | 是 | **状态追踪**:PENDING/PROCESSING/INDEXED/FAILED |
|
||||||
|
| chunk_count | INT | 否 | 分块数量 |
|
||||||
|
| error_message | TEXT | 否 | 失败原因 |
|
||||||
|
| indexed_at | DATETIME | 否 | 索引完成时间 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 核心设计决策
|
||||||
|
|
||||||
|
### 1. doc_id:MySQL 与 Milvus 的桥梁
|
||||||
|
|
||||||
|
```
|
||||||
|
作用:
|
||||||
|
- MySQL:通过 doc_id 管理文档元数据
|
||||||
|
- Milvus:每个 chunk 的 metadata 中携带 doc_id
|
||||||
|
|
||||||
|
关联关系:
|
||||||
|
api_document (MySQL)
|
||||||
|
doc_id: doc-001
|
||||||
|
↓ 1:N
|
||||||
|
Milvus chunks
|
||||||
|
chunk_1: {doc_id: 'doc-001', text: '...', vector: [...]}
|
||||||
|
chunk_2: {doc_id: 'doc-001', text: '...', vector: [...]}
|
||||||
|
|
||||||
|
管理操作:
|
||||||
|
- 删除文档:
|
||||||
|
DELETE FROM milvus_collection WHERE metadata["doc_id"] == 'doc-001';
|
||||||
|
DELETE FROM api_document WHERE doc_id = 'doc-001';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. file_hash:文件去重
|
||||||
|
|
||||||
|
```
|
||||||
|
去重流程:
|
||||||
|
1. 用户上传文件
|
||||||
|
↓
|
||||||
|
2. 计算文件 MD5
|
||||||
|
file_hash = md5(file_content)
|
||||||
|
↓
|
||||||
|
3. 检查是否已存在
|
||||||
|
SELECT * FROM api_document WHERE file_hash = 'abc123...';
|
||||||
|
↓
|
||||||
|
4a. 如果存在 → 提示"文档已存在"
|
||||||
|
4b. 如果不存在 → 继续导入
|
||||||
|
|
||||||
|
唯一约束:UNIQUE INDEX uk_file_hash (file_hash)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. status:状态追踪
|
||||||
|
|
||||||
|
```
|
||||||
|
状态流转:
|
||||||
|
PENDING (待处理)
|
||||||
|
↓
|
||||||
|
PROCESSING (处理中)
|
||||||
|
↓ 成功
|
||||||
|
INDEXED (已索引)
|
||||||
|
↓ 失败
|
||||||
|
FAILED (失败)
|
||||||
|
|
||||||
|
用途:
|
||||||
|
- 批量导入时监控进度
|
||||||
|
- 失败重试
|
||||||
|
- 统计索引成功率
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 硬删除策略(MVP)
|
||||||
|
|
||||||
|
```
|
||||||
|
删除文档时:
|
||||||
|
1. 删除 Milvus 中的所有分块
|
||||||
|
2. 删除 MySQL 元数据
|
||||||
|
3. 可选:删除原始文件
|
||||||
|
|
||||||
|
特点:
|
||||||
|
- 简单直接
|
||||||
|
- 数据彻底删除
|
||||||
|
- 不可恢复(需谨慎)
|
||||||
|
|
||||||
|
Phase 2 可增强:
|
||||||
|
- 软删除(archived_at)
|
||||||
|
- 启用开关(enabled)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据流
|
||||||
|
|
||||||
|
### 场景1:导入新文档
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户上传文件
|
||||||
|
↓
|
||||||
|
2. 计算 hash
|
||||||
|
↓
|
||||||
|
3. 检查去重(MySQL)
|
||||||
|
↓
|
||||||
|
4. 插入元数据(status=PROCESSING)
|
||||||
|
↓
|
||||||
|
5. 后台处理:解析 → 分块 → 向量化 → 存入 Milvus
|
||||||
|
↓
|
||||||
|
6. 更新状态(status=INDEXED, chunk_count=15)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景2:删除文档
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户删除文档
|
||||||
|
↓
|
||||||
|
2. 删除 Milvus 数据(WHERE metadata["doc_id"] == 'xxx')
|
||||||
|
↓
|
||||||
|
3. 删除 MySQL 元数据
|
||||||
|
↓
|
||||||
|
4. 可选:删除原始文件
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景3:重新索引
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 删除旧数据(Milvus + MySQL)
|
||||||
|
↓
|
||||||
|
2. 重新导入(同场景1)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 典型查询
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 查看文档列表
|
||||||
|
SELECT doc_id, file_name, version, status, chunk_count, indexed_at
|
||||||
|
FROM api_document
|
||||||
|
WHERE fault_source = '广东'
|
||||||
|
AND status = 'INDEXED'
|
||||||
|
ORDER BY indexed_at DESC;
|
||||||
|
|
||||||
|
-- 查询失败的文档
|
||||||
|
SELECT doc_id, file_name, error_message
|
||||||
|
FROM api_document
|
||||||
|
WHERE status = 'FAILED';
|
||||||
|
|
||||||
|
-- 统计各状态文档数量
|
||||||
|
SELECT status, COUNT(*) as count
|
||||||
|
FROM api_document
|
||||||
|
GROUP BY status;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与 Milvus 的协作
|
||||||
|
|
||||||
|
### Milvus Collection Schema
|
||||||
|
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
"collection_name": "api_doc_collection",
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "type": "VARCHAR", "is_primary": true},
|
||||||
|
{"name": "content", "type": "VARCHAR"},
|
||||||
|
{"name": "vector", "type": "FLOAT_VECTOR", "dim": 1536},
|
||||||
|
{"name": "metadata", "type": "JSON"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# metadata 结构
|
||||||
|
{
|
||||||
|
"doc_id": "doc-001", # 关联 MySQL
|
||||||
|
"_source": "/path/to/file",
|
||||||
|
"_file_name": "xxx.docx",
|
||||||
|
"chunkIndex": 0,
|
||||||
|
"totalChunks": 15
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Java 代码示例
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 插入时携带 doc_id
|
||||||
|
Map<String, Object> metadata = new HashMap<>();
|
||||||
|
metadata.put("doc_id", docId); // 关联 MySQL
|
||||||
|
metadata.put("_source", filePath);
|
||||||
|
metadata.put("chunkIndex", chunkIndex);
|
||||||
|
|
||||||
|
// 删除文档的所有分块
|
||||||
|
String expr = String.format("metadata[\"doc_id\"] == \"%s\"", docId);
|
||||||
|
milvusClient.delete(DeleteParam.newBuilder()
|
||||||
|
.withCollectionName(COLLECTION_NAME)
|
||||||
|
.withExpr(expr)
|
||||||
|
.build());
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据示例
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 外部接口文档
|
||||||
|
INSERT INTO api_document VALUES
|
||||||
|
(1, 'doc-001', 'EXTERNAL_API', '广东', '社保查询', 'v2.1',
|
||||||
|
'广东社保查询v2.1.docx', '/docs/guangdong/social-v2.1.docx',
|
||||||
|
'abc123...', 1048576,
|
||||||
|
'INDEXED', 15, NULL, '2024-06-15 10:30:00', NOW(), NOW());
|
||||||
|
|
||||||
|
-- 内部服务文档
|
||||||
|
INSERT INTO api_document VALUES
|
||||||
|
(2, 'doc-002', 'INTERNAL_ERROR', 'order-service', '订单服务API', 'v1.0',
|
||||||
|
'订单服务API文档.pdf', '/docs/internal/order-service-api.pdf',
|
||||||
|
'def456...', 2097152,
|
||||||
|
'INDEXED', 20, NULL, '2024-06-14 15:20:00', NOW(), NOW());
|
||||||
|
|
||||||
|
-- 处理失败的文档
|
||||||
|
INSERT INTO api_document VALUES
|
||||||
|
(3, 'doc-003', 'EXTERNAL_API', '江苏', '公积金查询', 'v1.5',
|
||||||
|
'江苏公积金查询.html', '/docs/jiangsu/fund-v1.5.html',
|
||||||
|
'ghi789...', 512000,
|
||||||
|
'FAILED', 0, '不支持HTML格式', NULL, NOW(), NOW());
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据量预估
|
||||||
|
|
||||||
|
```
|
||||||
|
预估:100-200 条
|
||||||
|
- 外部接口文档:50-100 条
|
||||||
|
- 内部服务文档:20-50 条
|
||||||
|
- 其他文档:30-50 条
|
||||||
|
|
||||||
|
存储:
|
||||||
|
- 单条记录:约 1KB
|
||||||
|
- 200 条:约 200KB
|
||||||
|
|
||||||
|
结论:数据量很小
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MVP 版本的简化
|
||||||
|
|
||||||
|
```
|
||||||
|
Phase 1(当前):
|
||||||
|
✅ 基础字段和表结构
|
||||||
|
✅ 文件去重(file_hash)
|
||||||
|
✅ 状态追踪(status)
|
||||||
|
✅ 硬删除
|
||||||
|
✅ 通过 doc_id 关联 Milvus
|
||||||
|
|
||||||
|
Phase 2(未来增强):
|
||||||
|
❌ enabled(启用开关)
|
||||||
|
❌ archived_at(软删除)
|
||||||
|
❌ batch_id(批次管理)
|
||||||
|
❌ status 细化
|
||||||
|
❌ tags(标签分类)
|
||||||
|
```
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
# case_library - 案例库表
|
||||||
|
|
||||||
|
## 表定位
|
||||||
|
|
||||||
|
**知识沉淀表**:存储高质量诊断案例,支持相似案例推荐
|
||||||
|
|
||||||
|
## 设计理念
|
||||||
|
|
||||||
|
### 知识沉淀,系统越用越智能
|
||||||
|
|
||||||
|
**核心价值**:
|
||||||
|
- 质量过滤:只存储高质量案例(成功诊断 + 用户反馈有用)
|
||||||
|
- 知识沉淀:历史诊断经验可复用
|
||||||
|
- 提升准确率:相似问题提供历史参考
|
||||||
|
- 加速诊断:快速推荐相似案例
|
||||||
|
|
||||||
|
**MVP版本设计原则**:
|
||||||
|
- ✅ 能用:满足基本案例推荐功能
|
||||||
|
- ✅ 简单:字段不多,逻辑清晰
|
||||||
|
- ✅ 可扩展:后续可增加字段
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 表结构(MVP版)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE case_library (
|
||||||
|
-- 主键
|
||||||
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
case_id VARCHAR(64) UNIQUE NOT NULL COMMENT '案例唯一ID(UUID)',
|
||||||
|
|
||||||
|
-- 来源关联
|
||||||
|
diagnosis_id VARCHAR(64) COMMENT '关联诊断记录(可选,人工录入时为空)',
|
||||||
|
source_type VARCHAR(16) DEFAULT 'AUTO' COMMENT '来源类型(AUTO:自动生成/MANUAL:人工录入)',
|
||||||
|
|
||||||
|
-- 案例分类
|
||||||
|
fault_category VARCHAR(32) COMMENT '故障类别(EXTERNAL_API/INTERNAL_ERROR/DATABASE...)',
|
||||||
|
fault_source VARCHAR(128) COMMENT '故障源(省份/服务名/类名...)',
|
||||||
|
fault_target VARCHAR(256) COMMENT '故障目标(接口URL/方法名/SQL...)',
|
||||||
|
error_code VARCHAR(64) COMMENT '错误码',
|
||||||
|
|
||||||
|
-- 案例内容
|
||||||
|
title VARCHAR(256) NOT NULL COMMENT '案例标题(简短描述)',
|
||||||
|
root_cause TEXT NOT NULL COMMENT '根因分析',
|
||||||
|
solution TEXT NOT NULL COMMENT '解决方案',
|
||||||
|
|
||||||
|
-- 简单统计
|
||||||
|
reference_count INT DEFAULT 0 COMMENT '引用次数(被推荐的次数)',
|
||||||
|
|
||||||
|
-- 元数据
|
||||||
|
created_by VARCHAR(64) COMMENT '创建人',
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
INDEX idx_fault_category (fault_category),
|
||||||
|
INDEX idx_error_code (error_code),
|
||||||
|
INDEX idx_fault_source (fault_source),
|
||||||
|
INDEX idx_fault_target (fault_target(100)),
|
||||||
|
INDEX idx_diagnosis_id (diagnosis_id),
|
||||||
|
INDEX idx_reference_count (reference_count),
|
||||||
|
INDEX idx_created_at (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='案例库表(MVP版)';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 字段说明
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| case_id | VARCHAR(64) | 是 | 案例唯一标识(UUID)|
|
||||||
|
| diagnosis_id | VARCHAR(64) | 否 | 关联诊断记录(人工录入时为空)|
|
||||||
|
| source_type | VARCHAR(16) | 是 | 来源:AUTO(自动)/MANUAL(人工)|
|
||||||
|
| fault_category | VARCHAR(32) | 否 | 故障类别 |
|
||||||
|
| fault_source | VARCHAR(128) | 否 | 故障源 |
|
||||||
|
| fault_target | VARCHAR(256) | 否 | 故障目标(与 diagnosis_record 一致)|
|
||||||
|
| error_code | VARCHAR(64) | 否 | 错误码 |
|
||||||
|
| title | VARCHAR(256) | 是 | 案例标题 |
|
||||||
|
| root_cause | TEXT | 是 | 根因分析(核心内容)|
|
||||||
|
| solution | TEXT | 是 | 解决方案(核心内容)|
|
||||||
|
| reference_count | INT | 是 | 引用次数(用于排序)|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 核心设计决策
|
||||||
|
|
||||||
|
### 1. 案例来源
|
||||||
|
|
||||||
|
```
|
||||||
|
来源1:自动生成(source_type=AUTO)
|
||||||
|
├─ 触发条件:诊断成功 + 用户反馈"有用"
|
||||||
|
├─ 关联诊断:diagnosis_id 不为空
|
||||||
|
└─ 质量保证:用户验证过
|
||||||
|
|
||||||
|
来源2:人工录入(source_type=MANUAL)
|
||||||
|
├─ 运维团队总结的经典案例
|
||||||
|
├─ diagnosis_id 为空
|
||||||
|
└─ 质量最高
|
||||||
|
|
||||||
|
注意:诊断失败或用户反馈"无用"的不自动生成案例
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 简化的评分机制(MVP)
|
||||||
|
|
||||||
|
```
|
||||||
|
MVP版本:只按 reference_count 排序
|
||||||
|
- 引用次数多的排前面
|
||||||
|
- 简单有效
|
||||||
|
|
||||||
|
Phase 2 可增强:
|
||||||
|
- 增加 useful_count(用户反馈有用次数)
|
||||||
|
- 增加 score(综合评分)
|
||||||
|
- 增加 is_featured(人工标记的经典案例)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 与 diagnosis_record 的关系
|
||||||
|
|
||||||
|
```
|
||||||
|
关系:一对一(可选)
|
||||||
|
- 一次诊断 → 可以生成一个案例
|
||||||
|
- 通过 diagnosis_id 关联
|
||||||
|
- diagnosis_id 可为空(人工录入案例)
|
||||||
|
|
||||||
|
流程:
|
||||||
|
diagnosis_record(成功)
|
||||||
|
↓
|
||||||
|
用户反馈"有用"
|
||||||
|
↓
|
||||||
|
自动生成 case_library
|
||||||
|
↓
|
||||||
|
后续可人工修正、合并相似案例
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据示例
|
||||||
|
|
||||||
|
### 示例1:外部接口故障案例
|
||||||
|
```sql
|
||||||
|
INSERT INTO case_library VALUES
|
||||||
|
(1, 'case-001', 'diag-001', 'AUTO', 'EXTERNAL_API', '广东', '/api/v1/guangdong/social-security', '40003',
|
||||||
|
'广东社保查询idCard字段缺失',
|
||||||
|
'请求报文中未传入idCard字段,导致参数校验失败',
|
||||||
|
'前端表单增加idCard必填校验;后端增加参数校验提示',
|
||||||
|
15, 'system', NOW(), NOW());
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例2:内部错误案例
|
||||||
|
```sql
|
||||||
|
INSERT INTO case_library VALUES
|
||||||
|
(2, 'case-002', 'diag-045', 'AUTO', 'INTERNAL_ERROR', 'order-service', 'OrderController.createOrder()', 'NullPointerException',
|
||||||
|
'订单服务创建订单空指针异常',
|
||||||
|
'OrderController.createOrder()方法中user对象为null,未做空判断',
|
||||||
|
'在第45行添加空判断:if (user == null) throw new BizException("用户信息不存在")',
|
||||||
|
8, 'system', NOW(), NOW());
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例3:人工录入案例
|
||||||
|
```sql
|
||||||
|
INSERT INTO case_library VALUES
|
||||||
|
(3, 'case-003', NULL, 'MANUAL', 'DATABASE', 'mysql-master-01', 'UPDATE orders SET status=? WHERE order_id=?', '1213',
|
||||||
|
'订单库存更新死锁通用处理',
|
||||||
|
'两个事务互相等待对方释放锁',
|
||||||
|
'调整事务加锁顺序:统一先锁订单,再锁库存;或使用乐观锁',
|
||||||
|
3, 'admin', NOW(), NOW());
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 典型查询
|
||||||
|
|
||||||
|
### 精确匹配查询
|
||||||
|
```sql
|
||||||
|
-- 按错误码查询
|
||||||
|
SELECT * FROM case_library
|
||||||
|
WHERE error_code = '40003'
|
||||||
|
ORDER BY reference_count DESC
|
||||||
|
LIMIT 5;
|
||||||
|
|
||||||
|
-- 按故障类别 + 错误码 + 故障目标查询
|
||||||
|
SELECT * FROM case_library
|
||||||
|
WHERE fault_category = 'INTERNAL_ERROR'
|
||||||
|
AND error_code = 'NullPointerException'
|
||||||
|
AND fault_target = 'OrderController.createOrder()'
|
||||||
|
ORDER BY reference_count DESC
|
||||||
|
LIMIT 5;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 统计分析
|
||||||
|
```sql
|
||||||
|
-- 统计案例分布
|
||||||
|
SELECT
|
||||||
|
fault_category,
|
||||||
|
COUNT(*) as count,
|
||||||
|
AVG(reference_count) as avg_reference
|
||||||
|
FROM case_library
|
||||||
|
GROUP BY fault_category
|
||||||
|
ORDER BY count DESC;
|
||||||
|
|
||||||
|
-- Top 引用案例
|
||||||
|
SELECT title, reference_count, created_at
|
||||||
|
FROM case_library
|
||||||
|
ORDER BY reference_count DESC
|
||||||
|
LIMIT 10;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与 Milvus 的配合
|
||||||
|
|
||||||
|
### 混合检索策略
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 精确匹配(MySQL)
|
||||||
|
- 按 error_code 查询
|
||||||
|
- 按 fault_category + fault_source 查询
|
||||||
|
- 优点:快速、准确
|
||||||
|
|
||||||
|
2. 语义检索(Milvus)
|
||||||
|
- 将案例内容向量化
|
||||||
|
- 按语义相似度查询
|
||||||
|
- 优点:能找到相似但不同错误码的案例
|
||||||
|
|
||||||
|
3. 混合策略(推荐)
|
||||||
|
Step 1: 先精确匹配(MySQL)
|
||||||
|
Step 2: 如果结果 < 3 个,补充语义检索(Milvus)
|
||||||
|
Step 3: 合并去重,按 reference_count 排序
|
||||||
|
Step 4: 返回 Top 5
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据量预估
|
||||||
|
|
||||||
|
```
|
||||||
|
预估:500-1000 条
|
||||||
|
- 初期:每月新增 10-20 条
|
||||||
|
- 稳定期:每月新增 5-10 条
|
||||||
|
- 总量:1-2 年达到稳定
|
||||||
|
|
||||||
|
存储:
|
||||||
|
- 单条记录:约 2KB
|
||||||
|
- 1000 条:约 2MB
|
||||||
|
|
||||||
|
结论:数据量很小
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MVP 版本的简化
|
||||||
|
|
||||||
|
```
|
||||||
|
Phase 1(当前):
|
||||||
|
✅ 基础字段和表结构
|
||||||
|
✅ 自动生成案例
|
||||||
|
✅ 人工录入案例
|
||||||
|
✅ 按 reference_count 简单排序
|
||||||
|
|
||||||
|
Phase 2(未来增强):
|
||||||
|
❌ useful_count + score(复杂评分)
|
||||||
|
❌ 版本管理
|
||||||
|
❌ 标签分类(tags)
|
||||||
|
❌ 案例合并功能
|
||||||
|
```
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
# diagnosis_record - 诊断记录表
|
||||||
|
|
||||||
|
## 表定位
|
||||||
|
|
||||||
|
**核心业务表**:存储每次诊断任务的完整记录
|
||||||
|
|
||||||
|
## 设计理念
|
||||||
|
|
||||||
|
### 兼容多种故障类型
|
||||||
|
|
||||||
|
**问题背景**:
|
||||||
|
- 初始设计过于聚焦"外部接口故障"
|
||||||
|
- 实际故障类型更丰富:空指针异常、数据库死锁、缓存穿透、线程池耗尽等
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 字段泛化:business_id 替代 order_id,fault_source 替代 province
|
||||||
|
- 增加分类:fault_category 显式区分故障类别
|
||||||
|
- 增强错误信息:error_message、stack_trace 支持内部错误
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 表结构(v2.0)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE diagnosis_record (
|
||||||
|
-- 主键
|
||||||
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
diagnosis_id VARCHAR(64) UNIQUE NOT NULL COMMENT '诊断唯一ID(UUID)',
|
||||||
|
|
||||||
|
-- 关联信息
|
||||||
|
session_id VARCHAR(64) COMMENT '会话ID(关联Redis)',
|
||||||
|
business_id VARCHAR(128) COMMENT '业务标识(订单号/请求ID/线程ID/任务ID...)',
|
||||||
|
trace_id VARCHAR(64) COMMENT '链路追踪ID',
|
||||||
|
|
||||||
|
-- 故障分类(泛化设计)
|
||||||
|
fault_category VARCHAR(32) COMMENT '故障类别(EXTERNAL_API/INTERNAL_ERROR/DATABASE/CACHE/NETWORK/THREAD/MEMORY/CONFIG)',
|
||||||
|
fault_source VARCHAR(128) COMMENT '故障源(省份/服务名/类名/数据库实例...)',
|
||||||
|
fault_target VARCHAR(256) COMMENT '故障目标(接口URL/方法名/SQL语句/缓存键...)',
|
||||||
|
|
||||||
|
-- 错误信息(通用)
|
||||||
|
error_code VARCHAR(64) COMMENT '错误码(业务错误码/HTTP状态码/异常类名)',
|
||||||
|
error_message TEXT COMMENT '错误消息',
|
||||||
|
stack_trace TEXT COMMENT '堆栈信息(内部错误时记录)',
|
||||||
|
|
||||||
|
-- 诊断结果
|
||||||
|
problem_type VARCHAR(32) COMMENT '问题类型(参数/网络/权限/逻辑/空指针/死锁...)',
|
||||||
|
root_cause TEXT COMMENT '根因分析',
|
||||||
|
solution TEXT COMMENT '修复方案',
|
||||||
|
report_markdown TEXT COMMENT '完整诊断报告(Markdown格式)',
|
||||||
|
|
||||||
|
-- 评估指标
|
||||||
|
status VARCHAR(16) DEFAULT 'PENDING' COMMENT '诊断状态(PENDING/RUNNING/SUCCESS/FAILED)',
|
||||||
|
confidence INT COMMENT '诊断置信度(0-100)',
|
||||||
|
duration INT COMMENT '诊断耗时(毫秒)',
|
||||||
|
|
||||||
|
-- 用户反馈
|
||||||
|
feedback VARCHAR(16) COMMENT '用户反馈(useful/not_useful/null)TODO: 后续可拆分为独立反馈表',
|
||||||
|
|
||||||
|
-- 调试字段
|
||||||
|
tool_calls JSON COMMENT '工具调用记录',
|
||||||
|
|
||||||
|
-- 元数据
|
||||||
|
created_by VARCHAR(64) COMMENT '创建人',
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
INDEX idx_business_id (business_id),
|
||||||
|
INDEX idx_trace_id (trace_id),
|
||||||
|
INDEX idx_session_id (session_id),
|
||||||
|
INDEX idx_fault_category (fault_category),
|
||||||
|
INDEX idx_fault_source_target (fault_source, fault_target(100)),
|
||||||
|
INDEX idx_error_code (error_code),
|
||||||
|
INDEX idx_created_at (created_at),
|
||||||
|
INDEX idx_status (status)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='诊断记录表(v2.0 泛化版)';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 字段说明
|
||||||
|
|
||||||
|
### 核心字段
|
||||||
|
|
||||||
|
| 字段 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| diagnosis_id | 诊断唯一标识 | diag-001 |
|
||||||
|
| session_id | 会话ID(支持追问) | sess-abc |
|
||||||
|
| business_id | **泛化**:业务标识 | 订单号/请求ID/线程ID |
|
||||||
|
| trace_id | 链路追踪ID | trace-xyz |
|
||||||
|
|
||||||
|
### 故障分类字段(泛化设计)
|
||||||
|
|
||||||
|
| 字段 | 说明 | 外部接口示例 | 内部错误示例 |
|
||||||
|
|------|------|-------------|-------------|
|
||||||
|
| fault_category | 故障类别 | EXTERNAL_API | INTERNAL_ERROR |
|
||||||
|
| fault_source | 故障源 | 广东 | order-service |
|
||||||
|
| fault_target | 故障目标 | /api/v1/social | OrderController.create() |
|
||||||
|
| error_code | 错误码 | 40003 | NullPointerException |
|
||||||
|
|
||||||
|
### fault_category 枚举值
|
||||||
|
|
||||||
|
```
|
||||||
|
EXTERNAL_API - 外部接口调用失败
|
||||||
|
INTERNAL_ERROR - 系统内部错误(空指针、NPE)
|
||||||
|
DATABASE - 数据库问题(死锁、慢查询)
|
||||||
|
CACHE - 缓存问题(穿透、雪崩)
|
||||||
|
NETWORK - 网络问题(超时、连接失败)
|
||||||
|
THREAD - 线程问题(线程池满、死锁)
|
||||||
|
MEMORY - 内存问题(OOM、内存泄漏)
|
||||||
|
CONFIG - 配置问题(配置错误、缺失)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据示例
|
||||||
|
|
||||||
|
### 示例1:外部接口故障
|
||||||
|
```sql
|
||||||
|
INSERT INTO diagnosis_record VALUES (
|
||||||
|
NULL, 'diag-001', 'sess-abc', '202406150001', 'trace-001',
|
||||||
|
'EXTERNAL_API', '广东', '/api/v1/guangdong/social-security', '40003',
|
||||||
|
'参数缺失:idCard', NULL,
|
||||||
|
'参数问题', 'idCard字段缺失', '补充前端校验', '完整报告...',
|
||||||
|
'SUCCESS', 85, 5234, NULL,
|
||||||
|
NULL, NOW(), NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例2:空指针异常
|
||||||
|
```sql
|
||||||
|
INSERT INTO diagnosis_record VALUES (
|
||||||
|
NULL, 'diag-002', 'sess-def', 'req-xyz789', NULL,
|
||||||
|
'INTERNAL_ERROR', 'order-service', 'OrderController.createOrder()', 'NullPointerException',
|
||||||
|
'Cannot invoke "User.getName()" because "user" is null',
|
||||||
|
'java.lang.NullPointerException: ...\n at OrderController.java:45\n ...',
|
||||||
|
'空指针异常', 'createOrder方法中user对象为null', '添加空判断', '完整报告...',
|
||||||
|
'SUCCESS', 90, 3456, NULL,
|
||||||
|
NULL, NOW(), NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例3:数据库死锁
|
||||||
|
```sql
|
||||||
|
INSERT INTO diagnosis_record VALUES (
|
||||||
|
NULL, 'diag-003', 'sess-ghi', 'txn-20240615-001', NULL,
|
||||||
|
'DATABASE', 'mysql-master-01', 'UPDATE orders SET status=? WHERE order_id=?', '1213',
|
||||||
|
'Deadlock found when trying to get lock', NULL,
|
||||||
|
'数据库死锁', '两个事务互相等待对方释放锁', '调整事务加锁顺序', '完整报告...',
|
||||||
|
'SUCCESS', 88, 4567, NULL,
|
||||||
|
NULL, NOW(), NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 典型查询
|
||||||
|
|
||||||
|
### 按故障类别统计
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
fault_category,
|
||||||
|
COUNT(*) as count,
|
||||||
|
ROUND(AVG(duration), 2) as avg_duration_ms,
|
||||||
|
ROUND(AVG(confidence), 2) as avg_confidence
|
||||||
|
FROM diagnosis_record
|
||||||
|
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||||
|
GROUP BY fault_category
|
||||||
|
ORDER BY count DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 内部错误Top异常
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
error_code,
|
||||||
|
fault_target,
|
||||||
|
COUNT(*) as count
|
||||||
|
FROM diagnosis_record
|
||||||
|
WHERE fault_category = 'INTERNAL_ERROR'
|
||||||
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
|
||||||
|
GROUP BY error_code, fault_target
|
||||||
|
ORDER BY count DESC
|
||||||
|
LIMIT 10;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 诊断成功率
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total,
|
||||||
|
SUM(CASE WHEN status = 'SUCCESS' THEN 1 ELSE 0 END) as success,
|
||||||
|
ROUND(SUM(CASE WHEN status = 'SUCCESS' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as success_rate
|
||||||
|
FROM diagnosis_record
|
||||||
|
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 核心设计决策
|
||||||
|
|
||||||
|
### 1. 一次诊断 = 一条记录
|
||||||
|
- 用户发起一次诊断任务,创建一条记录
|
||||||
|
- 不是聊天记录(不存多轮对话)
|
||||||
|
- 追问对话上下文暂存 Redis(30分钟过期)
|
||||||
|
|
||||||
|
### 2. report_markdown 字段的必要性
|
||||||
|
- 固化结果:Prompt变化不影响历史报告
|
||||||
|
- 快速展示:不需要重新生成
|
||||||
|
- 历史审计:可以看到当时的诊断结果
|
||||||
|
|
||||||
|
### 3. 字段泛化的好处
|
||||||
|
- 支持多种故障类型(不限于外部接口)
|
||||||
|
- 灵活填写(根据故障类型选择字段值)
|
||||||
|
- 易于扩展(新增故障类型只需增加枚举值)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据量预估
|
||||||
|
|
||||||
|
```
|
||||||
|
场景:中型企业运维团队
|
||||||
|
- 日均诊断:100 次
|
||||||
|
- 月均诊断:3000 次
|
||||||
|
- 年均诊断:36000 次
|
||||||
|
|
||||||
|
存储预估:
|
||||||
|
- 单条记录:约 5KB(含报告)
|
||||||
|
- 年存储量:36000 × 5KB = 180MB
|
||||||
|
- 三年存储:540MB
|
||||||
|
|
||||||
|
结论:数据量不大,可以全量保留
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 版本历史
|
||||||
|
|
||||||
|
| 版本 | 日期 | 变更内容 |
|
||||||
|
|------|------|---------|
|
||||||
|
| v1.0 | 2024-06-15 | 初版,基础字段 |
|
||||||
|
| v2.0 | 2024-06-22 | 字段泛化,支持多种故障类型 |
|
||||||
Reference in New Issue
Block a user