0%

《Agent时代的人月神话》读后感

1. 概要

Agent 时代,能够加速的是执行过程( 编码、调试等 )

  • 说明:执行过程最多占开发活动的 50% 时间,来自 Portman 的数据

但涉及到目的、判断等核心的流程,还是需要人工介入。
由于执行过程足够快,需要人工介入的工作会越来越多,瓶颈还在人,提效会遇到天花板。
从某个角度讲,AI 加速了我们的生活,其实是变相地增加了人生的长度( 犹如开倍速看电影 )。

如果通过 Agent 进行 Coding,关键的约束:

  • 从需求开始就让 Agent 了解
  • 和 Agent 不断对话沟通,形成决策纪要和执行计划
  • 执行计划尽量细化,每个步骤尽量有过程约束,而不是指标约束。否则容易作假
  • 如果 Agent 给出的结果不好,不要直接修改代码,而是修改执行计划,说清楚来龙去脉
  • 执行过程中有遇到不明确的,让 Agent 不要自己发挥,需要人工补全确认
  • 如果上下文耗尽等导致效果不佳,重新开一个窗口按执行计划让 Agent 接着工作( 有状态+业务上下文 )
  • Code Review 等也用新窗口拿着执行计划执行,避免不干净的上下文影响

核心就是让 Agent 有足够的上下文,有可验证的过程产出,而非简单的评估指标。

2. 精简照抄

《人月神话》是 Fred Brooks 1975 年写的一本管理书。
他管过 OS/360,那是 IBM 的大型机操作系统,1960 年代人类做过的最大一次软件工程。
项目结束他没写技术总结,写了一本关于为什么大项目总是延期、为什么加人只会加得更慢、为什么概念完整性是设计的最高目标的书。
《人月神话》写完之后成为整个软件行业的地基。
+++
Brooks 那本书的第一批读者是 1970 年代的项目经理。这本书的读者是 2026 年之后的开发者。
中间隔了半个世纪,一切都在变,唯有一件事没变:软件工程的核心是判断的组织( 把各种决策判断有机整合 )。
软件最贵的成本是维护与演进。好的组织方式,能让你在“增加新判断”或“修改旧判断”时,付出最小的边际成本。
+++
在 Agent 时代卓越的工程师,
应该投时间在判断和决定的文档上,
文档写成能被机械执行的源码级材料,
因为代码是 Agent 从文档编译的产物。

+++
Agent 是伟大偶然困难的消灭者,写代码、写文档、写测试、跑 debug、追依赖等的成本大幅下降。

Agent 没有触及本质困难。判据谁持有、目的谁负责、概念完整性谁守护、里程碑谁设计。
这些工作没有因为 Agent 而减少,反而因为总产出多了,占用总成本上升了。
在项目里,判断的成本在过去两年可能翻了一倍不止。
+++
人机分工线沿着”能不能被形式化定义”这条边界走。
能被形式化的(代码、测试、文档格式),交给 Agent。
不能被形式化的(目的、判据、处境判断),留给人。
守住这条分工线,两侧都做得最好;打乱这条分工线,两侧都做不好。
+++
Mills 提出的外科手术队伍编制表大概是这样:

  • 主刀(chief programmer / surgeon):定义规格,写核心代码,做所有关键设计决策,为整个产品的正确性和完整性负责。这是唯一持有整个系统概念的人。
  • 副手(copilot):主刀的影子,能替代主刀(比如主刀请假时接手),日常也参与讨论和评审。这个角色的存在让主刀敢做决定,因为知道有人在同一个理解水位上审核。
  • 管理员(administrator):处理项目管理事务(预算、进度、行政),把主刀从这些事务里解放出来。
  • 文档编辑(editor):把主刀写的初稿文档整理成正式文档。
  • 程序录入员(program clerk):管理项目的所有文件、版本、变更历史。1970 年代这是重体力活。
  • 工具管理员(toolsmith):维护开发环境、工具链、编译器。
  • 测试员(tester):设计和跑测试用例。
  • 语言律师(language lawyer):精通编程语言的深奥细节,供主刀咨询。
  • 秘书(secretaries):更基础的文书工作。

当代最小可用软件编制:一个人做主刀,一群 Agent 担任支持团队。
+++
Brooks 说,一个成功的架构师团队的纪律:

  • 记住实现者才是承担创造性责任的人。架构师只能建议,不能替实现者做实现层的决定。
  • 随时准备为自己的建议提供一种可行的实现方法,同时随时准备接受实现者提出的其他可行方案。
  • 对自己的建议保持低调和平静。
  • 随时准备为你建议的改进放弃功劳。
  • 认真听取实现者在体系结构上的改进建议。

3. 原始摘抄

原文地址:Agent时代人月神话 - Github

Brooks 的核心观察是,一段能跑的程序,跟一件能被人依赖的软件产品之间,工作量差九倍。这个九倍不是拍脑袋数字,是两个三倍的乘积。

  • 产品化
  • 系统集成

产品化:从”我自己能跑”到”别人也能跑”,中间要加:文档(别人怎么用)、测试(哪些情况经过验证)、错误处理(用户输入奇怪的东西怎么办)、边界情况(空输入、超大输入、并发调用)、可维护性(半年后你想加个功能,代码结构容不容易改)、可观测性(挂了你怎么知道)。这一层的工作在演示视频里看不见,在产品运行的每一分钟都在起作用。

系统集成:从”独立跑得动的模块”到”能嵌入一个更大系统的构件”,中间要加:接口对齐(跟其他模块的契约怎么定)、版本兼容(依赖升级会不会挂)、多环境隔离(本地、预发、生产表现一致吗)、部署方案(怎么发布、怎么回滚)、监控告警、备份策略。这一层跟第一层是正交的,两者都要做,且都各自吃三倍工作量。

不对称塌陷比 1975 年的均匀焦油坑更危险,因为它制造了一个更强的错觉。”我做完了”的心理判断被大幅提前,从”这个系统上线运行了三个月”提前到”这段代码在我本地跑通了”,甚至提前到”agent 说它跑通了”。九倍矩阵剩下的八份工作没有消失,它们被延后到上线之后、用户投诉之后、下一版重构时,一次性地爆发在维护阶段。

软件项目里最痛苦的部分之一,是你为之工作的那些东西,上游 API、操作系统、第三方库、云服务商,不受你控制,但你要为它们的坏特征负责。

agent 时代新增了一层不可控物:agent 本身。你不能直接决定它下一步会怎么响应,同一个提示词今天的输出和明天的输出可以不同,同一个任务这次给强档模型和下次给弱档模型可以走完全不同的路径。你负责结果,但你不能完全控制过程。这是一种升级版的”权威不等同于责任”。

Brooks 观察到,就算是最有创造性的软件工作,大部分时间也花在枯燥的例行公事上:写单元测试、修构建脚本、追依赖版本、读日志找错。

等到你的项目大到不能一次性把所有代码直接塞进模型上下文,枯燥劳动立刻随之而来。

越接近完成收敛越慢。这条五十年不变,agent 时代也不变。原因是任何软件的最后 10% 都是最”处境化”的部分:边界情况、性能调优、和真实用户交互的细节。这些都是 agent 目前最难做的部分,判据都住在处境里,不住在被写的代码里。9 成完成到 10 成完成这段路,在 agent 时代甚至可能变得更慢,因为你前 9 成用 agent 做得太快,进入最后 10% 时你会突然发现 agent 帮不上什么忙,节奏被打断,速度骤降。开发者会体验到一种前 5 天像一日千里、最后 3 天像陷在泥里的落差。这种落差在 1975 年也存在,只是没有 2026 年这么锋利,那时候前 5 天没有这么快,落差不明显。

人月神话当代版:一个 agent 会话十小时才能做完的活,开十个 subagent 一小时就能做完。

  • 这个 refactor 太大了,我们把它拆成十个 subagent 并行做吧
  • 用五个并行的 Claude Code 修完了整个仓库的 lint 错误

Brooks 说程序员是乐观主义者,一切都将运作良好。他把根源归到介质。
程序员工作在纯粹思维的介质上,脑子里能想通的东西就以为等于键盘上能敲对的东西。介质越纯,人越乐观。
脑子和产物之间的摩擦越少,越容易误以为产物就是脑子的直接投影。

2026 年的 agent 用户是这条乐观主义的极限形态。介质又纯了一层,从代码退到了自然语言。
你现在的产物和你的思考之间隔的不再是”我能不能把这段逻辑写对”,是”我能不能把这段要求说清楚”。
而说话,是所有人都从两岁开始就在做的事情。
人对自己”能不能说清楚”这件事的自信心,天生就比对”能不能写对”的自信心高。
随说:有几个人可以说清楚一件事?没有和别人碰撞的情况下

