"导出已修好,还得检查",工作就停在了这里。第二天您打开项目,却不知道改了哪些文件、导出检查的是哪个版本,也不知道检查进行到哪一步。

要继续工作而不必从头调查,下一阶段需要已保存的结果、检查情况和紧接着要做的事。我们用一个任务来看交接怎么写:它可以由一个会话、多个执行者负责,也可以由您自己分两次完成。

交接一份可以打开的结果

购物清单应用的 CSV 导出出了问题。要求是:导出的内容只包含当前显示的行,并保持它们在屏幕上的顺序。列表为空时,双方约定保留标题行,不包含数据行。列格式和分隔符都不改。

我们不只写一句"修好了,还得检查",而是留下一份记录,凭它就能找到改动并继续工作。下面的哈希和结果都是虚构的教学示例,没有对应的真实运行记录。

HANDOFF
目标:CSV 只包含当前显示的行,并保持现有顺序。
输入版本:基础 commit 4f1c2ab。
交接状态:分支 fix-export 上的 commit 9d3e740,没有额外改动。
结果:src/export-csv.js - 导出使用筛选和排序后的列表。
在 9d3e740 上手动检查:原始记录 A、B、C;屏幕上显示 C、A;
  CSV 数据行是 C、A,不含记录 B。标题行不算记录。
尚未检查:空列表;"仅未完成"模式。
决定:列格式和分隔符保持不变。
下一步:主会话检查剩下的两个场景。
整体任务状态:检查尚未完成。

字母代表列表中的三条记录。这个场景同时检查两件事:隐藏的记录 B 没有出现在导出结果中,C、A 的顺序也与屏幕上一致。如果列表中本来就只有两条记录,导出两行并不能证明筛选有效,因为不做筛选也会得到同样的结果。

您可以把记录保存在 HANDOFF.md 中,也可以追加到现有的任务文档里。字段没有强制标准。重点是,下一位执行者能连同相关文件一起打开这份记录,即使无法查看之前的对话也能继续。

如果检查是通过命令完成的,请记下命令、实际结果和代码版本。"12 项全部通过"并没有说明检查了什么行为。手动场景则需要记录输入数据、操作和观察结果,就像上面的例子一样。

让 Claude 整理交接记录

可以让 Claude Code 起草记录:"根据当前文件和已完成的检查整理交接。区分事实和推测。写明检查的是哪个状态、还剩什么,以及接下来从哪里继续。不要把尚未执行的检查说成已经通过。"使用之前,请将版本与文件核对,并将结果与手动检查记录或命令输出对照。

设定输入和输出条件

交接的作用,是让下一阶段判断收到的信息是否足够。对这个任务来说,可以用三行说明。

阶段输入输出验收条件
澄清要求和当前文件附有代码位置的故障原因、预期行为明确导出哪些行、顺序如何,以及空列表时如何处理
修改已确认的行为和输入版本导出改动,以及本地检查记录可以访问保存的状态,列出已修改文件,并区分已检查和未检查的内容
检查交接的状态和测试场景每个场景的观察结果、限制和问题结果对应交接的版本;每个场景都有结论,每个问题都注明下一步

这里最重要的是最右边一列。交接到检查阶段时,它回答的是"可以开始检查了吗?"这个问题。即使改动描述得很完整,也仍可能是错的。检查结束后也可能发现问题,需要退回修复:一份有用的报告不一定要宣布成功。

如果没有写明版本,先确认文件的当前状态。可以检查这个状态,但不能未经核对就把旧报告套用到它上面。阶段也不必对应不同的智能体或文档:小任务完全可以由同一个会话用一份记录走完三个阶段。

保留已确认的状态

交接时,很容易把三件不同的事混为一谈:

  • 已保存的代码状态 - 可以恢复到的具体版本;
  • 工作进度记录 - 做过什么、检查了什么、达成了哪些约定;
  • 结果验收 - 判断已完成的工作是否足以达到目标。

commit 指向其中保存的文件。但如果 commit 之后还有额外改动,这个引用就无法描述完整的交接状态:这些改动也要保存并单独列出,新文件也不例外。交接一组改动时,还要说明比较它们所依据的初始版本。只写分支名不够,因为分支还会继续变化。

想象一下:记录中写着 9d3e740,但导出文件后来又改过。接手的人看到熟悉的哈希,却要面对不同的代码。首先得查清改了什么。如果改动影响了行的筛选或顺序,先前 C、A 的检查结果就不能证明当前行为正确。如果只改了注释文字,本身并不构成重跑场景的理由。

