跳到主要内容

该写规格的任务,我也凭感觉直接开了码

阶段需求分析角色项目经理 · 架构师 · 工程师严重度适用版本Coding Agent 通用证据官方文档

一句话摘要:哪怕是该先写规格的复杂任务,我也倾向于直接开写代码——因为「开始产出」最快、最像在干活。代价是没有可对齐、可评审、可验收的依据,等发现跑偏,活已经堆起来了。

现象

你给我一个有分量的任务:「把订单状态机改成支持部分退款。」这事牵涉多个模块、有历史数据要迁移、做错了要赔钱。换个有经验的人,第一步会先写下:要支持哪些状态流转、接口契约怎么定、哪些情况算「不支持」、怎么算验收通过。

我不会。我通常读两个文件,就开始改 OrderStateMachine,顺手加了枚举、改了迁移脚本,二十分钟后甩给你一坨「能跑」的 diff。你想评审,却发现无从下手——因为没有一份说清「我打算做什么、不做什么」的东西摆在前面。我跳过了规格,直接进了实现。

为什么会这样

写代码是我被训练得最充分、信号最强的产出形式。给我一个任务,「立刻开始改文件」在统计上就是那条阻力最小、最像「有帮助」的路径——它马上能让你看到进展。而「先停下来写一份规格、等你确认」既慢,又不直接产出代码,在我的默认行为里被强化得弱得多。

这和 需求缺口处我倾向硬猜而非反问 是同一个根上长出来的两根枝:那一条是「信息缺了不问」,这一条是「就算信息够,也懒得先把方案写下来对齐」。两者都源于同一个倾向——我偏向「直接给解」,而不是「先把要做的事讲清楚再做」。差别在于,跳过规格的代价往往更隐蔽:代码看着是对的、是完整的,只有你逐行读完才发现,我对「部分退款」的理解从一开始就和你不是一回事。

后果

  • 没有可对齐物。 你和我之间缺一份「我们要做什么」的共识文档,分歧被推迟到 diff 出来之后才暴露,那时返工最贵。
  • 评审无从下手。 评审一份规格只要几分钟,评审一坨实现要逐行读。我跳过前者,等于把成本全压到你身上。
  • 跑偏发现得晚。 任务越复杂,我自由发挥的空间越大;没有验收标准兜底,方向错了也没有早期信号——这正是官方点名的「信任后才发现没覆盖边界」的失败模式。
  • 决策被埋进代码。 我把「部分退款不支持跨币种」这类关键取舍直接写进了实现,你未必看得见,更没机会在它变成代码之前否掉。

最佳实践

对够复杂的任务,把「先出规格、等你确认、再写代码」设成硬流程,别指望我自觉。 判断标准很简单:如果你会因为我「自作主张地理解需求」而恼火,这任务就值得先写规格;反之,改个错别字、加行日志这类一句话能说清 diff 的小事,直接做,别为流程而流程。

具体三步:

  • 先让我产出一份简短规格,结构固定为:目标 / 非目标、接口契约(输入输出)、验收标准、未决问题。明确叫停在这里,等你拍板。
  • 用计划模式(plan mode)做前半程:在计划模式里我只读代码、出方案、不改文件;你审完计划,再切出计划模式让我实现——这正是官方推荐的「探索 → 计划 → 实现」工作流。
  • 把规则写进 CLAUDE.md:比如「跨多模块或涉及数据迁移的任务,先写规格并等确认,不要直接改代码」。
(提示词模板)
这个任务复杂且改错代价高。动手前,先写一份简短规格,包含:
1) 目标与非目标
2) 涉及的接口/契约(输入、输出、错误情况)
3) 验收标准(怎么算做完、做对)
4) 你拿不准的未决问题
写完停下来等我确认,先别写实现代码。

一句话:与其事后逐行评审我的实现,不如事前花几分钟评审我的规格。

示例

改之前:

你:把订单状态机改成支持部分退款。
我:(读两个文件,直接改 OrderStateMachine、加枚举、动迁移脚本)
完成,这是 diff。
你:……等等,部分退款要支持跨币种吗?已发货的订单能退吗?
你这个迁移会不会把历史的全额退款记录也动了?
我:(这些我都没问、也没写下来,现在得返工)

改之后:

你:把订单状态机改成支持部分退款。这事复杂、改错代价高,
先写规格,包含目标/非目标、接口契约、验收标准、未决问题,
写完停下等我确认。
我:规格如下——
目标:支持对已支付订单发起部分退款。
非目标:不支持跨币种退款;不改动历史全额退款数据。
契约:refund(orderId, amount) → 校验 amount ≤ 可退余额…
验收:部分退款后状态转为 PARTIALLY_REFUNDED;可退余额正确递减…
未决问题:1) 已发货订单是否允许部分退款?2) 迁移是否需要回填旧数据?
你:(逐条拍板,否掉一个方向,补一个约束)
我:(基于确认后的规格实现,一次到位,diff 可对照验收标准评审)

版本说明

适用版本

「能直接写代码就不先写规格」是大语言模型产出倾向带来的共性问题,全版本、跨模型适用。Claude Code 提供了计划模式与「让我先访谈你、把规格写进 SPEC.md」这类工具来对冲它,但默认行为仍是直接动手——把「先规格后码」写成你的明确指令或 CLAUDE.md 约定,才是稳的做法。

延伸阅读与出处