Brooks 的比喻是收麦子和生孩子。收麦子人越多越快,生孩子安排多少人都是九个月。
软件里对应两类工作,可以并行的(每个人做一个子任务,最后拼起来)和不能并行的(这一步必须等上一步完成、这一次判断必须等上一次判断收敛)。

一个 refactor 需要跨模块修改。你把它拆成”改 A 模块”、”改 B 模块”、”改 C 模块”三个 subagent 并行。
听起来合理。真实情况是,
改 A 时你会发现 A 依赖 B 的一个内部约定,那个约定改完之后 A 里的一些假设变了;
改 B 时你会发现 B 里有一个被 C 隐式依赖的性质;
改 C 时你才发现它的正确性其实建立在 A 的一个旧行为上。
这些依赖是语义层的,不是 API 层的,任务图上没有这些边,agent 也无法预先声明它们。
三个 subagent 并行做完,你拼回来的时候得到的是三份互相踩坑的 diff,
然后需要一个主 agent 或者一个人花几倍时间来 reconcile。

上面三种场景的共同底层原因是:子任务之间存在语义依赖,语义依赖不在图上。
它住在处境里,需要一个持有全局的主体不断更新对全体子任务的理解。
这个主体在 subagent 结构里通常缺位,主 agent 不看子 agent 的中间过程,子 agent 之间不通气。

Brooks 说不能任意分割的工作强行分割,损失从两方面来:一是子任务需要合理排序(有依赖),二是子任务之间必须沟通(信息不能孤立)。
agent 时代这两条不变,甚至更狠。agent 之间的沟通没有电话可打,它们必须借助文档或者主 agent 的转达,这两个渠道都要额外算力。

主 agent 要么盲信(承担风险),要么完全读一遍(多花时间,与使用子 Agent 的理念冲突了 )。

第一种辩护,只让主 agent 做抽样验证。听起来省时间,不用每个 subagent 的产出都全读,抽查几个就好。
抽样在工厂里成立,靠的是一个前提:流水线上的产品是同质的,抽到的几件能代表没抽的那些。

Brooks 法则:向进度落后的项目中增加人手,只会使进度更加落后。
它的机制拆开来是这样:项目已经落后,老手正忙,新加进来的人要培训,老手不得不放下手上的活来培训,老手产出下降,项目更慢,你更想加人。一个负反馈死循环。
2026 年的重演有两种形态,一种温和,一种严厉。
温和版:向进度落后的 agent 项目里加更多并行会话。

你有一个功能卡了两天没做出来。你的第一反应是”我开三个平行会话试三种思路,总有一个能成”。三个会话开出来,你现在必须同时管理三个会话的上下文、读三份日志、做三份判断。你的判断带宽本来就是这个项目的瓶颈(毕竟功能都卡了两天了),现在还要一分为三。

Brooks 把加人的成本拆成三项:任务重新分配、培训新人、额外沟通。
agent 时代这三项一项没少,只是换了名字。

  • 任务重新分配:在人时里是重新划分职责。在 agent 时代是上下文切分。你必须决定主 agent 保留什么、subagent 拿走什么、结果回来后怎么合并到主上下文
  • 培训新人:在 agent 时代是装填背景。每一个新 subagent(或者每一次新会话)都要从零装填项目背景。项目越复杂,要用的规则越多,上下文也就越长。
  • 额外沟通:在人时里是开会。在 agent 时代是读 agent 的产出并验证。你的每一份并行工作都需要你去看、去核、去判断合不合并回主线。你以为并行三个 subagent 有三倍效率,实际是三倍产出量、三倍验证量、三倍上下文切换成本。而人的验证带宽是常数,三倍产出压过来,你的时间大半花在追产出上,真正的推进只占零头。
    三项成本合起来的结构性论断是:agent 时代的沟通开销没有变便宜,反而因为按 token 计费变得更贵也更显眼。它从藏在会议室里、变成了明明白白印在账单上的一笔支出。这是好事,因为可测量的成本才是可以管理的成本;也是坏事,因为很多团队把它当成 agent 系统天生的固定开销,于是不去优化它。

对于绝大多数需要连贯判断的任务,用一个最强档模型单线跑,往往比用一堆低档模型并行跑要快、要便宜、也要准。

Brooks 那句”无论安排多少位女性,婴儿仍需要九个月才能出生”,
在 2026 年的翻译是:理解一个问题仍需要一个持有全景的主体投入连续时间,无论开多少个 subagent 平行工作。

既然大项目需要人多,又不能让人多这件事本身摧毁概念完整性和沟通效率,该怎么编制?
Brooks 给出的答案是 Harlan Mills 的方案,外科手术队伍(chief programmer team)。
核心思想是不要用平等的团队,用一个明确以某一个大脑为中心、其他人全部作为支持角色的结构。
就像手术室里,主刀一个人拿刀,其他所有人(副手、麻醉师、护士、器械管理员)都在为主刀提供支持。
责任集中在一个人身上,生产率来自整个团队。
原因:大型软件的概念完整性没有办法从多个大脑的共识里长出来,只能从一个大脑的持续持有里长出来。
共识可以搞定编排,可以搞定接口,搞不定概念。
一旦概念被多个大脑分头持有,就长出多个互相不兼容的版本,而这种不兼容比任何技术问题都要昂贵。

1975 年十倍差全部作用在人上,你选哪个程序员决定一切。
2026 年十倍差分成三个作用点:选哪个人、选哪个模型、用哪个 harness。
选人的重要性没有下降,从”选一个能写 10 倍代码的程序员”变成了”选一个能编排 10 倍系统的架构师”。
而且这三个十倍差是乘性的。
一个好的架构师配一个强档模型再配一个精心设计的 harness,跟一个平庸架构师配弱档模型再配粗糙 harness 之间的产出差距,理论上可以达到 1000 倍。

Mills 提出的外科手术队伍编制表大概是这样(不同资料细节略有出入,我按 Brooks 的描述整理)。
主刀(chief programmer / surgeon):定义规格,写核心代码,做所有关键设计决策,为整个产品的正确性和完整性负责。这是唯一持有整个系统概念的人。
副手(copilot):主刀的影子,能替代主刀(比如主刀请假时接手),日常也参与讨论和评审。这个角色的存在让主刀敢做决定,因为知道有人在同一个理解水位上审核。
管理员(administrator):处理项目管理事务(预算、进度、行政),把主刀从这些事务里解放出来。
文档编辑(editor):把主刀写的初稿文档整理成正式文档。
程序录入员(program clerk):管理项目的所有文件、版本、变更历史。1970 年代这是重体力活。
工具管理员(toolsmith):维护开发环境、工具链、编译器。
测试员(tester):设计和跑测试用例。
语言律师(language lawyer):精通编程语言的深奥细节,供主刀咨询。
秘书(secretaries):更基础的文书工作。

当代最小可用软件编制:一个人做主刀,一群 agent 担任支持团队。

那么主刀这个角色在 2026 年做什么?Mills 1971 年为主刀写的职责说明,2026 年可以一字不改地领用。
持有整个系统的概念。
拍板所有关键设计决策。
亲自写核心代码(关键路径、有创造性的部分)。
为最终产品负责。
四条一条没改。变的只是如何做这四件事。2026 年的主刀不用亲手敲全部代码,他用讨论、指令、审阅去完成这些职责。四条职责的内容和权重完全没变。
主刀必须持有目的,是 Mills 编制里最深、也最容易被 agent 时代的乐观派忽略的一点。

对比对话式编程 agent,你的介入手段是什么?直接改代码。你不满意 agent 写的某段,你自己删掉重写;不满意某个决策方向,你在对话里说”停,改用 X 方案”,然后 agent 从那一步继续。这就是修正权。修正权的一个具体测试标准是:你能不能在过程中间改产物,而不用重跑一遍。能,就有;不能,就没有。

概念完整性来自少数头脑,生产率来自多位协助。

Brooks 说,团队协作是好东西,评审是好东西,但系统的骨架不能靠投票决定。
骨架必须由一个头脑持有、由一个头脑推演、由一个头脑对每一处不一致做出裁决。
这就是他所谓的”贵族专制”。

每个带有各自特点的方案,每一个单独看都是小事,合起来就是不可维护。
用户读文档时的困惑、后续开发者接手时的震惊、bug 排查时的抓瞎,全部住在这些小小的不一致里。

概念完整性的价值不是审美的,是认知经济的。
概念完整性为什么必须由一个头脑持有?
Brooks 给的理由很直接:因为一个头脑能保证一致性,多个头脑的合成不能。

