ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Hermes Agent+SSH远程调度Claude Code:多机AI编码编排实战

Hermes Agent+SSH远程调度Claude Code:多机AI编码编排实战 先说结论这套组合打完我十几台开发机终于不用再逐台登录、重复配置也不用靠聊天窗口传任务了。Hermes Agent 承担编排中枢SSH 负责打通控制节点和各台工作机之间的安全通道Claude Code 则作为真正干活的 AI 编码代理被远程唤起。三个角色各管一摊配合起来能覆盖多机并行编码、远程审查、跨平台构建这类真实场景。如果你手里同时有 Windows、Linux、macOS 几套环境或者团队里有人想统一调度 Claude Code这篇文章就是按我踩过的坑写下来的。1. 整体设计思路为什么是 Hermes Agent SSH而不是其他方案1.1 真实痛点AI 编码助手被“锁”在了单机上Claude Code 本身是一个跑在终端里的交互式编程代理装在哪台机器上它就只能访问哪台机器的文件系统、执行哪台机器的命令。这带来一个很实际的问题我在本地 Mac 上调试好的一套提示词、配置、项目上下文换到 Windows 工作机上就全不认了。项目还没跨机器脑子先得跨一次。更麻烦的是多机并行。一个仓库拆成几个模块我想同时让两台机器分别处理订单模块和库存模块就得开两个终端窗口分别登录两台服务器手动把任务粘贴进去。任务跑完没有统一收口结果散落在各个屏幕里。时间一长哪个任务成功、哪个失败、失败原因是什么根本没法追溯。还有一个隐蔽痛点Claude Code 的会话和配置默认存在用户目录下。团队里不同人用同一台构建机时一旦 A 的配置覆盖了 B 的目录要么登录态失效要么模型参数被改掉排查起来相当费劲。这些问题的根源都一样缺少一个能统一管理“在哪台机器上、以什么身份、执行什么 AI 任务”的调度层。1.2 三层架构拆解编排层、通道层、执行层我最终采用的方案是很朴素的三层结构。第一层是编排层也就是 Hermes Agent。它负责维护任务队列、记录每台工作机的状态、把任务拆成可执行命令并下发最后回收执行结果。你可以把它理解成一个“任务管家”真正写代码的人不是它但它知道把活派给谁、什么时候派、怎么汇总。第二层是通道层SSH。控制节点和工作节点之间所有通信都走 SSH 协议。选 SSH 不是因为多高深而是因为它足够通用Linux 和 macOS 自带服务端Windows 也可以装 OpenSSH Server 或 Bitvise SSH Server客户端更是全平台覆盖。密钥认证配好之后控制节点可以免密登录任意工作机批量执行命令就像在本地一样。第三层是执行层Claude Code。它必须安装到每台工作机上作为实际执行 AI 编码任务的进程被唤醒。Hermes Agent 并不会替 Claude Code 做决策它只负责通过 SSH 把任务文本传过去然后启动一个claude -p的非交互进程来干活。这样做的优势是Claude Code 的所有能力都被保留远程调度只是换了一个启动方式。1.3 方案选型对比为什么不直接用 MCP 或 tmux有人会问Claude Code 不是支持各种 Agent 连接方式吗为什么还要套一层 SSH我的观点是MCP 适合在单机进程内扩展能力解决的是“Claude Code 能不能访问某个工具”的问题而我面对的是“多台物理机器上的多个 Claude Code 实例如何被统一控制”的问题这属于进程编排和资源调度不是 MCP 协议擅长的事。还有人会用 tmux SSH 手动管理先登录每台机器开几个 tmux 窗口跑 claude再用 SSH 粘过去看输出。这套方案在只有两三台机器时能用但一旦任务多了会话列表管理、超时清理、结果结构化返回都会变成体力活。Hermes Agent 的价值就是把这一层自动化任务失败自动重试结果按任务 ID 归档worker 状态集中可见。它不会替你写出更好的代码但能让你从“人肉运维多台终端”里解放出来。1.4 执行层为什么选 Claude Code 而不是 Codex执行层这个小节值得单独说。我也试过直接用 Codex 来做远程编码代理它的模型能力没话说但在我这个场景里有两个问题一是它的 CLI 在无头环境下的批量、非交互调用方式不如 Claude Code 顺手二是我需要跨平台统一调度的工具链Claude Code 通过 npm 安装Windows、Linux、macOS 三套系统命令一致而 Codex 在某些发行版上的依赖配置要额外处理。另外 Claude Code 支持-pprint非交互模式可以传入单条任务指令配合--output-format json拿到结构化输出。这个能力对编排系统极其重要Hermes Agent 不需要解析人类可读的终端文本直接吃 JSON 就够了。所以我的取舍很简单Herman Agent 做大脑SSH 做神经网络Claude Code 做手和脚。2. 环境准备控制节点与工作节点的部署2.1 Hermes Agent 本地部署的正确姿势Hermes Agent 的部署方式我这里以自己用的版本为例。它支持 Docker 和本机直接运行两种方式我更推荐在控制节点上用本机运行因为调度任务时经常要读取本地的密钥文件和配置目录容器方式还得额外挂载稍微麻烦一点。部署时先确认控制节点的系统环境。我用的是 Ubuntu 22.04 作为控制节点执行安装脚本或者拉取可执行文件后第一件事不是急着配置而是先初始化配置目录。启动之后一般会在用户目录下生成一个配置文件夹里面至少包含一个主配置文件、一个存放 worker 信息的目录、一个存放任务运行日志的目录。我习惯把日志单独放到/var/log/hermes并做按天轮转因为编排系统跑起来之后日志量会比想象中大很多。Windows 上也有便携版解压即用适合临时把某台 Windows 机器当控制节点。但我个人还是倾向让 Linux 机器当控制节点因为后续要写批量脚本、处理定时任务Linux 下的工具链更成熟。Windows 节点更适合作为被调度的 worker而不是调度方。2.2 各工作机上安装 Claude CodeClaude Code 的安装相对简单前提是每台工作机上都有 Node.js 18 以上版本。安装命令是 npm 全局安装npm install -g anthropic-ai/claude-code装完先手动执行一次claude完成登录认证。这一步必须在工作机本机上做因为认证信息会写进当前用户的配置目录。如果你想隔离不同项目的配置可以通过环境变量指定独立的配置目录比如export CLAUDE_CONFIG_DIR/data/claude-config/project-a claude这一点在多机编排时非常关键。如果所有任务共用同一个配置目录不同项目的模型参数、MCP 插件配置会互相污染我的做法是一个项目一个配置目录Hermes Agent 下发任务时把对应的CLAUDE_CONFIG_DIR一起带过去。Windows 上的安装有几点需要注意。首先确认 npm 全局 bin 目录在 PATH 里否则远程执行claude会提示命令找不到。其次 Windows 默认 PowerShell 的执行策略可能会拦截 npm 生成的脚本需要调整执行策略或者在 Hermes Agent 里给 Windows worker 指定 shell 为powershell.exe -ExecutionPolicy Bypass -Command。2.3 SSH 服务端选型Windows、Linux、macOS 三平台对照SSH 服务端的选择直接决定你后面省不省心。我用下来的对照关系是这样的工作机系统SSH 服务端方案备注LinuxOpenSSH Server发行版自带systemctl enable --now ssh即可macOS系统自带远程登录系统设置里开启“远程登录”Windows Server / Win10Windows OpenSSH Server 或 Bitvise SSH Server微软可选功能即可安装Bitvise 图形化管理更友好Windows 上如果只是临时用我建议直接启用 Windows 自带的 OpenSSH Server在“可选功能”里添加然后把服务设为自动启动。追求管理便捷、要多用户虚拟账户映射的话再考虑 Bitvise SSH Server。不过要注意Bitvise 默认的权限模型和 OpenSSH 的 authorized_keys 有差异如果用 Hermes Agent 统一走 OpenSSH 风格的密钥认证还是推荐 Windows 自带方案少一层适配。所有工作机的 SSH 服务端配好后先在本机用密码登录一次确认能通再进入下一步密钥配置。这一步别跳很多后面看似诡异的问题根源就是服务端连密码登录都没开。3. 多机编排的命门SSH 密钥体系与通道打通3.1 专用密钥比默认密钥更省心很多教程上来就让你用~/.ssh/id_rsa作为编排密钥我强烈不建议。原因很简单权限粒度。控制节点可能同时连生产服务器、测试机、同事的电脑如果把个人默认密钥当作调度凭证一旦泄露所有机器都暴露了。正确做法是单独生成一把只用于 Hermes Agent 调度的密钥权限收窄出现风险时可以单独吊销重换。我生成密钥用的是 ed25519 算法性能好、长度短、安全性足够ssh-keygen -t ed25519 -C hermes-agent-overseer -f ~/.ssh/hermes_ed25519生成后不要设置 passphrase。不是说安全不重要而是在编排场景下Herman Agent 需要免交互地加载私钥如果加了 passphrase每次 SSH 连接都会卡在密码输入上。真要加固私钥应该靠控制节点本身的文件系统权限和系统账户安全而不是给私钥加口令。3.2 公钥分发与权限检查最常见翻车点密钥生成的下一步是把公钥写入每台工作机的authorized_keys。最简单的命令是ssh-copy-idLinux 和 macOS 上都有ssh-copy-id -i ~/.ssh/hermes_ed25519.pub dev192.168.1.21Windows 工作机没有ssh-copy-id命令可以手动追加cat ~/.ssh/hermes_ed25519.pub | ssh dev192.168.1.22 mkdir -p ~/.ssh cat ~/.ssh/authorized_keys后面这个命令在 Windows 的默认 shell 下可能不生效因为cat 在 PowerShell 里不是这个语义。我在 Windows 工作机上更推荐用 PowerShell 执行$key Get-Content $env:USERPROFILE\.ssh\hermes_ed25519.pub Add-Content $env:USERPROFILE\.ssh\authorized_keys $key公钥传上去之后权限检查是绕不开的坑。Linux 和 macOS 上~/.ssh目录权限必须是 700authorized_keys必须是 600多一个组可写权限 SSH 都会拒绝加载公钥。我遇到过太多次Permission denied (publickey)最后发现是authorized_keys是 664。执行下面这条命令修复chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys3.3 连接复用与批量连通性验证所有工作机的公钥分发完成后先在控制节点上写一个批量验证脚本确认每台机器都能免密登录。脚本内容不复杂核心就一句话for host in dev-linux dev-win dev-mac; do ssh -i ~/.ssh/hermes_ed25519 -o ConnectTimeout5 -o BatchModeyes hermes$host hostname claude --version done这个-o BatchModeyes参数很关键它会让 SSH 在需要交互输入密码时直接失败而不是卡住等待。批量任务一旦有一个节点卡在密码输入上整个编排任务都被拖死。连接量比较大的时候一定要开启 SSH 连接复用。默认情况下SSH 每次连接都会重新做一次密钥交换和握手对于短命令批量调度握手时间甚至比命令执行时间还长。我在控制节点的~/.ssh/config里加了这段Host dev-* IdentityFile ~/.ssh/hermes_ed25519 ControlMaster auto ControlPath ~/.ssh/control-%r%h:%p ControlPersist 10m这样第一个连接建立后后续连接直接复用同一个 TCP 通道批量调度几十台机器时速度提升非常明显。3.4 在 Hermes Agent 中登记 worker 节点通道打通之后下一步就是把各工作机登记进 Hermes Agent。我用的是配置文件方式在配置文件的 workers 段里逐台声明。每台 worker 至少包括三部分信息连接地址、SSH 身份、远程 shell 类型。shell 类型必须明确因为后面下发命令时要决定用 bash、sh 还是 powershell 来包一层。我常用的简化配置长这样workers: - name: linux-build host: 192.168.1.23 user: hermes identity: ~/.ssh/hermes_ed25519 shell: bash - name: win-dev host: 192.168.1.24 user: hermes identity: ~/.ssh/hermes_ed25519 shell: powershell - name: mac-mini host: 192.168.1.25 user: hermes identity: ~/.ssh/hermes_ed25519 shell: zsh登记完先跑一个 worker 自检确认 Hermes Agent 能通过 SSH 连上所有节点并拿到基础信息。这一步跑不通就继续排查 SSH跑通了再开始下发任务省得后面任务失败时还得判断是通道问题还是任务本身问题。4. 实操SSH 远程调度 Claude Code 跑跨平台任务4.1 第一步单台机器上跑通第一个远程 AI 任务不要一上来就玩多机并行先在单台机器上把链路完整跑通。我在 Hermes Agent 里定义了一个最简单的任务让远程 Linux 构建机扫描指定目录里的 TODO 注释生成一份文档。任务定义大致如下tasks: - name: scan-todo-linux worker: linux-build command: | cd /data/repos/order-service CLAUDE_CONFIG_DIR/data/claude-config/order-service \ claude -p 请扫描 src/ 目录下的所有 TODO、FIXME 注释汇总输出到 docs/todo.md \ --output-format json然后通过 Hermes Agent 触发执行。关键点在于目标机器上必须已经安装并且认证过 Claude Code否则远程执行时claude命令不存在或者需要交互登录任务直接就卡住了。所以我一直强调工作机上的 Claude Code 要在配置阶段手动跑一次把登录态准备好。第一次跑通时注意看返回结果里是否带了--output-format json的结构化内容。如果能看到 JSON说明远程执行链路已经没问题了后续可以放心做批量和并发。4.2 多机并行任务分发、并发控制与超时单机跑通后我开始把同一个仓库的不同模块任务分到不同机器上。比如订单模块在 Linux 构建机上改前端仓库在 Windows 机器上动模型评估脚本在 Mac mini 上跑。Hermes Agent 的任务定义里每个 task 指定一个 worker再整体设置并发数避免同时把所有 worker 打满。并发控制这块吃过一次亏。最开始我把并发数设得很大结果 5 台工作机同时拉起 claude 进程每台机器还有多个任务在跑内存直接被打到 swap任务全部超时。后来我把并发策略调整为每个 worker 同时最多只能跑一个任务整体并行度通过跨 worker 控制。任务队列里再多的任务也只能排队进入这样每台机器上的 Claude Code 都能稳定工作不会因为资源争抢导致整机卡死。超时设置也值得讲。AI 编码任务的执行时间波动非常大短的可能几十秒长的可能要跑十几分钟。我按任务类型区分超时代码生成类给 10 分钟大规模重构或测试补全给 30 分钟。Herman Agent 里对每个任务单独设置 timeout超时后自动标记失败并记录日志方便后续重跑或人工介入。4.3 跨平台坑shell 差异、路径差异、换行符跨平台调度最难受的不是 AI 本身而是三套系统之间的差异。第一个坑是 shell。Linux 用 bashmacOS 默认 zshWindows 的默认 shell 在不同 SSH 服务端下可能是 cmd 也可能是 PowerShell。我在 worker 配置里强制声明 shell命令下发时用对应的 shell 执行。比如 Windows 节点上所有命令都包一层powershell -Command确保语法一致。第二个坑是路径。Linux 的/data/repos/order-service在 Windows 上就是D:\repos\order-service。我通常把仓库路径和 Claude Code 的配置目录设计成“按机器设置独立变量”。具体做法是在 Hermes Agent 里给每个 worker 挂一组环境变量而不是在任务命令里写死路径。这样同一份任务模板分发到不同机器时自动替换成对应路径任务定义里不出现任何硬编码的绝对路径。第三个坑是换行符。我在 Windows 工作机上执行 bash 风格的多行命令时遇到过\r导致命令解析失败的问题。解决方法是跨平台任务的命令尽量写成单行或者写成独立脚本文件先通过 scp 推送到目标机再远程执行这个脚本。这比在命令行里拼一堆引号和转义要稳得多。4.4 结果回传与日志聚合任务执行完结果不能留在工作机上否则又要手动登录去看。我让 Hermes Agent 在每个任务完成后自动回收两个东西命令的标准输出以及生成的产物文件列表。标准输出的回收很简单执行完后把返回内容写进按任务 ID 命名的文件里统一存到控制节点的日志目录。产物文件的处理稍微复杂些。比如远程让 Claude Code 生成了一份review.md脚本需要在任务命令最后显式执行一次回传scp -i ~/.ssh/hermes_ed25519 /data/repos/order-service/review.md hermesoverseer:/var/lib/hermes/artifacts/20250115-review.md早期我偷懒只回收标准输出结果 Claude Code 明明在远程生成了文件我却看不到内容还得手动登录确认多机编排的体验直接打对折。现在我的原则是凡是任务中可能产生文件的地方都在命令里显式回传。日志聚合我放在最后一步。Hermes Agent 自带的任务日志只记录了调度的生命周期比如开始时间、结束状态、退出码。Claude Code 进程本身的详细输出我要求通过--output-format json落到标准输出再被 Hermes Agent 回收。这样每个任务的完整轨迹都能在控制节点上查询出问题时不用逐台机器翻日志。4.5 连接 VSCode Remote-SSH人工兜底与图形化全自动调度再香也总有需要人工介入的时候。比如 Claude Code 在某个 PR 上产生了歧义需要打开具体文件看上下文。这时候我会用 VSCode 的 Remote-SSH 插件直接连到对应工作机图形化界面里查看文件树、diff、终端状态。Hermes Agent 跑完一个任务后会生成一个结果链接里面包含机器名、项目路径、产物文件路径。我在 VSCode 里新建 Remote-SSH 窗口用同一把密钥连上去直接打开那个路径就能在编辑器里继续人工 review。这一步不算优雅但胜在可靠是全自动流程和人工审查之间的缓冲带。另外一些特别复杂的任务比如涉及大量交互式确认的代码重构我干脆不自动化。直接在 VSCode 里连上远程机器打开对应目录在集成终端里手动跑claude需要确认时人工回答。我的经验是能用-p全自动跑的交给 Hermes Agent需要反复确认的保留人工交互入口。两者结合既不牺牲自动化率也不至于让 AI 卡在某个问题上空转。5. 常见问题与排查实录5.1 高频报错速查表这一节把这些年遇到的高频问题整理成表方便你排查时直接对照。现象常见原因解决思路SSH 提示 Permission denied (publickey)authorized_keys 权限不对、公钥没追加成功、sshd 配置里禁用了公钥认证检查 700/600 权限在服务端打开 PubkeyAuthentication yes用sshd -t验证配置SSH 提示 Host key verification failed控制节点 known_hosts 里没有目标机指纹或指纹已变化首次连接手动确认或提前用ssh-keyscan target ~/.ssh/known_hosts预置指纹远程执行时提示 claude: command not foundnpm 全局 bin 目录不在 PATH 中或 shell 未重新加载环境变量在命令前显式export PATH$PATH:$(npm prefix -g)/binWindows 检查用户 PATH远程执行 claude 后一直卡住没有使用-p非交互模式claude 进入了交互式界面等待输入调度命令统一加-p并加--output-format jsonWindows 节点命令执行到一半报错默认 shell 是 cmd语法和 bash 不同在 Hermes Agent worker 配置里把 shell 设为 powershell并统一 PowerShell 语法多机并发后某台机器内存被打满并发数设置过大Claude Code 进程数量超限降低单 worker 并发数增加任务排队机制必要时单独限制内存批量 SSH 连接速度慢每次连接都在执行完整握手开启 ControlMaster 和 ControlPersist 连接复用Ubuntu 上 SSH 服务无法连接sshd 未启动或被防火墙拦截systemctl status ssh检查服务sudo ufw allow 22/tcp放行端口5.2 远程执行时命令被转义和引号地狱远程调度 AI 任务和本地执行最大的区别在于命令要经过本地 shell、SSH、远程 shell 三层解析。只要命令里出现引号、管道、特殊字符就有被某一层错误拆分的风险。我在早期被这个问题折磨了很久一个命令在本地明明能跑通过 SSH 调过去就报错。我的解决方案是三步走。第一所有复杂命令不要写在任务定义的 command 字段里而是单独写成一个 shell 脚本比如scripts/remote-task.sh提交到项目仓库。第二Herman Agent 下发任务时先通过 scp 把脚本推送到工作机再远程执行bash /tmp/remote-task.sh。第三脚本内部再调用 claude这样格式问题只在脚本内部检查。如果确实需要在命令行里拼多行命令也要注意 SSH 命令参数本身是一个字符串。我习惯先在本机把命令用bash -n做语法检查再通过 SSH 执行。这里有一个细节配合set -euxo pipefail让远程脚本在任何一步失败时及时退出避免一个命令失败后继续往下跑最后拿到一个不完整的结果。5.3 安全加固别让编排入口变成攻击入口Hermes Agent 控制节点一旦配置完成相当于拿到了所有工作机的钥匙。这把钥匙如果丢了所有机器都会沦陷。所以安全加固在我这里不是可选优化而是必须做的。首先禁用工作机上的 SSH 密码登录只保留密钥认证。编辑 sshd_config设置PasswordAuthentication no然后重启 sshd。这一步能挡住大部分暴力破解。其次不要让 Hermes Agent 使用 root 或管理员账户登录而是为每台工作机创建专用系统用户权限只开放给它需要操作的项目目录和命令。比如 Linux 上我用hermes用户配合 sudoers 里白名单放行少数命令而不是直接给全部 root 权限。第三个措施是限制来源。工作机上的 sshd 可以加AllowUsers hermes只允许这个用户登录再配合防火墙只在控制节点 IP 上放行 SSH 端口。我还见过有人直接在 sshd_config 里限制公钥来源AuthorizedKeysCommand从统一平台拉取公钥这样密钥轮换时不用逐台机器手动更新。这个方案适合团队规模较大的场景我目前的状态是机器数量不多用传统 authorized_keys 也能管理得过来。最后定期轮换编排密钥。我给自己定的周期是每三个月换一次换的时候生成新密钥分发到各工作机然后从控制节点删除旧密钥。步骤繁琐但考虑到这套系统掌握了多台机器的执行权限这点麻烦值得。5.4 我踩过的最大的几个坑第一个坑是公私钥路径混淆。最初在 Hermes Agent 配置里把公钥路径写成了私钥路径结果 SSH 直接报错。这类问题排查起来不复杂但很消耗时间后来我把密钥文件名起得非常明确比如私钥id_ed25519和公钥id_ed25519.pub配置时一眼就能看出问题。第二个坑是没有对齐 Claude Code 的配置目录。有一次我在 Linux 构建机上跑任务远程 claude 用的模型和我预期的不一样折腾了很久才发现工作机的CLAUDE_CONFIG_DIR指向了另一个项目的历史配置。从那以后我在每个任务命令开头都显式声明CLAUDE_CONFIG_DIR不让 claude 用默认路径从源头避免配置串号。第三个坑是 Windows 工作机的 PATH 问题。npm 全局安装的 claude 放在%APPDATA%\npm下这个目录不一定在系统 PATH 中。远程通过 PowerShell 执行时如果 PATH 没加载就会提示找不到 claude。我在 Windows worker 的任务命令里固定写全路径或者先把 npm prefix 加到 worker 的环境变量里。这个坑很隐蔽因为你在 Windows 机器上手动打开 PowerShell 时 PATH 是正常的但通过 SSH 非交互登录时加载的环境变量可能不完整。最后是控制节点磁盘回收问题。日志和产物默认全部堆积在控制节点跑一段时间磁盘就满了。我现在给日志目录写了按天轮转产物目录只保留最近 7 天再用 cron 定期清理任务结束后留下的临时文件。编排系统本身就容易产生大量中间文件尽早把清理机制做好后面能省很多事。这套“Hermes Agent 多机编排 SSH 远程调度 Claude Code”的方案说到底不是某个单个工具的魔法而是把三个环节串起来之后产生的规模效应。我在实际使用中最大的体会是先把 SSH 通道和使用方式练熟再上编排调度会顺手很多。编排系统确实方便可一旦通道不稳定或者权限混乱它带来的麻烦也成倍放大。如果你手头已经有多台开发机建议先从两台机器开始把心跳、密钥、单任务跑通再去扩展规模。调度层带来的收益是在机器数量和处理规模上来之后才能真正体现出来的。
返回列表