不必每做一步就创建一个 commit,也不必把自己和其他人的改动合并到一个 commit。关键是交接的状态完整存在,而且接手的人能访问;如何保存由项目规则决定。如果文件不在原处,先检查保存的版本。如果改动没有保存在任何地方,一份记录也无法把它们恢复出来。

恢复对话本身并不会让文件回到描述中的版本。Claude Code 的编辑检查点也不包含所有改动:通过 Bash 做的修改不会被追踪,恢复其他执行者所做改动也有限制。因此交接要依靠已保存的文件及其版本。更多说明:Checkpointing。

查明工作为什么中断

"没成功"至少可能指三种不同情况。

本地运行被中断。命令没有结束,或者检查进行到一半就停了。先弄清楚已经执行了什么、改动了什么。如果原因已解决,而且重试不会重复已完成的操作,就可以重做未完成的步骤。这个例子里,我们约定只重试一次;如果又中断,就记录停止原因和继续工作所需的信息。重试次数取决于操作本身,无限重试并不能解释问题。

预期行为不明确。例如,执行者不知道启用筛选后哪些行才算显示出来。先核对写下来的要求;如果里面没有答案,就向负责确定要求的人提出具体问题。得到答复后才能继续修复,重新运行并不能代替答复。

新事实推翻了已确认的决定。后来发现 CSV 会被另一个程序读取。澄清之后,双方同意使用不同的列,而顺序要求也取消了。工作要退回澄清阶段:记录新的标准,并重新评估依赖该标准的改动和检查。之前通过的场景仍可能有参考价值,但已不能证明更新后的整个任务都符合要求。

三个阶段依次推进;新事实会让工作退回到作出已被推翻决定的阶段澄清原因和标准修改改动和运行检查事实和问题新事实推翻了已确认的决定
本例需要重新评估澄清阶段的决定,以及依赖该决定的结果

这里要退回澄清阶段,是因为最初的决定变了。如果要求没有变化,只是在实现中发现错误,退回修改阶段就够了。需要重新评估的是依赖受影响决定的结果。

从当前进度继续

恢复工作时,可以按这五步来:

  1. 完整阅读交接记录,包括尚未检查的内容;
  2. 将交接的状态与当前可用文件及额外改动核对;
  3. 如果有操作被中断,查明它的实际结果;
  4. 判断之前的哪些结果仍然有效;
  5. 完成下一个尚未完成的步骤,并更新记录。

回到最初的例子,要求并没有变化。下一个会话打开交接记录并核对状态:commit 9d3e740 可以访问,没有额外改动,数据和检查条件也都没变。C、A 场景已经完成,结果仍然适用,不必重新编写修复。

现在由接手的人检查空列表。按任务要求,CSV 应保留标题行,不含数据。在这个教学示例的后续中,实际结果正是如此。只需把检查结果补进记录,并更新剩下的步骤:

在 9d3e740 上手动检查:导出空列表时只包含标题行。
之前检查的 C、A 场景仍然有效。
尚未检查:"仅未完成"模式。
下一步:主会话检查此模式。
整体任务状态:检查尚未完成。

交接记录也随着工作进展而更新。两个剩余场景中已经完成一个,另一个仍列在记录里。部分结果并没有达成最初的目标;若要把检查移到另一个任务,需要另行决定是否调整范围。

如果运行中断,可能需要从头重做被中断的场景:并非每种工具都支持从中途继续。只要代码、输入数据和条件仍然一致,之前已完成的检查依旧有效。

重试前,先查明会有什么后果

即使没有收到结果响应,操作也可能已经执行。在重试发送数据、发布内容或写入文件之前,先确认操作是否已经发生。执行位置不能保证不会重复:本地命令也可能再次添加相同的数据。结果尚不明确时,重试不能替代状态检查。

由谁准备交接

Claude Code 可以收集事实、核对下一阶段的输入,并执行已经确认的步骤。您需要检查记录是否与文件和运行结果相符。有争议的要求和范围变更由人或指定的负责人决定;在我们的流程中,最终验收仍由人来做。

保存的版本能帮助继续工作,却不会扩大执行者的权限。如果交代的任务是检查导出,有恢复点也不代表可以顺手改动列格式。交接之后,任务边界依然有效。