两个头脑做设计时,一致性必须外化。头脑 A 做的决策,头脑 B 不知道;要让 B 知道,就要写文档、开会、评审。
这些沟通渠道全部会漏东西。文档写不全所有隐含约定(很多约定 A 自己都没意识到,只是”这样感觉对”);
开会讨论的是明面上的分歧,摸不到暗处的默契;评审只能捕捉最严重的不一致,捕捉不到细微的风格漂移。
结果就是,两个头脑合作出的系统在每一处不一致点都会付一次学费:
要不然一致性错了(长出真正的不兼容),要不然一致性对了但代价高昂(花了大量沟通成本来对齐一件本应自动对齐的事)。
随说:协作成本高

推论有点反直觉:哪怕改动非常小,也最好让 agent 自己改。
一行改动的成本从来不在打字上,在于这个决定有没有进入持有项目状态的那个上下文。
随说:手动托管改动数据,会导致 Agent 缺乏上下文

修正权的完整动作从来是两步:改,加上让持有项目状态的那个头脑知道你改了。

守概念完整性的方式在 1975 年是”由一个人做设计”。
在 2026 年是”由一个人持有判据”。两者是同一个动作的两种表述。

体系结构工作的性质是判断(这个功能要不要有、接口应该长什么样、错误处理选择哪种语义),
判断需要持有目的、需要跨领域的处境感、需要对长期演化路径的直觉。这些能力人有,agent 没有。

实现工作的性质是执行(把已定的接口写出来、把边界情况覆盖住、把错误码返回对)。
这些工作需要的是耐心、细致、对语言语法的熟悉、对常见坑的记忆。
这些能力 agent 有,且做得比人更快也更仔细。

体系结构层的产物是文档:需求规范、接口约定、决策记录、协作纪律。
实现层的产物是代码:能跑的、能测试的、能部署的。
文档由人写,写的时候会迫使上百个细小决定显形(第 10 章会详细展开这个机制)。
代码由 agent 写,写的时候要严格贯彻文档里的每一条决定。

从工程实践的角度:写一份好的需求文档、把接口约定说清楚、把命名规范定下来。
这些”写文档”的工作在 agent 时代是最值得投入的一次性成本。它们不是为了记录,是为了给 agent 一个能在里面高效工作的框架。
没有这个框架,agent 每写一段代码就是在做一次即兴设计,而即兴设计的合成就是破碎。

软件系统的骨架,不是被采样出来的,是被设计出来的。
而设计需要一个能持续持有整体图景的主体,且这个主体的位置只有人能坐。

一位架构师做第一个系统的时候,往往是初出茅庐的年轻人。
经验有限,胆子小,也没什么时间。他做出来的第一个系统通常是精简的、抓住核心的、有克制的。
第二个系统来了。这次他是架构师,有资源,有信誉,有话语权。他开始把过去憋着的想法一个一个装进去。
它几乎必然过度设计,几乎必然试图讨好所有过去被亏欠的用户,几乎必然是这位架构师职业生涯里最糟糕的作品。

Brooks 说,一个成功的架构师影响实现团队的方式,应该遵守五条纪律。我按 Brooks 的意思重述一遍:
第一条,记住实现者才是承担创造性责任的人。架构师只能建议,不能替实现者做实现层的决定。
第二条,随时准备为自己的建议提供一种可行的实现方法,同时随时准备接受实现者提出的其他可行方案。
第三条,对自己的建议保持低调和平静。
第四条,随时准备为你建议的改进放弃功劳。
第五条,认真听取实现者在体系结构上的改进建议。

Agent 时代的第二系统,有点像 gpt5.6 的博文
https://developers.openai.com/api/docs/guides/prompt-guidance-gpt-5p6
好的长期提示词往往比新手想的短。它只写真正的核心约束(安全底线、关键接口、重要术语),把风格和判断留给 agent。

Brooks 这一章的教训可以压缩成一句话:架构师的第二个作品是他最危险的作品,因为他把所有过去憋着的想法都装进去了。
随说:要克制

2026 年的宿主是提示词、agent 框架、和你自己的 workflow。
三个宿主各自都有第二系统效应的完整症状:加得越多、失去得越多;
每一项都能证明必要、合起来的产物却不好用;
设计者觉得自己在进步、用户觉得自己在退步。

好的做法:把需求原文完整给 agent,让 agent 自己读。
如果原文里有 agent 不理解的部分,让它问你,你在对话里补充说明。
提前拆解相当于是转述,会丢失一部分信息。

我给自己项目定的规矩明确写在纪律文件里:测试断言不是金标准。
测试失败先归因:这次失败是改动的错,还是断言本身写错了?该改断言就改断言。
翻译成 Brooks 的语言:记叙性定义(需求)是标准,形式化定义(测试)是辅助,冲突时形式化一侧服从记叙性一侧。

守住”记叙性优先”这条纪律,是 agent 时代 harness 设计里最关键的原则之一。
随说:因为记叙性是意图,没有具体的指标,Agent 就没法为了某个指标瞎优化。

一份能跑的代码比一万字描述都准。

开发团队自己做的测试永远有盲点,因为写测试的人和写代码的人共享同一套假设,他们的盲区是重合的。
真正能挖出问题的是完全不同背景的人,独立于开发过程之外的评审者。
随说:独立董事也是基于这个假设?

“意图如何在实现团队里贯彻”的问题。Brooks 给的答案是三层:文档要精确到不可转述、形式化和记叙性都要有且指定标准、约束要焊进结构而不是靠自觉。

在 2026 年是”测试配需求文档”,且冲突时的标准从”形式化优先”改成了”记叙性优先”。因为形式化定义在 agent 时代变成了可被优化的攻击面。

软件项目失败的机制没变过。资源、技术、人才、时间都不是最常见的死因,最常见的死因永远是交流断裂。而交流一旦断裂,各个团队开始基于各自对系统的假设独立工作,产物合起来时就是巴比伦塔的当代形态:几十个模块每个都能跑,合起来跑不了。

这一章的三个关键,五十年后依然:
一,假设代替核对是交流断裂的第一形态,也是最常见的形态。
二,组织需要一份工作手册,把散落的决策、文档、决议汇成一个可查询的整体。
三,信息隐藏是好事还是坏事,取决于你在讨论执行还是问责。

团队 A 在做一个模块,它需要调用团队 B 的模块。团队 A 不确定 B 的模块的某个行为具体怎么样,但没时间去查、没时间去问、也不想被认为”不知道这个”。于是团队 A 假设 B 的模块的行为是 X。写完了、跑通了、交上去了。然后 B 的模块的实际行为是 Y。集成时炸了。查根因,发现团队 A 从一开始就假设错了,而这个假设从来没被核对过。

这不是任何一个团队的错,是整个组织的结构错:没有让”核对”成为最省力的选项。假设不用付学费(立刻能写代码),核对要付学费(要问、要等、可能显得不专业)。学费结构决定了行为,行为决定了组织的失败模式。
随说:很多时候重复造轮子,不愿意直接问,背后可能就在怕别人知道自己不懂。或者怕对方不合作。

你的需求里有一段没写清楚,你自己以为写清楚了,因为你脑子里有默认假设。
agent 读完不会停下来问你,它会用它对你意图的最可能猜测直接开工。
解法:先讨论、再动手,需求不明先复述确认,别带着猜测开写。

分层的判据是这样:在做事的时候用信息隐藏、在追责的时候撤销信息隐藏。做事的时候 agent 只看自己的接口,做得对不对由做事的判据说了算;追责的时候审计者看全部,看得懂看不懂由审计的深度说了算。两层的用户不同,需求不同,结论就不同。

agent “自动记忆” 的想法挺好,但是 Agent 没能力识别这些记忆还有效吗?怎么抉择?
信息隐藏的思路:历史信息默认不可见,只在明确请求时才展开。( 这不是做成了 RAG ?)

Brooks 说,团队组织的目标是为了减少必要的交流和协作量。
Brooks 说组织设计要在两层之间找平衡。分得太粗,都在开会;分得太细,都在瞎猜。

Brooks 说好的组织需要在树状结构上叠加一层网状的沟通渠道。
这些渠道不是正式的汇报线,是”直接联络”的授权:允许工程师跨部门直接沟通,不用经过多层审批。

对治办法五十年没变:让必要交流有渠道、让所有参与者读同一份现实、让核对比假设便宜、让共享状态成为默认。

Brooks 说过一句话,值得逐字重述:仅仅通过对编码部分的估计,然后乘以其他部分的相对系数,是无法得出对整项工作的精确估计的。
随说:无法从编码时间倒推

不同项目的编码份额差别很大,不同任务的其他工作(讨论、测试、部署、debug)占比也差别很大。用一个平均倍数外推,只会得到一个平均没意义的数字。

