资讯动态

多Agent集群实战:自动化开发工作流与SSH远程管理

发布时间:2026/10/26 16:29:28 来源:尧图企业网站定制
1. 从一台吃灰的服务器说起为什么要折腾多 Agent 集群去年年底我盘了一下手头的设备发现角落里有一台 32 核 64G 的服务器平时就跑跑定时脚本和几个 Docker 容器CPU 长期在 5% 以下晃悠。与此同时我每天的工作流里有一大堆重复性劳动拉取代码、跑测试、整理日志、生成日报、监控服务状态、处理一些简单的数据清洗。这些事情单拎出来都不难但架不住量大一天下来光是在终端里来回切换就耗掉不少精力。于是我开始琢磨一件事能不能让这台机器 7×24 小时替我干活而且不是那种简单的 cron 定时任务而是真正能“理解任务、拆解任务、执行任务、汇报结果”的智能体集群。这就是我打造多 Agent 集群的起点。说白了我想搞一套自动化开发工作流让多个 Agent 各司其职像一个小团队一样持续运转。这里要先说清楚“多 Agent 集群”到底是什么。你可以把它理解成一个虚拟的工作小组有的 Agent 负责接收和解析任务有的负责写代码或执行命令有的负责审查结果还有的负责把最终产出归档或通知我。它们之间通过消息队列或者共享状态来协作而不是一个 Agent 从头干到尾。这样做的好处是职责清晰、可并行、单点故障影响小坏处是协调复杂度上来了调试起来也更费劲。这套东西适合谁如果你手头有闲置算力日常有大量重复性的开发或运维任务并且愿意花时间做前期搭建那它非常值得一试。如果你只是想找个现成工具点点鼠标那这套方案可能偏重了。我接下来的分享会尽量把每个环节讲透包括我踩过的坑和最后稳定下来的配置你可以直接抄作业也可以按自己的场景裁剪。2. 整体架构设计多 Agent 集群到底怎么搭2.1 核心角色划分与职责边界我最终定下来的架构里有四类核心角色这个划分是反复调整后觉得最顺手的调度 AgentDispatcher常驻进程负责监听任务来源比如一个 HTTP 接口、一个消息队列、或者监控某个目录的文件变化把任务解析成结构化指令再分发给下游。它不干具体活只做路由和状态跟踪。执行 AgentWorker真正干活的角色可以起多个实例。每个 Worker 注册自己擅长的任务类型比如“代码相关”“运维相关”“数据处理相关”。调度器按类型派发避免让一个只会跑 shell 的 Worker 去处理需要理解代码语义的任务。审查 AgentReviewer对 Worker 的产出做二次校验。比如 Worker 说“测试全部通过”Reviewer 会去实际拉取测试报告确认Worker 说“服务已重启”Reviewer 会去探活确认。这一步是多 Agent 集群相比单 Agent 最大的价值点之一能显著降低“Agent 自说自话”的风险。通知 AgentNotifier负责把最终结果汇总按优先级推送到我关心的渠道。低优先级的攒成日报高优先级的立即推送。为什么要拆这么细因为我试过让一个 Agent 包揽所有事情结果就是它的上下文越来越长行为越来越不可预测一旦某一步出错整个任务链就断了还很难定位是哪一环的问题。拆开之后每个 Agent 的职责单一提示词可以写得很聚焦出错时也能快速定位到具体角色。2.2 通信机制选型为什么不用简单的函数调用一开始我图省事直接用 Python 的函数调用把各个角色串起来跑了两天就发现不行。问题在于Worker 执行任务可能耗时几分钟甚至几十分钟同步调用会把调度器阻塞住而且一旦某个 Worker 崩了整个调用链就挂了。后来我换成了基于消息队列的异步通信。具体选型上我用的是 Redis 的 Stream 结构原因有几个部署简单我服务器上本来就有 Redis支持消费者组多个 Worker 可以竞争消费同一个队列消息可以持久化Worker 重启后不会丢任务。相比 RabbitMQ 或 KafkaRedis Stream 对中小规模集群足够用运维成本低得多。任务流转的逻辑是这样的调度器把任务写进task:queue这个 StreamWorker 用消费者组worker-group去读处理完后把结果写进result:queue审查 Agent 再从result:queue读。每个任务带一个全局唯一的task_id所有环节都围绕这个 ID 记录状态方便追踪。提示用 Redis Stream 时一定要设置合理的MAXLEN否则消息越积越多会把内存吃满。我一开始没设跑了三天 Redis 内存从 200M 涨到 4G差点把服务器搞挂。2.3 部署形态为什么最终选择了远程 SSH 管理集群搭起来之后面临一个现实问题Agent 进程怎么管理我试过几种方案。最早是直接在服务器上开 tmux 会话跑但一旦服务器重启或者会话意外断开进程就没了。后来用 systemd 托管稳定性好了很多但每次改配置、看日志还是得 SSH 登上去操作。再后来我把管理方式统一到了 SSH 远程管理这条路上。这里说的 SSH 不是别的就是最标准的远程登录协议。我在本地配好了到服务器的密钥认证然后用脚本批量执行管理命令。这样做的好处是无论我在哪台机器上只要能 SSH 过去就能管理整个集群而且可以把常用的管理操作封装成脚本一键完成重启、查看状态、拉取日志等动作。关于 SSH 密钥配置我踩过一个典型的坑本地生成的密钥对公钥追加到服务器的~/.ssh/authorized_keys之后登录还是提示认证失败。排查了半天发现是两个问题叠加一是authorized_keys文件权限必须是 600目录.ssh必须是 700权限不对 SSH 会直接拒绝二是我复制公钥时不小心带上了换行和空格。这两个问题解决后密钥登录一次成功。如果你在 Windows 上用 VSCode 连接远程服务器配置文件里通常会写IdentityFile指向你的私钥路径这个路径千万别写错Windows 下反斜杠和正斜杠的处理也要注意。3. 核心细节解析Agent 集群稳定运行的关键点3.1 任务幂等性设计避免重复执行的灾难多 Agent 集群里最容易出问题的地方就是任务重复执行。设想一下Worker 执行了一个“给用户发通知”的任务执行完还没来得及把结果写回队列就崩了消息队列因为没收到确认会把任务重新投递给另一个 Worker结果用户收到了两条通知。如果是“扣款”“删除数据”这类操作重复执行的后果更严重。我的解决方案是给每个任务设计幂等键。具体做法是任务在创建时就生成一个基于业务内容的哈希值作为idempotency_keyWorker 执行前先检查 Redis 里有没有这个 key 的执行记录有就直接跳过并返回上次的结果。执行成功后再把 key 写入设置一个合理的过期时间我一般设 24 小时。这个机制听起来简单但实际落地时要注意幂等键的生成必须包含所有影响执行结果的参数。我一开始只用任务类型做 key结果两个不同参数的同类型任务被误判为重复直接跳过了。后来改成任务类型 关键参数哈希才正确。3.2 超时与重试策略给每个任务装上保险丝Agent 执行任务时可能因为各种原因卡住网络请求没响应、外部服务挂了、代码进了死循环。如果没有超时机制一个卡住的任务会一直占着 Worker时间长了整个集群的吞吐就下来了。我的配置是这样的每个任务在派发时带上timeout字段Worker 在执行时用信号或者异步超时来强制中断。超时时间按任务类型区分轻量任务 30 秒中等任务 5 分钟重量级任务 30 分钟。超过时间就标记为失败进入重试流程。重试策略我用的是指数退避第一次失败等 10 秒重试第二次等 30 秒第三次等 90 秒最多重试 3 次。3 次都失败就标记为“需人工介入”推送到通知 Agent 提醒我。这里有个经验不是所有失败都值得重试。比如参数错误、权限不足这类失败重试多少次都是一样的结果纯属浪费资源。所以我在 Worker 里区分了“可重试错误”和“不可重试错误”只有前者才进入重试流程。3.3 状态追踪与可观测性出问题时能快速定位集群跑起来之后最怕的就是“黑盒”——任务发出去了不知道现在到哪一步了出问题也不知道卡在哪。所以我花了不小精力做状态追踪。每个任务从创建到完成会经历pending、dispatched、running、reviewing、completed、failed这几个状态。每次状态变更都写进 Redis 的一个 Hash 结构key 是task:{task_id}同时记录时间戳和操作者。这样我随时可以查一个任务的完整生命周期。日志方面我要求每个 Agent 输出结构化日志JSON 格式包含task_id、agent_id、level、message、timestamp这几个字段。所有日志统一收集到一个文件里排查问题时用grep按task_id过滤一条任务链的所有日志就都出来了。这个习惯帮我省了大量时间强烈建议一开始就做好。注意结构化日志的字段名要统一别这个 Agent 用taskId那个用task_id到时候过滤都过滤不出来。我在项目初期就统一了命名规范后面省了很多事。4. 实操过程从零把集群跑起来4.1 环境准备与依赖安装先说服务器环境。我用的是 Ubuntu 22.04Python 3.11。基础依赖不多Redis 用于消息队列和状态存储Python 的redis库用于交互paramiko或者直接用系统 SSH 命令做远程管理。如果你打算让 Agent 执行代码相关任务还需要装好 Git、对应的语言运行时等。Redis 的安装很简单apt install redis-server之后改一下配置主要是设置密码和绑定地址。我建议至少设置个密码别裸奔。绑定地址如果只在服务器内部用绑127.0.0.1就行如果本地也要连就绑内网 IP同时配好防火墙规则。Python 环境我强烈建议用虚拟环境别直接往系统 Python 里装包。python3 -m venv venv然后source venv/bin/activate干净利落。依赖用requirements.txt管理方便迁移和重建。4.2 SSH 密钥配置与远程管理打通这一步是很多人的拦路虎我详细说一下。首先在本地生成密钥对ssh-keygen -t ed25519 -C agent-clustered25519比 RSA 更短更安全现在主流系统都支持。生成时会问你要不要设 passphrase如果追求自动化可以不设如果在意安全设一个并用ssh-agent管理。然后把公钥传到服务器ssh-copy-id -i ~/.ssh/id_ed25519.pub useryour-server-ip如果ssh-copy-id不可用就手动把公钥内容追加到服务器的~/.ssh/authorized_keys。传完之后立刻检查权限chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys这两个权限是硬性要求不对的话 SSH 会静默拒绝。我见过太多人卡在这里反复检查公钥内容却忽略了权限。配置好之后在本地~/.ssh/config里加一个别名以后管理就方便了Host agent-cluster HostName your-server-ip User your-user IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60ServerAliveInterval 60是让 SSH 每 60 秒发个心跳防止长时间空闲被断开。配好之后ssh agent-cluster就能直接登录管理脚本里也用这个别名换服务器时只改配置文件就行。4.3 Agent 进程的托管与自启动Agent 进程必须能开机自启、崩溃自拉起否则“24 小时不停工作”就是空话。我用 systemd 来托管每个 Agent 类型写一个 service 文件。以调度 Agent 为例[Unit] DescriptionAgent Dispatcher Afternetwork.target redis.service [Service] Typesimple Useryour-user WorkingDirectory/opt/agent-cluster ExecStart/opt/agent-cluster/venv/bin/python dispatcher.py Restartalways RestartSec5 StandardOutputappend:/var/log/agent-cluster/dispatcher.log StandardErrorappend:/var/log/agent-cluster/dispatcher.err [Install] WantedBymulti-user.target关键点是Restartalways和RestartSec5进程挂了 5 秒后自动重启。After里声明依赖 Redis保证 Redis 先起来。日志重定向到文件方便排查。Worker 因为要起多个实例我用 systemd 的模板服务worker.service启动时传实例编号systemctl start worker1、worker2以此类推。这样管理起来很清爽。配好之后systemctl daemon-reload然后systemctl enable --now各个服务就实现了开机自启。之后我通过 SSH 批量执行systemctl status就能一眼看到所有 Agent 的健康状况。4.4 一个完整的任务流转实例光说架构太抽象我拿一个真实任务走一遍。假设我提交了一个“检查所有服务的健康状态并生成报告”的任务。调度 Agent 收到请求生成task_id解析出任务类型是health_check写入task:queue状态置为dispatched。三个 Worker 在竞争消费其中一个抢到任务状态改为running开始执行。它通过 SSH 依次连接各个服务节点执行探活命令收集结果。执行过程中每完成一个节点就更新一次进度到 Redis。执行完成后Worker 把结果写入result:queue状态改为reviewing。审查 Agent 读到结果做两件事一是校验结果格式是否符合预期二是抽查几个节点的状态是否与结果一致。校验通过后状态改为completed结果交给通知 Agent。通知 Agent 判断这是低优先级任务攒进日报队列等晚上统一推送。整个过程从提交到完成大概 40 秒全程无需我干预。如果中间任何一步失败状态会停在对应环节并触发重试或告警。这就是多 Agent 集群的价值把一串手动操作变成了一个自动流转的流水线。5. 常见问题与排查技巧实录5.1 任务卡住不动了怎么排查这是最常见的问题。我的排查顺序是这样的先查任务状态task:{task_id}停在哪个状态就知道卡在哪一环。如果停在dispatched说明没有 Worker 消费可能是 Worker 全挂了或者消费者组配置有问题如果停在running说明 Worker 在执行中卡住去看这个 Worker 的日志通常是外部依赖超时如果停在reviewing去看审查 Agent 的日志。我整理了一个速查表遇到问题按这个顺序走基本能定位到根因现象可能原因排查动作任务一直 pending调度器没运行检查 dispatcher 服务状态任务停在 dispatchedWorker 未消费检查 worker 服务、消费者组任务停在 running 超时外部依赖卡住查 Worker 日志、检查网络任务反复重试失败不可重试错误被误判检查错误分类逻辑结果重复推送幂等键失效检查幂等键生成和过期时间Redis 内存暴涨Stream 未设 MAXLEN检查队列长度配置5.2 SSH 连接相关的典型故障因为集群管理重度依赖 SSH这块的故障我遇到不少。最常见的是“认证失败”前面说过八成是权限问题或者公钥格式问题。还有一种情况是连接超时通常是网络问题或者服务器防火墙拦了端口先ping一下确认网络通不通再用telnet或者nc测端口。另一个坑是“连接数过多”。SSH 服务端默认有最大连接数限制如果我的管理脚本并发太高会触发MaxStartups限制导致部分连接被拒。解决办法是在脚本里控制并发数或者调整服务端的MaxStartups配置。我一般把并发控制在 5 以内既够用又不会触发限制。还有个小细节长时间运行的 SSH 连接可能因为网络抖动断开导致远程执行的命令中断。我在脚本里加了ServerAliveInterval和ServerAliveCountMax让客户端主动保活断线时能及时发现而不是傻等。5.3 Agent 行为不可预测怎么办这是多 Agent 系统里比较头疼的问题。Agent 有时候会“自作主张”比如该执行 A 操作却执行了 B或者输出格式不符合预期。我的应对策略有三条第一收紧提示词。把 Agent 的职责、输入格式、输出格式、禁止行为写得尽可能明确减少歧义空间。我甚至会把几个典型的错误案例写进提示词里告诉它“不要这样做”。第二加输出校验。审查 Agent 不只是校验业务结果还要校验格式。格式不对直接打回重做不让错误结果往下流。第三限制工具权限。给 Agent 能调用的工具做白名单它只能调用我允许的工具不能随意执行任意命令。这一条是安全底线尤其是当 Agent 能执行 shell 命令时权限控制必须严格。提示给 Agent 执行 shell 命令的能力时一定要做命令白名单和参数校验别让它有机会执行rm -rf这类危险操作。我见过有人图省事直接放行所有命令结果 Agent 误删了重要目录血的教训。5.4 资源占用与性能调优集群跑久了资源占用会慢慢上来。我遇到过几个典型情况Redis 内存持续增长前面说过是 Stream 没设上限Worker 进程内存泄漏跑几天就占满靠 systemd 的自动重启兜底但根治还是要查代码日志文件无限增长把磁盘写满这个用 logrotate 解决。性能调优上我的经验是Worker 数量不是越多越好。我一开始起了 10 个 Worker结果 Redis 连接数暴涨上下文切换开销也大整体吞吐反而下降。后来压测了一下发现 4 个 Worker 是这台机器的甜点再多收益就很小了。所以 Worker 数量要根据实际任务类型和机器配置压测确定别拍脑袋。6. 我踩过的坑和最后稳定下来的配置回过头看这套集群从能跑到稳定跑了大概两个月中间踩的坑主要集中在几个方面。一是幂等性没做好导致重复执行后来加了幂等键才解决二是超时和重试策略太粗糙早期所有错误都重试浪费了大量资源后来做了错误分类三是可观测性不足出问题全靠猜后来补上了结构化日志和状态追踪排查效率提升了一个量级。最后稳定下来的配置是4 个 Worker1 个调度器1 个审查1 个通知全部用 systemd 托管Redis 做消息队列和状态存储SSH 做远程管理。这套配置在我那台 32 核 64G 的机器上CPU 长期在 20% 以下内存占用稳定在 8G 左右每天能处理几百个任务基本不用我操心。如果你也想搭一套我的建议是先跑通最小闭环再逐步加角色。别一上来就搞四五个 Agent先把调度加一个 Worker 跑通确认任务能正确流转再往上加审查和通知。每加一个角色都要想清楚它解决什么问题不然就是徒增复杂度。另外日志和状态追踪一定要从第一天就做好这是后期排查问题的命根子等出了问题再补成本高得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