不要把报错直接丢给 AI:正确的排障上下文长什么样

0 阅读17分钟

在这里插入图片描述

开篇

遇到线上报错时,很多人的第一反应是把错误信息复制给 AI:

帮我看看这个报错怎么解决?

有时 AI 会马上给出一个看起来合理的答案:

可能是空指针,请增加判空。
可能是数据库连接问题,请检查配置。
可能是网络超时,请增加重试。

这些建议不一定错。

但它们通常没有真正回答你的问题:

  • 问题发生在哪个请求或任务中?
  • 哪个版本开始出现?
  • 之前是否发布过相关变更?
  • 失败发生前系统已经完成了什么?
  • 这次错误是偶发、持续,还是只影响某一类用户?
  • 现在最应该做的是回滚、止损、修复,还是继续收集证据?

一行报错只是现象,不是完整的问题。

AI 能不能帮助你快速定位根因,取决于你提供的上下文是否足以区分不同假设。

这篇文章不讨论“如何让 AI 猜得更准”,而是讨论一个更基础、也更重要的问题:

正确的排障上下文,究竟应该包含什么?

本文不会讨论什么

排障上下文不是把所有日志和代码无差别地发送给 AI。

本文不会:

  • 建议直接上传生产密钥、令牌、Cookie 或完整用户数据。
  • 认为 AI 的第一个猜测就是根因。
  • 用“重启服务”“增加重试”等经验性建议代替证据分析。
  • 把线上问题简单归结为某一行代码。
  • 让 AI 在没有确认风险的情况下直接修改生产配置。

本文关注的是一套更稳妥的流程:

保护现场
  ↓
整理事实
  ↓
描述影响
  ↓
提供最小代码和日志
  ↓
让 AI 建立假设
  ↓
设计最小验证动作

一、为什么一行报错通常不够

假设你把下面这条异常发给 AI:

java.lang.NullPointerException
    at OrderService.createOrder(OrderService.java:86)

AI 可以推测很多原因:

  • 查询结果为空。
  • 参数没有传递。
  • 某个依赖没有初始化。
  • 配置没有加载。
  • 并发状态发生变化。
  • 测试环境和生产环境不一致。

问题在于,这些假设都可能成立。

错误堆栈告诉我们“在哪里观察到了异常”,却没有完整告诉我们:

谁触发了它
  ↓
输入是什么
  ↓
之前执行了什么
  ↓
系统当时处于什么状态
  ↓
最近发生了什么变化
  ↓
影响了哪些用户和数据

因此,排障问题至少需要区分三种内容:

内容含义示例
事实已经通过日志、监控或代码确认的内容生产环境从 10:20 开始出现 500
现象用户或系统实际观察到的结果创建订单失败,但库存已扣减
假设目前认为可能导致问题的原因事务边界可能没有覆盖库存扣减

事实和现象可以直接提供给 AI。

假设则应该明确标记为假设,不能混成结论。

二、正确的排障上下文,至少包含 8 个部分

我通常会把排障上下文整理成一个“问题上下文包”。

1. 问题摘要

用一句话说明发生了什么:

从 2026-08-22 10:20 开始,生产环境创建订单接口的 5xx 错误率从 0.2% 上升到 8%,主要影响华东地区用户。

不要只写:

订单接口报错了。

问题摘要应该尽量包含:

  • 发生时间。
  • 环境。
  • 功能或接口。
  • 错误类型。
  • 影响范围。
  • 当前趋势。

2. 预期行为和实际行为

这是排障中经常被忽略的一部分。

预期行为:
用户提交有效订单后,订单创建成功,库存扣减一次,并返回订单号。

实际行为:
部分请求返回 500,订单表中偶尔已经存在订单记录,但客户端没有拿到订单号。

只有把预期和实际放在一起,AI 才能分析“哪里开始偏离”。

3. 时间线

线上问题通常不是静态错误,而是一个随时间变化的过程。

10:00 发布订单服务 v2.8.1
10:12 监控发现数据库连接池使用率上升
10:20 创建订单 5xx 开始增加
10:25 用户反馈重复点击后订单状态异常
10:30 暂停流量并保留现场日志

时间线可以帮助 AI 判断:

  • 问题是否与发布相关。
  • 错误和资源指标谁先发生。
  • 是否存在逐渐恶化。
  • 某次配置变更是否可能是触发因素。

4. 环境和版本

至少说明:

- 环境:生产
- 服务版本:order-service v2.8.1
- 部署方式:容器化部署
- 数据库:MySQL 主从
- 运行区域:华东
- 相关依赖:库存服务 v1.6、支付服务 v3.2
- 最近一次发布:2026-08-22 10:00

同一段代码在本地、测试和生产环境中的行为可能不同。

