1986 年,Frederick Brooks 在《没有银弹》里提前否定了一次人工智能革命。
当时,人们已经期待人工智能、自动编程、专家系统、图形化编程和程序验证把软件开发变成另一件事。Brooks 的判断很冷静:它们当然有用,却不可能让生产率、可靠性与简单性同时获得数量级提升。因为软件最困难的部分从来不是把想法敲成代码,而是形成那个复杂、正确而一致的概念结构。
四十年后,Agent 像是专门回来反驳他的。
它能阅读陌生仓库,检索文档,提出方案,修改几十个文件,运行测试,查看页面,追踪故障,再让另一个 Agent 审查自己的结果。一位开发者可以同时启动几个任务,等它们各自交回补丁。一次原本要跨越调查、实现、测试和文档的工作,开始可以被整段委托。
这看上去已经不只是更好的编辑器或更高级的编程语言。狼人站在面前,我们手里的东西也确实闪着银光。
但在扣动扳机以前,有一个问题必须先回答:
Agent 和一位同事,究竟有什么本质区别?
如果答案只是更廉价、更快速,那么 Agent 只是软件外包的极限形态。可廉价和速度其实都是表面结果。更深的变化是:同事是一个持续存在、共同承担后果的组织成员;Agent 是一个可以复制、重置、隔离,并由上下文临时实例化的执行过程。
这改变的不是一个岗位,而是软件工程组织劳动的方式。
同事加入组织,Agent 被实例化进任务
一位新同事加入项目,不是多了一双立刻可用的手。
他需要理解产品为什么会变成今天这样,认识代码里没有写下的历史原因,知道哪些接口虽然难看却不能破坏,也要逐渐形成与其他人的信任、分工和沟通习惯。与此同时,他并不是一个等待调用的函数。他会质疑目标、形成偏好、承担声誉与后果,并把今天学到的东西带到明天。
这正是《人月神话》里人月无法互换的原因之一。人不是均匀的计算资源。增加一个人,会增加培训、沟通和协调,也会改变整个团队的关系结构。晚项目增加人手可能更晚,不是因为新人不会编程,而是因为他必须进入组织。
Agent 的进入方式完全不同。
它可以在一个隔离工作树里启动,加载一份任务说明、相关文件、项目规则和测试,然后只完成一个有限任务。任务结束后,这个实例可以消失;需要探索另一条路线时,可以从同一个起点复制三个;方向错误时,可以丢掉全部输出,重新开始。它没有必须延续的职业身份,也不会因为方案被推翻而维护沉没成本。
所以,Agent 不是一位极其便宜的同事。更接近的说法是:
同事需要加入组织;Agent 可以由组织知识编译出来。
目标、约束、代码状态、测试和完成标准组成了这次“编译”的输入。如果这些知识仍只存在于几位老同事脑中,Agent 就不会自动获得它们。复制一个缺少上下文的 Agent,也不是增加产能,而是把同一个误解并行执行几遍。
- 在合作中逐渐获得隐性知识
- 协商目标,并共同承担结果
- 形成长期存在的沟通关系
可比较的结果回到同一个决策点,并行降低了迭代成本。
图的左边,连续性由人携带:他在合作中积累隐性知识,也长期承担结果。右边没有这种天然连续性。每个 Agent 只是短暂实例,连续性必须由仓库、规格、测试、任务状态和反馈共同携带。
这也是为什么增加 Agent 有时不会触发 Brooks 定律,有时却会制造一场更快的灾难。独立、边界明确的任务可以被隔离并行,而共享设计没有被表达时,并行只会放大分歧。Agent 消除了人的一部分组织成本,却把原本隐性的组织知识变成了必须设计的系统接口。
消失的首先不是编程,而是维持编程发生的摩擦
一个软件项目中,真正把手放在键盘上编写新逻辑,只是工作的一部分。
还要定位应该修改哪里,读历史实现,复现故障,搭环境,比较方案,拆分任务,更新依赖,写迁移脚本,补测试,检查差异,回应审查,整理文档,等待另一个团队确认接口。很多工作不直接产生产品功能,却维持着工程可以继续前进。
Agent 擅长的恰好不只是一段代码。它可以把这些零散工作串成一次执行:先调查,再修改,再运行检查,最后交付差异与证据。OpenAI 对 Codex 使用的研究显示,用户正在从一次性问答转向分钟乃至小时级的长程委托;虽然其中的任务时长由模型估计,只能作为趋势,但工作单位确实已经从“生成一段文本”转向“代理一段流程”。How agents are transforming work
这让《人件》提出的老问题发生了偏移。《人件》提醒软件行业:项目的主要问题常常不是技术,而是环境、组织与协作。Agent 没有让这些问题消失,却开始代理它们的机械部分。计划、文档、审查清单和状态汇报不再只是人类团队为了互相同步而付出的管理成本;它们同时成为机器可以读取和执行的组织结构。
过去,一份详尽计划可能被嫌弃为写给抽屉的文档。现在,它可以让一个从未参加过会议的 Agent 在隔离环境中直接开始工作。过去,测试只是质量保障的一环。现在,它也是一次性执行者判断自己是否偏离的外部感官。
原本为了维持团队协作而存在的许多“非编程工作”,正在从人类劳动变成 Agent 的运行环境。
但这不等于产出的代码越多,软件工程就越成功。DORA 对生成式人工智能辅助开发的研究发现,人工智能改善了文档、代码质量和审查速度等部分流程指标,却可能同时降低交付吞吐与稳定性;报告提出的一个解释是,生成速度让变更批次变大,而小批次和可靠测试被忘在了后面。DORA:生成式人工智能对软件开发的影响
Agent 可以让错误方向上的所有步骤都变得更顺滑。摩擦减少以后,方向本身反而成为主要问题。
只给出目标,是把瀑布开发压缩成一句话
既然 Agent 能调查、设计、编程和测试,人类是否只需要给出最终目标?
“做一个团队任务管理系统。”
“重构这套权限模块。”
“让这个页面更简洁。”
然后让 Agent 自己决定一切,最后由人验收。听起来,这才是真正的自主。
可这套协作方式暗含了一个古老前提:人类在项目开始前已经知道完整需求,只是缺少把它实现出来的劳动力。目标可以一次性交付,随后设计与实现只是向它逼近。
Brooks 认为最困难的恰恰不是逼近目标,而是发现目标。他在《没有银弹》中写道,客户在亲手试过一些版本之前,几乎不可能完整、精确而正确地说明现代软件的需求。软件会行动,会与人、机器和其他系统发生关系;仅靠想象,人很难预先看见这些动态结果。因此,软件建设者最重要的工作,是和客户反复提炼需求。
如果把一句模糊目标交给 Agent,几个小时后才检查成品,我们并没有发明一种未来工作法。我们只是把瀑布开发压缩进了一条提示词:一次规格、一次实现、最后验收。
速度甚至会让它更危险。过去,一个错误理解要经过排期、讨论和开发才会变成大量代码,中途还有机会暴露;现在,它可以在第一次人类反馈到来以前就完整实现、补齐测试并写好文档。
真正的“人在回路”不是人坐在流程末端按下批准键,而是人的理解随着工作软件一起变化:
- 看见第一个版本,才意识到自己在意的不是功能数量,而是操作路径;
- 看到两种实现,才发现原来那个没有说出口的取舍;
- 运行真实数据,才知道性能约束与业务规则发生了冲突;
- 推翻一个已经可用的版本,因为它解决了错误的问题。
同事可以在长期合作中主动参与这场目标协商。Agent 则要求我们把协商设计进循环:让中间产物足够早地出现,让当前假设可以被看见,让推翻方案的成本足够低。
人类并不是为 Agent 提供一个静止的目标。人类与 Agent 通过一次次真实产物,共同把目标制造出来。
TDD 不是纪律复古,而是一次性执行者的感官
这解释了为什么测试驱动开发(TDD)在 Agent 编程中重新显得锋利。
如果把 TDD 只理解为“先写测试再写代码”,它很容易变成一种僵硬仪式。它更重要的作用,是在生产代码出现以前,先把下一步期待的行为变成环境能够否定的东西:
- 红:当前系统还不能满足这个判断;
- 绿:只加入足以满足判断的变化;
- 重构:在行为仍被保护时整理结构。
这不是一次微型瀑布,而是一次微型生长。每一步都有可运行的软件,也允许下一步根据真实结果重新决定。
对人类开发者来说,经验、耐心和责任感还能帮助他察觉“虽然测试通过,但事情不对”。Agent 没有天然的项目责任,也不会因为过度实现浪费了团队两周而心痛。它需要一个独立于自身文字判断的反馈源。测试不是证明 Agent 聪明,而是让它不必靠自信判断自己是否完成。
superpowers 之所以把红—绿—重构、细粒度任务、规格审查和完成前验证连成强制工作流,不是因为 Agent 不会写代码,恰恰是因为它可以太快地写代码。它甚至倾向于为每个有限任务启动一个新的执行实例,再分别检查规格符合性和代码质量。superpowers 工作流
所谓“零上下文计划”也因此有了更深的含义:它不是追求文档越长越好,而是在测试一个工程决定能否离开原作者的脑袋,被另一个临时执行者可靠地重新加载。
当然,测试只能保护已经表达出来的意图。Brooks 在讨论程序验证时早就指出,即使能完美证明程序符合规格,最困难的仍然是得到完整而一致的规格;软件工作的很大一部分,本来就是调试规格本身。
所以 TDD 不能代替人。它把已经想清楚的部分交给机器反复检查,从而让人的注意力留给还没有想清楚的部分。
Agent 让敏捷第一次可以快到字面意义
敏捷软件开发后来长出了冲刺、站会、故事点和一整套组织仪式,但它最初的原则其实非常朴素:尽早并持续交付有价值的软件,欢迎需求变化,频繁交付工作软件,以工作软件衡量进度,并把简单视为尽量减少不做之事的艺术。敏捷软件开发宣言背后的原则
这些原则都建立在同一个事实之上:需求不是项目开始前被发现的,而是在工作软件与人相遇时逐渐形成。
Agent 没有让敏捷过时,反而把它推进到了过去无法承受的时间尺度。原来以周为单位的原型和迭代,现在可以缩短到小时;原来因为成本太高而只能争论的两个方案,现在可以都做出来;原来舍不得推翻的实现,现在可以在发现方向不对时直接丢弃。
这时,人类与 Agent 最好的分工也逐渐清楚:
- Agent 大量产生候选、执行变化、收集证据,并压低每轮试错的成本;
- 人类保持跨轮次的意图、品味、责任与概念完整性,决定什么值得进入下一轮;
- 测试、规格和运行环境把可以形式化的判断从人脑移出,让不同 Agent 的结果能够比较;
- 工作软件不断把双方都没有预见的事实带回来。
这不是“人给目标,Agent 完成”。也不是“Agent 做完,人来审查”。它更像一种选择压力:Agent 让变化大量出现,环境淘汰明显错误,人类决定哪些变化属于我们真正想造的东西。
银弹射中的不是复杂性,而是试错成本
现在可以回到开头。
Agent 是银弹吗?
如果银弹意味着一种技术可以独自消灭软件的复杂性、变化性与不可见性,Brooks 仍然是对的。Agent 可以写出更多代码,却不能让现实世界的规则停止冲突;可以生成规格,却不能替所有人决定什么值得建造;可以运行测试,却不能保证测试表达了真正的意图。
但 Agent 确实改变了一件 Brooks 当年无法假设的事:一个可运行版本的边际成本正在急剧下降。
Brooks 认为最有希望攻击软件本质困难的方法,是需求提炼、快速原型与增量生长,因为人只有面对真实软件,才能发现自己真正需要什么。Agent 没有消灭这种反复,反而让反复本身变得便宜、并行,甚至可以随时推倒重来。
所以,如果这一次真的有一件东西接近银弹,它不是那个收到一句目标后独自完成项目的超级 Agent。
它是一个被极度加速的循环:
人提出暂时的意图,Agent 让它迅速变成现实,测试与环境暴露差距,人再根据真实结果改变意图。
Agent 和同事的本质区别,也终于落在这里。Agent 不是一位更快、更廉价的人。它是一种可以为每次尝试重新生成、在失败后迅速死亡的工程劳动力。它不天然携带组织的连续性,所以我们才需要把连续性写进代码、规格、测试与反馈;它也不必像人一样被长期保留,所以我们终于可以大规模生成方案,又毫不留情地只留下其中极少的一部分。
当实现不再稀缺,软件工程的中心就会移动。
过去,人类通过亲手完成大量实现来推动项目;以后,人类更重要的工作,也许是保持一个足够清楚的判断:面对所有已经可以实现的东西,究竟什么值得被留下。