我把 coding agent 挪到常开机器上,手机随时指挥
上一篇剩下的问题
上一篇我把账号轮换搞定了:几个 claude 账号在撞五小时墙之前自己切到下一个,不用重登,session 也不掉。但那套东西有个问题没解决——agent 还是跑在我笔记本上,我一合盖它就没了。账号会自己轮了,人还是得坐在电脑前看着。
我想要的用法大概是这样的:比如排队等编译的间隙,或者干脆躺床上,掏出手机看一眼几个 agent 在干什么,卡住的那个补一句话,顺手再派个新活,然后手机收兜里,它们接着跑。机器在云上常开,笔记本合不合盖跟它没关系。
要做到这个,得把三件事拆开:session 在哪跑、agent 之间怎么通讯、手机怎么连进去。这三段各自是独立的问题,我各挑了一个工具。
三个工具各管一段
- herdr —— session 层。你可以理解成懂 agent 的 tmux:一个 headless 的 server 托管所有 agent 的终端 pane,你把观察窗关掉、SSH 断掉、手机退出,server 和里面的 agent 照跑。detach / reattach 是它的看家本事,整套方案的常开骨架就是它。
- hcom —— 通讯层。让一堆各自独立的 agent 互相发消息(
@名字、@组)、互相召唤、协同干活;用hcom claude/hcom codex把 agent 拉起来挂到总线上,外部脚本也能往总线里丢任务。反正就是一群平级 agent 的群聊。 - Moshi —— 手机层。iOS 原生的终端 app,连上那台常开机器,看 pane、操作 pane、收推送。
拆完之后分工就清楚了:agent 全部常驻在那台常开机器上,笔记本跟手机一样,就是个连上去看和操作的客户端。长活直接派在常开机器上跑,笔记本随便合盖。
三个开源件各管一段:herdr 管 session、hcom 管通讯、Moshi 管手机,全常驻在一台常开机器上,手机和笔记本只是连上去看的客户端。
先搞一台常开的机器
云上一台便宜的小 VM 就够了。我用的是一台 8 核的 Linux 机器,但说实话跑 agent 不怎么吃 CPU,吃的是常开和网络稳定。家里闲置的机器、树莓派级别以上的东西,也都行。要求就两条:一直开着,你能 SSH 进去。
机器上装这些:agent 本体(claude、codex),三件套(herdr、hcom、moshi-hook),再加上你平时依赖的工具链。三件套都是一行安装脚本的事,各自 repo 里有。
具体搭起来就四步
第一步,把 herdr 做成常驻服务。 整套方案「合盖不掉」的根就在这一步。用 systemd 的用户级 service 把 herdr 的 server 拉起来,同时打开 linger——这样它不依赖你的登录 session,退出登录、甚至重启机器它都能自己回来:
loginctl enable-linger "$USER" # 服务不依赖登录会话
systemctl --user enable --now herdr.service
service 本身就三行,ExecStart=%h/.local/bin/herdr server 加 Restart=on-failure。这一步有个我踩过的坑,放到后面单说。
第二步,让 hcom 把 spawn 路由到 herdr。 装好 hcom 之后告诉它用 herdr 当终端后端,之后 hcom claude 起的 agent 就直接进 herdr 的 pane、被 server 托管:
hcom config terminal herdr
第三步,手机上配对 Moshi。 手机装 Moshi,在机器上跑一次 moshi-hook host setup 完成配对。配好之后手机就能连进那台机器的 herdr session,看到所有 pane。
第四步,验收。 从手机连上去,开一个 pane,敲 hcom claude(或者直接 claude),派个活,看它跑。手机上能开 pane、能跑 agent、能看它干活,第一层就算通了。
SSH 和 mosh 的差别比想象的大
这一段得讲清楚,因为它直接决定手机上的体验卡不卡。
免费版的 Moshi 只走 SSH。SSH 是 TCP 的,没有本地回显,也没有预测渲染——你在手机上每滚一下、每敲一个键,都要发到远端、等它重画整屏、再把字节流传回来,一个完整往返。手机 wifi 再一抖、一丢包,TCP 就要重传,整条流卡住。结果就是滚动一顿一顿的。
真正让它顺起来的是 mosh 协议,Moshi Pro 解锁。mosh 走 UDP,不怕丢包,没有 TCP 的队头阻塞,再加上本地预测渲染——你一滚,本地立刻画出来,后台再跟远端对账。手机上开终端这个场景,mosh 当年就是为它发明的。我实测过,手机到机器的网络路径其实很干净,直连、几十毫秒,卡顿不是网络的锅,是 SSH 这个传输层没有预测能力。
手机终端为什么卡:SSH 每次操作都要发到远端、整屏重画、字节流传回,一个完整往返;mosh 走 UDP 加本地预测渲染,你一滚本地立刻画出来,所以顺。
所以要是认真打算把手机当主控,mosh 那一档几乎是必须的,它顺带还给你原生的 herdr session 选择器和「贴图给 agent」。免费版够你验证整套流程能不能跑通,跑通了再上 Pro。
撞用量墙之后自动续跑
到这里手机能看、能指挥了,但还差一块:撞用量墙的时候,不需要我在看。
这就接回上一篇的账号轮换。我在那台常开机器上放了三个 claude 账号,配了一条 fallback 链,最后一个账号留 30% 的余量做储备。然后再加一个小看门狗,逻辑是这样的:claude 每次因为用量墙中断,会触发一个 hook 落一个标记文件;一个每两分钟醒一次的定时器读到标记,就去检查账号余量,账号管家还没切的话就切到有余量的号,然后往卡住的那个 pane 里补一句「continue」,让它接着跑。实在续不上,就在群里 @ 我一声。
撞用量墙自动续跑的看门狗回路:agent 中断落一个标记文件,每两分钟醒一次的定时器读到标记就自动换号、往卡住的 pane 里补一句 continue。
于是完整的画面是:我在地铁上派了个重构任务,手机收兜里。它跑着跑着撞了五小时墙,底下账号自动轮到下一个号,看门狗把任务续上,我全程没看手机。等我下地铁掏出手机,活已经往前走了一大截。
有一点值得说:这套看门狗是我自己写的胶水,不是三件套自带的。而且 hcom 反而看不见用量墙——它那一堆 hook 里没有专门管这个的类型,所以探测得靠 claude 原生的中断 hook,hcom 在这套里只当通知总线用。我原本以为 hcom 会把这块也包了,结果没有,得自己补一段。搭这类系统的时间有不少就花在这种事上。
几个前提,和踩过的坑
这台机器是全放开权限的。 agent 要无人值守地跑,就不能每一步停下来等批准,所以机器上的 claude 是 bypass 权限、codex 是关审批加关沙箱。这么干的前提是这台机器单一用途、个人身份、网络锁死——只有我能连,只跑我的活。反过来说,永远别在这种机器上放工作凭据、别碰生产系统。放开权限的边界,就是这台机器物理上够不着重要的东西。
detach 不等于持久。 关手机 app、断 SSH、退出登录,agent 都活着,这正是 herdr 的意义。但 server 进程真的重启(崩溃、机器重启)的时候,内存里那些终端就没了,正在跑的 agent 跟着死,server 回来是空的。这是所有终端多路复用器的通性,tmux 也一样。所以长活得放在那台常开机器上跑:合盖对它没影响,而笔记本哪天一重启,里面跑着的东西就全没了。
herdr 常驻的那个坑。 herdr 的 server 可以管一个默认 session,也可以管一个具名 session。我一开始让 systemd 起了个具名 session,结果手机连上去看到的是空的——我的 agent 全活在默认 session 里,两边对不上。改成让 service 管默认 session 就好了。手机连上去是空的,先查这个。
别在非交互 SSH 里 spawn。 从 ssh 机器 '一行命令' 这种非交互方式里用 hcom 起 agent,容易卡在 launch_blocked;从交互式 session 或者手机上起就正常。原因是一行式的 SSH 不加载你的 shell 配置,环境差一截。
哪些验过了,哪些还没
账号撞墙自动续跑这套,是我这两天才接上的。我用一个假的中断信号验过:会切号、会往 pane 里补话、续不上会在群里 @ 我。但一次真实的五小时墙撞上去到底什么样,我还没亲眼见过,这个得说清楚。
「合盖不掉」倒是天天在验。晚上笔记本一合就去睡了,第二天早上用手机连上去,昨晚派的活还在那台机器上跑着,或者已经跑完在等我 review。

