获胜者是规格先行、分阶段验收的 Spec-Driven Development 流程:只要项目存在多模块协作、需求容易变化,或 AI Coding Agent 经常改错文件,就应先建立项目约束和可判定的 Specification,再生成设计、任务与代码;只有一次性的小型脚本,才适合直接提示式开发。
这篇文章适合 3 类人:经常需要反复纠正 AI Coding Agent 的个人开发者;准备把 AI 编程引入团队流程的技术负责人;以及需要为 Agent 生成代码建立审计、测试和验收依据的工程团队。
先固定项目边界,再让 Agent 开始理解需求
实施 Spec-Driven Development 的第一步,不是先写一份很长的 Prompt,而是先把项目中不应被每个任务重复解释的规则固定下来。
项目约束可以放在仓库内的开发规范、贡献指南或专门的项目宪章中,至少覆盖以下内容:
- 技术栈和运行方式,例如使用哪种语言、构建工具、包管理器和测试框架;
- 目录与命名规则,例如业务逻辑、接口层、测试文件分别放在哪里;
- 安全边界,例如密钥不得写入代码,用户输入必须经过校验,哪些接口不能由 Agent 自动修改;
- 允许与禁止修改的区域,例如数据库迁移、认证模块、部署脚本是否必须人工批准;
- 完成定义,例如代码必须通过哪些测试、静态检查、类型检查和人工审查;
- 兼容性要求,例如不得破坏已有接口、配置格式或旧版本数据。
官方的 Agentic SDD 流程把项目宪章放在前置阶段,并说明它会成为后续规格、计划和任务的评估依据。(github.com)
这一步解决的是 3 个常见隐性成本:
- 上下文重复成本:没有固定约束时,每次对话都要重新说明目录、测试和权限要求。
- 越权修改风险:Agent 可能为了让测试通过,顺手修改数据库结构、认证逻辑或部署配置。
- 团队审查成本:不同开发者给出不同提示,Agent 产生的实现风格和验收标准也会变化。
项目约束不应写成无法执行的价值判断,例如“代码要优雅”“体验要好”。更好的写法是:“所有新增接口必须有输入校验和失败响应测试”“不得修改 migrations/,除非任务明确包含数据库迁移”。
把用户目标改写成可判定的 Specification
Specification 需要写到什么程度,取决于 Agent 是否能够据此判断输入、行为、异常和完成状态,而不是取决于文档有多长。
一条可执行的 Specification,通常应包括:
- 目标:这项功能解决哪个用户问题;
- 行为:在什么条件下触发,系统要完成什么动作;
- 输入与输出:字段、格式、必填条件和返回结果;
- 异常情况:权限不足、数据不存在、重复提交、网络失败时如何处理;
- 非功能要求:安全、可维护性、日志、兼容性和可观察性;
- 验收条件:测试、检查命令、接口示例或人工操作结果。
例如,“增加文件上传功能”无法直接指导实现。改写后可以是:
已登录用户可以上传
PNG、JPEG文件;单个文件超过项目限制时拒绝保存并返回明确错误;上传成功后返回文件标识和访问状态;未登录请求不得写入存储;重复提交不能生成无法追踪的孤立记录。
这类规格没有虚构性能数字,却已经包含行为、边界、权限和结果。它也更容易被转化为测试用例。
官方说明中,specify 阶段重点描述用户可见的目标和行为,而技术栈、架构及实现细节应留到 plan 阶段;如果需求存在歧义,还可以先运行澄清阶段,针对未说明的区域提出最多 5 个定向问题。(github.com)
怎样判断一份规格已经足够具体?
可以用下面的检查方式判断:
- [ ] 每个用户故事都有明确的触发条件;
- [ ] 每个输入字段都有格式、必填和非法值说明;
- [ ] 成功路径和失败路径都写出可观察结果;
- [ ] 权限、数据隔离和敏感信息处理规则已经说明;
- [ ] 每条关键要求都能映射到测试、静态检查或人工验收;
- [ ] 明确哪些内容不在本次范围内;
- [ ] 没有把具体实现方案伪装成用户需求;
- [ ] 没有使用“尽可能快”“体验良好”等无法判定的词语。
关于需求变化后的失控风险,处理原则也应在规格阶段确定:先修改 Specification 的范围、行为或验收条件,再重新分析设计和任务;不要只通过临时提示要求 Agent“顺便适配一下”。
⚠️ 经验提醒:如果一条规格无法被测试或人工检查验证,通常不是 Agent 不够聪明,而是需求仍停留在愿望描述阶段。
让 Agent 先产出设计,再生成小颗粒任务
当 Specification 已经能够判定完成与否,下一步才是设计和任务拆分。此时不要直接要求 Agent “把整个功能做完”,而应要求它先说明:
- 将修改哪些模块;
- 哪些接口、数据结构或依赖会受到影响;
- 哪些方案被排除,以及排除理由;
- 哪些任务存在前置依赖;
- 每个任务完成后用什么命令或证据验证。
官方流程通常把 specify、plan、tasks 和 implement 作为核心链路,计划阶段负责把需求转换成技术设计,任务阶段再生成有依赖顺序的执行清单。(github.github.com)
如何把规格转成 Agent 能够稳定执行的任务?
可以采用“一个任务只跨越一个主要变更边界”的原则。例如,一个用户资料功能不要拆成“完成用户资料模块”这种大任务,而应拆成:
- 增加资料字段的数据模型和迁移;
- 增加读取资料的服务层接口;
- 增加更新资料的输入校验;
- 增加接口层错误响应;
- 增加服务层和接口层测试;
- 更新文档与示例请求。
任务粒度过大,会出现 3 个问题:
- Agent 一次读取过多文件,容易在上下文中混淆不同模块;
- 失败后难以判断是规格、设计还是某个代码改动出了问题;
- 审查者只能面对一个巨大差异,无法逐项对应原始要求。
任务粒度也不能过细。若每个任务只修改一行配置,执行过程会产生大量无意义的上下文切换。判断标准是:任务是否可以独立实现、独立验证,并且在失败后单独回退。
按任务执行代码,并保留可审查的中间证据
进入实现阶段后,每一轮只给 Agent 当前任务需要的材料:
- 当前任务对应的规格条目;
- 相关设计和依赖说明;
- 必须遵守的项目约束;
- 允许读取或修改的文件范围;
- 验证命令和预期结果。
修改前要求 Agent 先输出简短计划,至少说明准备修改哪些文件、为什么修改,以及不会触碰哪些边界。修改后要求它提交 4 类结果:
- 实际修改的文件;
- 与规格对应的行为变化;
- 执行过的测试或检查命令;
- 未完成事项、风险和需要人工决定的问题。
如果项目运行在远程 Mac 或临时开发环境中,环境本身也要纳入约束:代码目录、依赖缓存、测试命令、环境变量和重置方式都应记录清楚。需要临时准备 Mac 开发节点时,可以先查看 Zutcloud 的 Mac 环境帮助中心,确认远程访问、环境准备和使用边界,再把这些条件写进项目规则。
一个可执行的单任务提示可以采用以下结构:
任务:实现资料更新接口。
依据:
- Specification:用户只能修改自己的显示名称;
- 计划:复用现有用户服务层,不新增数据库表;
- 约束:不得修改认证中间件,不得记录原始敏感字段;
- 验证:运行服务层测试、接口测试和静态检查。
开始前:
1. 说明准备读取和修改的文件;
2. 说明输入校验和权限判断的位置;
3. 指出无法确认的假设。
完成后:
1. 列出文件差异;
2. 说明每条规格如何被覆盖;
3. 粘贴验证命令及结果;
4. 列出仍需人工确认的事项。
这不是把 Prompt 写得更长,而是把每轮上下文变成有范围、有输入、有退出条件的执行单元。
用规格映射验收结果,并在失败处回退
验收不能只看“测试是否通过”。需要建立从规格到证据的对应关系:
- 用户行为规格 → 接口测试、端到端测试或人工操作;
- 输入输出规格 → 参数校验和响应断言;
- 安全规格 → 权限测试、越权测试和敏感信息检查;
- 兼容性规格 → 旧测试、迁移验证和接口回归;
- 代码质量规格 → 类型检查、静态分析和格式检查。
官方的 analyze 用于跨规格、计划和任务进行只读一致性分析,可以发现没有对应任务的需求、与规格冲突的设计或缺少覆盖的任务;如果发现问题,应回到拥有该问题的阶段修复,而不是继续添加临时提示。(github.com)
官方文档还将 converge 设计为实现后的收敛检查:如果发现遗漏,可以把新任务追加到任务清单,再次执行实现和收敛;如果没有缺口,则得到规格、计划和任务均已满足的结果。(github.com)
验收阶段可以使用这份清单:
- [ ] 每条高优先级规格都有至少一项验证证据;
- [ ] 测试覆盖成功、失败、权限和边界输入;
- [ ] 静态检查与构建命令执行成功;
- [ ] 接口示例与实际响应一致;
- [ ] Agent 没有修改禁止区域;
- [ ] 差异中没有无关重构或批量格式化;
- [ ] 未通过项已经定位到规格、计划或具体任务;
- [ ] 修复前没有继续追加模糊提示;
- [ ] 验收记录已经绑定到提交或变更编号。
如果失败来自需求歧义,应回到 Specification;如果需求明确但架构不成立,应回到设计;如果设计正确但实现遗漏,应回到任务。这个回退层级比“让 Agent 再试一次”更容易留下审计证据。
将规格、实现和测试放进同一版本流程
Spec-Driven Development 的长期价值,来自规格不会在代码合并后消失。规格文件、计划文件、任务清单、测试和代码应在同一版本控制流程中演进,并通过提交记录或合并请求保持关联。
当需求发生变化时,推荐按照以下顺序处理:
- 修改 Specification,明确新增、删除或改变的行为;
- 标记受影响的接口、数据模型、权限和测试;
- 重新生成或修订设计计划;
- 更新任务依赖和验收条件;
- 重新运行一致性分析;
- 只实现受影响的任务;
- 执行回归测试和人工验收。
对于大型项目,不应把所有需求塞进一份持续膨胀的规格。官方的“规格分片”思路是把路线图拆成相互独立的子规格,每个子功能拥有自己的 spec.md、plan.md 和 tasks.md,再通过稳定的标识保持追踪关系。(github.com)
如果团队需要自动化流程,还可以使用可暂停、可恢复的工作流,把规格审查、计划审查和实现串联起来。官方工作流说明支持人工审批节点、条件分支、循环以及任务并行;但其中的 Shell 步骤会以本地权限执行,并不自动提供安全沙箱,因此权限边界仍必须由运行环境和团队流程负责。(github.com)
这也是为什么 AI Coding Agent 不应直接连接生产环境。更稳妥的方式是准备可重置的开发环境、隔离的测试数据和明确的凭据权限;涉及远程 Mac 自动化测试时,应先确认系统版本、访问方式、依赖安装和重置流程是否满足项目要求。若需要临时验证 Apple 平台构建或测试流程,可参考 Zutcloud 的 Mac mini 租用方案,但长期稳定重负载、必须连接本地硬件或需要专用外设的团队,仍应评估自购设备。
当前方案与 Mac 方案,应该怎样取舍
直接在个人电脑上运行 AI Coding Agent,优点是代码和环境都在本地,但常见缺点也很明确:电脑休眠或关机后任务中断;依赖安装、系统权限和网络代理容易污染主力环境;多人共享同一套验证环境时,问题难以复现。
纯云端开发环境则通常面临网络延迟、远程桌面体验不稳定、构建环境重置成本以及 Apple 平台测试能力受限等问题。对于需要临时执行 Specification 驱动开发、验证 CI/CD、运行自动化测试或让团队共享一套可重置环境的场景,Mac 方案的价值不在于替代所有本地设备,而在于提供更容易隔离、交接和复现的执行节点。
因此,若需求是短期测试、阶段性构建或团队需要统一验收环境,租赁 Zutcloud 的 Mac 体验往往比临时改造个人电脑更直接;若任务是长期满负载运行、必须连接本地硬件,或每天都要使用同一台设备,则应优先比较自购 Mac、现有服务器和租赁方案的总成本与管理边界。进一步了解服务范围时,可阅读 Zutcloud 的服务条款,再决定是否把远程 Mac 纳入 AI Coding Agent 的开发链路。
为 AI Coding Agent 准备一台随时可用的远程 Mac
使用 Zutcloud Mac mini 租赁,快速获得稳定的远程 macOS 开发环境,让规格编写、代码生成与验收流程随时可执行。
无需购置和维护本地设备,按需租用远程 Mac,降低个人开发者与研发团队开展 AI 辅助开发的成本。 立即订购