返回笔记

笔记

奥卡姆很忙

aisoftware-engineeringagentsarchitectureprotocolsjudgment

最近,我在尝试让多个 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、流程、文档和架构,而是:

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

相关材料

本页目录