1. 从一次线上故障说起:AI 是怎么介入 Bug 排查的
那天凌晨两点,监控告警突然炸了。一个核心接口的 P99 延迟从 80ms 飙到 3.2s,错误率从 0.01% 跳到 7%。值班的同学第一反应是回滚,但诡异的是——回滚到上一个稳定版本,问题依然存在。这就说明,Bug 大概率不在最近这次发布里,而是某个更早埋下的雷,被某个特定条件触发了。
我们当时面对的局面,是很多团队都遇到过的经典困境:日志量太大、调用链太长、复现路径不明确。一个请求要穿过网关、鉴权、业务服务、缓存、消息队列、数据库,中间还有好几个异步任务。靠人肉去 grep 日志,基本等于大海捞针。也就是在这个背景下,我们开始尝试把 AI 拉进排查流程,让它帮我们做一件事:从海量上下文里,找到那个最可疑的异常点。
这篇文章想聊的,就是"我们是怎么让 AI 找到那个 Bug 的"这件事的完整过程。它不是一篇讲 AI 多神奇的文章,恰恰相反,我想说的是:AI 在 Bug 排查里能发挥作用,靠的不是它有多聪明,而是我们把问题拆得足够细、把上下文喂得足够准、把验证闭环做得足够严。适合谁看?后端工程师、测试同学、SRE,以及任何正在琢磨"AI 到底能不能真正落到研发流程里"的人。不管你是刚接触 AI 工具的新手,还是已经在用 AI 辅助编程的老手,这里面的思路和踩坑记录,应该都能对上你的某些场景。
我先给个结论,免得你看到一半觉得我在绕:AI 找到 Bug 的本质,是把"人凭经验猜"变成了"人给 AI 划定范围,AI 做模式匹配和关联分析,人再做最终判断"。它替代的是重复的、机械的检索和比对工作,而不是替代你的判断力。想清楚这一点,后面的所有操作你都能理解为什么那么设计。
2. 为什么传统排查方式在这个 Bug 上失效了
2.1 这个 Bug 的三个"反人类"特征
我们后来复盘,这个 Bug 之所以难查,是因为它同时具备三个特征,每一个单独出现都不算难,叠在一起就变成了噩梦。
第一个特征是偶发性。它不是每次请求都触发,而是大概每几千次请求出现一次。这种概率意味着你没法稳定复现,本地跑一百遍可能一次都不出现。很多同学遇到"无法复现的 bug"就头大,原因就在这里——你连触发条件都摸不到。
第二个特征是跨服务。异常最终暴露在 A 服务,但根因可能在 B 服务的某个缓存写入逻辑,而触发点又在 C 服务发来的某条消息。调用链一拉,七八个服务,每个服务几百行日志,人眼根本看不过来。
第三个特征是时间错位。错误发生的时间和根因发生的时间差了将近 40 秒,中间隔了一个异步队列。也就是说,你在错误日志附近找原因,永远找不到,因为真正的问题在 40 秒之前。
提示:判断一个 Bug 是否适合交给 AI 辅助,先看它是不是"信息量大但规律性强"。如果信息量小、靠灵感,AI 帮不上;如果信息量大、人看不过来但存在隐藏关联,AI 就是利器。
2.2 人工排查的成本账
我算过一笔账。当时我们三个人轮流查,前后花了将近 11 个小时。这 11 个小时里,真正有价值的动作其实只有几个:定位到异常请求的 traceId、拉出完整调用链、比对正常请求和异常请求的差异。剩下的时间全花在翻日志、复制粘贴、肉眼比对上。
这就是典型的"高信息密度、低认知密度"工作。信息很多,但每一步的判断其实很简单,只是量大到人扛不住。这种活儿,恰恰是 AI 最擅长的。它不会累,不会看漏,能在几秒钟内把几千行日志里的异常模式给你标出来。
所以我们的思路很明确:把"翻和比"交给 AI,把"判断和决策"留给人。这个分工是整件事能成的前提。
3. 让 AI 找到 Bug 的完整实操流程
3.1 第一步:把非结构化的日志变成 AI 能吃的"饲料"
很多人一上来就把原始日志整段丢给 AI,然后抱怨 AI 胡说八道。问题不在 AI,在于你喂的东西太脏。原始日志里混杂着时间戳、线程名、无关的 INFO 日志、格式不统一的堆栈,AI 要在这种噪声里找信号,准确率自然低。
我们的做法是先做一轮结构化清洗。具体来说,分三步:
- 按 traceId 聚合。把同一个请求链路的所有日志抽出来,按时间排序。这一步用脚本就能做,不需要 AI。
- 过滤日志级别。只保留 WARN、ERROR 以及关键业务节点的 INFO,把大量无意义的 DEBUG 和心跳日志扔掉。这一步能把日志量压到原来的 5% 到 10%。
- 统一格式。把不同服务输出的日志,统一成"时间 | 服务名 | 级别 | 内容"的格式,方便 AI 做跨服务比对。
清洗完之后,一个异常请求的完整上下文,从原来的几万行压缩到了两三百行。这个体量,AI 处理起来又快又准。
注意:清洗规则一定要可复用。我们把它写成了一个脚本,后面每次排查都直接跑,不用重新造轮子。这一步的投入,回报是长期的。
3.2 第二步:给 AI 划定"对比样本",而不是让它凭空猜
这是我认为最关键的一步,也是很多团队忽略的一步。不要只给 AI 一个异常样本,要给它一个异常样本加一个正常样本。
为什么?因为 Bug 的本质是"异常与正常的差异"。如果你只给异常,AI 只能告诉你"这里看起来不太对",但它不知道什么算"对"。给了正常样本,AI 就能做差异比对,直接告诉你"异常请求在 B 服务的缓存写入这里,比正常请求多了一次空值写入"。
我们当时的提示词大概是这样组织的:
下面是一个异常请求的完整调用链日志,以及一个正常请求的完整调用链日志。 请对比两者,找出异常请求中独有的、或者明显偏离正常模式的行为。 重点关注:错误日志、异常堆栈、耗时突增的节点、参数异常、状态码异常。 请按可疑程度从高到低列出你的发现,并说明判断依据。实测下来,这个提示词的效果比"帮我找找哪里有问题"强太多了。因为前者给了 AI 明确的对比框架和输出格式,后者只会让 AI 泛泛而谈。
3.3 第三步:让 AI 输出"可疑点排序",而不是"结论"
这里有个心态上的坑,我必须提醒。不要让 AI 直接给你结论,让它给你可疑点排序。
原因很简单:AI 没有你的业务上下文,它不知道某个字段为空在你们系统里是正常的还是异常的。它只能基于模式做判断。所以它的输出应该是"候选清单",而不是"最终答案"。
我们当时让 AI 输出的格式是这样的:
| 可疑程度 | 位置 | 现象 | AI 的判断依据 |
|---|---|---|---|
| 高 | B服务 CacheWriter | 写入了一个 null 值 | 正常请求此处写入的是有效对象 |
| 中 | C服务 消息发送 | 消息体缺少 traceId | 正常请求消息体包含完整字段 |
| 低 | A服务 重试逻辑 | 重试了 3 次 | 耗时增加但非根因 |
拿到这张表之后,人要做的事情就简单了:按可疑程度从高到低验证。我们验证到第一行就命中了——B 服务在某个边界条件下,会把一个 null 对象写进缓存,导致后续读取时反序列化失败,进而触发重试和超时。
3.4 第四步:验证闭环,别让 AI 的猜测变成"看起来对"
AI 给的候选点,一定要用可复现的方式去验证。我们的验证方法是:构造一个最小复现用例,手动触发那个可疑路径,看是否能稳定复现 Bug。
这一步不能省。因为 AI 有时候会"过度联想",把一些无关的巧合当成因果。比如它可能说"这个请求的 User-Agent 很特殊",但实际上那只是巧合。只有通过复现验证,才能把"相关"变成"因果"。
我们当时的验证过程大概是:写一个单元测试,模拟 B 服务在特定输入下写入 null 的场景,然后跑一遍,果然复现了。到这一步,Bug 就算真正找到了。
4. 提示词怎么写,AI 才真的能帮上忙
4.1 三个必须写进提示词的要素
我试过很多版本的提示词,最后发现有效的提示词都包含三个要素:角色、任务、输出格式。
角色,是告诉 AI 以什么身份思考。比如"你是一名资深后端工程师,擅长分布式系统排查"。这个设定会影响 AI 的推理风格,让它更偏向工程视角而不是泛泛而谈。
任务,是明确要它做什么。要具体到"对比两份日志,找出差异",而不是"帮我看看"。
输出格式,是约束它怎么给结果。表格、列表、还是分点,都要说清楚。格式约束能大幅提升结果的可读性和可用性。
4.2 一个我反复用的提示词模板
你是一名资深后端工程师,擅长分布式系统故障排查。 背景:我们的系统出现了一个偶发 Bug,错误率约 0.1%,无法稳定复现。 下面是异常请求和正常请求的调用链日志(已按 traceId 聚合、按时间排序)。 任务: 1. 对比两份日志,找出异常请求中独有的行为或明显偏离正常模式的地方。 2. 对每个发现,说明你的判断依据。 3. 按可疑程度从高到低排序。 输出格式:Markdown 表格,列为:可疑程度 | 位置 | 现象 | 判断依据。 注意:不要下最终结论,只给候选清单,我会自己验证。这个模板我用了很多次,稳定性很好。关键在于最后那句"不要下最终结论",它能让 AI 保持克制,减少幻觉。
4.3 提示词里的常见错误
我踩过的坑,列几个给你避雷:
- 错误一:一次问太多。既让它找 Bug,又让它给修复方案,还让它写测试。结果每样都做得不深。正确做法是一次只做一件事。
- 错误二:不给对比基准。只给异常样本,AI 只能瞎猜。一定要给正常样本做参照。
- 错误三:不约束输出。AI 会给你一大段散文,你还得自己提炼。直接要求表格或列表,省事得多。
- 错误四:把 AI 当权威。AI 说的每一句都要验证,尤其是它给出的"因果推断"。
提示:提示词不是一次写好的,是要迭代的。第一版效果不好,就根据输出调整措辞,通常迭代两三次就能达到可用状态。
5. 常见问题与排查技巧实录
5.1 AI 说"没发现问题"怎么办
这是最常见的情况。AI 回复"两份日志看起来没有明显差异",这时候别急着放弃,通常是两个原因:要么是清洗不够,噪声太多把信号淹没了;要么是差异太细微,需要你主动提示方向。
我的做法是缩小范围再问。比如先只给它 B 服务的日志,问"这两段有没有差异";如果还没有,就再缩小到某个具体方法。范围越小,AI 越容易发现细节。
另一个技巧是换角度提问。不要问"哪里有问题",改问"这两段日志里,哪个字段的值不一样"。把开放性问题变成封闭性问题,AI 的准确率会明显提升。
5.2 AI 给了十几个可疑点,怎么快速筛
可疑点太多,说明你的提示词约束不够。但既然已经拿到了,筛选方法也有讲究。我一般按这个优先级排:
- 先看错误日志和异常堆栈。这是最硬的信号,优先级最高。
- 再看耗时突增的节点。性能问题往往藏在这里。
- 然后看参数异常。空值、越界、类型不符,都是常见根因。
- 最后看状态码和返回值。这是结果,不是原因,放最后。
按这个顺序,通常前两三个就能命中。
5.3 无法复现的 Bug,AI 能帮上什么
无法复现的 Bug 是最难的,但 AI 恰恰能帮上忙。因为无法复现往往意味着"触发条件很隐蔽",而 AI 擅长从大量数据里找隐蔽模式。
我们的做法是:收集所有出现过的异常请求日志,让 AI 找它们的共同点。比如"这些异常请求有没有共同的参数特征、共同的时间段、共同的上游服务"。找到共同点,就找到了触发条件的线索。
这一步人工做几乎不可能,因为样本太多。但 AI 可以在几分钟内把几十个异常样本的共同特征提取出来。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| AI 说没发现问题 | 日志噪声太多 | 加强清洗,缩小范围 |
| AI 给的点都不对 | 缺少正常样本对比 | 补充正常请求日志 |
| AI 输出太啰嗦 | 提示词没约束格式 | 明确要求表格或列表 |
| AI 结论前后矛盾 | 一次问太多任务 | 拆成多次单任务提问 |
| AI 漏掉关键点 | 上下文被截断 | 分段喂,或先摘要再细查 |
5.5 几个我踩过的坑
第一个坑是过度信任 AI 的因果推断。有一次 AI 说"因为 A 所以 B",我差点直接改代码,后来验证发现 A 和 B 只是同时出现,没有因果关系。从那以后,AI 给的任何因果,我都要求自己复现一遍。
第二个坑是日志清洗规则写得太死。早期我按固定字段切分日志,结果某个服务改了日志格式,清洗直接失效。后来改成用正则做宽松匹配,容错性好很多。
第三个坑是把敏感数据喂给 AI。日志里难免有用户信息、内部地址。我们后来加了一道脱敏处理,把手机号、身份证、内部 IP 都替换掉再喂给 AI。这一步既是合规要求,也是好习惯。
6. 这套方法能复用到哪些场景
6.1 不止是线上 Bug,测试阶段同样适用
我们后来把这套方法用到了测试阶段。测试同学跑自动化用例失败时,不再手动翻报告,而是把失败用例的日志和通过用例的日志一起喂给 AI,让它找差异。效率提升很明显,尤其是那些"偶发失败"的用例。
6.2 代码 Review 里的应用
同样的思路,可以用在代码 Review。把改动前后的代码、相关的测试用例、以及历史上有过 Bug 的相似代码一起给 AI,让它找"这次改动可能引入的风险点"。它给出的候选清单,能帮 Review 的人快速聚焦。
6.3 性能问题的定位
性能问题本质上也是"异常与正常的差异"。把慢请求和快请求的调用链对比,让 AI 找耗时差异最大的节点,思路完全一样。我们用它定位过几次慢查询,效果不错。
6.4 这套方法的边界在哪
说了这么多好处,也得说边界。AI 不擅长处理没有对比基准的问题,也不擅长需要业务领域知识才能判断的问题。比如"这个字段为空到底算不算 Bug",AI 判断不了,只有懂业务的人知道。
所以我的经验是:AI 负责缩小范围,人负责做最终判断。这个分工不能乱。指望 AI 全自动找到并修复 Bug,目前还不现实,但让它帮你把排查范围从"整个系统"缩小到"三个可疑点",它是完全胜任的。
7. 我个人的一些实操体会
用这套方法排查了大半年,我最大的体会是:AI 在 Bug 排查里的价值,不在于它多聪明,而在于它多"耐烦"。人看日志看两个小时就眼花,AI 看两万行还是那个状态。把重复劳动交给它,人就能把精力放在真正需要判断的地方。
另外一点,提示词的质量直接决定结果的质量。我见过很多同学抱怨 AI 不好用,一看他们的提示词,就一句"帮我找 Bug"。这种问法,换谁来都答不好。花十分钟把提示词写清楚,比事后花一小时筛选垃圾结果划算得多。
最后分享一个小技巧:把每次成功的排查过程记录下来,形成你自己的提示词库。不同的 Bug 类型,对应不同的提示词模板。下次遇到类似的,直接套用,效率翻倍。我们团队现在已经攒了十几个模板,覆盖了超时、空指针、并发、缓存穿透等常见场景,用起来很顺手。
这套方法后续还能继续扩展,比如把 AI 接入到告警系统里,告警一触发就自动拉取上下文、生成可疑点清单,推送给值班同学。我们正在试这个方向,目前看效果还行,等跑稳了再单独写一篇聊聊。