# 奥卡姆很忙

当 Agent 能直接读取代码、状态和结果，许多为上下文断裂建立的结构都需要重新证明价值。真正不能省略的，是目标、边界、证据与回退。

## Metadata

- HTML: https://glenzli.com/notes/occam-is-busy/
- Markdown: https://glenzli.com/notes/occam-is-busy.md
- Collection: Notes
- Language: zh-CN
- Published: 2026-07-26
- Updated: 2026-08-17
- Tags: ai, software-engineering, agents, architecture, protocols, judgment

## Content

最近，我在尝试让多个 Agent 同时开发一个复杂的桌面应用，高并发地推进不同部分。

一提到多个 Agent 协作，人们很容易先想到 A2A 协议：消息格式、任务状态、调度方式、冲突处理，最好一开始就定义完整。

我一直不太热衷于这样做。

协议还没见到协作，协作已经被安排得明明白白。缺少具体场景时，我们能预想到的，往往只是角色、消息、状态和调度这些通用名词。真正决定协作能否进行的细节，要等参与者进入同一个项目、开始修改同一批文件，才会一个个冒出来。

所以这次，我没有先替 Agent 写一套完整协议。只给了它们最初的关系和边界：共同完成这个项目，其他 Agent 是协作者；先维护一份初始契约，再根据实际工作修正它。

契约很薄。大家服务于同一个目标；共享文件中的修改会影响别人；工作发生重叠时需要调整；任务完成以后，要留下可以检查的结果。

至于任务如何声明、共享文件怎样交接、什么时候必须沟通，没有要求第一版就全部覆盖。

先让协作发生。

## 协调就在工作里

这里的协调，并不是让 Agent 分别扮演产品经理、架构师和工程师，再像人一样开会。

人类团队需要会议、汇报和明确的角色分工，很大程度上是因为上下文散落在不同人的脑子里。大家不得不暂时离开工作对象，用语言重新拼出彼此做了什么、正在做什么、接下来准备做什么。

Agent 面对的条件不太一样。

权限允许时，它们可以读取同一个代码库、任务状态、测试结果和变更历史。从工作声明里看见别人正在处理的范围，从补丁里看见真实意图，从测试结果里得到比口头汇报更直接的证据。

一次范围更新、一份补丁、一个新的测试结果，本身就可能完成了信息交换。协调不一定是一段对话，也可以直接长在工作里。

那次开发中，两个 Agent 的工作发生了冲突。一方持有的锁，暂时阻断了另一方。如果提前设计一套完整流程，很容易加上轮询、超时、中止和恢复。实际运行时，等待的一方直接利用了 Codex 已有的跨任务通知：状态变化以后收到消息，随即恢复工作。没有轮询，也没有退出。

之后，它们又根据实际占用形成了更细的交接方式。一方只是轻量修改，另一方却要长期占用同一范围，前者就把任务交出去；一方需要修改文件，而另一方在这个文件上还有未完成需求，它也可以顺手把那部分需求申领过来。

这些规则不是预先写好的角色分工。它们来自修改粒度、占用时间和当时的共享状态。

不过，环境很快也暴露了边界。

一个 Agent 完成自己的任务后，未必会再去唤醒需要接续工作的另一个 Agent。

链路没有断，只是未必有人把它重新接上。

于是，哪些状态必须持久记录，什么时候可以等待，什么时候必须留下显式交接，依然需要额外判断。

这次失败比一条预先写好的“恢复机制”更有用。它告诉我们，通知机制可以复用，但中断后的接续不能靠想象。

我也没有退出这个过程。Agent 可以修订局部的协作习惯，但共同目标、权限范围和高风险操作的确认条件，不会因为一次配合顺手就跟着漂移。

协作跨越厂商、组织和信任边界时，身份、权限、消息来源和失败语义当然需要提前标准化。但在共享代码库和共同目标的环境里，协议写到什么程度，应该由已知风险、环境约束和实际失败共同决定。

协议可以晚一点，边界不能。

## 条件变了

从这个案例往外看，最近 AI 软件工程里的许多变化，其实都在碰同一个问题。

实现成本下降，过去为了避免返工设置的完整前置流程，需要重新计算成本；反馈变快，需求、开发和使用不必永远保持固定顺序；Agent 成为软件用户，界面、说明书和初始流程也不再完整限定软件的用法；模型能力继续变化，为暂时缺口搭起的脚手架，可能还没来得及刷漆就已经过期。

并不是某种结构突然变坏了。是供养它的条件变了。

许多软件结构原本就在应对昂贵的实现、缓慢的反馈、断裂的上下文，以及几乎无法解释意图的组件。它们有明确的来历，也确实解决过问题。

