2376 字
约 7 分钟
21
S24-A14 · AI 辅助排障:它给的是假设,不是结论

一次接口 500 的排查里,把错误堆栈贴给助手,它给出三条可能原因,第一条是"数据库连接池耗尽"。工程师照着查了半小时,连接数一切正常。真实原因在第三条——一个 @Transactional 加在私有方法上导致事务没生效。教训不是"助手不可靠",而是它给的三条都是假设,而人把第一条当成了结论。

助手在排障上的价值与风险是同一个性质:它极擅长在几秒内列出候选假设,而这些假设的排序与真实系统的状态无关。它不知道你的流量形态、最近的发布、刚才改的配置。


1. 助手在排障各阶段的作用

阶段 助手的价值 风险
误读错误信息 高(翻译、定位关键字) 低
列候选假设 高(广度) 中(排序不可靠)
判断根因 低 高(无系统状态)
写验证脚本 中高 中(可能测错东西)

第二项与第三项的落差是核心:它擅长"可能是什么",不擅长"这次是什么"。而排障的时间恰恰花在"这次"上。

这个定位也解释了为什么"提示越完整,助手越有用":它无法主动索取信息,你不给的东西它只能猜,而猜出来的内容与你的真实系统无关,却会被读成"它知道"。

所以正确的用法是把它的输出当成待验证清单,而不是答案。

2. 假设的排序该由什么决定

依据 例子
变更时间线 最近发布/配置变更优先
影响范围 全量 vs 单实例
历史相似度 上次同类现象的原因
可验证成本 十分钟能查的优先

第一项最有效:大多数突发问题的答案在"最近改了什么"里。助手不知道这条,所以你必须在提示里给它,或者自己先排一遍。

第四项是实践上的排序原则:先查成本低的假设,即使它概率略低——因为排障是串行的,错一条就浪费一轮。

// 给助手的上下文:这四项缺一项,它的排序就会跑偏
1. 变更时间线(最近 24h 的发布、配置、数据变更)
2. 影响范围(全部/部分实例、单用户/全体、特定地域)
3. 错误形态(报错文本、状态码、日志样例)
4. 已排除项(已经查过什么,结论如何)
// 缺第 4 项最常见:它会把已排除的假设重新列一遍

3. 它最容易错在哪

错误类型 表现
时代错位 按旧版本行为解释(框架升级后已变)
配置无关 忽略你的实际配置,按默认值推理
因果倒置 把伴随现象当原因
过度自信 给出确定语气,实际是猜测

第一项在快速迭代的框架上很常见:它的知识停在某个版本,而你的行为已经变了。所以"这条在新版还成立吗"要单独确认。

第四项最难防:语气与可信度无关。同样一句"可能是连接池耗尽",加上"最可能"三个字就会让人先查它。

// 让助手显式标注可信度,比让它给结论有用
要求输出格式:
- 假设(一句)
- 支持证据(来自我给的日志的哪一行)
- 反证(什么现象会推翻它)
- 验证方法(一条命令或一个查询)
// 缺"反证"的假设不值得先查

4. 验证脚本的用法与陷阱

用法 说明
生成查询/命令 省时间,需确认语义
生成日志过滤正则 好用
生成复现脚本 需在小范围验证
直接在生产执行 绝对不要

第一项(生成查询)的用法要配一条纪律:让助手同时给出"预期结果"。有了预期,你才能判断"结果为空"是"确实没有"还是"查询条件写错了"。

-- 让助手给出查询 + 预期 + 反证
-- 假设:连接池耗尽
SELECT COUNT(*) FROM information_schema.processlist WHERE command='Sleep';
-- 预期:若接近 max_connections(如 190/200)→ 支持假设
-- 反证:若只有 20 条连接 → 该假设可排除

第四项不是谨慎问题而是顺序问题:助手写的命令往往"看起来对",而排障时人手快、心躁,容易直接粘贴。稳妥做法是先 --dry-run 或在只读副本上跑。

第二项有一个具体陷阱:正则里的转义、grep -E 与 grep -P 的差异,会让过滤结果"少了几条",从而误导判断。

// 助手给的正则先在样本上验证命中数,再用于生产
// 反例:直接用于 grep,命中偏少却以为日志里没有
grep -cE 'ERROR.*timeout' app.log
// 正例:先用已知存在的一行验证模式
echo '2026-11-10 ERROR upstream timeout' | grep -E 'ERROR.*timeout' && echo pattern-ok

5. 与人的分工

环节 谁做
收集现象 人(决定看什么)
列假设 助手(广度)
排序 人(结合变更与范围)
验证 人(执行与判断)
收敛根因 人

助手无法替代的是"判断哪些现象值得看":它的输入完全由你决定,你给什么它分析什么。所以输入的选择本身就是最关键的一步。

这个习惯还有一个副作用:写五行时你自己往往会想到答案。因为把"现象"与"解释"分开这个动作,本身就是在做归因排序。

一个实用习惯:先把现象写成五行,再贴给助手。这五行强迫你把"现象"与"解释"分开,而多数误判源于把解释当现象。

// 现象五行的写法(现象,不含解释)
1. 时间:11-10 14:02 起持续
2. 范围:order 服务全部 3 个实例
3. 表现:接口 5xx 比例 12%,日志出现 "upstream timeout"
4. 变更:13:50 发布过 order 服务(版本 v2.31)
5. 已排除:数据库连接数正常、下游健康检查通过
// 写成"连接池可能耗尽"就是解释,不是现象

6. 排错:五种"听了助手的话查错方向"

现象 成因 处理方向
查了半天不是那个原因 假设未排序 按变更时间线重排
它说的现象我这没有 版本/配置不同 补上下文再问
反复回到同一假设 没给已排除项 显式列出排除项
按它的命令操作出问题 直接在生产执行 先 dry-run
结论对了但过程没法复用 只记了结论 记假设与验证

排障结束后还有一步值得做:把"验证有效的假设"写成可复用的检查项。例如"私有方法上的 @Transactional 不生效"应当变成一条代码评审检查项,而不是留在某个人的记忆里。

第五项是复盘层面的损失:如果只记"是事务没生效",下次遇到类似现象仍然要重来一遍。记下"我们查了什么、怎么排除的",才是可复用的资产。

7. 边界:什么情况不必用它

场景 为什么 做法
已明确根因 无需假设 直接修
现象明确且唯一 无需广度 直接查
涉密日志 不能外发 脱敏或不用
时间极紧的故障 排序成本高 按流程执行

还有一条与保密有关的边界:贴日志前先想一遍里面有什么。堆栈常带参数值、SQL、内网地址与用户标识;把它整段外发,等于把一份生产数据副本交出去。脱敏的成本远低于事后追责。

判断口径一句话:我需要的是"可能的原因列表"还是"这次的原因"。前者交给助手,后者只能靠你手上的系统状态。


8. 自测

  1. 助手在排障四个阶段中的作用与风险,哪一处的落差最大?为什么?
  2. 假设排序的四项依据里,哪一项最有效?为什么助手不知道它?
  3. 给助手的上下文若缺"已排除项",会发生什么?
  4. 为什么"语气自信"与"结论正确"无关?要求它输出"反证"有什么作用?
  5. "现象五行"为什么要排除解释?把解释当现象会造成什么后果?
  6. 判断"该不该用助手排障"的那个问题是什么?
S24-A14 · AI 辅助排障:它给的是假设,不是结论
https://www.clxhxhhr.top/posts/6458/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。