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:
zhuyongxin
2026-06-22 18:47:00 +08:00
parent 80eada415d
commit 429413fe64
11 changed files with 5408 additions and 0 deletions
+240
View File
@@ -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 | 字段泛化,支持多种故障类型 |