写给 agent 的故障报告:目标不是描述清楚,而是一次修好
给人写的报告目标是让人理解,给 agent 写的报告目标是让它一次修好、不返工。本指南把故障报告升级为修复规格:六个必备部分、证据的正确用法、可验证的预期行为、五种返工写法,以及可直接套用的模板。

先说结论:写给 agent 的故障报告,目标不是“描述清楚”,而是“一次修好”
给人写的故障报告,目标是让人理解问题;给 agent 写的故障报告,目标是让 agent 一次就把问题修好、不返工、不改出新问题。这两个目标听起来接近,做法却完全不同。人看到“登录有时候失败”会主动追问、会自己去复现、会在脑子里补全缺失的信息;agent 看到同一句话,会直接按它自己的猜测动手——猜对了是运气,猜错了就是一次返工,外加一段本来没问题的代码被改坏。
所以这篇指南的核心主张是:故障报告要从“问题描述”升级为“修复规格”。一份合格的报告应该让 agent 在不动手之前就知道:问题是什么、在哪里复现、预期行为是什么、哪些地方绝对不能动、修完之后怎么证明修好了。缺了其中任何一项,agent 都不得不在猜测中工作,而猜测正是返工的源头。
边界说明:这篇指南不是什么
先把边界划清楚,避免拿错文档。这篇指南讲的是“已经发现了一个具体故障,如何写一份报告让 agent 一次修好”——对象是一个故障,动作是写报告,终点是修复被验证通过。它不是任务验收清单:验收清单管的是一个任务从开始到交付的全流程(需求、实现、测试、文档、发布齐不齐),本篇只管其中“修故障”这一个环节的输入质量;验收清单可以告诉你“修故障的任务算不算做完”,但它不会告诉你“报告里该写哪几项才能让 agent 一次修好”。
它也不是用户反馈分流指南:反馈分流管的是“收到一堆用户反馈之后,怎么分类、排优先级、分给谁”,是面向反馈流量的管理动作;本篇管的是“分流之后、动手之前,单个故障的报告怎么写”,是面向单个故障的写作动作。两者接力关系,不是替代关系——分流分得再好,报告写得含糊,修复还是会返工;报告写得再好,分流分错了人,修复也会走弯路。同样,它也不是故障复盘指南:复盘问的是“为什么会出这个故障、流程上怎么改进”,本篇问的是“现在怎么把这个故障修好”,时间方向不同,不要混用。
一份报告的六个必备部分:缺一不可
第一,标题:一句话说清“谁、在什么操作下、遇到了什么”。反面例子:“登录有问题”。正面例子:“已登录用户在个人设置页点击保存后,页面报错且修改未保存”。标题的检验标准是:只看标题,一个不了解背景的人能不能猜出故障的大致位置?猜不出,标题就不合格。标题不是摘要,是定位的第一线索。
第二,复现步骤:按顺序写出从“正常状态”到“故障出现”的每一步,包括前置条件。关键是写出“最小复现”:如果去掉某一步故障就不出现,那一步就是关键步骤,要标出来;如果某一步可有可无,就删掉它。复现步骤里必须包含具体的输入值——不是“输入一个邮箱”,而是“输入 test@example.com,密码留空,点击登录”。agent 无法复现的故障,几乎必然修不对,因为它连问题长什么样都不知道。
第三,实际结果与预期结果:并排写,越具体越好。实际结果要写“看到了什么”:报错文案原样贴出来、页面状态描述出来、返回码写出来;预期结果要写“应该看到什么”:不是“应该正常”,而是“应该显示保存成功提示,且刷新后修改仍然存在”。预期结果写得越具体,agent 的修复目标就越清晰;预期结果写成“应该正常工作”,等于没写。
第四,环境与版本:操作系统、浏览器或 App 版本、后端版本、数据状态(新账号还是老账号、有没有特殊数据)。很多“在我机器上能复现、在你机器上不能”的故障,根源就是环境差异没写清楚。写环境时有一个原则:写到“换一个人、换一台机器,按这份报告能复现出来”为止;达不到这个标准,环境部分就是没写完。
第五,影响范围与紧急程度:影响了多少用户、是不是阻塞主流程、有没有 workaround。这一项决定了 agent 修复时的策略:阻塞主流程的故障,修复要优先保证“先恢复”,可以接受临时方案;非阻塞的边缘故障,修复要优先保证“不引入回归”,宁可慢一点、稳一点。没有影响范围,agent 就无法判断该用“快而糙”还是“慢而稳”的策略。
第六,绝对不能动的地方:这是最容易被省略、也最重要的一项。明确写出“修复时不要改动某某模块、不要改动某某接口的返回格式、不要为了修这个而重构某某部分”。agent 没有业务上下文,它不知道哪段代码是“看着别扭但绝对不能动”的历史遗留,也不知道哪个接口的返回格式被外部系统依赖。不写这一项,就等于默许 agent 为了修一个小故障而重构半个系统——而重构引入的新问题,往往比原故障更难查。
证据怎么给:日志、截图、录屏,各自的正确用法
证据不是越多越好,而是越“能定位”越好。日志要给完整的错误堆栈,而不是只截最后一行——最后一行往往是“某某异常”,真正的原因藏在堆栈中间的某一帧。给日志时要标注时间点和触发操作,让 agent 能把日志行和复现步骤对上号;一堆没有时间标注的日志,agent 只能猜哪几行和这次故障有关。
截图的价值在于“页面状态”:报错时的完整页面、控制台的错误信息、网络请求的返回。截图时不要只截报错弹窗,要把地址栏、页面上下文一起截进去——弹窗本身往往信息最少,上下文才是定位的关键。录屏的价值在于“操作序列”:当故障依赖于一连串操作的顺序、或者只在特定操作节奏下出现时,录屏比文字复现步骤更可靠。录屏时要放慢操作速度、把每一步的停顿留出来,让看的人能跟上。
还有一类证据经常被忽视:对比证据。如果这个功能以前是好的,找出“从什么时候开始坏的”——最近一次正常的时间、最近一次相关的代码变更、最近一次发布。这类证据能把排查范围从“整个系统”缩小到“某一次变更”,对 agent 来说价值极大。写报告时如果知道这些信息,一定要写;不知道,也要写一句“最后一次正常的时间未知”,让 agent 知道这条线索是缺失的,而不是默认它不存在。
怎么写“预期行为”:从“应该正常”到“可验证的断言”
预期行为是整份报告里最容易写含糊的部分,也是返工的最常见源头。把“应该正常工作”升级为“可验证的断言”,有三个具体方法。第一,写出具体的输出:不是“应该保存成功”,而是“点击保存后页面显示‘已保存’,刷新页面后修改仍然存在,数据库里对应字段的值已更新”。第二,写出边界情况:正常情况之外,空值、超长输入、特殊字符、并发操作分别应该怎样?如果这些边界情况的预期行为你自己也不确定,就在报告里标出来“边界行为待确认”,而不是让 agent 自己猜。第三,写出“修完之后怎么验证”:列出验证步骤,比如“按复现步骤重走一遍,确认报错消失;跑某某测试套件,确认全部通过;检查某某日志,确认没有新的错误”。
验证步骤还有一个重要作用:它给了 agent 一个“完成标准”。没有完成标准,agent 只能凭感觉判断修好了没有,感觉对了就交、感觉不对就继续改——前者可能交出一个没修好的版本,后者可能把本来好的地方越改越糟。有了验证步骤,agent 每改一轮都可以自己跑一遍验证,改到验证通过为止,返工的循环就有了出口。
这里要提醒一个常见的误区:不要把“猜测的原因”写进预期行为。比如不要写“应该是数据库连接池的问题,修一下连接池”——原因猜测是 agent 的工作,不是报告的工作;报告的工作是把现象和预期说清楚,让 agent 自己去定位原因。把猜测写成结论,只会把 agent 引向错误的方向,而且一旦猜错,agent 还会因为“报告就是这么说的”而不敢质疑。现象归报告,原因归排查,这个分工不能乱。
常见反模式:五种让 agent 返工的写法
第一种,情绪代替信息:“这个功能完全不能用”“太糟糕了”。情绪不能定位问题,也不能指导修复,写进报告只是占用 agent 阅读注意力的噪音。第二种,多个故障写进一份报告:“登录有问题,而且个人页加载也很慢,顺便搜索也有点怪”。一份报告只讲一个故障;三个故障就是三份报告,混在一起的结果是 agent 修了一个、漏了两个,或者三个都没修彻底。第三种,只有结论没有过程:“保存失败了”。没有复现步骤的报告,agent 只能靠猜测复现,猜不对就修不对。
第四种,假设 agent 知道背景:“还是那个老问题”。agent 没有你的记忆,它不知道“那个老问题”是哪一个、当时是怎么修的、为什么又复发了。背景信息必须写进报告,不能依赖“你应该知道”。第五种,把多个可能原因都列出来让 agent 自己选:“可能是 A,也可能是 B,还可能是 C”。这不是严谨,是推卸——报告的责任是把现象钉死,排查的责任是 agent 的;把现象之外的猜测都列出来,只会让 agent 在三个方向上各试一半,最后哪个都没试透。
对照这五种反模式自查一遍你的报告,是写报告之前最值得花的两分钟。很多返工不是 agent 能力问题,而是报告在第一步就把 agent 推向了错误的方向。
一个可直接套用的模板
标题:[谁]在[什么操作]下[遇到什么]。复现步骤:前置条件、按顺序的每一步、最小复现标注。实际结果:报错文案原文、页面状态、返回码。预期结果:具体输出、边界情况、验证步骤。环境:系统、版本、数据状态。影响范围:影响用户数、是否阻塞主流程、有无 workaround。绝对不能动:模块、接口、返回格式的清单。证据:日志堆栈、截图、录屏、最后一次正常的时间。把这个模板存下来,每次写报告时照着填,填不出来的项就标“未知”而不是空着——“未知”本身也是一种信息,它告诉 agent 这条线索需要它自己去补,而不是默认不存在。
最后说一句:写故障报告不是文书工作,是修复工作的一半。一份好的报告能让一次修复就成功,一份差的报告能让三次修复都白费。时间花在写报告上,永远比花在返工上便宜——因为返工的成本不只是 agent 的时间,还有被改坏的代码、被拖延的发布、和被消耗掉的信任。把报告写好,再让 agent 动手,这个顺序不能反。
给不同角色的写法差异:用户、测试、开发各写什么
同一份模板,不同角色填出来的重点不一样,提前说清楚能省掉大量来回追问。用户或客服写报告时,重点是“现象”和“复现”:你做了什么、看到了什么、能不能稳定复现——不需要猜原因,也不要写技术推测;一张报错截图加三步复现路径,比一页技术分析更有用。测试人员写报告时,重点是“覆盖面”:除了主路径,边界值、异常输入、不同环境下是否都复现?有没有已经确认“好的版本”可以对照?测试报告的价值在于帮开发和 agent 缩小排查范围,而不是只证明“确实有问题”。
开发人员自己写报告(比如把故障交给 agent 或同事修)时,重点是“约束”和“证据”:已经排查到哪一步、排除了哪些可能、哪些模块绝对不能动、相关的代码位置和最近的变更记录。开发写报告最容易犯的错是“写得太像技术笔记”——满篇都是排查过程,却没有一句清晰的预期行为和验证标准。记住:报告的读者是“要动手修的人”,不是“要了解你排查过程的人”;过程可以附在后面当参考,但前面必须先有现象、复现、预期、约束这四项。团队可以在故障模板里给不同角色预设不同的必填项:用户必填现象与复现,测试必填覆盖面与对照版本,开发必填约束与证据——同一份模板,三种必填组合,报告质量会立刻上一个台阶。
还有一个跨角色的通用规则:报告写完后,自己先按“陌生人测试”读一遍——假设读者完全不了解这个项目、没参与过这个功能的开发,只凭这份报告能不能复现、能不能判断修没修好?如果不能,缺的那一项就是你要补的。很多报告的问题不是写作者不用心,而是写作者默认读者知道背景;陌生人测试正是用来打破这个默认的。每次写完花两分钟做这个测试,返工率会肉眼可见地下降。
最后补一个容易被忽视的细节:报告里的“时间”要写清楚。故障第一次出现的时间、最近一次复现的时间、以及“最后一次正常”的时间,这三个时间点能帮排查者把范围缩小到某一次发布或某一次变更之间。很多报告只写“今天发现的”,却不写“上周是否正常”——而“上周正常、本周坏了”本身就是一条极有价值的线索,它意味着排查可以从“最近一周的变更”开始,而不是从整个系统开始。写报告时养成习惯:现象、复现、预期、约束之外,再加一行时间线,排查效率会立刻不同。
一句话总结:报告写到“陌生人能复现、agent 能一次修好、修完能验证通过”这个标准,再提交;达不到,就先补报告再动手。
附注:模板里的每一项填不上时请写“未知”,不要留空。
评论 (0)
相关文章

模型写代码是按概率拼出最像正确的代码,而不是按理解推导正确的代码——错误往往藏在完全正确的语法里。本指南给出合并前四步:先读 diff、跑模型没跑过的路、查安全与隐私、问三个关于未来的问题,附可直接贴进 PR 模板的速查表。

自动保存保住的是最新版,回收站装的是删掉的东西,备份恢复的是整个系统——它们都回答不了“回到两小时前”。本指南为 vibe 项目做一套文件版本历史:版本模型、产生策略、对比与恢复铁律、分层保留与权限设计,附可直接验收的用例清单。

密钥不出事时只是字符串,出事时却是能刷爆账单的通行证。本指南不讲密钥存放,只讲定期换血与出事止血:双活窗口轮换六步、泄漏分级与十五分钟时间线、不支持双活的短窗口切换法,以及四十五分钟泄漏演练剧本。