“agent 在玩具任务上成功”到”agent 能交付产品”之间隔着的,就是这条不可外推线加上第 1 章说的九倍矩阵。
“玩具任务的数据”跟”你要做的这件事”处在两个完全不同的复杂度区间。
玩具任务的每一步都在 agent 训练数据的分布内,
你的实际项目每一步都在分布外。
agent 在分布内的效率极高,在分布外的效率骤降。
这两个效率的差距可以达到十倍甚至一百倍,但没人在 demo 里演示这个。

Brooks 引用 Portman 的数据说,全职程序员真正花在编程和调试上的时间只有 50%。
剩下的 50% 花在别的事上:开会、写文档、装配硬件、去食堂、处理组织事务。

一个典型的时间账:
需求讨论(策划):几小时到几天,看项目复杂度。这是最花时间的一部分,且这一份时间没有 agent 可以替代。
方案讨论(策划):几小时,跟 agent 讨论架构、接口、边界。
Agent 编码:几分钟到几小时,具体看功能规模。
审读产出(测试):跟编码时间同一个数量级。你要看 agent 写了什么,是不是对,是不是符合你要的。
修改、返工(测试):审读发现的问题的处理,往往是审读时间的一半到一倍。
集成、部署(系统测试):这一份没有可预测的数字,看你的环境有多标准。

Brooks 那条”编码不是主要工作”的洞察在 2026 年成了字面为真。
所有的工作重心都在编码之外:想清楚、写清楚、看清楚、修清楚。

但这个 5 倍的边界要用 Brooks 自己 1986 年在《没有银弹》里的话来画。
高级语言消除的是表达的复杂度,构思的复杂度原地未动。
他那个判断精确得刺骨:软件的根本困难在于决定说什么,而不是如何说。

要建立基线,需要两件事:一批肯记账的人(不管是个人开发者、公司团队、还是学术研究者),和一段时间的积累(大概十到二十年,看行业形态演化速度)。第一件事每个人都可以贡献。第二件事需要耐心。

2026 年的上下文窗口有几个特点:物理有限(几万到几百万 token)、访问快(比工具调用快几个数量级)、贵(价格按 token 计)。agent 用户必须决定哪些信息”住”在上下文里、哪些放在外部工具里按需取。住在上下文里的东西 agent 立刻能用,但装不下太多;放在工具里的东西便宜,但每次取要花一次工具调用。
随说:和之前内存很贵一个道理

agent 时代的”新的削足适履手册”

  • 上下文分层,渐进式披露。原则是『这次任务需要吗』
  • 按需检索,RAG 等工具进行查询
  • 摘要与索引,长上下文塞不进去,先塞索引,有需要再加载
  • 过期清理
  • 分级模型,不是所有的任务都需要用最好的模型去跑

数据的表现形式是编程的根本。

2026 年下一个稀缺介质出现了:上下文窗口。这一章的所有原理(设立规模目标、控制规模、发明减少规模的方法、警惕局部优化、投资于表现形式)一条不改地重新成立。而且比 1975 年更重要,因为上下文管理的好坏差异可以造成十倍的账单差异和数倍的产出质量差异。

1975 年是”架构师保持警觉、培养开发人员从系统整体出发的态度”。

先讨论再动手、测试失败先归因、别带着猜测开写、局部改动要考虑对系统整体的影响。

正确的做法是分级派活。搜索、格式转换、简单分类:低档模型。写代码、多步推理、判断歧义:中档模型。核心决策、关键判断、需要跨领域推理:强档模型。每一档就是一个”组件版本”,你根据任务的实际需求选。

行业里下一个稀缺介质是什么?

  • 可能是 agent 的注意力带宽(一个人能同时管理多少 agent,是一个正在被逼近上限的资源)。
  • 可能是判断带宽(一个人一天能做多少高质量拍板,是一个远比人们想象的低的数字)。
  • 可能是评审带宽(一份 agent 产出被人读一遍需要多少时间,随产出量线性增长)。每一个都会成为下一次”削足适履”的宿主。

第 10 章 · 提纲挈领
文档核心内容:目标、手册、进度、预算、组织架构、说明书;
Brooks 说这不是巧合。任何一个多主体协作的组织,都必然需要这五类东西来维持自身的存在:
一,目标。这个组织要做什么。
二,手册(在软件项目里是产品规范)。做出来的东西是什么样、怎么用。
三,进度。什么时候做出什么、当前进度到哪。
四,预算。资源多少、怎么分配。
五,组织。谁负责什么、决策链是怎样的。

Agent 时代文档需求:
一,需求规范。条文级、带章节号可引用。这是”目标”和”手册”的合体:说清楚要做什么、做出来是什么样。它必须是可寻址的(每一条能被单独引用),因为 agent 讨论时会频繁引用具体条文。
二,决策记录。每一个重要决策一条,说清楚做了什么决定、什么理由、有没有过勘误。这是”组织”的当代形态:决策链的记录。它必须带勘误史,因为项目会演化,早期决策的修正必须能被看到,而不是被覆盖。
三,当前热点。哪些事在做、还没落地。约定”落地即剔除”(第 7 章讲过)。这是”进度”的当代形态。它必须永远描述现状与未做,让新会话读完就知道从哪接手。
四,协作纪律。项目里的规矩:先讨论再动手、测试断言不是金标准、局部改动要考虑整体影响。这是”组织”的另一半:工作方式的规约。它写下来是为了每次新会话装填,让协作方式不因执行者变化而变化。
五,预算与资源。API 费用、token 消耗、时间投入。这是”预算”的当代形态。它没进第 7 章的入职材料,因为它不是给新会话读的,是给你自己读的。多数项目忽略这一份,直到账单让人吃惊时才后悔。

书写这项活动需要上百次的细小决定,正是由于它们的存在,人们才能从令人迷惑的现象中得到清晰、确定的策略。

你把”决定清楚”这份工作留在了自己这一侧,agent 只做实现,实现变得可靠。

这就引出这一章最重要的一句话,我想单独列出来说:文档是源码,代码是编译产物。

从文档到代码的翻译,以前是手工,现在可以自动。
你写清楚文档,agent 读文档、生成代码、跑测试、把细节做完。
让”文档即源码”从一种哲学立场变成了工作方式。
文档可验证:你写的文档能不能被 agent 编译成对的代码,就是你的文档是不是清楚的可验证判据。

“文档即源码”框架下的做法。发现一个 bug,先问:这个 bug 是文档里的哪个决定错了/含糊了?找出文档里对应的段落,修它。
然后回到 agent,让 agent 根据新版文档重新生成或修补代码。核心动作是修文档。

2026 年的工具让预警机制更精细。
第一个具体的做法:把关键需求写成条文级规范,agent 每次提交代码时被要求引用具体条文(”这段代码实现了 4-3-2 条”)。如果 agent 写了没在规范里的行为,你能立刻看到。如果规范里的某条一直没被引用,说明这条需求没实现。规范和代码的偏差成了可扫描的信号。
第二个做法:热点文档按”落地即剔除”维护。它因此永远应该等于现状:每次你读它,发现它和现实对不上,就说明有事漏了。这个”读它就能发现问题”的性质,就是 Brooks 说的预警机制的当代形态。
第三个:决策记录里的每条决策要有明确状态,已经推翻的结论要合并到新结论的记录。项目演化时,人容易记得新的决定,忘掉旧的决定被推翻这件事。留一条明确的”废弃”标记,未来的读者(包括未来的自己和 agent)就不会用错决定。
三个做法合起来,让文档系统成为一个活的现状快照。任何跟现实脱节的地方都会浮现出来。这就是 Brooks 所说的”状态监督”在 agent 时代的具体机制。

项目经理的日常:
项目经理的基本职责是使每个人向着相同方向前进。
项目经理的主要日常工作是沟通,不是做决定。
只有 20% 左右的管理时间用于从头脑外部获取信息。剩下的 80% 是向外传递信息(把决定和方向讲给相关人)、做决定、处理关系。

  • 我的时间大头花在向外表达(需求、纠偏、拍板的理由),从外面收信息(读产出、读日志)占的是小头。
    管理层看到 agent 系统的仪表盘一切正常,就以为系统在做正事。等到真实产出的问题浮现,才发现仪表盘监控的所有指标都不是关键指标。

不要被指标的繁荣蒙蔽。
无论是对人还是对 Agent,监控“过程参数”都不等于理解“真实意图”;
能被量化呈现在仪表盘上的,往往都不是最关键的失效点。

文档承载决定,决定驱动一切。

第 11 章 · 未雨绸缪
Brooks 用化学工业做类比开场。化学工程师早就知道一件事:实验室里做通的反应过程,没有办法直接搬到工厂规模。中间必须有一个”实验性工厂”(pilot plant),比实验室大、比正式工厂小,用来发现实验室规模下看不见的问题。工厂建成后,实验性工厂通常被拆掉。它的价值不在它自己,在它揭示的问题。

