资讯详情

资讯详情

从Codex到A2A:多Agent协作机制与落地实践

1. 为什么“多 Agent 协作”突然成了所有团队都在聊的话题多 Agent 协作、Codex、A2A这三个词最近在我常逛的技术社区里出现的频率高得吓人。乍一看它们好像分属三个赛道一个是工程实践方法一个是具体工具一个是企业级通信协议。但说句实话我是在自己把 Agent 真正接入团队研发流程之后才意识到这三者根本不是孤立的东西而是一条链路上的三个环节——单个 Agent 怎么干活多个 Agent 怎么沟通企业系统里 Agent 之间怎么互相发现和派活。这篇文章我想把这条链路从头拆一遍把我拆过的机制、踩过的坑、以及最后怎么把 Codex 这类 Agent 工具接进 A2A 服务体系的实操过程都写出来。先说个背景。我在团队里负责自动化流程建设去年开始大量试用各种 Agent 编程工具Codex 是其中用得最久的一个。一开始我只是把它当成一个加强版代码补全工具让它单个会话处理一个仓库的改造任务。跑了几个月后发现问题很明显单个 Agent 处理小型任务确实效率高但一旦任务被拆成十几个子任务比如后端接口改造、前端页面适配、测试用例补全、部署脚本更新同时进行单会话的上下文窗口根本扛不住。它会做到后面忘了前面甚至把两个模块的修改互相污染。后来我换成了多实例并行——每个模块开一个独立的 Codex 会话各干各的最后人工合并结果。这个方案能跑通但很快又发现新问题这些会话之间是完全隔离的A 会话改了一个公共接口签名B 会话完全不知道还在按旧签名调用。这就是典型的多 Agent 协作问题——不是有没有 Agent 的问题而是 Agent 之间靠什么协作的问题。所以我开始认真研究两个方向一个是 Codex 这类工具内部的 Agent 机制到底怎么设计的另一个是 A2A 这类协议凭什么能让企业里的 Agent 互通。这篇文章就是这两个方向的拆解和落地总结。2. Codex 内部机制拆解单个 Agent 是怎么把活拆出去的2.1 Codex 不是代码补全工具而是一个完整的 Agent 循环很多第一次接触 Codex CLI 的人会把它误当成 IDE 里的补全插件这是最大的误解。Codex 的核心是一个 agentic loop翻译成大白话就是不断循环执行“读任务、想方案、动手、看结果、调整、再动手”的过程直到任务满足退出条件。我实际观察下来Codex 的工作流大致是这样的你给它一句自然语言指令它会先规划一个执行路径然后在沙箱环境里逐条执行 Shell 命令或文件编辑操作每执行一步都会读取命令输出或文件变化根据结果决定下一步动作。它保留了完整的执行记录所有步骤、命令、输出、关键决策都以结构化日志存下来方便回放和审计。这一点非常关键。多 Agent 协作里最容易被忽略的就是可观测性。两个 Agent 能否配合前提是彼此知道对方做了什么、做对了没有。Codex 的设计里执行日志就是它的“记忆体”没有这个记忆体任何协作都是空中楼阁。2.2 多实例并行Codex 实际能胜任的多 Agent 形态Codex 本身并没有内置“多 Agent 互相协商”的机制至少我目前测试的版本里没有。但实际工作中我们完全可以利用它的会话隔离特性做出一个能用的多 Agent 并行体系。具体做法是把一个大任务按模块边界拆成多个独立子任务每个子任务启动一个独立会话指定不同的工作目录和输出范围在 CI 流水线里同时跑多个 Codex 实例。每个实例拥有独立的上下文和操作空间互不干扰。最后再用一个汇总流程把结果合并。这个模式跑起来之后我总结出三个关键的支撑要素任务分解必须在启动前把边界切干净子任务之间不能有交叉的文件依赖。上下文隔离每个会话只加载自己那部分的代码和说明不要把整个仓库塞进去。结果合并的校验多个会话的产物合并后要有统一的数据类型校验和测试回归。2.3 Codex 设计给我的三条启发拆完 Codex 的内部机制我觉得它对多 Agent 协作最大的贡献不是“它本身能做多 Agent”而是它验证了三件极其重要的事。第一工具调用能力比模型聪明程度更影响协作效果。Codex 真正稳定产出靠的是它执行命令、读写文件的可靠性而不是某个时刻的灵感。Agent 之间的协作也需要类似的东西——消息能不能准确送达动作能不能被对方理解比谁的提示词写得漂亮更重要。第二状态管理决定了 Agent 的边界。Codex 里一个会话就是一个状态容器所有中间结果都沉淀在文件系统和日志里。多 Agent 协作时每个 Agent 的状态存在哪里、何时共享、何时隔离是这个体系设计的核心问题。第三失败恢复不能依赖重试。我看过很多团队做多 Agent 时Agent A 调用 Agent B 失败就简单重试结果往往是把同一个错误重复十遍。Codex 的设计里更值得学习的是“观察结果、纠正动作”的循环协作协议里同样应该有明确的错误反馈和状态转移而不是盲目重试。3. 真正决定协作质量的是消息与协议不是模型的“聪明程度”3.1 没有协议的时候多 Agent 协作是怎么做的在没有统一协议之前我们这些搞 Agent 集成的只能临时拼方案。最常见三种做法。第一种是共享文件系统。Agent A 把结果写到一个约定目录Agent B 定时扫描发现新文件再处理。遇到简单场景还能凑合但很快你就会遇到读写竞争、格式理解不一致、清理不干净导致串数据这类问题。第二种是共享数据库。把任务状态和结果都存到表里Agent 之间通过轮询实现对业务状态的感知。这个方案比文件略好但本质上是在用数据表模拟消息队列任务状态机的调整要改表结构Agent 的接口跟着改维护成本很高。第三种是人肉编排。一个 Agent 跑完人工把结果搬给下一个 Agent。这其实是目前大多数团队的真实状态。所谓多 Agent 协作中间夹着无数个“人肉消息总线”。做得少的时候没事任务一多人的精力就成了瓶颈。这些方案的共性问题在于协作的语义是隐性的全靠约定没有显式的消息格式和生命周期规范。一旦参与协作的 Agent 数量超过三个隐性约定就会崩。3.2 稳定的协作需要显式的消息契约真正的 Agent 协作协议不管长什么样核心都包括三块消息格式、状态流转、能力发现。消息格式上目前主流的方向是 JSON-RPC 2.0。为什么选它因为简单、成熟、序列化成本低而且生态里有现成的库可以处理请求响应、错误码、通知这三类基本消息。A2A 协议用的就是这套消息框架。状态流转上Agent 之间传递的不只是一段文本还要有明确的状态机。比如一个任务从提交到完成可能经历这样的状态已提交、执行中、等待补充信息、已完成、失败。双方都必须理解这些状态才能在合适的时机采取行动。Agent 不可能一直在“执行中”如果超时了另一方要能介入处理。能力发现上每个 Agent 必须能告诉别人“我擅长什么、期望什么输入、产出什么格式”。类似一个公开的服务说明文件。没有这一层Agent 之间只能靠猜。3.3 为什么说协议比提示词重要我见过一个团队为了多 Agent 协作把大段大段的协作规则写进提示词里让每个 Agent 启动时先读一遍规则。效果非常不稳定——稍微换一个模型版本或者提示词上下文被压缩Agent 就开始自作主张。这是提示词方案的天花板它是概率性的本质上是靠模型“自觉”遵守规则。而协议是强制性的消息结构不对就解析失败状态不合法就拒绝流转规则层面就堵死了。我现在调试多 Agent 系统时判断标准很简单如果把提示词全部删掉只保留协议描述各 Agent 之间的消息往返还能不能成立。如果能这套协作体系就是健康的如果不能那协作的根基还是不牢。4. A2A 协议拆解企业服务里的 Agent 怎么互相发现、派活、交付4.1 A2A 是什么以及它解决什么问题A2A全称 Agent2Agent是 2025 年 4 月由 Google 牵头发布的一个开放协议目标是为企业场景里的 Agent 互操作提供统一标准。发布时拉上了思科、Salesforce 等五十多家合作伙伴后来逐步演进成开源项目规范和示例代码都在 a2a-protocol 仓库里维护。为什么企业服务需要这个标准因为企业内部往往不是只有一个 Agent。我见过一个中型公司里同时存在销售助手 Agent、客服问答 Agent、数据分析 Agent、代码生成 Agent它们各自为战。销售想调用数据分析的结果只能让工程师写脚本去数据库拉数据再做格式转换。A2A 要解决的就是让这些 Agent 能像人一样互相递名片、接需求、汇报结果而不是每次都依赖人来翻译。4.2 A2A 的四大核心机制我把它拆成四个部分来理解分别是 AgentCard、A2A 客户端与服务端、任务生命周期、消息层。AgentCard 是每个 Agent 的“名片”。它是一个公开的 JSON 文件描述了 Agent 的标识、能力列表、支持的技能类型、安全策略、接入端点。任何其他 Agent 或编排系统通过访问这个文件就能判断要不要调用它。这解决了能力发现的问题。A2A 客户端与服务端定义了角色。发起调用的叫 A2A Client接收任务并提供能力的叫 A2A Server。一个 Agent 可以同时是某些场景的客户端又是另一些场景的服务端。比如数据分析 Agent 对业务部门来说是服务端但它在执行时又要调用报表生成 Agent这时候它就变成客户端。任务生命周期定义了业务往来怎么跟踪。A2A 协议用任务对象来承载一次协作从提交到结束有明确的状态迁移支持长时间运行的任务轮询也支持服务器主动推送状态更新。解决的是“活派出去之后怎么知道干到哪一步”的问题。消息层基于 JSON-RPC 2.0定义了具体的方法名和参数结构比如提交任务、获取任务状态、取消任务这些标准方法。有了这层两边不需要关心对方是什么语言写的、跑在什么框架上只要实现标准方法就能互通。4.3 A2A 和 MCP 的分工很多人搞混了这个问题我最近被问了很多次。MCP模型上下文协议是 Chanthropic 那边提出的一种协议它解决的是 Agent 和工具之间的连接——一个 Agent 想调用数据库、调用网页服务、调用内部 API通过 MCP 来标准化这些工具接口。A2A 解决的则是 Agent 和 Agent 之间的连接。两者完全不在一个平面。我打个比方。MCP 像是给一个员工接线接通电话、接通电脑、接通内网权限让他能使用各种工具。A2A 像是打通两个员工之间的沟通渠道让一个人能给另一个人派活、汇报结果。前者是人和工具的关系后者是人和人的关系。实际落地时两者经常叠加使用。一个 Agent 通过 MCP 去读取数据和分析分析结果又通过 A2A 协议响应给另一个等待结果的 Agent。不要把这两个协议对立起来它们是互补的。4.4 企业服务里一个典型的 A2A 协作流程我们在内部尝试过沙盘推演这样一个场景业务人员向采购流程 Agent 提交了一个“供应商资质审核”请求。采购 Agent 发现自己缺供应商财报分析能力它通过 A2A 协议把分析子任务指派给数据分析 Agent。两个 Agent 之间完成了消息交换、任务状态同步。数据分析 Agent 执行时通过 MCP 调用财务系统的接口拉取数据生成报告通过 A2A 返回结果。采购 Agent 汇总后给业务人员交付。整个过程里业务人员只跟第一个 Agent 对话中间的协作对他是透明的。这就是 A2A 想达到的效果——Agent 之间把所有复杂的关系消化掉对外表现为一个统一入口。5. 从 Codex 到 A2A 的落地实践安装、排障与最小服务编排5.1 Codex CLI 的安装与初始配置想实验这套体系先得有个能跑的 Agent。我这里以 Codex CLI 为例说一下我自己的安装流程。Codex CLI 目前主要提供两种安装方式通过 npm 全局安装或者通过 Homebrew 安装。用 npm 方式的话命令是这样的npm install -g openai/codex装完之后先验证一下版本codex --version如果命令找不到通常是 npm 全局 bin 目录没有加进 PATH。这时候去查一下 npm 配置的全局目录把它加到 shell 配置文件里就行。首次运行还需要身份认证和模型配置。在命令行里执行 codex login按照提示完成登录授权。完成后会生成一份配置文件里面指定了默认模型、会话模式、沙箱策略等参数。我这里建议新手从非沙箱模式开始跑简单的修改任务熟悉了再切到沙箱模式。沙箱模式能隔离命令执行的副作用但配置不好会造成很多误伤比如明明只是想读文件却被沙箱策略挡在外面。5.2 运行中遇到连接中断的排查过程我在实际使用 Codex 过程中遇到过几次任务跑到一半突然中断的情况。症状是 Codex 在处理 /responses 这个接口时本地网络栈切换失败整个请求被重置会话直接终止。错误信息里会提示 local proxy failed 这样的字眼容易让人误以为是模型服务的问题其实问题是出在本地网络环境。我排查的步骤一般分为四步。第一步退出当前 Codex 会话检查本机网络环境变量的残留配置确认是否有指向已经失效的旧出口地址第二步重新登录一次强制刷新本地凭证和连接状态第三步检查任务日志里最后一段命令执行记录看是不是某个命令引起了网络状态变化第四步彻底重启 CLI 进程把本地网络栈重新初始化后再复用原任务描述。这个问题的本质是本地网络状态和 Codex 的长连接之间出现了不一致。Codex 会维持一个长时间的请求连接如果中途本地网络出口发生变化比如切换了网络、调整了局域网配置连接就会失效而 CLI 不会自动重连。这不是模型的问题也不是任务本身的问题是网络栈层面的状态同步问题。后来我在跑批量任务时就养成了一个习惯关闭所有会造成网络状态变化的自动化工具只保留纯净网络环境再启动 Codex 批量执行。5.3 把 Codex 包装成 A2A 服务中的一员现在到了本文最关键的部分——怎么把 Codex 接进 A2A 体系。Codex 本身不提供 A2A 能力但它有良好的命令行接口我们可以写一个适配层把它包成 A2A Server。我实现的最小方案分三步。第一步写一个脚本封装 Codex CLI接收标准输入的任务描述调用 codex exec 执行然后把输出转成结构化结果第二步写一个简单的 HTTP 服务对外暴露 A2A 协议要求的端点同时提供一个 AgentCard JSON 文件声明能力第三步启动一个简单的事件循环让外部请求进来时脚本把任务提交给 Codex并返回任务 ID后续通过状态查询反馈结果。这个适配层的核心代码逻辑并不复杂关键点在于任务状态的映射。A2A 协议的状态机和命令行执行过程并不是一对一的需要把“命令正在跑”“命令跑完了”“命令出错”映射到协议规定的状态上。我实现时做了一层状态包装把命令行进程的退出码和输出内容作为判断依据。跑通过这个最小方案之后我就有了第一个真正意义上的“原生工具 Agent 被协议化”的实例。后续再接入别的 Agent思路都是一样的先封装能力再注册 AgentCard再按协议处理任务生命周期。代码骨架可以复用替换的只是任务描述和执行命令。6. 多 Agent 协作的边界什么时候不要硬上把 A2A 和 Codex 这套链路跑通之后我必须给自己泼几盆冷水。多 Agent 协作不是银弹很多场景下硬上多 Agent效果反而不如老老实实一个 Agent 跑到底。首先是通信开销问题。单 Agent 处理一个任务所有上下文都在本地没有序列化和网络传输。多 Agent 协作每往返一次消息都要经过编解码、传输、解析长任务的状态同步还要轮询或推送。任务本身很小的时候通信开销甚至可能超过执行本身的时间。I 实测过一个数据清洗任务单 Agent 十分钟跑完拆成两个 Agent 协作后变成二十五分钟多出来的十五分钟全花在状态同步和等待上了。其次是一致性问题。多 Agent 各自维护自己的上下文对同一件事的理解很容易出现分歧。代码重构这种场景尤其明显一个 Agent 改了公共函数签名另一个 Agent 还按旧签名在写调用。协议能约束消息格式但约束不了语义理解的一致性。处理办法只有两种要么在任务分解阶段就把语义边界切死要么在协作的关键节点引入人的确认。再次是失败恢复问题。多 Agent 链路里任何一个环节失败影响都会被级联放大。Agent A 执行成功但消息发送失败Agent B 就进入超时状态Agent B 超时后重试可能造成重复执行。协议层面的任务状态机可以兜住一部分问题但真正稳定还是要依托于底层基础设施的重试、补偿和幂等设计。如果你所在的团队连基本的消息队列和幂等机制都没有我建议先别碰多 Agent。说了这么多最后给出我的个人建议按这个顺序来推进先把单个 Agent 用到极致让它覆盖完整的任务闭环再尝试多实例并行结合人工汇总体验多 Agent 的收益和成本最后才考虑引入 A2A 这类协议做动态编排。协议只是最后一公里的通信规则前面几公里的任务设计、上下文管理、失败处理才是多 Agent 协作真正花时间的地方。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →