开篇
遇到线上报错时,很多人的第一反应是把错误信息复制给 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:32 | 10:20:14 |
| 参数特征 | 1 个商品、无优惠券 | 3 个商品、有优惠券 |
| 库存响应 | 120 ms | 2,030 ms |
| 支付响应 | 成功 | 超时 |
| 最终结果 | 201 | 500 |
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:
某个地方出现了异常
而正确的排障上下文,需要进一步说明:
- 什么时候发生。
- 在什么环境发生。
- 影响了什么功能和用户。
- 预期行为与实际行为是什么。
- 失败前后系统做了什么。
- 最近发生过哪些变化。
- 哪些事实已经确认。
- 哪些原因还只是猜测。
- 下一步如何低风险验证。
我最常用的排障节奏是:
先保护现场
↓
再整理事实
↓
提供最小上下文
↓
让 AI 列出假设
↓
设计验证动作
↓
根据结果收敛根因
请记住:
好的排障 Prompt,不是让 AI 更快猜出答案,而是让错误的答案更快被证据排除。
下一篇文章,我们进入测试阶段:
AI 辅助写单测:如何覆盖边界,而不是凑覆盖率。
如果这篇文章对你有帮助,欢迎点赞、收藏、关注专栏。
也欢迎在评论区留言:你排查线上问题时,最容易缺少日志、时间线,还是成功与失败的对照样本?
✍坚持原创,求关注,点赞,收藏