ACDL研发流程09:完成代码、验证并更新环境
ACDL研发流程系列第9篇,共15篇。
Agent写完代码只是实施的中间状态
进入这一章时,一轮ACL(Agentic Coding Loop)已经有明确目标、已经确认的设计、起点提交、启动方案和核对过的工作树。Agent现在可以主导实施,但它要交付的不是“已经修改了若干文件”,而是一个能够被证明、被评审、必要时能安全进入环境的结果。
Agent生成代码的速度很快,真正限制研发速度的往往是判断和验证:它是否理解了正确问题,是否在未经确认的地方自行作出了决定,测试是否真的覆盖风险,以及这些修改在真实环境中能不能正常工作。
因此,本章不把“编码”和“测试”看成前后两个大阶段。Agent会在很多次短循环中实施和验证,直到范围内的目标完成并取得相应证据。
第一步:从验收场景找出最容易出错的地方
实施前,Agent先从REQ的验收场景和已经确认的设计出发,列出这次改动最容易出错的地方。这份风险判断会决定要查哪些代码,以及后面需要什么测试,不按前端、后端和数据库等目录机械列工作量。
以收藏会话为例,除了页面上有一个可以点击的入口,Agent还要考虑:
- 收藏、取消收藏和重复操作得到什么结果;
- 刷新和重新登录后,收藏状态是否仍然保留;
- 员工失去会话访问权或会话被删除后,数据和页面怎样变化;
- 两次请求同时到达时,是否会生成重复关系或错误状态;
- 存储、接口或页面失败时,员工看到什么,系统能否恢复;
- 新数据结构怎样迁移,发布失败后怎样回到可用状态。
任务范围不同,需要关心的风险也不同。纯文档修正不需要虚构并发和恢复场景,数据迁移则不能只看类型检查通过。要根据可能发生的错误选择验证方法,不是为了形式完整每次复制同一份清单。
第二步:用短反馈循环推进实施
Agent每完成一个有意义的小结果,就运行与它最直接相关的验证。修改一个纯函数时先运行相关单元测试,改动进程之间的契约时先运行契约和两端映射测试,修改数据状态时使用专用测试库验证迁移、事务和恢复。
一次常见的短循环是:
1 | 读取当前设计和代码 |
短循环的目的是尽早暴露问题。每改几行就运行整套验证会让反馈变慢,等几天后再一次性测试又会让失败难以定位。定点测试是与当前改动最直接相关的检查,用来指导实施;统一验证覆盖更大的受影响范围,用来证明整项修改合在一起以后仍然正常,两者不能互相替代。
验证失败时,Agent先理解错误,不为了得到绿色结果而盲目改测试。如果测试正在拒绝已经确认的设计中明确禁止的行为,就修复代码;如果测试与已确认设计不一致,就更正测试。无法判断谁错时,回到REQ和设计找答案,不让当前实现自动获得优先权。
第三步:让代码、测试和文档一起更新
文档是代码的“源码”,所以实施不是先把代码写完,最后再想起更新文档。Agent每形成一个稳定结果,就检查三种内容是否仍然一致:
- 设计文档说明系统现在应该怎样工作;
- 代码实现已经确认的行为和技术边界;
- 测试在关键输入上证明代码没有削弱这些要求。
设计已经说清、代码只是没做到时,修改代码和测试,不需要为了显示工作完整而改几句无关文档。实施让接口、事务、迁移、错误码、部署或恢复方式形成新的长期约定时,负责该结论的能力设计或横切设计也要同步反映最终答案。
已经编号的稳定设计要求需要长期追踪时,在要求账本登记测试、检查、分析或实机验证方式。测试只有真的能判断某项具体要求是否满足时,才把它记为直接验证;只是主题相关时,保留为支持性证据。不用“有一个相关测试”代替对要求的真正判断。
实施记录也在同一过程中追加。当前步骤、已完成步骤、阻塞事项和下一动作写入“当前摘要”;真实修改、提交、环境、验证结果、失败和跳过项随着工作发生而记录。启动方案保留开始前的决定,不用最后的实际做法反过来改写原方案。
第四步:实施中发现新情况时先分类
代码会暴露设计时没有看到的事实。这不一定表示设计失败,但Agent要先判断新情况属于哪一类,再决定能否继续:
- 私有函数怎样拆、局部变量怎样命名、已有约定下怎样组织局部代码,通常由Agent在实施中决定;
- 实施顺序、定点检查或局部做法需要调整,但本轮目标、范围和已经确认的设计不变时,在实施记录追加方案变更;
- 需要改变某项能力的用户流程、对象状态、接口含义、事务、迁移或长期恢复约定时,暂停受影响实施并回到相应能力设计,产品问题变化时同时回到REQ;
- 需要改变多个能力共同遵守的安全、数据、接口、审计或部署规则时,回到横切设计;
- 需要改变产品定位、核心进程、存储或外部边界时,回到系统设计,并重新判断是否需要ADR。
暂停受影响的部分不等于整轮ACL失败。Agent保留已经取得的事实和证据,Director与Agent更新并确认相关需求和设计后,再根据新确认的设计判断是继续当前ACL,还是调整范围或启动新的ACL。
第五步:完成功能后,再验证整项修改
定点验证可以告诉Agent一个局部改动是否正确,但不能证明它没有破坏其它包、契约、构建或运行入口。当范围内实施和定点回归已经完成,Agent再根据实际差异运行一次统一验证。
统一验证不是一条永远不变的命令清单。它会根据改动范围选择需要执行哪些检查:纯文档要检查结构、状态、追踪和差异格式;普通代码要增加静态、类型、依赖、构建和非数据库自动化测试;数据库、进程、单节点部署和运维变化还需要专用测试库、镜像或对应运行环境。现行工具版本、命令和分类规则从《开发与验证》读取,不在教程中复制一份容易过期的清单。
验证结果要能对应到实际被测内容。工作树干净时,完整提交可以唯一定位代码;还有未提交差异时,只记录HEAD会遗漏真正被测的内容,还要保存能够精确对应已提交、未提交和未跟踪文件的Git树标识。验证过程中如果差异发生变化,这次结果就不能用来证明最后代码。
第一次统一验证失败时,保留失败结果,找到失败阶段和根因,再完成定点修复与回归。根因修复以后只自动重跑一次统一验证;第二次仍然失败就停止并报告,不通过连续重跑等待一次偶然成功。实施记录同时保存首次统一验证是直接通过,还是经过定点修复后通过。
第六步:停止继续修改,重新检查为什么还不能交付
验证通过后,Agent先停止继续增加改动,将实现整理成一个或几个能够单独理解的Git提交,然后重新阅读最后准备交付的完整差异。这次自检不是解释自己为什么这样写,而是尝试找到不能交付的理由。
自检时,把REQ验收场景、已经确认的设计、启动方案、完整差异、测试和实施记录放在一起对照,重点查找:
- 代码是否超出本轮目标,或者遗漏了本轮承诺的结果;
- 实现是否偷偷改变了已经确认的用户行为、权限或数据边界;
- 正常流程、失败、并发、迁移、回退和恢复是否都有与风险高低匹配的处理;
- 测试是否只覆盖了容易通过的路径,以及跳过项是否被错写成通过;
- 文档是否把计划中的结果提前写成了已经发生的事实;
- 调试输出、临时文件、生成垃圾、真实Secret或其它无关差异是否被带入提交。
阻塞问题修复后,重新运行受影响的验证。需要Director确认实施结果或Loop结论的工作,先形成固定候选提交、验证证据和Review记录,不在确认前把候选直接写入目标分支。如果当次评审必须取得远端证据,可以按仓库当前协作方式使用评审分支或Pull Request。
第七步:按需要使用远端CI复验
本地验证会受到工作站操作系统、已安装依赖、缓存和未提交文件影响。仓库当前的Quality Workflow可以在干净的Linux环境中重新检出固定提交,安装锁定依赖,并执行文档、追踪、静态、类型、构建和非数据库自动化检查。它能够发现本机现状掩盖的问题,结果也可以精确对应到远端提交。
远端CI、评审分支和Pull Request都不是每轮ACL的固定门禁。需要在Director确认前取得远端证据时,再按仓库当前托管平台和工作流建立评审入口;不能为了触发检查就提前把待确认结果写入目标分支。
Quality Workflow当前不是进入main前必须通过的检查。只有Director明确要求,或者当前正式发布步骤依赖远端结果时,才把等待它作为当前同步步骤。非强制不表示已知失败可以忽略;远端失败仍要保留结果,并根据失败阶段开展定点诊断。
这项远程复验不使用业务Secret和测试数据库,不构建产品镜像,也不连接或发布任何环境。它通过不能代替真实PostgreSQL测试、镜像检查、容器宿主行为、浏览器验证或环境发布。
第八步:在需要时把结果更新到环境
不是每轮ACL都需要更新环境。纯文档、不影响运行结果的工具修改,以及已经由自动化证明的局部重构,可以在完成本地验证后停止。只有需要检查真实网络、容器、Secret、存储、浏览器路径或外部系统时,才把结果更新到相应环境。
发布前,Agent和Director核对:
- 目标环境的当前记录、运行状态和正在进行的其它工作;
- 准备发布的完整源码提交或完整Git树、制品和配置输入;
- 与这次改动相关的测试已经通过,未覆盖风险已经明确;
- 数据、文件和当前服务是否需要快照,迁移、回退和恢复入口是否可用;
- 本次操作是否在已授权范围内,超出范围的事项是否已经取得Director确认;
- 发布失败后保留哪些现场,在什么条件下停止、回退或恢复。
当前项目同时提供小范围快速发布和完整发布入口。选择哪一种由实际差异决定,不由Agent想要更快完成决定。小范围源码改动在快速发布明确支持时可以使用它;包清单、锁文件、数据库迁移、Runtime模板、部署编排、网络、Secret或宿主配置变化超出快速范围,需要先保存快照并走完整发布。发布工具因输入、起点或范围不符而拒绝时,先查明原因,不绕过拒绝也不自动改换发布方式。
发布后,Agent检查实际运行进程、健康状态、入口、关键用户路径、数据和恢复材料,确认环境中运行的源码、制品、迁移结果和配置确实来自这次发布。环境记录保存当前状态、发布时间、输入、结果、证据和恢复入口;ACL实施记录保存本轮为什么更新环境以及发布结论。
发布失败时,保留失败步骤、服务和数据状态及已经生成的证据。在已授权范围内恢复环境,再定点诊断根因;涉及删除数据、扩大权限、改变Secret、不可逆迁移或其它超出授权范围的操作,先取得Director确认。
第九步:整理实际结果并提交Director评审
实施和范围内验证完成后,Agent更新实施记录,让下一个读者无需回放整段对话也能看懂真实结果:
- 实际修改了什么,对应哪些提交和被测Git内容;
- 运行了哪些测试和检查,在什么环境下得到什么结果;
- 第一次统一验证是直接通过、定点修复后通过,还是仍未通过;
- 是否开展远端CI复验,已知结果和失败怎样处理;
- 发布了什么,目标环境现在运行什么,并通过了哪些发布后检查;
- 哪些原定步骤发生变化,为什么改,影响了什么;
- 有哪些失败、跳过、尚未覆盖的风险和剩余问题;
- 当前是否达到启动方案中的完成条件。
“代码写完”、“测试都过了”或“环境已更新”都不是足够的结论。Agent需要明确它建议本轮进入Review的理由,也要直接说明什么仍然不能被证明。
形成评审候选以后,ACL还没有进入Completed,REQ也没有进入已完成。Director可以先确认这轮ACL的实施结果,也可以根据风险另行开展DFL(Developer Feedback Loop)或ERL(Engineering Review Loop)。DFL和ERL都不是ACL之后必须依次执行的步骤,下一章会说明它们各自在什么情况下有价值。
回头检查这条路径
1 | 已启动的ACL |
环境更新成功只证明这组结果已经进入某个环境,不表示真实使用中没有遗漏,也不表示ACL已结束或正式版本已形成。