如果不提供环境,AI 很容易把生产问题当成本地代码问题。

5. 输入和触发条件

要尽量描述什么样的请求可以触发问题:

只在以下条件下比较容易出现:
- 订单包含多个商品。
- 使用优惠券。
- 库存服务响应时间超过 2 秒。
- 用户在客户端重复点击提交。

触发条件越具体,越容易把排查从“猜原因”转成“验证条件”。

6. 日志、堆栈和请求链路

不要只贴最后一行异常。

更有价值的内容包括:

  • 完整异常堆栈。
  • 请求 ID 或 Trace ID。
  • 关键时间点的结构化日志。
  • 上游和下游服务的响应。
  • 数据库、缓存和消息操作记录。
  • 同一请求的成功样本和失败样本。

示例:

Trace ID: 8f31c2
Request: POST /orders
User ID: user-***-42
10:20:14.120 进入 OrderController
10:20:14.145 库存预占成功
10:20:16.152 支付服务请求超时
10:20:16.153 OrderService 返回 500
10:20:16.160 客户端连接断开

注意,日志需要脱敏。

7. 最近变更

排障时要告诉 AI 最近发生了什么:

  • 代码发布。
  • 配置变更。
  • 数据库迁移。
  • 依赖升级。
  • 流量变化。
  • 机器或网络调整。
  • 第三方接口规则变化。

如果问题在发布后立即出现,最近变更就是重要线索,但仍然不能直接等同于根因。

8. 已经尝试过什么

很多排障对话效率低,是因为 AI 不知道你已经验证过哪些方向。

可以写成:

已确认:
- 回滚到 v2.8.0 后错误率恢复正常。
- 数据库连接数没有超过上限。
- 库存服务本身没有出现大面积错误。

已尝试:
- 重启 2 个实例,问题短暂缓解后再次出现。
- 增加接口超时时间,错误率没有明显下降。

这可以避免 AI 反复建议已经做过的动作。

三、先保护现场,再让 AI 分析

线上排障与普通代码调试最大的区别,是你面对的系统可能仍在受到影响。

在复制日志、修改配置或重启服务之前,先确认:

是否需要止损?
是否需要保留证据?
是否会改变现场?
是否涉及用户数据或资金?
是否需要通知相关负责人?

1. 止损动作和分析动作要分开

例如:

止损:
- 暂停有问题的流量入口。
- 回滚最近版本。
- 关闭可能导致重复写入的功能。

分析:
- 比较发布前后的调用链。
- 检查事务和异常路径。
- 对比成功与失败请求。

不要为了收集更多信息,让高风险故障持续扩大。

2. 记录每次操作

10:30 回滚 order-service 到 v2.8.0
10:34 5xx 从 8% 降到 0.5%
10:40 暂停优惠券入口
10:45 重现失败请求并保存 Trace ID

操作记录本身也是排障上下文。

3. 不要让 AI 直接执行高风险操作

可以让 AI 帮你分析命令的影响:

请解释下面这条生产操作的影响范围、前置条件和回滚方式。
暂时不要执行,也不要建议我跳过审批。

但涉及生产数据、流量、权限和资金的动作,仍然需要按照团队流程执行。

四、如何给 AI 提供“最小但够用”的日志

日志不是越多越好。

把几十兆日志直接丢给 AI,往往会降低分析质量,还可能带来隐私和安全风险。

1. 优先选择对照样本

建议准备:

一个失败请求
一个成功请求
一个问题发生前的请求
一个问题发生后的请求

每个样本尽量使用相同格式,便于比较:

字段成功样本失败样本
Trace ID已脱敏已脱敏
请求时间10:19:3210:20:14
参数特征1 个商品、无优惠券3 个商品、有优惠券
库存响应120 ms2,030 ms
支付响应成功超时
最终结果201500

2. 优先保留结构,不要保留隐私

可以保留:

  • 字段名。
  • 状态码。
  • 耗时。
  • 错误类型。
  • 调用顺序。
  • 数据量级。

应该脱敏或删除:

  • 密码。
  • Token。
  • Cookie。
  • 手机号和邮箱。
  • 身份证号。
  • 完整地址。
  • 银行卡和支付信息。
  • 生产密钥。

可以用占位符替换:

user_id=USER_42
phone=PHONE_MASKED
token=TOKEN_REMOVED

不要为了让 AI 识别格式而保留真实敏感数据。

3. 保留顺序和时间

下面两段日志包含的信息量不同:

库存成功
支付超时
订单失败
10:20:14.120 inventory.reserve start
10:20:14.241 inventory.reserve success
10:20:14.245 order.insert success
10:20:16.152 payment.create timeout
10:20:16.160 response 500

