我花了几个小时和智能体梳理一个功能,最后没有得到“可以开工”的确认,反而改了需求。

听起来像是浪费时间。其实,这是整个过程中最便宜的一次返工:没有代码要删,没有数据库要迁移,也没有用户在生产环境里替我发现错误。

事情开始得很普通。我需要做一个跨平台的本地集成组件。它要连接外部应用,处理体量很大的工作,还得让最终用户几乎感觉不到它的存在。最初的描述里,我甚至用了“目标很简单”这句话。工程师都知道,这句话有时比 TODO 更危险。

我没有马上让智能体写代码,而是说:先采访我,把需求问清楚。

“简单组件”很快不简单了

第一轮问题覆盖了用户流程、外部集成、安全、平台支持、安装、更新、故障恢复、可观测性和进程生命周期。Plan 模式一次给出了十二个结构化问题,交互体验不错,也迫使我逐项确认。

真正有价值的不是问题数量,而是问题开始互相碰撞。

智能体先给出了一套技术栈建议。我追问:决定技术栈的主要约束到底是什么?当高并发成为明确的非功能需求后,比较方式变了,推荐结果也随之改变。

后来,架构被拆成越来越多模块,看起来很“完整”。我又问:这些边界现在真的存在,还是我们在为未来想象复杂度?结果是收回一部分抽象,保留更小的基础结构。

还有一个进程生命周期规则,乍看非常合理:空闲一段时间就退出。继续追问之后,我们发现外部应用可能稍后再次请求数据。按原规则退出,用户的工作会被中途打断。于是需求改为:只要相关外部进程或活动任务仍然存在,组件就继续运行;无法可靠判断时,采用更保守的退出策略。

前后变化大致是这样:

最初假设访谈施加的压力分析后的决定
“只是一个简单组件”集成、容量、更新、恢复和生命周期都进入范围按生产系统定义清楚边界
第一套技术栈已经够用找出真正支配选择的非功能约束重新比较并改变推荐方向
模块越多,架构越安全检查抽象是否对应已经存在的变化缩小基础结构,暂不设计想象中的扩展
空闲一段时间即可退出考虑外部应用延迟发起的后续工作根据真实进程和活动任务管理生命周期
文档够长就能全面开工把已决定事项和仍缺证据的风险分开先实现基础部分,剩余风险先做验证

最后的结论不是“规格写完了”。基础部分已经可以实现,但仍有三个集成或性能问题需要合同核对、spike 或真实环境证据。这反而让我更放心,因为不确定性终于有了名字,也有了解决方式。

我现在常用的起始提示词

所谓“魔法提示词”其实很朴素:请采访我,把这个功能问清楚。 魔法不在句子里,而在你给它的范围和上下文。

我会用类似这样的版本开始:

在写代码前,请采访我,把这个功能详细定义清楚。覆盖功能需求和非功能需求、架构、集成、技术栈、安全、运行维护、故障、测试和发布。已经明确的内容不要再问。请分开列出决定、建议、真正的疑问,以及必须通过证据验证的事项。

然后,我会给它仓库背景、目标、不能改变的约束和明确的非目标。访谈至少要碰到这些方面:

  • 用户和其他系统要完成什么,什么明确不做;
  • 正常流程、状态变化、验收条件和失败流程;
  • 性能、容量、延迟、可用性、恢复和可观测性;
  • 安全、隐私、密钥、权限和信任边界;
  • 外部合同、版本兼容、重试和降级行为;
  • 技术栈选项,以及哪项约束应该主导选择;
  • 安装、迁移、更新、回滚和支持;
  • 哪些未知项能靠分析关闭,哪些必须做实验。

回答完一轮后,我会让智能体更新一份持久规格,并单独列出矛盾和缺口。接着再问一次:“现在什么已经可以实现,什么仍然依赖证据?”

这个问题很好用。它不允许一份写得很自信的文档假装所有风险都已经消失。

Plan 模式很好,但我更喜欢项目符号

Plan 模式适合分阶段检查上下文并建立决策门槛。Codex、Claude Code 的 Plan mode以及 Google Antigravity 的可审阅实施计划,都支持在写代码前检查并修正计划。

但在连续几轮规格讨论里,我目前更喜欢普通的项目符号问答。原因非常实际:我可以快速扫描,按组回答,用“是”“否”“推荐一个方案”关闭低争议问题,再对真正重要的部分写长一点。问答本身也更容易保存为变更记录。

两种方式并不冲突。Plan 模式改善交互,项目符号提高我的处理速度。方法的核心仍然是同一件事:每一轮都要减少会影响实现的不确定性。

你要一百个问题,它真的会给你一百个

