| 编辑推荐: |
本文主要介绍了团队使用
AI 编写代码大半年后,遇到"开发速度快、代码质量糙"的困境,作者分析了 OpenSpec
等 SDD 框架在命令复杂、意图丢失、粒度难控、文档脱节、流程启动时机模糊、团队协作缺失等六方面的问题,进而引入亚马逊
AWS 的 AIDLC(AI 驱动开发生命周期)工作流,通过动态工作流规划与动态团队协作两大能力,并做了 Skills 化、审批执行分离、审计签名等本地化定制,最终把团队
AI 代码质量重新拉了起来。希望对你的学习有帮助。 本文来自于微信公众号Token 漫游,由火龙果软件Alice编辑推荐。 |
|
到这个月底,我们团队已经用 AI 写了大半年代码。
最大的感受就一句话:开发速度确实上去了,但代码质量还是很糙。
经常是开发只花半天,找 Bug 却要花好几天。写的时候很爽,上线之后很慌。
所以最近一个多月,我干了一件事:把我们团队的 AI 编码工作流重新梳理了一遍。简单说,就是用
AIDLC 替换掉原来的 OpenSpec,用更细致的软件开发流程和更强的团队协作,把代码质量重新拉起来。
效果还挺明显。今天这篇文章,就聊聊我们是怎么做的。
01 AI 写代码,焦点已经变了
AI 编码火了一年多,大家关注的重点也在变。
一开始,大家问的是:哪个模型更强?能提升多少效率?
现在,越来越多人开始问:
- 怎么保证 AI 生成的代码质量?
- AI 写的代码,出了问题谁负责?
如果你半年前问我,我可能会说:最好的答案是 SDD,也就是规范驱动开发。
像 SpecKit、OpenSpec 这类规则框架,思路都差不多:先用问答方式把需求和实现规则聊清楚,然后把
spec 文件作为提示词喂给大模型,让模型严格按照规范写代码。
听起来很美好,对吧?
我甚至一度觉得,这就是 AI 编码的最佳方式。网上也有很多关于 OpenSpec 的使用技巧,我看了不少,也尝试了不少。
但后来,当我把这套方法推广到整个团队时,我才发现:SDD
适合小项目。一旦项目变大、周期拉长、需要多团队协作,OpenSpec 就有点撑不住了。
02 OpenSpec 到底哪里出了问题?
我说它撑不住,不是随口下结论。我们实际用下来,主要遇到了几个很现实的问题。
1. 用起来太复杂
OpenSpec 在 GitHub 文档里有多少命令?你现在还记得几个?
你知道什么时候该用 explore,什么时候该用 propose 吗?
我把 OpenSpec 推广给团队时,专门写了一份文档,解释每个命令什么时候用,还要求大家按照我梳理的流程走。
结果还是乱。
explore 到底该在 propose 前面还是后面?为什么不能直接跳到 plan
agent?我估计很多人也答不上来。
因为命令和使用场景太复杂,团队里每个人最后都用出了自己的版本。有人一开始还装模作样用 OpenSpec,后面干脆切回纯凭感觉写代码。
这说明什么?额外的学习成本,并没有给开发者带来足够回报。
2. 它没有保留原始意图
再说到 explore 和 plan agent 的区别,就引出了另一个问题:
OpenSpec 写出来的 spec 文件,不会保存用户最初的意图和原始需求,也不会保留用户在
plan 阶段和 AI 的对话。
结果就是,我审查另一个同事写的 spec 时,经常一头雾水:
- 这个用户故事为什么这么写?
- 这个方法设计到底想解决什么问题?
时间一长,连写代码的人自己都可能忘了,当初为什么这么设计。
一旦原始意图丢了,项目每迭代一次,就会离最初目标更远一点。
3. 需求粒度太难把握
OpenSpec 的 explore 模式,或者其他 SDD 框架里的 brainstorm 模式,确实很强。
但它也很容易让人掉进"许愿式编程"的坑。
你会忍不住希望:我只说一句话,OpenSpec 就能跟我聊,帮我把需求一步步拆细,最后自动搭出一个完整产品。
但现在的 AI 还做不到。
当前这一代大模型很擅长"抄近路"。如果你只给一个模糊目标,就指望它拆出精细需求和迭代计划,通常不现实。
最后你得到的,往往只是一个主功能能跑的 demo,细节实现全缺,离生产系统还差得远。
所以有经验的开发者知道:做 SDD 开发,最好把产品功能拆小,让 OpenSpec 一轮一轮迭代。
比如第一轮搭项目骨架和技术栈,第二轮做登录和认证系统,再往后一点点补。
只有这样,项目才可能慢慢打磨成真正能用的产品。
但问题是,需求拆到什么程度才合适?
拆太粗,项目变成 demo;拆太细,开发速度又掉下来。而且有些必要功能,开发者一开始自己都没想到,很容易漏细节。
4. 文档和现实脱节
接下来是文档一致性问题。
团队成员一开始用 OpenSpec 写 spec 文档,然后开始编码,过程中不断调整实现。
但因为他没有再显式调用 OpenSpec 命令,这些调整就不会写回任何文档。
还有一种情况:生成规则文件时,你发现 tasks.md 有问题,顺手改了。但除非你专门要求,AI
不会主动去改 design.md。
项目每迭代一次,这种不一致就多一堆。
最后,spec 文件完全失去参考价值。剩下的,就是一堆乱糟糟的代码。
5. 你永远不知道什么时候该启动流程
我问过一个同事:大家都知道 SDD 能提升代码质量,你为什么还是选择凭感觉写?
他给的理由是:命令和开发阶段的对应关系太复杂,他真的不知道什么时候该启动流程。
举个例子。
你刚用 apply 写完代码,突然发现生成的代码有 Bug。你是直接让 AI 修,还是先走一遍
propose 工件流程?
再比如,你修 Bug 修到一半,突然想到一个优化点,或者想删掉一块代码重写。你是先走
OpenSpec 流程,还是直接改?
这种时候,很多人就会放弃流程。
6. 团队协作直接崩掉
像 OpenSpec 这样的开源框架,都默认了一件事:
有了 AI 帮助,每个人都能变成超级开发者,一个人从头到尾搞定所有事。
但现实是,我们团队每个人都有明确角色。现代业务已经复杂到,没有人能独自包揽全部工作。
你写完需求分析文档和用户故事,难道不该和产品团队确认一下?至少指标怎么算,得对齐吧?
架构设计和编码计划也一样,不该给其他开发者或架构师看看吗?万一设计方向有问题呢?
但 OpenSpec 完全忽略了这类问题。
从你开始用 propose 写 spec 工件,到完成编码,整个工作流只发生在你自己的环境里。除非你主动拿给别人看,否则没人会
review 你写的文档。
OpenSpec 也很难插入质量门禁或评审机制。
当然,再好的框架也有缺陷。但 OpenSpec 这类 SDD 框架的问题,会让它在企业开发团队里很难真正成功。
03 那我的解决方案是什么?
一开始,我也像很多程序员一样想:
干脆自己造个轮子,让 AI 在我的指导下写一套全新工作流。
但我很快意识到,这行不通。
一个没经过大量开发团队验证的新流程,很可能只是另一个 AI 玩具。它没有企业开发环境需要的可靠性。
后来我想起半年前看到的一条新闻,关于亚马逊 AWS 的 AI 编码工作流。
当时有一条推文说:
亚马逊正在召开强制会议,讨论 AI 破坏其系统的问题。官方说法是"正常业务的一部分"。简报提到,近期出现了一种"高爆炸半径"的事件趋势,由"Gen-AI
辅助变更"导致,而"最佳实践和保障措施尚未完全建立"。翻译成人话就是:我们把 AI 交给工程师,然后事情不断出问题?
《金融时报》也报道了类似内容:
亚马逊电商业务召集了大批工程师开会,深入调查一连串服务中断事件,其中包括与
AI 编码工具使用相关的事件。这家在线零售巨头表示,近几个月出现了一种"事件趋势",特点是"高爆炸半径"和"Gen-AI
辅助变更"等因素。根据 FT 看到的会议简报,在"促成因素"下,还包括"新型 GenAI 使用方式,其最佳实践和保障尚未完全建立"。亚马逊高级副总裁
Dave Treadwell 说:"各位,你们可能也知道,网站和相关基础设施的可用性最近并不好。"
亚马逊似乎遇到了和我们一样的问题。
不可靠的 AI 开发流程,在生产环境里引发了灾难。所以他们要求:初级和中级工程师写的
AI 辅助代码,必须由团队里更资深的人签字才能推送。
这和我们遇到的情况几乎一模一样。
我当时想,这可能只是临时补救。半年过去了,他们应该已经有一套更系统、更工程化的方案。
后来我查了查,找到了他们推出的方案:aidlc-workflows。
补充一句:亚马逊后来已经发布了 aidlc-workflows 2.0,但这篇文章还是基于
1.0,加上一些自定义修改。我觉得 1.0 足够轻量,也容易扩展,用起来更方便。
04 AIDLC 是什么?
AIDLC 的全称是 AI Driven Development Life Cycle,也就是
AI 驱动开发生命周期。
它对应的是传统 SDLC,软件开发生命周期。
传统 SDLC 会把企业级软件开发拆成六到七个主要阶段:规划、需求分析、设计、开发、测试、部署、维护。
AIDLC 在这些阶段之上,又加了两项新能力:
它是怎么做到的?
首先,AIDLC 不只是继承 SDLC 的七个阶段,还把这些阶段分成了三大块:
- Inception,启动阶段:处理工作区检测、条件子阶段和工作流规划,回答"做什么"和"为什么做"。
- Construction,构建阶段:处理设计、实现、构建和测试,回答"怎么做"。
- Operations,运维阶段:目前是未来部署和监控工作流的占位。
配图里可以看到,AIDLC 下面分三大阶段,每个阶段又有很多子阶段。
看起来步骤很多,但别担心。不是每个新需求都要走完所有子阶段。
图中绿色的子阶段总会运行,黄色的只在满足条件时才运行。
决定哪些运行、哪些跳过的,就是 AIDLC 的"动态工作流规划"能力。
05 什么是动态工作流规划?
当我们提出一个新开发需求时,AIDLC 和传统 SDD 框架不一样。
传统 SDD 通常是:先聊天,再写文档,然后实现。
AIDLC 会根据当前项目环境和用户在对话中的选择,分叉到不同条件路径,每条路径加载不同子工作流。
复杂项目加载更多子阶段,小项目加载更简单的流程。
举个例子。
AIDLC 第一次加载时,会检查当前项目环境是全新的,也就是 Green Field,还是已经存在的,也就是
Brown Field。
如果是已有环境,它会加载逆向工程工作流,分析现有代码已经做了什么。
如果是全新环境,就跳过逆向工程子工作流。
当我们提出一个新需求时,AIDLC 会检查它是否影响产品最终用户。
如果影响,就加载用户故事工作流,做用户故事分析。
如果只是非功能需求,或者纯粹是前端页面开发,它就跳过用户故事,直接进入下一个子阶段。
AIDLC 还会维护一个叫 aidlc-state.md 的文件。
除了跟踪当前工作流处在哪个阶段,它还有另一个作用:
如果你想做"许愿式开发",AIDLC
会把你一句话的需求拆开,找出最紧急、最需要先做的子需求,先为它启动工作流。其他子需求记录在 aidlc-state.md
里,等待下一轮工作流再启动。
这就解决了需求粒度的问题。
AIDLC 的核心工作流就像一个管家,始终待在对话里。
当你说的话或者项目状态触发某个条件时,管家就从柜子里拿出匹配的子工作流文档,让那个子流程接管。
这样,你不需要记住什么时候用哪个命令。管家会替你判断。
你也不用担心学不会新命令,更不用想什么时候启动流程。管家都处理好了。
06 什么是动态团队协作?
AIDLC 的动态团队协作有两部分:需求分析记录和审批门。
传统问答式对话,大多把聊天历史留在上下文里。
AIDLC 不一样。它会在子工作流需要时,随时发起对话,向开发者提问。每个问题和开发者做出的选择,都会记录到一个叫
{current-phase}-questions.md 的文件里。
每个子阶段结束时,如果你想调整当前阶段输出,或者有新想法,这些调整和 AI 的回应会被整理保存到
audit.md。
这就解决了原始意图没有被记录的问题。
每个子阶段结束时,AIDLC 会忠实记录你输入了什么、大模型回应了什么、模型如何总结这个阶段的工作。
然后工作流会暂停,等待人工审查。
如果你是一个人工作,只要检查文档没问题,回复"continue"就行。
但如果你是团队协作,需要另一个角色帮你审查文档,你可以通过 Git 提交代码,发给同事
review。
同事的审查意见和标记会记录到 audit.md,再发回给你。
你的 AIDLC 实例只有看到当前阶段的批准标记后,才会进入下一阶段。
audit.md 只支持增量更新,永远不会被编辑覆盖。所以你总能看到每一次变更和每一条审查记录。
配图里展示的流程是:工程师进入需求分析,需要审批时发给上级,审批记录进入
audit.md,批准后回到需求分析,再进入代码生成,最后阶段结束。
AIDLC 还允许你通过 extensions 文件夹扩展工作流。
你可以设置哪些关键阶段需要哪些角色审查,也可以设置每一轮审查都记录审查人信息,方便以后追溯。
所以,和 OpenSpec 相比,AIDLC 更强调团队协作。
07 我们团队是怎么落地 AIDLC 的?
每个人关注点不同,所以我讲具体项目可能对你帮助不大。
这一部分,我不讲某个具体项目,而是讲讲我根据团队实际开发需要,做了哪些本地化定制。
为了方便使用,我已经把这些定制都改写成了 Skills。你只需要拿到源码,放到正确位置,让编码代理加载。之后它就会自动生效。
1. 把 AIDLC 变成 Skill
AIDLC 的核心在两个文件夹里:
- aws-aidlc-rules:核心工作流定义;
- aws-aidlc-rule-details:按需加载的子工作流文件。
默认情况下,它支持亚马逊自己的编码代理 Kiro。
对于其他常见编码代理,官网给的安装步骤很复杂,复杂到没人有耐心看完。
但 AIDLC 本质上就是十几个 Markdown 文件。这意味着,你完全可以把它变成一个
Skill。
转换也很简单:
- 在 .agents/skills 下创建一个 aidlc-workflows 文件夹;
- 把 aws-aidlc-rules/core-workflow.md 复制进去,改名为 SKILL.md;
- 按照 Agent Skills 规范,把 aws-aidlc-rule-details 里的文件复制到 aidlc-workflows/references;
- 最后让你的编码代理修正所有文件路径,让它们指向正确位置。
2. 扩展 AIDLC 工作流
前面说过,AIDLC 的工作流很容易扩展。
除了 reference 文件夹里已经为 Inception、Construction、Operations
阶段定制好的子工作流,它还支持 extensions 文件夹,让你添加可选的自定义工作流,动态加载。
测试、安全、弹性部署,都属于这一类。
一个扩展工作流通常分成两个文件:
- 核心工作流文件:{workflow-name}.md;
- 引导文件:{workflow-name}.opt-in.md。
{workflow-name}.opt-in.md 里包含一个需要用户澄清的问题。这个问题的答案,决定扩展工作流适用于哪些阶段。
opt-in 文件会在需求分析阶段加载,根据用户回答,决定之后是否加载扩展工作流。
如果你的自定义扩展工作流只有 {workflow-name}.md,没有 opt-in 文件,那这个工作流就会一直加载。
这个机制可以保证多个扩展动态加载,所以你可以维护很多扩展,而不会把上下文撑爆。
下面说几个我定制的扩展。
3. 保持文档一致
这个扩展要求 AIDLC 在代码发生变化时,更新所有相关工作流文档。
这样就能保持文档和代码一致,避免 SDD 里代码改了、spec 文档却没同步的问题。
4. 把审批和执行分开
默认 AIDLC 流程里,你批准一个阶段后,工作流会自动继续运行。
一个人工作时没问题,但当你需要审查同事文档时,就会出问题。
比如你是产品经理。需求文档批准后,你不可能让 AI 直接在你电脑上生成代码吧?
所以我把"批准"拆成了两个动作:approve 和 continue。
你在某个阶段批准文档后,工作流不会自动进入下一步。
你应该把文档发给负责下一阶段的人。同事看到你已经批准文档,回复"continue",工作流才会继续。
这样就把审批和执行分开了,确保不同角色处理软件开发过程的不同阶段,也让每个人的专业能力用在最需要的地方。
5. 给审计记录签名
这个扩展解决的是:AI 写的代码,到底谁负责?
默认流程里,AIDLC 会把每轮用户和 AI 的对话记录到 audit.md。
这方便审计需求来源,也方便追踪每个阶段的批准历史。
但默认的 audit.md 不记录是谁提出需求或变更,也不记录是谁批准了文档。
团队协作时,你很难只靠 audit.md 的历史判断该找谁。
所以我用扩展修改了 audit.md,加了两个键:User 和 Email。
我用 git config user.name 和 git config user.email 填充这两个键。
这样我总能知道每条历史记录属于谁。
6. 使用提问工具
AIDLC 原版是为 Kiro 构建的工作流模块,所以和其他 AI IDE 配合得不太好。
它问用户的问题会写进 {phase-name}-questions.md,然后期望用户去这个文件里回答并记录。
但我用上 AI IDE 后,已经很久没碰 VS Code 这类传统编辑器了。
我真的不想为了回答几个问题,专门打开一个完整 IDE。太麻烦了。
因为我主要用 OpenCode,所以我做了一个扩展,让 AIDLC 生成问题后,直接使用
OpenCode 的提问工具问用户,然后把用户答案写回文档。
这样我永远不用离开 OpenCode,也不用去另一个 IDE 里改文件。
7. 测试和其他最佳实践
下面几个是 AIDLC 默认扩展,不是我做的,但我觉得值得聊。
为什么我们选亚马逊的 AIDLC,而不是又一个开源 SDD 框架?
除了它经过大公司软件开发流程测试,我们还希望通过 AIDLC 学习顶级科技公司的软件工程经验。
AIDLC 确实做到了。
在 extensions 文件夹下,testing、security、resiliency
这些子文件夹,分别放着这家公司在软件测试、安全和持续集成部署方面的最佳实践。
举个例子。
以前 AI 给我们写单元测试时,有时会改源码,或者改测试,只为了让覆盖率数字好看。
说白了,AI 自己出考试题,然后改自己的答案来骗指标。
但 AIDLC 不一样。它要求使用 Property Based Testing,也就是基于属性的测试,简称
PBT。
PBT 不检查单个固定输入,而是随机生成大量输入条件,让代码很难提前"背答案"。
AI 不知道下一个输入是什么,也就没法调整代码来糊弄测试。
对很多创业团队来说,这些实践是日常工作中很难接触到的宝贵经验。
如果有机会,我建议你打开相关选项试试。
08 最后总结一下
以上就是我用 AIDLC 重新改造团队 AI 编码流程的过程。
从我们实际使用情况看,这套工作流确实很好用。
基本没有学习曲线,拿起来就能用。
而且因为它来自大公司的最佳实践,所以特别重视动态工作流和动态团队协作。
你可以很方便地根据团队实际开发流程做定制。
它也更容易明确每个团队成员在开发各阶段的责任。
如果生产环境出了问题,也更容易追溯根因,找到责任人,然后修复。
有一点值得注意:这套工作流非常强调软件生命周期管理式的开发。对话中需要澄清的问题,也会更偏技术。你可能需要多学一些软件工程知识,才能完全掌握这套流程。
但软件工程本来就是每个开发者应该掌握的基础知识,所以我觉得这不算大问题。
这套工作流给我们团队带来了很大提升,不管是开发效率还是代码质量。
|