Brooks 说,软件也一样。你写的第一个系统几乎必然不好用。这是因为你在写它之前不知道要做什么。等你写完,你才知道你本来要做的是什么。这时候正确的做法不是修补第一个系统,是把它扔掉,用你学到的东西重写。

写第一个版本时,你不知道很多事情。你不知道用户真正的需求(你以为你知道,往往不对),不知道系统会遇到的边界情况(你没经历过),不知道你选的技术栈的坑(你还没踩过),不知道你的架构假设中哪些成立哪些不成立。第一个版本被写出来的过程,是这些”不知道”逐一被回答的过程。等第一个版本写完,你手上有的不是”一个能用的系统”,是”一堆关于原来不知道的事情的答案”。

好的 agent 工作流应该明确地为”侦察 vs 产出”留出两个阶段。侦察阶段的产物随时可以丢,学到的东西记进决策记录。产出阶段的产物是要用的。这两个阶段的模式完全不同:侦察阶段快速尝试、勇于犯错;产出阶段严格纪律、每步核对。混着做,两种效果都得不到。

你以为的甲方要求,跟甲方最后想要的东西,中间隔着”甲方看到你做出来之后的反应”。

用户在没看到你做出来之前,往往不知道自己到底要什么。他给的需求描述是他以为的需求。
他看到你的产物后,会立刻发现自己真正想要的其实是别的东西。
这不是他故意为难你,是他现在有了新的信息(他看到了)。
这就是”lean startup”、”MVP”这些当代概念的深层依据。
随说:原型很重要

全自动 agent 系统在这里有一个结构性缺陷。
它试图把”用户反馈”这个环节也自动化:用评分函数模拟”用户满意度”、用另一个 agent 扮演”用户”。
这两种模拟都不可靠。评分函数模拟不了”我看了才想到”这类反馈;
扮演用户的 agent 没有真实用户的处境,它猜的用户偏好只是训练数据里的平均口味,不是你的具体用户的真实需求。
少了真实用户,这个流程就退化成 agent 自己跟自己讨论,输出稳定但方向乱漂。
随说:评估自动化有点类似?那所谓的数据飞轮有啥用

程序员不愿意为设计书写文档的原因,不仅仅是由于惰性;
更多的是源于设计人员的踌躇,要为自己尝试性的设计决策进行辩解。
一旦你把决定写下来,别人(也包括未来的自己)就会问:为什么这样选?为什么不那样选?考虑过 X 吗?考虑过 Y 吗?
所以人回避写文档,把决定留在自己的脑子里,不用面对辩解义务。

具体做法可以有几种:每个 bug 修复必须附一条决策记录(三行也行),说明根因、选的修法、放弃的备选。

所有修改都倾向于破坏系统的架构,增加了系统的混乱程度;
即使是最熟练的软件维护工作,也只是放缓了系统退化的进程。

当你发现当前会话的 agent 越来越糊涂,最好的选择不是”再解释一次”,是把当前的结论沉淀成一份文档,
然后开新会话,装填这份文档,从零开始。新会话的 agent 上下文干净,判断力也回到最高水位。

Brooks 这一章的核心信息可以压缩成一句:软件不是造出来一次就完事的东西,它是一个持续演化的过程。
你的任务不是”造出一个完美的产物”,是”设计一个能承受持续变化的过程”。

第 12 章 · 干将莫邪
Harness 工程是当代工具策略

2026 年的对应物是 harness 工程。当代所有严肃的 agent 使用都涉及一个 harness 层:给 agent 装什么工具、怎么装填上下文、怎么处理错误、怎么记录判断、什么时候停、什么时候求助。这个 harness 层的每一个设计决定都直接影响 agent 的实际能力。

Harness 工程的具体内容 Brooks 用了另一套词汇讨论过:工具集合、目标机器、机时分配、逻辑仿真装置、程序库。这些在当代的对应物大概是:
Agent 可调用的工具集(读写文件、执行命令、访问 API、搜网页),对应 Brooks 的”通用工具集合”。
模型档位选择(强模型用于关键决策、弱模型用于批量简单任务),对应”机时分配”。
参考代码库和文档索引(agent 能随时查询的资料),对应”程序库”。
沙箱和测试环境(agent 可以安全试错的地方),对应”调试机器”。
预算与止损(每个任务的 token 上限、时间上限、错误重试上限),对应”资源规划”。
五套东西的每一样都值得花精力设计。

一个对话式编程 agent 做的事情,本质上是:读文本(源代码、日志、文档)→ 改文本(生成新代码、修补现有代码)→ 跑文本(执行代码看结果)→ 再读文本(看输出和错误)→ 循环。这就是文本编辑的完整闭环,只不过每一步都被自动化了。

全自动研究系统是批处理,人在回路是交互式。两者的适用域之分,Brooks 五十年前已经画完了:批处理适合真正无需人判断的负载,人在回路适合需要中途判断的负载。混淆这两种适用域,就是当前 agent 生态里最大的一类工程失误。

在选 agent 架构之前先问自己,这项工作里是否有中途需要判断的时刻。

一个思想实验:两个团队做同一个功能,一个用对话式 agent(Claude Code 之类)交互式做,一个用全自动 agent 系统批处理(类似 Claude Code 的 /goal 命令)做。前者可能六小时一次通过,后者可能几天都出不来。这个差别的根本原因不是模型好坏,是交互式反馈闭环和批处理反馈闭环的物理差异。

第 13 章 · 整体部分
Brooks 的答案是反直觉但有实证支撑的:详尽的体系结构工作不但让产品更易使用,还让开发更快、bug 更少。
项目里有两类工作时间。
一类是”生产性”时间,真的在往前推进。
另一类是”填坑”时间,在处理架构没想清楚导致的问题,比如接口对不上、模块假设冲突、事后发现需要重构、集成时才发现依赖漏了。
填坑时间几乎没有产出,全是浪费。

架构做得马虎的项目里,填坑时间可能占总时间的一半以上。
你以为在赶进度,实际上大部分时间在填自己刨的坑。

这条命题在 agent 时代格外重要,因为 agent 让实施阶段变得极其快。
慢的部分只剩前期的架构和后期的集成审查。
如果你不把架构做透,前期省下的一点时间,会被后期几倍地花回去。

Brooks 引用他的同事 Vyssotsky 一句话:许许多多的失败完全源于那些产品未精确定义的地方。

你给 agent 一份需求文档。agent 读完,开始工作。文档里没有的部分(就是你以为不用说的 E),agent 会用它对你意图的猜测填补。它的猜测可能是好的(如果它训练数据里的常识跟你的常识对齐),也可能是坏的(如果不对齐)。你事先无法预测哪种情况会发生。

未精确定义之处在 agent 时代比 1975 年更危险。1975 年程序员遇到含糊会犹豫,含糊有物理痕迹。2026 年 agent 遇到含糊不犹豫,含糊没有物理痕迹。你要靠自己的注意力去发现所有含糊,且发现动作全部要发生在验收时,因为过程里 agent 不会告诉你。

翻译成 agent 时代的具体做法:人在回路不是可选项。凡是任务涉及”未精确定义之处”的项目(就是绝大部分真实项目),都必须有人在场,随时准备回答 agent 遇到的含糊。全自动系统在这类项目上必然失败,因为它没有回答问题的接口。

Brooks 引用 Vyssotsky 的另一条:在编写任何代码之前,规格说明必须提交给测试小组,以详细地检查说明的完整性和明确性。开发人员自己不会完成这项工作。
随说:需要交叉

Brooks 在这一章介绍了 Wirth 的自顶向下设计方法。核心思想是:先做高层设计(整个系统的结构),然后逐步展开到细节,每一层的设计对应下一层的目标。这样每一步都在明确的框架里做,不会陷入”边写代码边想架构”的困境。
有时必须回退,推翻顶层设计重新开始。自顶向下不是一次到底的直线过程,它有反复。
随说:自顶向下设计

跟 agent 会话是一种极其高效的”终端工作”,几分钟能推进过去要几小时才能推进的东西。但会话的产出质量取决于会话前你想清楚多少、会话中你判断多少、会话后你消化多少。这三份”桌面工作”的时间投入必须跟得上会话本身,否则会话的产出会成为一堆没被消化的产物,堆在项目里没人清理,最后混乱不堪。
随说:历史上是 1:1 的时间,一半写代码,一半思考。

