用途
该技能解决的核心问题是:当同一套昂贵流程需要逐项处理大量条目,而方法本身仍可能出错时,不要逐项端到端地跑完整批任务。串行执行会带来最坏处境——在第 3 个条目上发现缺陷时,只能在“用已知有误的方法继续完成”和“丢弃已完成的工作”之间二选一,两者都无法挽回。
何时使用
- 同一昂贵流程需要在许多条目上运行,且大部分成本来自无法脚本化的逐项智能体工作。
- 方法仍可能出错,而条目正是揭示错误的方式。
- 某个步骤会消耗不可逆资源。
何时不使用
- 只有一两个条目——检查点没有可摊销的对象。
- 逐项工作足够廉价,重做整批可以承受。
- 方法已在此类条目上验证过;该批是生产而非探索。
- 不消耗任何不可逆资源,也没有昂贵的逐项工作。直接运行即可。
所需输入
- 在任何条目被处理之前就固定下来的条目列表。
- 按顺序排列各步骤的逐项流程。
- 所有条目共享的方法或工具。
操作步骤
-
列出不可逆资源。 列出工作中消耗后无法撤销的内容。典型包括:全新的随机种子与留出数据(观察它们会污染同一抽取的后续使用)、一次性 API 或算力配额、已发布或对外可见的输出、人工审阅者的首次阅读,以及任何会制约后续决策的观察。该列表可以合法地为空:仅成本来自昂贵逐项工作的批次仍符合条件。应如实记录为空,而不是编造条目,并将其带入第 2 步。
-
找到拆分点。 可逆阶段结束于第一个触及第 1 步所列内容的步骤——或者当该列表为空时,结束于第一个其逐项成本导致重做整批变得昂贵的步骤。在此之前的一切都可以自由重做。
-
建立机械停止点,而非规则。 添加一个标志、子命令或模式,使其运行可逆阶段并在第一个不可逆步骤之前返回。仅靠书面纪律不够:如果到达门禁的唯一方式是越过它,那么该结构就无法按设计执行,也不会被执行。
-
对每个条目运行可逆阶段。 不是抽样。检查点看到的该方法可能出错的方式数量,恰好等于条目数量。
-
输出逐项门禁报告。 对每个条目机械地判断:不可逆阶段能否产出可用结果;若不能,是哪个具体要求未通过。包含一个断言字段,声明未触及任何不可逆资源。最小记录形态参见 references/gate-report.md;仅当该格式无法承载本批的停止原因时才另创格式。
-
在所有报告齐备后,一次性进行方法冻结检查点。 记录决策、其依据,以及其重新冻结范围——即若该决策日后被推翻,哪些条目必须重做。不同候选变更的范围通常差异很大;记录一条笼统的“此处任何变更都重启一切”会掩盖这一点,使廉价变更看起来和昂贵变更一样昂贵。
-
仅在检查点之前按条目适配。 这是适配唯一合法的地方。此后,为挽救某个特定条目而适配,会使结果以结果为条件。
-
对通过门禁的条目运行不可逆阶段。
验证
- 门禁报告对每个条目携带一个可机器检查的断言,声明未消耗任何不可逆资源(如 held_out_accessed: false 或等价形式)。当第 1 步列表为空时,等价断言是昂贵阶段从未被进入。仅用文字承诺不算检查。
- 在不可逆阶段开始前,每个条目都有终态:通过,或以具名原因停止。
- 检查点决策在不可逆阶段运行之前连同其依据一并写下。如果依据无法在不引用不可逆阶段结果的情况下陈述,则说明检查点尚未被采取。
- 故意对一个预期会失败的条目运行门禁。一个对实际无效的工作报告成功的门禁,比没有门禁更糟,因为该报告随后断言了一个从未发生的检查。
常见失败模式
- 把门禁停止读作条目失败。 它是关于方法的结果。半批条目因同一要求而停止,是门禁能产出的最有信息量的东西;把这些条目转成低分会毁掉这一发现。
- 对预期会停止的条目做敷衍工作。 通过薄弱尝试得到的停止证明不了任何东西。对每个条目保持同一标准,尤其是那些预测会失败的。
- 抽样而非全覆盖。 在 7 个条目中只对 2 个运行可逆阶段,得到的检查点只看到了 7 种失败模式中的 2 种,而检查点成本几乎相同。
- 因为“我会小心”而跳过机械停止点。 你会越过它。
- 一旦停止使修复变得方便就修复方法。 检验标准是:该缺陷是否能在不引用它所挽救的那个条目的情况下被论证。无论哪种情况都要披露顺序:在看到它挽救哪个条目之后所做的修复,其证据强度弱于在之前所做的同样修复。
- 把检查点并入运行过程。 如果在不可逆阶段已在执行时才做决策,其重新冻结范围就不可知,冻结也就不成其为冻结。
输出
- 逐项门禁报告,每个条目一条记录,带有未访问不可逆资源的断言。
- 一份书面的检查点决策,携带其依据与重新冻结范围。
- 仅对通过门禁的条目执行不可逆阶段,停止的条目按其原因保留在记录中,而不是从记录中删除。