ACDL研发流程07:把设计拆成可以独立验证的任务

ACDL研发流程系列第7篇,共15篇。

上一篇:ACDL研发流程06:共同完成产品与架构设计

下一篇:ACDL研发流程08:让多个Agent在不同worktree工作

已经确认的设计还不是Agent可以直接执行的任务

经过需求管理和产品与架构设计,Director和Agent已经知道为什么要改,也共同确认了系统应该怎样工作。但一份已经确认的设计通常会同时涉及多个用户结果、代码模块和验证方式,它说明的是系统长期应该怎样工作,不是当前这一轮工作的大小。

如果只对Agent说“按设计把收藏会话做完”,它需要自己决定从哪里开始、这一次做到哪里、先处理哪些风险,以及什么证据才能说明已经完成。任务过大时,Agent可能在长时间实施中丢失目标;任务过碎时,又会留下一组单独通过测试、合在一起却不能工作的局部结果。

启动ACL之前的任务,就是把已经确认的设计变成一个或几个边界清楚、能够独立验证的实施目标。

先认识ACL(Agentic Coding Loop)

ACL的全称是Agentic Coding Loop,是由Agent主导的开发Loop。Agent读取已经确认的需求和设计,调查当前代码,实施改动,补充测试,运行验证,并记录真实结果。Director负责确认本轮的目标和边界,处理需要人作出的取舍与授权,并在最后判断这轮工作能否结束。

一轮ACL不是一次Prompt,也不是一个Git提交。Agent可以在其中经历很多次“调查—修改—测试—讨论”的短循环,也可以产生多个逻辑清楚的提交。只要这些工作仍在完成同一个独立目标,就没有必要为每一次Agent对话或每一个代码步骤新建ACL。

ACL也不是ACDL的缩写。ACDL是当前项目完整的研发体系,ACL只是其中把已确认改变变成代码和自动化验证的一种Loop。

第一步:判断是否真的需要拆分

拆分不是默认动作。如果一项改变范围不大,Agent能够在一轮能够持续理解的范围内完成端到端实施,而Director也能一次看懂完整差异和验证结果,用一轮ACL完成往往最清楚。

当出现以下情况时,才需要考虑拆成多轮ACL:

  • 一轮工作包含多个可以分别使用、分别验收的结果;
  • 任务大到Agent难以在一份启动方案和当前摘要中持续保持准确上下文;
  • 部分改动的数据、安全、迁移或发布风险明显不同,需要分开验证和停止;
  • 前一个结果能够形成已经确认、并且在并行期间不会变化的接口或数据结果,后一个结果可以从这个新起点单独开始;
  • 不同结果确实可以由不同Agent独立推进,无需彼此等待尚未定稿的结论。

文件多、预计代码行数多或可以分给多个Agent,都不是单独的拆分理由。先看能否形成可验证结果,再谈任务数量。

第二步:按结果拆分,不按代码层拆分

一个好任务要能回答:完成以后,系统新增了什么可以被证明的结果?

以收藏会话为例,如果完整改动在一轮ACL中仍然容易理解和验证,可以直接实现:

员工可以收藏和取消收藏自己有权访问的会话,重新登录后收藏状态仍然保留,并且能够在会话列表中找回它们。

如果这个目标已经太大,可以拆成两个用户结果:

1.员工可以收藏和取消收藏自己有权访问的会话,收藏状态能够持久保留。
2.员工可以在大量会话中筛选收藏内容,失去访问权或已删除的会话不会由此重新暴露。

这两项有明确依赖:第二项依赖第一项已经形成稳定的收藏含义和数据结果,因此可以拆开,但不应为了并行而同时开始。

下面这种拆法看上去容易分工,却不是三个可独立验证的任务:

  • 一个Agent只建表和写数据访问;
  • 一个Agent只写接口;
  • 一个Agent只做页面按钮和交互。

每一部分都要等待其它部分才能证明用户结果,契约还可能在三个Agent实施时继续变化。这些更适合成为同一轮ACL中的实施步骤,由一个Agent维持端到端上下文。

第三步:先想清楚怎样验证,再决定任务怎样拆

“可以独立验证”不是要求每个任务都能单独发布给用户,而是在它结束时,Director和Agent能够用实际证据判断目标是否达成。检查一个候选任务时,先试着写出它的验证方法:

  • 什么正常结果能证明它已经完成;
  • 哪些失败、权限、并发、数据或恢复风险必须用测试或实际操作检查;
  • 用单元、契约、集成、迁移、构建、浏览器或实际环境中的哪些方法取得证据;
  • 完成后留下的结果能否作为下一项工作的可靠起点。

如果一个任务只能写成“完成后与其它任务一起验证”,它很可能只是一个实施步骤。如果一个任务要同时使用十几种验证方式,而任何一组失败都会把整轮工作拉回起点,则需要再看它是否包含多个可分开的结果。

有些工作没有立即可见的用户界面,也能独立验证。例如一次数据迁移可以用输入拒绝、前后数据对照和回退演练证明,一项不改变对外行为的主线维护可以用定点测试和完整检查证明。重点是结果能被判断,不是每个任务都要变成一项新功能。