每段跟 agent 的会话之后,人这一侧要有几段等量或更长的桌面工作:
第一段是读产物。会话产生的代码、文档、决策,你要真的读一遍,不能只看 agent 的总结。这一段的时间几乎等于会话时间,因为你要覆盖 agent 生成的所有东西。
第二段是更新热点文档。会话推进的事情从热点文档里剔除,新发现的事情加进去。这一段几分钟到十几分钟。
第三段是把学到的修进确定性层。会话里发现的新的决策、约定、坑,写进决策记录或规范文档,让下次新会话能装填。这一段可能十几分钟到几小时。
第四段是规划下一步。你根据当前状态想清楚下一段会话要做什么、要提什么问题、要什么样的产出。这一段几分钟到十几分钟。
四段加起来,桌面工作时间跟会话时间的比例大概是 1:1 到 2:1。这跟 Brooks 说的 1975 年比例接近,甚至更极端。

Brooks 说系统调试花费的时间比预料的更长,且系统调试仅仅应该在所有部件能够运作之后开始。
在 agent 时代,这条纪律要落到一个新的具体形态:环境契约必须先自检。

场景。你要 agent 做一个跟外部系统交互的任务:调用某个 API、连某个数据库、访问某个服务。你告诉 agent”这些外部依赖都已经准备好了”,让它开始工作。
如果外部依赖真的准备好了,agent 的工作是纯粹的”实现”,只涉及它自己的代码。如果外部依赖没准备好(比如 API 密钥没配、数据库没启动、服务没部署),agent 的工作变成了”实现 + 环境 debug”的混合。它可能会误诊环境问题为代码问题、可能会写一段 workaround 绕过环境问题、可能会假装能连上继续做,然后所有产出的价值都被污染了。

Brooks 那条”部件正常前不能做系统集成”的当代版本是:给 agent 装填任务时,环境的正常性必须先被独立验证,不能靠 agent 自己”信任 harness 的承诺”。

agent 时代的常见违反形态是大而稀的整体重写。全自动 agent 系统每个节点是一次全量重写:所有代码作废、从头产生新的一份。变更量子无穷大,连 diff 这个概念都不存在,于是”这次改了什么”在结构上不可问。

独立评审、自顶向下加低成本回退、桌面工作与会话时间等量投入、环境契约先自检、增量集成,这些是这一章五条命题的当代具体形态。每一条都不是新的方法,是 1975 年就说清楚的老原理在新载体上的重新落地。

第 14 章 · 祸起萧墙
Brooks 用一个问题开场:项目是怎样延迟了整整一年的时间?答案是:一次一天。

Brooks 说,比起重大灾难,日复一日的进度落后更难以识别、更不容易防范、也更加难以弥补。重大灾难是可见的、可上报的、可动员的;小延迟是隐形的、习以为常的、没人愿意为它专门开会的。就是这种隐形,让它成为项目失败的主要模式。

这一章讨论的是如何让隐形的失败可见。Brooks 给的答案是:里程碑、状态报告、独立测试组、明确的进度纪律。
听起来是行政管理,实际上是让”你今天在哪个位置”这件事变得可回答、不模糊、也没得躲。

一个具体的、我给自己项目定的规则:任何一次 agent 尝试花了上下文预算的 30%、且没有明显进展,我就停下来重新讨论方向
2026 年一次一节点的延期,让 agent 用户同样防不住,除非把弃线规则焊进 harness。

形式化定义明确是指:这个规则能被自动检查。跑出数、分数高,都能自动检查。
里程碑定义明确是指:这个规则不能通过绕过它来满足。里程碑要求的是”完成了目标任务”,而不是”通过了自动检查”。

而”负债”这一环,第 13 章讲过按 Vyssotsky 命题的推论,永远不可能精确到形式化。所以收紧它的最后一步只能是人,即人作为里程碑的最终审计位点。

agent 不怕挨批(它没有情绪),不怕被追责(它没有人权也就没有办法负责),也不怕影响自己前途(它没有前途)。它没有 Brooks 说的那种”充分理由不共享信息”。但它同样是一个永远不主动上报坏消息的下属经理。
为什么?因为坏消息的识别需要判据,而判据在题外的前提链上,不在它的上下文里。

Brooks 的忠告是:仔细区分状态报告、毫无惊慌地接收报告、决不越俎代庖,将能鼓励诚实的汇报。
对治办法是 Brooks 说的那三条:

  • 区分状态与评价(”你做了 X 和 Y”是状态,”这不对”是评价,把两者混在一起会淹没状态);
  • 毫无惊慌地接收(当 agent 报告”我做的这个东西可能有问题”时,你的反应决定它下次还敢不敢报告,稳定接收才能鼓励再报);
  • 决不越俎代庖(不要在 agent 报告问题后立刻自己重做那部分,让它继续按你的指导修,不然它下次干脆不报告了)。

Vyssotsky 说两套不得互相污染。翻译过来是:不许拿事后的手改事前的账。
你不能因为实测发现了不利结论,就回去修改预注册的判据(”其实我们本来说的是 X”,明明预注册里写的是 Y)。
你也不能因为预注册写得比较模糊,就在实测里把它解读成对你有利的形态。

agent 时代的独立评审比 1975 年便宜太多。新会话不带任何前一天讨论的上下文进场,直接看当前状态。它会问一些内部会话不会问的问题:”你说做完了 X,我看代码里没有 X 的实现,怎么回事?”、”你说预期一周做完的 Y,为什么两周了还没交?”、”这份文档里说的方案 A 跟代码里实现的方案 B 有差别,是不是有个决定没被记录?”

里程碑本身是设计出来的,不是自然发生的。你不预先想清楚”什么算做完这件事”,就没有里程碑;
没有里程碑,就没有防止自欺的装置。
所以里程碑的设计工作,是所有想避免”一次一天”式延期的项目的第一步工作。

第 15 章 · 另外一面
Brooks 用一个双面的意象贯穿这一章:程序有两面。
一面朝向机器(源代码、编译产物、运行时行为),
一面朝向用户(能被理解、能被使用、能被继承的说明)。

Brooks 说这不是因为程序员懒。它是一件有具体心理机制的事:写文档要接受辩解义务(第 11 章讲过),而人天然抗拒辩解义务。
这条抗拒五十年没变,也不会因为下一波培训文化改变。
随说:不喜欢写文档是人性问题

即使你写的程序只给自己用,你也要写文档,因为半年后的你已经不记得当初为什么这么写。
用户和作者是同一个人这件事,不豁免文档需求。人对自己代码的遗忘速度比想象快得多。

Brooks 说,关键用户文档的绝大部分需要在程序编制之前书写。
这条 1975 年是给”先动手写再考虑用户”这个常见程序员反模式的对治。他说:写用户手册的过程会迫使你想清楚用户到底怎么用这个东西,这些”想清楚”会反过来影响你的实现选择。等实现完了再想用户,你已经把很多决定锁死了,用户手册变成了”给已有实现做辩护”。

这条在 agent 时代升级为一个更强的版本:先讨论后动手。

Brooks 说流程图是被吹捧得最过分的一种程序文档,且很少有程序需要一页纸以上的流程图。
这条 1975 年是给当时”流程图正确才能真正设计程序”这个流行观点的反驳。

Brooks 1986 年在《没有银弹》里对流程图做了更彻底的判决:程序员在开发之后而不是之前绘制流程图。也就是说,流程图不是设计工具,是事后美化的图示。真正的设计发生在别的地方(脑子里、白板上、伪代码里),流程图只是把已经想清楚的东西画成一张能给管理层看的图。
随说:流程图不是设计工具,是美化工具。

规范文档的变化和代码的变化必须同一个 commit。不允许”改了规范但代码还没跟上”或者”改了代码但规范还没更新”这种中间状态。这个纪律让规范和代码永远保持一致,也让审查者可以在同一个 commit 里同时看到”这次改动的意图(规范)和实施(代码)”(但实际上 agent 有概率手快了 commit 掉,这种时候最好在下个 commit 就补文档)。

程序员写文档时,总有一种诱惑:只写”这段代码做了什么”,不写”为什么这样做”。因为”做了什么”是可以从代码里直接读出来的,你把代码读一遍就知道。”为什么这样做”读不出来,它涉及外部信息(业务背景、当时的技术选型、当时被否决的备选方案、当时的约束)。

程序员倾向于写”做了什么”式的注释和文档,因为它容易写、也容易被验证(跟代码对照就能知道对不对)。他们回避写”为什么这样做”式的文档,因为它难写、也容易过时(业务变了、当初的理由不再成立)。

目的无法被语法完整表达,从 1975 年的洞察升级为 agent 时代的推论:所有能被自动化的表达工具都碰到同一堵墙,目的永远只能由持有目的的主体在场持有。

Brooks 那句”程序有两面,用户面跟机器面同样重要”,在 agent 时代要加一句:agent 就是让机器面变便宜的工具,用户面的成本一分未减,且现在占了总成本的大头。用户面这一半没有 agent 可以外包,它需要一个能持有用户视角的人做主体。