第二段能够帮助 AI 判断:

  • 订单写入是否早于支付请求。
  • 失败时是否已经产生部分副作用。
  • 超时发生在哪个边界。

五、不要只给错误信息,还要给相关代码

代码上下文也要控制范围。

不建议:

把整个项目目录和所有源文件全部发给 AI。

也不建议:

只发出错的那一行。

比较合适的最小代码范围是:

异常发生的方法
  +
直接调用方
  +
相关返回值和数据结构
  +
关键依赖的接口
  +
相关配置或事务声明
  +
对应测试

例如,排查订单创建异常时,至少要让 AI 看见:

  • Controller 或消息入口。
  • OrderService 的相关方法。
  • 库存和支付调用接口。
  • 事务注解或事务配置。
  • 订单写入逻辑。
  • 错误处理逻辑。
  • 相关单测和集成测试。

否则 AI 只能根据半段代码猜测完整行为。

六、把“现象”和“假设”分开写

这是排障 Prompt 中非常关键的一步。

推荐使用下面的格式:

已确认事实:
- 只有生产环境出现问题。
- v2.8.1 发布后 20 分钟开始出现。
- 回滚到 v2.8.0 后恢复。
- 订单表中存在部分已写入记录。

待验证假设:
- 支付超时后,订单事务没有正确回滚。
- 重试机制可能重复创建订单。
- 某个配置变更放大了支付服务延迟。

暂时不要假设:
- 不要直接认定是数据库问题。
- 不要直接认定是支付服务故障。
- 不要直接认定增加重试就能解决。

这样做的好处是:

  • AI 不会轻易把你的猜测当成事实。
  • 不同假设可以被分别验证。
  • 排障过程更容易形成记录。

七、让 AI 先列假设,再设计验证动作

不要直接问:

根因是什么?

线上问题往往不能仅凭一次对话确定根因。

更稳妥的 Prompt 是:

下面是一个线上问题的排障上下文。

请先不要给最终结论,请完成以下工作:
1. 提取已确认事实。
2. 区分现象、事实和待验证假设。
3. 列出 3 到 5 个可能原因。
4. 按可能性和影响范围排序。
5. 为每个原因设计最小验证动作。
6. 说明每个验证结果分别支持或排除什么。
7. 标出不能在当前信息下确认的内容。

要求:
- 不要把可能原因写成确定结论。
- 不要建议高风险生产操作作为第一步。
- 优先建议只读、可回滚、影响范围小的验证。

一个好的排障回答,应该长这样:

假设支持证据反对证据最小验证
支付超时导致状态未知失败请求均有超时部分请求没有支付调用对比支付 Trace 和订单状态
事务边界不完整订单记录已写入旧版本没有该现象检查事务配置和失败路径
重试产生重复请求同一用户多次提交并非所有失败都重复检查幂等键和请求日志

这比一句“可能是网络问题”更有行动价值。

八、正确的排障 Prompt 模板

下面是一份可以直接复用的线上问题 Prompt:

请作为一名谨慎的线上问题排障助手,帮助我分析下面的故障。

一、问题摘要
<用一句话描述问题、时间、环境和影响>

二、预期行为
<系统本来应该怎样工作>

三、实际行为
<用户和系统实际观察到了什么>

四、影响范围
- 环境:
- 服务:
- 接口或任务:
- 影响用户:
- 错误比例:
- 是否涉及数据、资金或安全:

五、时间线
<按时间顺序列出发布、告警、错误、操作和恢复>

六、环境和版本
<服务版本、配置变化、依赖版本、区域和部署信息>

七、请求与日志
<已脱敏的 Trace、堆栈、关键日志和成功/失败样本>

八、相关代码
<异常方法、调用方、关键依赖、配置和测试>

九、最近变更
<代码、配置、数据库、依赖、流量或基础设施变化>

十、已确认事实
<列出已经被日志、监控、代码或实验确认的内容>

十一、待验证假设
<列出当前怀疑但尚未确认的原因>

请按以下步骤回答:
1. 先整理事实,不要直接下结论。
2. 列出可能原因,并按优先级排序。
3. 为每个原因说明支持证据、反对证据和最小验证动作。
4. 区分止损动作、只读验证和修复动作。
5. 说明哪些操作可能改变现场或造成额外风险。
6. 最后给出下一步排障顺序。

约束:
- 不要建议上传敏感信息。
- 不要把假设写成事实。
- 不要在证据不足时直接要求重构或改生产代码。
- 优先选择可回滚、低风险、影响范围小的验证。

这份模板的核心是“先整理,再假设,后验证”。

九、不同排障场景,需要补充不同上下文

不是所有问题都使用同一套字段。

1. 接口 5xx