只是，条件改变以后，来历不能继续充当理由。

一个流程过去减少了什么风险，现在还在减少吗？一份文档过去保存了什么信息，现在能否从代码和历史里直接获得？一层接口过去隔开了什么变化，今天隔开的究竟是风险，还是理解？

结构不必因为古老而消失，也不能因为熟悉而免检。

## 看职责，不看名字

同一种结构，往往同时承担几种职责。

文档可能只是在复述代码，也可能保存了无法从当前状态重新推导的历史决定。工作流可能只是把任务塞进固定顺序，也可能在分配责任、确认风险、留下审计证据。Schema 既帮助系统交换数据，也让数据的含义穿过团队和版本以后不至于变形。

所以，Agent 能读代码，不等于文档已经没用；自然语言能表达意图，也不等于确定性接口可以全部换成临场理解。

名字决定不了去留，职责才可以。

有些结构负责组织当前工作：搬运信息、安排顺序、补偿眼下的能力缺口。参与者能够稳定获得同样的信息以后，它们可以缩小、临时生成，甚至直接消失。

另一些结构直接保护现实：划定权限，保存证据，固定责任，阻止一次误判穿透整个系统。执行者越有能力，这些结构越不能含糊。

两者并不总能分得干净。一份文件可能既在协调工作，也在保存不可丢失的决定。重要的不是替它贴上“临时”或“永久”的标签，而是说清楚：

> 如果删掉它，究竟会失去什么？

如果答案只是少了一次格式转换，它大概可以走了。如果答案是权限、事实和责任开始变得模糊，那它不仅应该留下，可能还得写得更清楚。

## 刀下留什么

AI 常常喜欢讲奥卡姆剃刀。它的意思并不复杂：如无必要，勿增实体。

放到软件工程里，刀下的“实体”便成了 API、文档、工作流、协议和架构。刀已经举起来了，但总得先知道什么不能砍。

把这些具体形式暂时放到一边，真正难以省略的东西并不多。

目标和判断要留下。系统需要知道为什么行动，哪些结果值得保留，什么时候继续，什么时候停止。执行越便宜，判断越不能跟着打折。否则，高速生产只是更快地重复错误。

权限和边界要留下。哪些数据可以读取，哪些系统可以修改，哪些操作必须由人确认，不能押在一句“模型应该能理解”上。能力越强，一次误判能扫过的面积越大。

事实、证据和必要的历史也要留下。参与者需要知道什么已经发生，什么可以相信，一个决定为何形成。代码、测试、运行记录和实际状态，通常比任何人对过程的精彩回忆更可靠。

最后是回退和责任。只要理解可能出错，错误就必须能够被发现、隔离和撤销。无法回退的操作，需要更严格的确认；真出了问题，也不能让责任消失在一串 Agent 的调用链里。

API、文档、工作流、协议和架构，如果仍在保护这些东西，就有存在的理由。

如果它们什么也没有保护，只是因为过去一直如此，就该把位置让出来。

## 奥卡姆很忙

奥卡姆剃刀从来不是无限删减。

它只要求，每一个被引入的实体，都得解释自己为什么存在。

AI 时代，这把刀会很忙。旧的软件结构需要重新接受检查，新出现的 A2A 协议、Agent 工作流和模型脚手架，也不能因为名字里带着 AI，就自动获得长期居留权。

它是在组织眼前的工作，还是保护不能交给协商的现实边界？

它保存了无法重新获得的事实，还是只在重复已有信息？

它来自已经发生的问题，还是来自“最好提前覆盖一切”的焦虑？

有些结构会消失，有些会缩小，有些会从永久设施变成按需搭建的临时脚手架。与此同时，那些直接连接现实后果的边界，反而需要变得更清楚。

AI 不会把软件工程带向一个没有结构的世界。

它只是让越来越多的结构，失去默认永久存在的资格。

最小秩序也不是规则最少。它是让必须提前确定的东西足够清楚，让能够从实践中形成的部分保留变化空间。

所以，当实现、理解和协作的条件都开始改变，软件工程真正需要回答的，不是还要不要 API、流程、文档和架构，而是：

> 它们今天究竟还在保护什么？

## 相关材料

- [AI 脚手架的半衰期](https://glenzli.com/notes/half-life-of-ai-scaffolding)
- [当软件的时间开始松动](https://glenzli.com/notes/software-time-loosens)
- [说明书之外](https://glenzli.com/notes/software-beyond-the-manual)
- [当速度开始改变探索](https://glenzli.com/notes/speed-matters)
- [AI Software Engineering Notes](https://github.com/glenzli/ai-software-engineering-notes)