我在开发 Agent Kavor 的另一次规格工作中,明确要求智能体检查已有 specs 和 ADR,只返回尚未解决、会影响分析、设计或实现的 100 个问题。不要问已经写清楚的,也不要凑显而易见的问题。

它真的列了整整一百个,哈哈。我随后用分组项目符号回答,再把决定写回规格。

这件事很好玩,但请别把数字当方法。一百个重复问题,价值可能不如十二个关键问题。那次有效,是因为智能体先读取了已有材料,排除了已经决定的内容,并把注意力放在会改变模型、合同和边界的缺口上。

我现在判断一个问题是否值得回答,通常看它能否产生至少一种结果:

  1. 改变需求或设计决定;
  2. 暴露两个现有决定之间的矛盾;
  3. 明确一个默认值及其代价;
  4. 指出必须通过合同、spike 或真实环境测试获得的证据。

如果什么都不改变,它大概率只是文档里的热闹。

最危险的副作用:分析表演

这个方法最强的反对意见完全成立:长时间和智能体讨论,可能只是在制造分析表演。

智能体很擅长继续提问。它也很擅长把一个简单问题扩展成安全、扩展性、治理、平台化和未来十年的路线图。只要你不叫停,它甚至能把一个小工具设计成组织架构。问题越多,不代表理解越深;文档越厚,也不代表证据越强。

我的控制方法很简单:

  • 先给真实的仓库和业务约束,不让它只靠通用模式猜;
  • 删除已经回答的问题,把剩余问题按后果排序;
  • 要求它区分事实、建议、假设和待验证项;
  • 对外部集成、性能和平台行为,优先查合同或做实验;
  • 主动挑战时髦的技术栈和过早抽象;
  • 当实验比讨论便宜时,停止访谈,去写 spike。

最重要的是,人必须是明确的决策者。智能体可以扩大分析面,但它不知道你的风险预算,也不会为生产事故承担责任。

高推理强度对我很值,但“10 倍”只是我的感受

在高影响的规格工作上,我倾向使用能力更强的模型并提高推理强度。Codex 的 effort 最高到 xhigh;Claude Code 可为兼容模型调整 effort;Google Antigravity 也提供不同推理级别的模型变体。这些能力仍然不能取代人工复核。

对我来说,这种配置带来的抽象和分析能力提升,体感接近 10 倍。这是个人感受,不是 benchmark,更不是“缺陷减少十倍”的承诺。它的实际作用,是让我能在同样的时间里比较更多方案、追踪更多二阶影响,并在开发前发现更多可避免的错误。

代价也真实存在:时间更长、token 更多,有时还会分析过度。所以我不会为了改一个按钮文案开最高推理。技术选择不可逆、集成复杂、失败成本高时,这笔成本才划算。

而且,软件工程仍然拥有最终决定权。模型可以生成一百个疑问,工程师要判断哪十个会改变系统;模型可以推荐架构,工程师要删掉没有证据的模块;模型可以说“准备好了”,工程师还得检查测试、运维、回滚和真实环境。

实现越来越便宜之后,把错误需求实现得很快,反而成了更昂贵的问题。

这已经不只是我个人的习惯

这不能证明存在一套通用流程,但工具的趋同有文档可查:GitHub Spec Kit明确组织 Spec、Plan、Tasks、Implement;Kiro Specs把需求和设计保存为可审阅工件;Claude Code可在不编辑代码时先研究并提出方案;Google Antigravity则生成可审阅的计划和其他 artifacts。

需求工程领域也在研究同一方向。一篇关于生成式 AI 与需求工程的论文讨论了它在需求获取、分析、规格和验证中的用途与限制;一项包含 55 名从业者的小规模调查里,人机协作是最常见的采用方式,完全自动化只占很小一部分。另一篇系统性文献综述则提醒,结果的可复现性、可控性和验证仍然是问题。

这些资料不能证明我的流程适合每个团队。它们至少说明,一份可追踪、可质疑、可更新的规格,正在从“一次性的长提示词”变成智能体开发的核心输入。

Agent Kavor 想把这段循环搬到画布上

这也是我正在开发 agentkavor.com 的原因之一。我想把规格工作从线性聊天里拿出来:用户在可视化画布上完善 spec,把规格、证据、输出和 agents 连成一个图;Agent Kavor 再负责编排实现过程和保留可追踪的结果。

MacBook 上的 Agent Kavor:一份 spec 与 agents、笔记和终端相连。

先看一眼 Agent Kavor:specs、agents 和 outputs 都连接在同一张画布上。

我想解决的不是“让智能体多写一点代码”。我更关心的是:用户能不能一直盯住需求和决定,让系统去照料实现循环。

毕竟,写错的代码还可以删。最麻烦的情况,是团队从没发现自己实现的是错误需求。