重点补充:

  • 请求路径和方法。
  • 请求参数特征。
  • 状态码和响应体。
  • Trace ID。
  • 上下游调用耗时。
  • 成功和失败样本。

2. 数据不一致

重点补充:

  • 业务操作顺序。
  • 数据库变更前后状态。
  • 事务边界。
  • 消息发布和消费状态。
  • 缓存状态。
  • 是否存在重复请求或补偿。

3. 性能下降

重点补充:

  • 发生时间和趋势。
  • P50、P95、P99 延迟。
  • QPS、错误率和资源指标。
  • 慢查询、线程池和连接池。
  • 发布和流量变化。
  • 单个请求的完整耗时分解。

4. 消息堆积

重点补充:

  • Topic、队列和消费者版本。
  • 堆积开始时间。
  • 消费速度和生产速度。
  • 重试、死信和失败原因。
  • 消费者并发数。
  • 是否存在毒消息。

5. 定时任务失败

重点补充:

  • 触发时间和调度规则。
  • 本次处理数据范围。
  • 上一次成功时间。
  • 是否支持断点和重跑。
  • 是否可能重复处理。
  • 外部依赖状态。

先判断问题类型,再准备上下文,比把所有信息混在一起更高效。

十、如何判断 AI 的排障回答是否靠谱

我会用下面几条标准检查:

[ ] 是否区分了事实、现象和假设
[ ] 是否引用了具体日志、代码或时间线证据
[ ] 是否解释了为什么提出这个假设
[ ] 是否提供了反对证据或不确定性
[ ] 是否给出了低风险、可验证的下一步
[ ] 是否区分止损、验证和修复动作
[ ] 是否考虑了数据、资金和安全风险
[ ] 是否避免把重试、重启和重构当成万能答案
[ ] 是否说明了验证结果如何支持或排除原因
[ ] 是否提醒了仍然缺少的上下文

如果 AI 直接给出一个非常肯定的结论,却没有证据和验证步骤,应该把它当作待验证假设,而不是根因。

十一、我会保存的排障记录模板

每次线上问题处理完后,可以保存成下面的格式:

问题:

影响:

开始时间:

恢复时间:

环境与版本:

已确认事实:

关键时间线:

主要假设:

验证过程:

最终根因:

止损动作:

修复动作:

数据补偿:

后续预防:

可以交给 AI 复盘的问题:
1. 哪些信号本来可以更早发现?
2. 哪些日志或监控缺失?
3. 哪些测试没有覆盖?
4. 哪些操作手册需要补充?
5. 哪些代码或配置应该增加保护?

排障记录不只是为了写事故报告。

它可以反过来帮助 AI 和团队改进:

  • 监控。
  • 日志。
  • 测试。
  • 告警。
  • 发布流程。
  • 代码保护。

十二、我的排障上下文检查卡

[ ] 我先确认了是否需要止损和保护现场
[ ] 我写清楚了问题摘要、时间、环境和影响
[ ] 我分别描述了预期行为和实际行为
[ ] 我提供了时间线和最近变更
[ ] 我提供了成功与失败的对照样本
[ ] 日志、参数和代码已经完成脱敏
[ ] 我给出了相关代码,而不是整个仓库
[ ] 我区分了事实、现象和待验证假设
[ ] 我让 AI 先列原因,再设计验证动作
[ ] 我要求 AI 标出不确定性和缺少的上下文
[ ] 我没有让 AI 直接执行高风险生产操作
[ ] 我记录了验证结果和后续修复

如果这张检查卡只完成了“复制报错”,那还不算完成排障上下文。

十三、总结

不要把报错直接丢给 AI。

一条错误信息只能告诉 AI:

某个地方出现了异常

而正确的排障上下文,需要进一步说明:

  1. 什么时候发生。
  2. 在什么环境发生。
  3. 影响了什么功能和用户。
  4. 预期行为与实际行为是什么。
  5. 失败前后系统做了什么。
  6. 最近发生过哪些变化。
  7. 哪些事实已经确认。
  8. 哪些原因还只是猜测。
  9. 下一步如何低风险验证。

我最常用的排障节奏是:

先保护现场
  ↓
再整理事实
  ↓
提供最小上下文
  ↓
让 AI 列出假设
  ↓
设计验证动作
  ↓
根据结果收敛根因

请记住:

好的排障 Prompt,不是让 AI 更快猜出答案,而是让错误的答案更快被证据排除。

下一篇文章,我们进入测试阶段:

AI 辅助写单测:如何覆盖边界,而不是凑覆盖率。

如果这篇文章对你有帮助,欢迎点赞、收藏、关注专栏。
也欢迎在评论区留言:你排查线上问题时,最容易缺少日志、时间线,还是成功与失败的对照样本?


✍坚持原创,求关注,点赞,收藏