多Agent集群实战:Codex接入与GitHub/SSH自动化运维 1. 从手动跑脚本到永动机我为什么要折腾多 Agent 集群最早动这个念头是因为我受够了自己那套人肉调度的工作方式。白天写代码、改需求、回消息晚上还得盯着几个自动化脚本跑没跑完跑挂了要手动重启跑出脏数据要手动回滚。时间一长我就意识到一个问题我真正缺的不是某一个更强的模型而是一套能自己转起来、自己纠错、自己交接班的多 Agent 集群。所谓多 Agent 集群说白了就是把一件复杂的事拆成若干角色每个角色由一个 Agent 承担它们之间通过消息、任务队列或者共享状态互相协作最终在没有我盯着的情况下把活干完。它解决的核心问题是单点依赖——单个 Agent 一旦卡住、超时、上下文爆掉整条链路就断了而集群化之后一个挂了还有别的顶上任务可以重试、可以转移、可以并行。这套东西适合谁如果你已经在用 Codex、Claude 这类工具做自动化但还停留在我发一条指令它回一条的阶段那这篇文章就是给你写的。如果你只是偶尔用 AI 聊聊天那可能暂时用不上但了解架构思路对以后搭任何自动化系统都有帮助。我下面讲的都是我自己踩过坑、跑通了、现在还在 7×24 运转的方案涉及 Codex 的接入、GitHub 的拉取、SSH 的远程管理以及最关键的——怎么让它们别互相打架。2. 集群的骨架角色划分与通信机制怎么定2.1 为什么不是一个超级 Agent而是一群小 Agent很多人第一反应是我搞一个上下文超长、能力超强的 Agent 不就行了我一开始也这么想实测下来直接崩。原因有三个第一上下文越长模型越容易中间迷失前面定的规则到后面就忘了第二单 Agent 串行执行一个任务卡住全链路停摆第三出错了你根本不知道是哪一步的问题日志全糊在一起。拆成多 Agent 之后每个 Agent 的职责单一上下文短、状态清晰、可独立重启。我现在的集群大致分四类角色调度 Agent负责拆任务和分派执行 Agent负责真正干活跑代码、调接口、写文件校验 Agent负责检查执行结果是否合格守护 Agent负责监控其他 Agent 的心跳、超时和异常并触发重启。这四类角色不是固定的你可以按业务增减但调度—执行—校验这个三角基本是刚需。2.2 通信方式消息队列还是共享状态Agent 之间怎么传话是架构里最容易埋雷的地方。我试过两种主流方案各有取舍方案实现方式优点坑点消息队列Redis / RabbitMQ 做任务队列解耦彻底天然支持重试和并行消息丢失难排查顺序不保证共享状态数据库 / 文件系统存任务状态状态可追溯调试直观并发写冲突需要加锁我最后选的是混合方案任务的分发走轻量消息队列任务的状态落库。这样调度 Agent 只管往队列里塞任务执行 Agent 取任务、干活、把结果写回数据库校验 Agent 轮询数据库里待校验的记录。为什么这么设计因为纯队列方案一旦消息消费失败你很难知道任务到底执行到哪一步了而纯共享状态方案在高并发下锁竞争严重吞吐上不去。混合之后队列负责快数据库负责准。提示队列里的消息一定要带唯一任务 ID并且和数据库记录一一对应。我早期没做这个映射结果一个任务被重复消费了三次脏数据查了一整晚。2.3 心跳与超时让集群知道谁还活着集群能永动的前提是它能感知成员的死活。我给每个 Agent 设计了心跳机制执行 Agent 每 10 秒往 Redis 写一个带 TTL 的 key守护 Agent 每 30 秒扫一遍发现某个 key 过期了就判定该 Agent 失联把它手上的任务重新入队并尝试重启进程。这里有个参数很关键——TTL 和扫描间隔的比例。我一开始设 TTL 30 秒、扫描 30 秒结果网络抖动一下就有 Agent 被误判死亡任务被重复执行。后来改成 TTL 30 秒、扫描 10 秒并且要求连续两次扫描都发现失联才判定死亡误判率直接降到几乎为零。这个连续两次确认的思路本质上是用一点点延迟换稳定性在分布式系统里非常值得。3. Codex 接入集群的大脑怎么接才不翻车3.1 Codex 在集群里扮演什么角色在我的架构里Codex 不是唯一的模型但它承担了最重的代码生成与推理任务。执行 Agent 遇到需要写代码、改配置、分析报错的场景就会把上下文打包发给 Codex拿到结果后再落地执行。这里的关键认知是Codex 是集群的一个能力提供方而不是集群本身。把它当成一个可以被调用、被替换、被限流的服务你的架构才不会绑死在某一个模型上。我特意做了模型抽象层所有对 Codex 的调用都走统一的接口封装。这样做的好处是哪天我想换成别的模型或者 Codex 临时不可用我可以直接切到备用模型集群不用改一行业务代码。这个抽象层看起来是多写了几十行但在实际运维里救过我好几次。3.2 接入时的常见报错与处理思路接入过程中我遇到过几类典型问题这里按排查顺序列一下方便你对照端点响应异常调用返回结构不符合预期通常是请求体格式或者鉴权头的问题。我的做法是先把请求原样打到日志里用最小请求体单独测一次确认是参数问题还是服务问题。组织设置加载失败这类多半是账号配置或权限范围的问题检查配置项是否完整、是否有对应权限即可不要一上来就怀疑网络。超时与限流Codex 这类服务在高频调用下会限流。我在封装层加了指数退避重试第一次失败等 1 秒第二次 2 秒第三次 4 秒最多重试 5 次。实测下来大部分瞬时失败都能靠重试救回来。注意重试一定要区分可重试错误和不可重试错误。参数错误重试一万次也没用只会浪费配额。我一般只对超时、5xx、限流这三类做重试。3.3 上下文管理别让 Codex 被喂撑多 Agent 集群里每个执行 Agent 都可能往 Codex 塞上下文如果不加控制token 消耗会失控。我的做法是给每个任务设定上下文预算调度 Agent 在分派任务时就估算这个任务大概需要多少上下文超过预算的部分强制摘要压缩。摘要由校验 Agent 或者一个专门的压缩 Agent来做把长历史压成关键结论。这个设计带来的直接好处是成本可控。我统计过加了上下文预算之后同样的任务量token 消耗下降了大概四成而且因为上下文更聚焦Codex 的输出质量反而更稳定了。这印证了一个经验给模型的信息不是越多越好而是越相关越好。4. GitHub 与 SSH集群的手脚怎么伸出去4.1 为什么集群必须能操作 GitHub我的集群大量任务涉及代码仓库拉取最新代码、提交改动、开分支、读 issue。这些动作都要通过 GitHub 完成。执行 Agent 里我封装了一套 Git 操作模块把常见的 clone、pull、commit、push、branch 都做成了原子操作每个操作都有超时和失败回滚。这里有个血泪教训并发操作同一个仓库必然冲突。我早期让多个执行 Agent 同时往一个仓库推代码结果频繁出现推送被拒、分支错乱。后来我加了一个仓库锁——同一时刻只允许一个 Agent 操作同一个仓库其他 Agent 排队。锁的粒度按仓库来不同仓库可以并行这样既保证了安全又没牺牲太多吞吐。4.2 SSH 远程执行集群的远程手很多任务需要在远程机器上跑比如部署、跑测试、清理环境。这时候 SSH 就是集群伸出去的手。我用 SSH 做远程执行时重点解决三个问题认证、批量、稳定性。认证方面我用的是密钥认证而不是密码密钥文件权限设成 600避免权限过宽被拒绝。批量方面我维护了一个主机清单文件格式大致是这样Host worker-01 HostName 10.11.225.193 User deploy IdentityFile ~/.ssh/id_cluster Port 22每个远程节点一条记录执行 Agent 读这个清单就能批量登录。稳定性方面SSH 连接容易因为网络抖动断掉我在封装层加了连接复用和自动重连并且给每条远程命令设了超时避免某条命令卡死拖垮整个 Agent。4.3 远程执行的常见故障对照表远程这块坑特别多我整理了一张对照表基本覆盖了我遇到过的绝大多数情况现象可能原因处理方式认证失败密钥不匹配或权限过宽检查密钥、chmod 600连接被关闭网络抖动或服务端限制加重连、检查服务端配置命令无输出卡住命令等待交互输入加超时、命令加非交互参数批量登录部分失败个别节点网络或配置异常逐节点重试、隔离故障节点提示远程执行一定要设超时而且超时时间要按命令类型区分。查询类命令 10 秒够了部署类可能要几分钟。一刀切设超时要么误杀正常任务要么卡死不释放。5. 让集群真正永动自愈、限流与成本控制5.1 自愈机制挂了能自己爬起来24 小时不停工作的核心不是永不故障而是故障后能自愈。我的自愈分三层进程级、任务级、集群级。进程级自愈最简单守护 Agent 发现某个执行 Agent 进程没了直接拉起来。任务级自愈是发现任务执行失败或超时把任务重新入队重试重试超过阈值就标记为需人工介入并告警。集群级自愈是当某类 Agent 整体不可用时调度 Agent 临时把任务路由到其他可用 Agent。这三层里任务级自愈最需要小心。我一开始无脑重试结果一个必然失败的任务被重试了几百次把队列堵死了。后来我加了重试上限 退避 死信队列重试最多 3 次每次退避时间翻倍超过上限的任务进死信队列不再自动重试等我来处理。这一套下来集群再没被毒任务拖垮过。5.2 限流别让集群把自己玩死集群跑起来之后最大的风险不是外部服务挂而是集群自己把自己玩死。比如某个时刻大量任务同时触发把 Codex 的配额打满或者把远程机器压垮。我在调度层加了令牌桶限流控制单位时间内分派出去的任务数量并且给不同类型的任务设不同的优先级——紧急任务优先批量任务排队。限流参数怎么定我的经验是从保守开始逐步放开。先设一个明显偏低的速率观察系统稳定性和资源占用再一点点往上加直到找到那个再高一点就开始出问题的临界点然后退回到临界点的 70% 左右作为长期运行值。留 30% 余量是为了应对突发流量。5.3 成本控制永动不等于烧钱24 小时运转成本是绕不开的。我的成本控制主要靠三招上下文预算前面讲过、任务去重相同任务不重复调用模型、结果缓存相似请求命中缓存直接返回。其中结果缓存最容易被忽略但收益很大。我给 Codex 的调用加了基于请求指纹的缓存指纹相同或高度相似的请求直接返回缓存结果实测命中率能到两成左右等于白省两成的调用量。注意缓存一定要设过期时间而且要能主动失效。代码类任务的结果可能因为仓库更新而过期缓存太久会返回错误结果。我一般设 1 小时过期仓库有推送时主动清相关缓存。6. 我踩过的几个看起来没问题的坑6.1 日志太多反而查不到问题集群跑起来后日志量爆炸。我一开始把所有 Agent 的所有输出都打到同一个文件结果出问题时翻日志翻到崩溃。后来我改成结构化日志 分级 按 Agent 分文件每个 Agent 一个日志文件日志带任务 ID、时间戳、级别查询时按任务 ID 一过滤链路清清楚楚。这个改动看起来是运维细节但它直接决定了你出问题时能不能在十分钟内定位而不是熬一整晚。6.2 状态不一致最隐蔽的杀手多 Agent 系统最隐蔽的 bug 是状态不一致。比如调度 Agent 认为任务已完成但执行 Agent 其实还在跑或者校验 Agent 认为结果合格但数据库里状态还是待校验。这类问题不会报错只会让数据慢慢变脏。我的解法是单一事实来源所有任务状态只以数据库为准任何 Agent 的内存状态都只是缓存定期和数据库对账。对账发现不一致就以数据库为准修正并记录告警。6.3 别让 Agent 拥有无限权力早期我给了执行 Agent 很大的权限能删文件、能改配置、能推代码。结果有一次一个 Agent 因为逻辑 bug把测试环境的一个目录清空了。从那以后我加了权限白名单 危险操作二次确认删除、覆盖、推送这类操作要么在允许列表内要么需要校验 Agent 确认。多 Agent 系统里每个 Agent 都应该遵循最小权限原则这不是保守是保命。7. 现在这套集群跑成什么样了目前我的集群稳定运行了几个月日常承担代码拉取、自动化测试、日志分析、定时部署这几类任务。调度、执行、校验、守护四类 Agent 各司其职任务队列基本不积压偶尔有 Agent 挂掉也能在几十秒内自愈。最直观的感受是我从盯着脚本跑变成了早上看一眼报表晚上终于能睡个整觉了。如果你也想搭一套我的建议是别一上来就追求大而全。先把调度—执行—校验这个最小闭环跑通哪怕只有一个执行 Agent先让它能自动完成一件小事。跑通之后再逐步加守护、加限流、加自愈。多 Agent 集群的复杂度是随着 Agent 数量指数上升的一步到位只会让你在调试地狱里出不来。我自己就是从两个 Agent 起步边跑边加才慢慢长成现在这个样子的。