第 16 章 · 没有银弹
没有任何技术或管理上的进展,能够独立地许诺十年内使生产率、可靠性或简洁性获得数量级上的进步。

这句话在 1986 年是刺耳的。当时的软件行业正处在极大的乐观情绪里。人工智能承诺解决编程、面向对象承诺解决复杂度、CASE 工具承诺解决估算、第四代语言承诺解决表达、专家系统承诺解决判断。每一茬技术都以”这就是银弹”的姿态出场。Brooks 说,不。这些技术每一样都有价值,但没有一样是银弹,因为它们攻击的都不是软件真正的困难所在。

Brooks 论文的标题用了一个具象的意象。银弹是传说里能一枪打死狼人和吸血鬼的武器,它的特点是一发解决问题。

Brooks 论证的核心是:软件的困难有一部分是可以被技术进步大幅便宜化的(他叫偶然困难),有一部分是本质上不可被技术进步消除的(他叫本质困难)。技术进步只能作用于前者。
本质困难有四个固有性质:复杂度、一致性、可变性、不可见性。

Brooks 说,软件的复杂度是本质的。它是软件对象本身的性质,不是可以通过更好的工具消除的偶然复杂度。

软件描述的是抽象概念系统:不同层的抽象、不同层之间的交互、不同类型的数据结构、不同风格的算法。这些抽象在任何两处几乎都不重复。
这跟物理系统很不同。物理系统里有大量重复(同样的钢梁、同样的水管、同样的电路),软件里几乎没有重复。
凡是”重复”的部分早就被抽象成函数了,剩下写出来的都是不重复的东西。
这个性质导致软件的复杂度随规模非线性增长。
一个 10000 行的程序不是 1000 行程序的十倍复杂,而是几十倍甚至几百倍复杂,因为部分之间的交互组合随部分数指数增长。

在 agent 时代,复杂度这条本质性质一分未减。
agent 让写代码变便宜了,但没有让代码变简单。
你产出的代码规模可以在同样时间里翻十倍,但那十倍代码的复杂度是同规模代码的十倍复杂,甚至更多,
因为你没有时间做同样精细的架构审视(我现在的个人项目就在这个泥沼中,我正在探索其它办法更好地解决整体的 review 问题)。

agent 时代软件系统的规模正在快速膨胀,而管理这些系统的复杂度的能力(本质上是判断能力)没有翻倍。
这个不对称的合成结果是每个人都在维护比五年前大得多的系统,也承担比五年前重得多的复杂度管理负担。

行业里已经有声音在讨论 AI slop(AI 批量产出的低质量内容)。
这个现象的软件版本就在眼前:AI 批量产出的低质量代码。
它不是骗人的代码,只是没有经过复杂度节制的代码。
每一段单独看都合理,合起来是一个没人能理解全貌的巨型系统。
这就是复杂度这条本质困难在 agent 时代长出的新形态。

Brooks 说的最刺骨的一句是:软件的复杂度大半是”随心所欲、毫无规则的人为惯例”。

比如你要写一个连接数据库的模块。你必须知道这个数据库客户端库的 API 长什么样、它的错误码怎么定义、它的连接池怎么配置、它的事务隔离级别怎么选、它对特殊字符的转义规则是什么。
这些东西没有一个是从”数据库的第一性原理”能推导出来的。
它们是这个具体客户端库的作者当年拍脑袋定下来、后来因为兼容性没法改的。
你必须记住所有这些约定,才能正确使用这个库。

模型再强,也只能记住惯例、不能推导惯例,因为惯例本身就没有”能被推导”这个性质。这是一致性困难的本质:不可推导性。

在 agent 时代,一致性困难的形态有个新特点。agent 训练数据里有大量的惯例知识(各种库的用法、各种协议的规范、各种平台的接口),这让 agent 处理常见惯例时比人快、比人准。这是好事。
但每次遇到一个训练数据外的惯例,agent 就得从零学起,且它无法从别的知识推导。它会用它对同类事物的经验做猜测,猜错的可能性很高,且它没法自我识别猜错。

任何一个投入使用的软件系统,它的需求会随着时间演化:用户的使用方式在变、环境在变、竞争对手在变、法规在变。
软件不像桥梁。桥梁建成后几十年不用改,软件建成后必须持续演化。

你以为需求稳定的时候,用户看了原型立刻改主意;改完让 agent 重做,做出来又改主意。
这个循环本身是好的(它让最终产品更贴合真实需求),
但它证明的正是可变性这个本质困难:需求本身在被建造的过程中会变化,装填是一次性快照,快照冻结的那刻起就在过期。

不可见性导致几个后果:设计难以在头脑里完整持有(超过一定规模就必须分块想)、沟通难以精确(图形辅助只能片段化)、审查难以彻底(没有一张能一眼看全的”设计图”)。

agent 的执行过程本身也是不可见的。你看不到 agent 在推理时”想了什么”。你看到的是它的输出(可能包括推理链的显示),但推理链不是它实际做的事情,而是它给自己产出物做的事后叙述。真正的推理发生在模型内部,几十亿个参数的联合作用,无法被完整可视化。

四个性质(复杂度、一致性、可变性、不可见性)在 2026 年一条没有被消灭。每一条都在当前的 agent 生态里按了指纹。

复杂度:agent 让产出规模翻了几十倍,复杂度按规模非线性增长,所以人的复杂度管理负担变重了,不是变轻了。
一致性:agent 处理已知惯例更快,但未知惯例(当地约定)的问题比过去更严重。
可变性:反馈闭环变短,需求变化的频率和幅度都在增加,可变性负担加重。
不可见性:agent 内部推理不可见,且它产出的代码规模让”看全”这件事更难。
四条本质困难,一条没被 agent 消灭,反而每一条都在 agent 时代长出了新形态、变得更硬。

模型档位从中等升到最强,代码质量肉眼可见地涨。偶然复杂度确实在被消灭。但死因(判据无人持有、口径无人审、目的无法被完整表达)住在根本任务里,模型轴上没有它的解。你在偶然困难的曲线上再涨十倍百倍,也涉及不到本质困难的领域,因为它们根本不在同一个维度。

Brooks 的论证是说 scaling law 是引擎变快,但软件的根本困难在月球方向。曲线继续也够不着。

数字审计有效的前提是先有人审过口径,论文评分有效的前提也一样。

全自动 agent 今天真正的可用域:它就是”判据幂等、方案空间已被人类踩平”的那些任务。这一类任务包括标准的数据处理、常见格式转换、成熟领域的模板生成、有清晰单元测试的算法练习。这些任务上 agent 系统能做得又快又好,因为它们精确落在 Parnas 说的例外域里。
凡是超出清单的任务(需要判断处境、需要跨领域拿定主意、需要在没有已知答案的地方创造),四十年后依然需要人做。

“agent 会不会取代人”这个问题一个具体答案:agent 提供的是人类专家平均能力的分发,它不能产生新的专家能力,只能复用已有的。
当行业没有专家产生新知识时,agent 也就没有新东西可学。

它的当代形态是”买模型能力”。你不用训练自己的模型,你调用 OpenAI、Anthropic、Google 的 API。
“等模型变强”也是一种购买策略。
它们继承购买策略的全部优点和同一条天花板:你买到的是通用能力,买不来对你那道题的判断,因为你买到的模型没见过你的处境。

越设计师是稀缺资源,且培养他们这件事本身不能被系统化。

Brooks 说最重要的投资是培养设计师。这句话四十年后依然对,且在 agent 时代变得更急迫。因为 agent 大幅提升了普通开发者的产出,卓越设计师和普通设计师的产出差距被放大了。一个卓越设计师现在能带动一整个 agent 支持团队,产出比过去大几倍。一个普通设计师用同样的 agent 团队,产出没有卓越那位的十分之一。差距不在 agent,在使用 agent 的那个头脑。

第 17 章 · 再论没有银弹
Brooks 说专家系统的价值在特定领域真实(医学诊断、设备故障、税务咨询),但没有成为通用编程工具,因为通用编程需要通用判断,专家系统的规则库只能覆盖特定领域。

敏捷改进的是”如何组织工作”这个偶然困难,通过更好的流程管理让工作被更有效地推进。
它没有触及”要做什么工作”这个本质困难。所以敏捷是一茬有价值的方法改良,不是银弹。

云计算。2000 年代兴起、2010 年代普及。它承诺的是通过按需使用计算资源,消除自建基础设施的负担。
三十年后成绩单:兑现了它的承诺,让”运维”这个偶然困难被大幅便宜化。没有触及本质困难。有价值,不是银弹。

微服务。2010 年代主流。它承诺的是通过把大系统拆成多个独立服务,让复杂度更可管理。
三十年后成绩单:微服务在部分场景兑现了它的承诺,在另一部分场景反而增加了复杂度。
它本质上是把”单一进程的复杂度”换成”多进程的复杂度”,没有减少总复杂度。有价值,不是银弹。

现在到本书要处理的这一茬:2020 年之后的大语言模型、编程 agent、multi-agent 系统、MCP、autonomous agents。这一波比过去任何一波都热,每一样都以”这就是银弹”的姿态出场。用同一个框架看。

Agent 让代码编写这件事的成本大幅下降,但编写代码这件事本身是偶然困难的一部分,它不涉及”要写什么代码”这个本质判断。

对话式编程 agent(Claude Code、Cursor、Aider、Codex 这一类)。
承诺的是通过让 agent 承担从需求理解到代码实施的完整循环,程序员从”敲键盘的人”变成”审阅者和指挥官”。
但它依然不是银弹。判断(决定说什么、要不要这样做、这个方案对不对)依然要由人做,本质困难没被触及。
它是一茬极其成功的偶然困难消灭者,且是当前最接近”接管全部偶然困难”的技术。但它没有对本质困难做任何事。

试图消灭需要判断的东西,就等于试图消灭软件的本质困难,而这件事按 Brooks 1986 年的分析是做不到的。
所以目前行业积极探索蓬勃发展的全自动系统不是银弹,且它是三十年来最直接、最系统地撞在这条论断上的一次尝试。

直接买现成的软件比自己开发要便宜几个数量级。
买软件不解决本质困难,但它让你的项目里的本质困难减少了,因为你不做的那一部分,本质困难就不落在你头上。

三十年后这条思路的当代形态是什么?买模型能力。你不训练自己的模型,你调用 API。你不搭自己的完整 agent 系统,你用开源框架(或者模型公司自己产的 app)加托管服务。这个”买而不建”的策略在 2026 年比任何时候都便宜,大部分核心能力都可以按 API 调用付费。
你买到的是通用能力,买不来对你实际面临的问题的判断。你的具体处境、你的具体判据、你的具体目的,无法被外部提供者理解。

采购策略对偶然困难有效,对本质困难只能规避、不能消灭。
所以它依然不是真正意义上的银弹。如果你的项目里剩下的本质困难需要判断,你还是要有人在场做那件事。

传统软件工程里,判据的持有主体是明确的:甲方或产品经理或架构师有需求和判据,程序员按判据实施。判据虽然可能不精确(Vyssotsky 命题),但至少有一个明确的持有主体。
agent 时代出现了一个新的困难:当 agent 承担越来越多的实施工作时,判据的持有主体变得容易被误判。

你会看到有些团队用 agent 做出的产品质量在半年内飘忽:刚开始时人很认真核查,agent 产出好;
用久了人变懒、开始接受 agent 的自评、质量在不知不觉中下降,这不是 agent 变差了,是判据持有的实际分工在悄悄漂移。

四十年过去,行业发生了很多事:面向对象普及、CASE 泡沫、第四代语言消亡、专家系统冷却、敏捷兴起、云计算落地、微服务成为主流、大模型出现、agent 时代到来。每一次浪潮都被称作”这次不一样”,每一次都被 Brooks 的框架容纳为”又一件消灭偶然复杂度的利器”,没有一次触及本质困难。

当下一茬技术出场,声称自己是银弹时,再读一遍人月神话。看这项技术攻击的是偶然困难还是本质困难。

第 18 章 · 死亡名单的分布
三级程序库(第 12 章)。Brooks 提议的”私有开发库 / 集成测试库 / 发布版本”三层结构,被现代分支模型完整兑现(feature branch / staging / production)。

Brooks 引用 Wirth 提出的”自顶向下设计、逐步精化”,五十年后成了每一个受过基础训练的工程师的默认工作方式。年轻一代不知道曾经有过别的写法。
随说:结构化编程

概念完整性:系统设计中最重要的因素依然要由一个头脑持有,多头脑持有就长出私有概念。agent 时代给这条命题提供了实验室纯度的反面样本。
人月不可互换:加人不能线性加速项目、subagent 不能线性加速任务、采样和理解不能互换。核心机制五十年没变。

五十年间,行业把大量精力投入到消灭偶然困难上(工具、语言、方法学、框架),所以偶然困难侧的命题要不然被兑现(成为默认),要不然被换代(旧载体死亡)。
本质困难侧一茬又一茬技术承诺解决,一茬又一茬都失败,所以那些命题原样活着。

模型的能力越强,对软件工程的提升越小。
因为剩下的都是本质困难:判断需要一个持有主体,主体的位置只有人能坐。

当 agent 能持有目的、能理解处境、能自主判断,那时候”主刀由人做”这条论断就不再成立,本书大部分论证的政策含义就要修改。

目的这个东西(”我为什么想要 X 而不是 Y”)必须挂在一个主体上。
这个主体有它的处境、有它的历史、有它的关系网、有它要为之负责的事情。
目的不是一段文字,是一整个持有网络。
你可以给 agent 更多信息、更强推理、更长的上下文,它依然不成为持有目的的主体,因为它没有真正的处境。它模拟处境,但模拟不等于持有。

你给最强档 agent 一段几十万字的处境描述,让它扮演一个具体的用户,然后让另一个 agent 跟它讨论产品需求。这两个 agent 讨论出的东西质量能有多高?在特定场景下不错,在一般场景下比真实用户参与差远了。为什么?因为扮演的 agent 是在模拟用户,它的”我要什么”是训练数据里那类用户会说的话,不是这个具体用户在这个具体处境里真正要的东西。差在身份。

 Brooks 的原书等到了自己的第三批读者:第一批管人,第二批管代码,第三批管 agent。

三代读者从 Brooks 那本书里带走的都是不同的东西。
第一代(1975-1995):外科手术队伍、Brooks 法则、进度估算、独立测试组。这些是关于如何管一个大项目的具体建议。他们把这些建议落地为软件工程管理的一套地基。
第二代(1995-2025):概念完整性、模块化、文档假设、为舍弃而计划、结构化编程。这些是关于如何写好代码的方法论。他们把这些方法论落地为敏捷、DevOps、TDD、云原生这些当代实践。
第三代(2024 之后):本书从头到尾展开的那些:文档即源码、审计权与修正权、判据持有、Vyssotsky 命题在人机分工线上的应用、Parnas 之争的分层解决、Goodhart 定律在评分函数上的复发。这些是关于如何在人机协作里守住软件工程本质的洞察。

总结:换了币种的人月照旧买不来婴儿,换了介质的巴比伦塔照旧败在组织上,换了物种的支持团队照旧需要主刀。写进提示词的乐观主义照旧要靠现实之外的质疑来纠正,未精确定义的地方照旧是失败之源,目的照旧无法被语法完整表达。

Brooks 说软件工程的困难是可命名的、结构性的、可以被面对的。

尾声:写给下一位读者

如果你读完了这十八章,你现在应该有几个直觉。
一,agent 是伟大的偶然困难消灭者,但不是银弹。它让软件工程的一大批老问题变便宜:写代码、写文档、写测试、跑 debug、追依赖。这些工作在 2026 年的成本降到了 1975 年成本的百分之几。这是软件工程史上最大的一次工具跃迁。
二,agent 没有触及本质困难。判据谁持有、目的谁负责、概念完整性谁守护、里程碑谁设计,这些工作没有便宜化,反而因为总产出规模的膨胀,占用总成本的比例上升了。你的项目里,判断的成本在过去两年可能翻了一倍不止。
三,人机分工的正确形态五十年前 Brooks 就写好了(虽然他自己没预见到 agent 的出现)。分工线沿着”能不能被形式化定义”这条边界走。能被形式化的(代码、测试、文档格式),交给 agent。不能被形式化的(目的、判据、处境判断),留给人。守住这条分工线,两侧都做得最好;打乱这条分工线,两侧都做不好。
四,这本书前面十七章讲的具体机制,都是这条分工线在具体场景里的落地:从概念完整性到 subagent 沟通开销,从外科手术队伍到 Vyssotsky 命题,从 Brooks 法则到 Parnas 之争。每一条具体机制都可以独立使用,合起来是一套完整的工作方法论。
如果你只带走一条建议,让它是这样:把你的时间投资到文档层。文档是决定的载体,决定是代码的源头,代码是决定的编译产物。你想在 agent 时代做一位真正有效的工程师,你的时间应该投入到判断和决定的显形上,不是敲代码上。代码由 agent 从文档编译,你的价值在于把文档写成能被机械执行的源码级材料。
Brooks 那本书的第一批读者是 1970 年代的项目经理。这本书的读者是 2026 年之后的开发者。
中间隔了半个世纪,一切都在变,唯有一件事没变:『软件工程的核心是判断的组织』。
你就是那个组织判断的头脑。要我说的话:嘿!你做得到。