ENZH

我把 coding agent 搬进了手机,合盖它接着跑

剪掉最后一根绳

上一篇我让几个 Claude 账号在撞五小时墙之前自己轮到下一个——不用重登、会话不掉线。但那时候人还拴在电脑前:agent 跑在我的笔记本上,我一合盖,它就没了。

真正想要的画面是这样的:排队等编译的间隙、地铁上、躺床上,掏出手机,看一眼几个 agent 在干什么,给卡住的那个补一句话,再派个新活,然后把手机收兜里——它们继续跑。机器在云上常开,笔记本合不合盖跟它没关系。

这需要把三件事拆开:会话在哪跑agent 之间怎么说话手机怎么连进去。我按这三段各挑了一个工具。

三个件,各管一段

  • herdr —— 会话层,你可以理解成「懂 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 的家,它降级成一个「当你坐在桌前时顺手用的客户端」。真正的家是那台常开机器。长活丢给它,笔记本随便合盖。

你需要一台常开的机器

云上一台便宜的小 VM 就够(我用的是一台 8 核的 Linux 机器,但跑 agent 其实不吃 CPU,吃的是常开和网络稳定)。家里一台闲置的机器、一块树莓派级别以上的东西,也行。要点只有两个:一直开着你能 SSH 进去

装的东西:agent 本体(claudecodex)、三件套(herdrhcommoshi-hook),外加你平时依赖的工具链。三件套都是一行安装脚本的事,各自 repo 里有。

搭起来:四步

第一步,herdr 做成常驻服务。 这是整套方案能「合盖不掉」的根。用 systemd 的用户级 service 起 herdr 的 server,并且打开 linger——这样它不依赖你的登录会话,退出登录、甚至重启机器都能自己回来:

loginctl enable-linger "$USER"          # 服务不依赖登录会话
systemctl --user enable --now herdr.service

service 本身就三行 ExecStart=%h/.local/bin/herdr serverRestart=on-failure。这里有个我踩过的坑,后面单说。

第二步,hcom 把 spawn 路由到 herdr。 装好 hcom 后告诉它用 herdr 当终端后端,之后 hcom claude 起的 agent 就直接进 herdr 的 pane、被 server 托管:

hcom config terminal herdr

第三步,手机上配对 Moshi。 手机装 Moshi,在那台机器上跑一次 moshi-hook host setup 完成配对。配对之后,手机就能连进那台机器的 herdr 会话,看到所有 pane。

第四步,验收。 从手机连上去,开一个 pane,敲 hcom claude(或 claude),派个活,看它跑。能在手机上开 pane、跑 agent、看它干活——第一层就通了。

手机上那块屏,卡不卡差一个协议

这里要非常诚实地讲一件事,因为它直接决定体验「丝不丝滑」。

免费版的 Moshi 只走 SSH。SSH 是 TCP,没有本地回显、没有预测渲染——你手机上每滚一下、每敲一下,都要发到远端、等它重画整屏、再把字节流传回来,一个完整往返。加上手机 wifi 一抖动、一丢包,TCP 要重传,整条流卡住。结果就是滚起来一顿一顿的。

真正让它丝滑的是 mosh 协议(Moshi Pro 解锁)。mosh 走 UDP(不怕丢包、没有 TCP 队头阻塞)+ 本地预测渲染(你一滚,本地立刻画出来,后台再跟远端对账)。这正是「手机上开终端」这个场景被发明出来要解决的问题。我实测过:手机到机器的网络路径其实很干净(直连、几十毫秒),卡顿不是网络的锅,是 SSH 这个传输层没有预测能力。

所以如果你认真要把手机当主控,mosh 那一档(Moshi Pro)几乎是必需的——它顺带还给你原生的 herdr 会话选择器和「贴图给 agent」。免费版足够验证整套流程能不能跑通,跑通了再上 Pro。

闭环:撞墙了它自己接着跑

到这里,手机能看、能指挥了。但「终极」还差一块:撞墙的时候,不需要我在看。

这就接回上一篇的账号轮换。我在那台常开机器上放了三个 Claude 账号,配了一条 fallback 链,还给最后一个账号留了 30% 的余量做储备。再加一个小小的看门狗:Claude 每次因为用量墙而中断,会触发一个 hook 落一个标记文件;一个每两分钟醒一次的定时器读到标记,就检查账号余量、(如果账号管家还没切)切到有余量的号、然后往那个卡住的 pane 里补一句「continue」,让它接着跑。跑不通就退一步,在群里 @ 我一声。

于是完整的画面是:我在地铁上派了个重构任务,手机收兜里。它跑着跑着撞了五小时墙——底下账号自动轮到下一个号,看门狗把任务续上,我全程没看手机。等我下地铁掏出来,活已经往前走了一大截。像手机从 Wi-Fi 切到蜂窝,电话不断。

(这套看门狗是我自己写的胶水,不是三件套自带的。有意思的是 hcom 反而看不见用量墙——它的一堆 hook 里没有专门管这个的那一类,所以探测得靠 Claude 原生的中断 hook,hcom 在这套里只当通知总线用。这种「以为某个工具全包了、结果得自己补一块」的细节,正是搭这类系统最花时间的地方。)

几个诚实的取舍,和踩过的坑

这台机器是全放开权限的。 agent 无人值守地跑,就不能每一步都停下来等批准。所以这台机器上的 Claude 是 bypass 权限、Codex 是关审批 + 关沙箱。这么做的前提是它单一用途、个人身份、网络锁死——只有我能连、只跑我的活。反过来说:永远别在这种机器上放工作凭据或碰生产系统。 放开权限的边界,就是这台机器物理上够不着重要东西。

detach 不等于持久。 关手机 app、断 SSH、退出登录——agent 都活着(这正是 herdr 的意义)。但 server 进程真正重启(崩溃、机器重启)时,内存里的那些终端就没了,正在跑的 agent 会随之死掉,server 回来是空的。这是所有终端多路复用器(tmux 也一样)的通性。所以长活要放在那台常开机器上,别放笔记本——笔记本合盖没事,但一重启就全没。

那个 herdr 常驻的坑。 herdr 的 server 可以管一个默认会话,也可以管一个具名会话。我一开始让 systemd 起了个具名会话,结果手机连上去看到的是空的——因为我的 agent 都活在默认会话里,两边对不上。改成让 service 管默认会话就好了。手机连上去是空的,先查这个。

别在非交互 SSH 里 spawn。ssh 机器 '一行命令' 这种非交互方式里 hcom 起 agent,容易卡在 launch_blocked;从交互式会话或手机上起就正常。原因是那种一行式 SSH 不会加载你的 shell 配置,环境差一截。

剪干净了

有一半我还没等到真实检验:账号撞墙自动续跑这套,是我这两天才接上的。我用一个假的中断信号验过它会切号、会往 pane 里补话、会在续不上时在群里 @ 我——但一次真实的五小时墙撞上去那一下到底什么样,我还没亲眼见到。这个诚实得留着。

倒是「合盖不掉」这件事,我天天在验。晚上把笔记本一合睡觉,早上摸出手机,昨晚派的活还在那台机器上跑着,或者已经跑完在等我 review。就这一件小事——不是「手机能连上机器」这种成立,是「我不在,它自己往前走」这种成立——已经把「我必须坐在电脑前才能干活」这个假设拆掉了。绳,剪掉了一根。

← PrevNext →

© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0