第四步:登记ACL,分别记录身份和版本关系

对于一项新需求,设计确认以后,Director还要决定是否准备实施,以及它当前准备服务哪个目标版本。确定后,REQ填写目标版本并进入已排期。目标版本只表示当前准备把这项工作放入哪次交付,不表示它已经完成,也不是不可改变的承诺。

之后,每个准备开始的独立任务登记一轮ACL。现行ACL统一使用ACL-六位编号。编号只表达身份,一经使用不回收、不复用;计划版本和实际纳入版本另用字段记录。排期变化时更新版本关系和原因,不修改ACL编号,也不为同一轮工作机械重建ACL。

当前项目提供命令帮助分配下一个ACL编号,同时新建登记表条目和实施记录:

1
2
pnpm loop:new -- --version=未确定 --title=主题 --source=工作来源 --goal=本轮目标 --dry-run
pnpm loop:new -- --version=未确定 --title=主题 --source=工作来源 --goal=本轮目标

启动内容已经准备好、但尚未发生第一次真实执行时,可以增加--ready创建为Ready;不加时会创建为In Progress并记录开始时间。命令只负责生成编号、登记入口和文档骨架,不会替Director判断需求是否已排期、设计是否已确认,也不表示Agent已经获得超出已有边界的授权。--mainline--with-plan已经移除,不应再使用。

第五步:在编码前写好启动方案

启动方案是这轮ACL的工作说明,用来防止Agent在长时间实施中逐渐忘记原始目标。它不需要预测每一处代码改动,但需要让新会话或接手的Agent不依赖原对话也能回答以下问题:

  • 这轮工作从哪项REQ、ISSUE、设计偏差或工程缺口而来;
  • 从哪个分支和完整Git提交开始,开始时已有工作树是什么状态;
  • 本轮要得到什么结果,哪些相关内容明确不做;
  • 以哪些已经确认的设计、ADR,以及环境当前运行的提交、配置和服务状态为依据;
  • 允许改动什么,需要使用哪些数据库、端口、容器、账号或其它外部资源;
  • 准备怎样实施和验证,遇到什么情况必须停下来;
  • 什么证据齐全后才能认为本轮达到完成条件。

非目标要写具体。例如“本轮实现员工个人收藏,不实现收藏文件夹、团队共享和全局搜索”,就比“不扩大范围”更能阻止Agent顺手增加未经设计的功能。

实施步骤可以使用S1S2等稳定编号。每一步写明前置条件、实施范围、完成判定和失败时怎样处理,方便在上下文压缩或新会话中继续。这些步骤是一轮ACL内的进度节点,不会因为有编号就自动变成新的ACL。

每轮ACL默认只有一篇主记录,启动方案、当前摘要、实施与验证、剩余问题和结论依次写在其中。启动方案在第一次真实执行后视为快照;后续变化追加原因和影响,不把最后结果反写成原计划。只有确实需要在执行前单独批准高风险或恢复边界时,才另建计划,不因任务复杂机械拆成两套状态。

第六步:让新会话能够继续当前任务

启动ACL时,不要把过去所有聊天记录和整个文档目录不加选择地丢给Agent。有用的上下文应当让它知道当前决定、真实现状和下一个动作:

1.读取本轮启动方案,确认目标、非目标、停止条件和完成条件。
2.读取相关REQ、已经确认的设计和必要ADR,理解产品行为与技术边界。
3.读取仓库对Agent的工程要求,再定位实际代码、测试、迁移、构建和发布入口。
4.核对当前分支、起点提交、工作树差异和需要使用的外部资源。
5.用自己的话复述本轮目标和预计路径,显示出它对任务的真实理解。

如果Agent不能说清本轮结束时应该看到什么结果,或者现场的Git状态与启动方案不一致,就先查明原因,不立即实施。这一步不是考试Agent,而是在编码前尽早暴露上下文缺口。

什么时候才算ACL已经启动

一轮ACL真正开始时,不只有一个编号,而且具备以下事实:

  • 工作来源和需要遵守的设计依据已经明确;
  • 计划版本已经写明,尚未确定时如实填写未确定
  • 本轮的主记录、启动分支、不会变化的起点提交和已有工作树状态可以追溯;
  • 目标、非目标、实施范围、验证方法、停止条件和完成条件已经写入启动方案;
  • Agent已核对上下文、当前工作树和外部资源,知道下一个要执行的动作。

其中任何一项缺失,就继续补齐准备,不用“先让Agent开始写,后面再补文档”掩盖起点不清。进入这个状态以后,Agent才从第一个实施步骤开始主导这轮ACL。

回头检查这条路径

1
2
3
4
5
6
7
8
已经确认的设计
→Director决定实施和目标版本
→REQ进入已排期
→按可验证结果确定一轮或多轮ACL
→登记ACL并记录起点提交
→写好启动方案
→Agent核对上下文、当前工作树和外部资源
→从第一个实施步骤开始ACL

拆分的目的不是让登记表出现更多编号,而是让每轮工作都有Agent能够持续理解的范围和可以判断的结果。一轮ACL启动后,如果还有其它能够独立推进的任务,就可以进一步判断它们是否适合由多个Agent在不同worktree中并行开发。