核心目标
当 E2E 测试失败时,AI 不应该盲目尝试,而应该科学诊断 → 假设推导 → 有针对性地改进。
本 skill 定义了一套系统的诊断框架,让 AI 能够:
- 从失败现象中识别根本原因
- 基于根本原因生成改进假设
- 按优先级设计改进方案
- 预测改进的可能效果
诊断框架:5 Why + 科学方法
第一步:获取完整的失败信息
当 E2E 测试失败时,不要只看结果,要收集完整的诊断包:
{
"test_name": "test_search_with_large_dataset",
"expected": "response_time < 100ms",
"actual": "response_time = 245ms",
"failure_type": "timeout",
"diagnostic_data": {
"metrics": {
"response_time": 245, // 实际时间
"data_size": 1000000, // 处理的数据量
"concurrency": 1, // 并发度
"cache_hit_rate": 0.15 // 缓存命中率
},
"time_breakdown": {
"db_query": 180, // 占 73%
"network": 30, // 占 12%
"processing": 35 // 占 14%
},
"logs": [
"Query executed: SELECT * FROM users WHERE name LIKE '%pattern%'",
"Scanned 1000000 rows, returned 5000 rows",
"No index on 'name' column"
],
"code_path": [
"searchHandler() -> query() -> db.execute()",
"Line 45: for loop iterating through results (5000 iterations)"
]
}
}关键点:
- ❌ 不要只看
response_time = 245ms就开始改 - ✅ 要看
time_breakdown,知道瓶颈在哪 - ✅ 要看日志,知道发生了什么
- ✅ 要看代码路径,知道怎么发生的
第二步:诊断根本原因(5 Why)
使用5 Why 方法,但不是简单地问 5 次”为什么”,而是根据领域知识来推导。
示例 1:查询超时(数据库)
观察:response_time = 245ms,db_query = 180ms(瓶颈)
第 1 个 Why:为什么数据库查询这么慢?
→ 日志显示扫描了 1,000,000 行,但只返回 5,000 行
第 2 个 Why:为什么要扫描这么多行?
→ SQL 是 SELECT * FROM users WHERE name LIKE '%pattern%'
→ 没有在 'name' 列上建索引
第 3 个 Why:为什么没有索引?
→ 需要查询历史,是设计疏漏还是最近才加的字段?
根本原因:
✅ 直接原因:缺少索引导致全表扫描
✅ 根本原因:查询条件设计时没有考虑索引
诊断结论:
Root Cause: Full table scan due to missing index
Confidence: 95% (clear evidence in logs)
Impact: 180ms / 245ms = 73% of total time
示例 2:查询超时(算法)
观察:response_time = 245ms,processing = 100ms(瓶颈)
第 1 个 Why:为什么处理这么慢?
→ 代码路径显示:for loop iterating through 5000 results
第 2 个 Why:为什么需要遍历 5000 个结果?
→ 在内存中做了一个 O(n²) 的排序操作
第 3 个 Why:为什么不用更高效的算法?
→ 可能原因:历史遗留代码,或者没有意识到性能问题
根本原因:
✅ 算法复杂度过高(O(n²) 对 5000 条数据)
✅ 应该用 O(n log n) 的排序或 O(1) 的哈希查找
诊断结论:
Root Cause: O(n²) algorithm on 5000 items
Confidence: 90%
Impact: 100ms / 245ms = 41% of total time
Opportunity: Could reduce to < 10ms with better algorithm
第三步:生成改进假设
关键原则:基于根本原因,生成有针对性的假设,而不是随意猜测。
假设的三层级别
假设层级:
- 高置信度假设(90%+ 成功率)
- 中置信度假设(70-90% 成功率)
- 低置信度假设(< 70% 成功率)示例:缺少索引的情况
根本原因:缺少索引导致全表扫描
假设 1(高置信度):在 'name' 列上添加索引
- 预期效果:db_query 从 180ms 降至 20-30ms
- 理由:索引可以让查询从 O(n) 变为 O(log n)
- 成功条件:扫描行数从 1M 降至 < 1000
- 副作用:插入/更新会慢一点,但可接受
- 实施难度:低(一行 SQL)
假设 2(中置信度):改进查询 SQL
- 预期效果:db_query 从 180ms 降至 80ms
- 理由:使用更精确的 WHERE 条件而不是模糊查询
- 成功条件:返回行数从 5000 降至 < 100
- 副作用:可能改变搜索结果,需要验证
- 实施难度:中(需要改应用逻辑)
假设 3(低置信度):换数据库
- 预期效果:可能有些帮助
- 理由:不明确,而且投入产出比太低
- 建议:不值得尝试
第四步:假设排序(按 ROI)
ROI = (预期效果) × (成功概率) / (实施成本)
假设 1:(180 - 20) ms × 90% / 1 = 144 得分
假设 2:(180 - 80) ms × 70% / 5 = 14 得分
假设 3:不列入考虑
优先级:假设 1 >> 假设 2
决策:
第 1 轮:先实施假设 1(索引)
- 如果成功:问题解决 ✓
- 如果失败:继续诊断,可能是其他原因
第 2 轮:如果假设 1 失败,重新诊断
- 是索引没有生效?
- 还是有其他瓶颈?
- 再考虑假设 2
常见问题的诊断模板
问题 1:查询超时
快速诊断检查清单:
□ 确认是 DB 瓶颈还是其他?
→ 看 time_breakdown,DB 是否占比 > 50%?
□ 如果是 DB,是全表扫描吗?
→ 看日志的 "Scanned rows" vs "Returned rows"
→ 比率 > 100 表示全表扫描
□ 是否有相关索引?
→ 查询 EXPLAIN PLAN
→ 或搜索表的索引定义
□ 数据量是否增长了?
→ 比较历史数据量
→ 是否到达了某个临界点?
□ SQL 本身是否可以优化?
→ 有没有 JOIN 太多表?
→ 有没有 SELECT * 而不需要所有列?
→ WHERE 条件是否有歧义?
诊断结果示例:
"Type: Full table scan on users table"
"Evidence: Scanned 1M rows, returned 5K rows"
"Fix: Add index on (name)"
"Expected gain: 90%+ improvement"
问题 2:内存溢出
快速诊断检查清单:
□ 当前内存占用是多少?
→ 看 metrics.memory_used vs limit
□ 在哪一行代码开始上升?
→ 看内存监测数据的时间线
→ 对应代码执行的顺序
□ 是否是数据结构问题?
→ 一次性加载太多数据到内存?
→ 应该用流式处理或分页?
□ 是否有内存泄漏?
→ 是否有对象没有被释放?
→ 看对象生命周期
□ 数据量是否合理?
→ 应该处理这么多数据吗?
→ 还是查询条件写得太宽泛?
诊断结果示例:
"Type: Excessive data loading"
"Evidence: Loading 100GB of data into memory for processing"
"Fix: Use streaming/pagination to process in chunks"
"Expected gain: Memory from 100GB down to < 1GB"
问题 3:准确率下降
快速诊断检查清单:
□ 准确率具体下降了多少?
→ baseline: 95% → current: 92%
□ 是所有场景都下降,还是特定场景?
→ 看 test case 的维度:
- 新用户 vs 老用户?
- 冷启动 vs 热启动?
- 特定数据分布?
□ 最近改了什么代码?
→ 对比最近 commit
→ 哪些改动可能影响准确率?
□ 是否是训练数据问题?
→ 数据分布变了吗?
→ 是否需要重新训练?
□ 是否是边界情况被遗漏了?
→ 新增的测试用例暴露了什么?
→ 是否应该增强算法的鲁棒性?
诊断结果示例:
"Type: Model drift due to data distribution change"
"Evidence: Accuracy 95% → 92%, specifically on high-value products"
"Root cause: Product catalog expanded, new categories not in training data"
"Fix: Retrain model with new data or add fallback logic"
"Expected gain: Recovery to 95%+"
迭代策略:快速逼近目标
策略 1:二分搜索策略
当参数可调整时(如缓存大小、超时时间、批处理大小),用二分搜索快速找最优值:
目标:延迟 < 100ms,目前 245ms
参数:batch_size(批处理大小)
初始值:1000
迭代 1:尝试 batch_size = 500
→ 延迟 = 180ms(进步,但不够)
迭代 2:尝试 batch_size = 250
→ 延迟 = 120ms(接近了)
迭代 3:尝试 batch_size = 300
→ 延迟 = 105ms(超过了)
迭代 4:尝试 batch_size = 280
→ 延迟 = 98ms(达到!)
最优值:batch_size = 280
花费时间:4 次迭代(快速收敛)
适用场景:
- 缓存大小
- 连接池大小
- 超时时间
- 批处理大小
策略 2:分层改进策略
当有多个可能的改进时,分层进行,每层都要有收益验证:
目标:响应时间 245ms → < 100ms
第 1 层(必做):消除明显的瓶颈
改进 1.1:加数据库索引
预期:180ms → 30ms
实测:180ms → 35ms(接近预期)
改进 1.2:优化 SQL 查询
预期:35ms → 20ms
实测:35ms → 22ms
结果:245ms → (245 - 180 + 22) = 87ms ✓ 达到目标
如果目标没达到,继续第 2 层:
第 2 层(细化优化):微调和优化细节
改进 2.1:连接池优化
改进 2.2:缓存策略
...
关键原则:
- ✅ 先解决 80% 的问题(找到最大瓶颈)
- ✅ 再优化剩下的 20%
- ✅ 每次改进都要验证效果
- ❌ 不要一次尝试太多改动(无法判断哪个有效)
策略 3:假设验证策略
当原因不确定时,用对比实验快速验证假设:
假设:缓存命中率低导致性能差
验证方案 1(成本低):
- 在 badcase 中打印缓存命中率
- 对比成功 case 的缓存命中率
- 如果有显著差异,假设成立
验证方案 2(成本中):
- 临时禁用缓存,看性能是否改善
- 如果禁用缓存后性能更差,假设成立
验证方案 3(成本高):
- 改进缓存策略,重新测试
- 如果性能改善,假设确认
优先级:1 → 2 → 3
AI 的诊断决策流程
E2E 测试失败
↓
[步骤 1] 收集诊断数据
├─ time_breakdown: 找到最大瓶颈
├─ logs: 理解发生了什么
├─ code_path: 知道在哪里发生的
└─ metrics: 量化观察
↓
[步骤 2] 识别根本原因(使用诊断模板)
├─ 是数据库问题?
├─ 是算法问题?
├─ 是内存问题?
├─ 还是其他?
└─ 用 5 Why 确认
↓
[步骤 3] 生成改进假设(按 ROI 排序)
├─ 假设 1(高置信度)
├─ 假设 2(中置信度)
├─ 假设 3(低置信度)
└─ 选择 ROI 最高的
↓
[步骤 4] 设计改进方案
├─ 决定实施哪个假设
├─ 预测改进效果
├─ 规划验证方案
└─ 开始实施
↓
[步骤 5] 验证和迭代
├─ 如果成功 → 进入下一个瓶颈
├─ 如果失败 → 回到步骤 2,重新诊断
└─ 每次改动都要测试
实践例子:端到端演示
场景:推荐系统的转化率优化
初始状态:
目标:转化率 > 15%
实际:转化率 = 12.5%
缺口:2.5 个百分点
E2E 测试失败,需要诊断...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
第 1 轮迭代
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[诊断]
问:用户在哪一步流失的?
答:分析显示,用户看到推荐但点击率低(5% vs 历史 10%)
问:推荐的准确度怎么样?
答:通过 badcase 分析,发现推荐了很多「不相关」的商品
根本原因:推荐算法的准确度下降了
[假设生成]
假设 1:推荐模型过时了,需要重新训练
- 成功率:80%
- 实施成本:2 小时
- ROI 分数:高
假设 2:推荐特征工程有问题,某些特征失效了
- 成功率:60%
- 实施成本:1 小时
- ROI 分数:中
优先级:假设 1
[改进实施]
执行:重新用最新数据训练推荐模型
[验证]
新的推荐相关性评分:0.72 → 0.85
用户点击率:5% → 8.5%
转化率:12.5% → 13.2%
结果:进步了 0.7 个百分点,但还没到 15%
决策:继续迭代
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
第 2 轮迭代
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[诊断]
问:点击了推荐,但为什么没有转化?
答:分析显示,用户点击后看到了商品详情,但没有下单
问:是商品价格问题,还是其他?
答:badcase 分析显示,推荐的商品大多是「高价商品」,
与用户历史购买价格不符
根本原因:推荐的商品与用户消费能力不匹配
[假设生成]
假设 1:推荐时加入「用户价格偏好」特征
- 成功率:85%
- 成本:1 小时
- ROI 分数:高
假设 2:推荐前做「用户分层」,分别用不同策略
- 成功率:70%
- 成本:3 小时
- ROI 分数:中
优先级:假设 1
[改进实施]
执行:在推荐特征中加入「user_price_preference」
[验证]
推荐商品的平均价格与用户偏好的匹配度:0.65 → 0.88
转化率:13.2% → 14.8%
结果:进步了 1.6 个百分点,接近目标!
决策:继续微调
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
第 3 轮迭代(微调)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[诊断]
缺口:0.2 个百分点
通过 A/B 测试和细粒度分析,发现:
- 新用户的转化率特别低(推荐不准确)
- 重复购买用户的转化率接近目标
根本原因:新用户的数据不足,模型对新用户的推荐不准确
[假设生成]
假设 1:对新用户使用「热启动」策略
- 基于相似用户的购买行为推荐
- 成功率:75%
- 成本:1.5 小时
假设 2:对新用户显示「热销品」而非个性化推荐
- 成功率:60%
- 成本:0.5 小时
优先级:假设 1
[改进实施]
执行:对新用户实施基于相似用户的推荐
[验证]
新用户转化率:8% → 11%
整体转化率:14.8% → 15.2%
结果:达到目标!✓
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
总结
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
目标:12.5% → 15.2%(+2.7 个百分点)
迭代次数:3 次
总投入时间:4.5 小时
改进的维度:
1. 推荐准确度(模型重训)
2. 用户消费能力匹配(特征工程)
3. 新用户冷启动(策略优化)
关键:
- ✅ 每次迭代都有**科学的根本原因分析**
- ✅ 每次改进都有**量化的预期和实测对比**
- ✅ 不是随意尝试,而是**基于诊断的有针对性改进**
- ✅ 快速逼近目标,投入产出比高
何时应用本 Skill
✅ 应该用:
- E2E 测试失败,需要理解为什么
- 有明确的指标目标,需要逐步优化
- 想要快速逼近目标,而不是随意尝试
- 需要与人类沟通改进思路
❌ 不需要:
- 需求还不明确的探索阶段
- 没有可靠的诊断数据
- 简单的功能bug(可以直接看代码修复)
与 ralph-loop 的配合
本 Skill 与 ralph-loop 的配合方式:
ralph-loop --max-iterations 10 \
"Optimize conversion rate to 15% using E2E-diagnostic-skill"
在每一次迭代中,AI 都应该:
1. 运行 E2E 测试(得到失败信息)
2. 应用本 Skill 诊断(找到根本原因)
3. 基于诊断生成改进方案
4. 实施改进并验证
5. 如果达到目标或陷入困境,反思是否需要人类介入
检查清单:验证诊断的质量
在每次诊断时,问自己:
□ 我看到的是「现象」还是「根本原因」?
- 现象:查询慢
- 根本原因:没有索引导致全表扫描
□ 我的假设是基于「事实」还是「直觉」?
- 直觉:可能是内存问题
- 事实:time_breakdown 显示 DB 占 73%
□ 我的改进方案有「成功标准」吗?
- 模糊:优化一下
- 清晰:db_query 从 180ms 降至 < 30ms
□ 我考虑过「副作用」吗?
- 索引会让写操作变慢
- 改算法可能改变结果准确度
□ 我的 ROI 计算是否合理?
- 收益和成本都量化了吗?
- 相比其他改进,这个是最优的吗?
持续改进本 Skill
随着实践的进行,记录:
- 哪些诊断方法最有效?
- 哪些假设生成策略最能快速逼近目标?
- 有没有新发现的瓶颈类型?
- 是否需要加新的诊断模板?
定期更新本文档,让 Skill 随着经验不断进化。