手机统一接管两台电脑上的编程 Agent
作者用 herdr 移动中继与 Cloudflare Tunnel,在一个手机应用中查看和响应两台电脑上的 Agent。方案还介绍通过 Tailscale 或 Cloudflare Access 连接家用电脑,并限制工作电脑接受入站连接。
AI 深度解读
把两台笔记本上的 AI Agent 接到同一个手机应用里,难点不在聊天界面,而在设备休眠、iOS 配对、远程会话和访问权限。作者用 herdr、Cloudflare Tunnel 和 Tailscale 搭了一套个人方案:手机看进度、答审批,工作电脑通过 SSH 操作家中电脑,同时限制工作电脑的入站连接。
这套方案值得看的,是作者记录了哪些配置看似生效,实际却会掉链子。它也有明确前提:个人设备、个人网络,以及一台需要长期保持清醒的家用 Mac。
一个手机应用,为什么还需要两个地址
两台电脑各自运行 herdr 和 herdr-mobile-relay,各自通过 Cloudflare Tunnel 主动建立出站连接。手机通过 relay 查看和操作 Agent,两台电脑都不用在公网监听端口,也不用配置路由器端口转发。

这里有两种地址,不能混为一谈。work-relay.example.dev、home-relay.example.dev 分别标识两台电脑的 relay;手机应用的部署地址则要统一。因为 iOS 会把主屏幕应用和安装来源地址绑定,分别从两个地址安装,就会得到两个独立应用。
作者让工作电脑提供应用入口,再从已安装的应用内部导入家用电脑的邀请,最终显示 2/2 relays。代价是首次安装和更新应用时,工作电脑必须在线。后续可通过 Configure App Deployment 迁到 Cloudflare Pages,但只应在负责发布更新的一台电脑上配置。
稳定域名也有成本。按作者描述,Cloudflare 在 Enterprise 以下套餐不能只接管一个子域的 DNS,因此他另买了专用域名。购买后区域生效可能需要一小时,可用 dig NS example.dev +short 检查是否返回两个 *.ns.cloudflare.com 地址。
安装入口如下,解决插件安装和稳定隧道配置:
herdr --version # 0.7.5 or newer
herdr plugin install 0cv/herdr-mobile-relay
herdr plugin action invoke install-service --plugin herdr-mobile-relay.events
注意最后一行:它会启动向导,创建隧道、DNS 记录和后台服务,并输出配对二维码。Cloudflare 登录生成的 ~/.cloudflared/cert.pem 是凭据,不能放进 dotfiles。
iOS 配对和合盖休眠,才是容易踩中的坑
iOS 浏览器与主屏幕应用使用独立存储。在浏览器里配对成功,不代表安装后的应用也已配对。
作者给出的顺序是:扫码后选择添加到主屏幕,再从主屏幕图标打开应用;不要点 Pair this browser instead。如果出现 refused this device,可能是浏览器已经消耗了一次性邀请,需要运行 herdr plugin action invoke setup-link --plugin herdr-mobile-relay.events 重新生成,再从应用内导入。多出的浏览器设备应在 gear > Devices 中撤销。
配对链接就是临时密码,不能当成普通安装链接转发。
原文称邀请只能使用一次,十分钟后过期。作者只允许自己的手机成为 controller,它能输入、审批、启动和停止 Agent;其他设备只读,并开启应用的 device lock。
另一类故障来自 Mac 合盖。sudo pmset -c sleep 0 只阻止接电时的空闲睡眠,挡不住 Clamshell Sleep。Herdr.app 的咖啡杯功能也一样。
作者在带 HDMI 接口的 MacBook Pro 上插了约 $10 的 HDMI dummy plug,让系统认为外接显示器仍在。接电合盖约 16.5 小时后,他通过 sysctl kern.sleeptime kern.waketime 检查,两个时间仍早于合盖,支持这次测试期间没有睡眠。
这不是所有 Mac 的保证。原文说 Apple 的合盖条件还包括外接键盘或鼠标,只是作者这台机器未连接也能工作。他试过 sudo pmset -c disablesleep 1,但发现它表现为全局设置,电池供电时也不睡,随后撤销。
其接电配置还包括 disksleep 0、womp 1、displaysleep 15,用 pmset -g custom 核对 AC Power。-c 表示仅接电设置。开启 FileVault 后,重启仍需要有人现场解锁,休眠参数解决不了这一关。
SSH 要解决的不只是连通,还有连接方向
手机适合看状态、答问题,完整 shell 操作则交给 SSH。作者平时用 Tailscale,另配了一条 Cloudflare Access 路径。
Tailscale 默认允许设备互访,作者将权限收缩到家用电脑的 22 端口:
{
"tagOwners": {
"tag:home": ["autogroup:admin"]
},
"acls": [
{ "action": "accept", "src": ["autogroup:member"], "dst": ["tag:home:22"] }
]
}
注意 dst:只有标记为 tag:home 的机器,其 22 端口被放行。这个标签只给家用电脑;原文还指出,带标签设备关闭密钥过期,避免每 180 天掉线。
工作电脑另设两道限制:系统关闭 Remote Login,不运行 SSH 服务;执行 tailscale set --shields-up=true 拒绝入站连接。验证要从家用电脑运行 nc -vz -G 3 <work-laptop> 22,结果必须失败。tailscale ping 仍可能响应,不能据此判断 22 端口开放。
家用 Mac 使用系统 OpenSSH,因为原文所用 macOS 版 Tailscale 应用不提供 Tailscale SSH 服务。作者每台机器使用独立 SSH 密钥,确认密钥登录成功后,设置 PasswordAuthentication no 和 KbdInteractiveAuthentication no,并保持旧会话打开,测试新连接后再退出。
另一条路径使用独立 SSH 隧道,工作电脑通过 ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h 访问 ssh-home.example.dev。Cloudflare Access 先验证指定邮箱,再由 SSH 校验密钥;客户端只建立出站连接。
两种 Access 用法要分清:SSH 域名前加 Access 是作者的方案,relay 域名前却不能照搬,原文称它会阻断手机应用。
远程接入应复用会话,也要让人认得出机器
herdr 的服务和 Agent 进程留在家用电脑上。执行 herdr --remote home-ts,或用 herdr --remote home-ts --session agents 指定会话,只是增加一个观察和操作入口。快捷命令是 hr-home,退出附着用 Ctrl+B,再按 Q。
关闭 SSH 后,Agent 继续运行。较小的终端会临时调整共享面板尺寸,断开后恢复。
正在运行的对话应该重新附着,不能再启动一个进程抢同一份会话。
因此作者不会对已在面板中运行的对话执行 omp --resume。Firstmate 也操作同一批 herdr 会话,直接输入它的 worker 面板,会被视为人工介入,并在后续检查中处理。
为避免把远程 shell 当成本地,作者给 Ghostty 加深紫背景和 REMOTE: <host> 标题。包装器只处理交互终端,跳过 ssh home uptime、ssh -N、ssh -T,还要区分 -p 22 和 -p22。转义序列写入 /dev/tty,避免污染管道输出,always 块负责失败后的颜色复位。
配套测试通过伪终端和假的 ssh、herdr 运行,不依赖真实主机或 Ghostty;入口为 cd 03-mobile-relay 后执行 make test。
我的判断
我认同作者把手机控制、SSH 和后台会话拆开处理。这样更容易判断故障究竟来自入口、权限、进程还是电源状态。
但它是一份个人配置经验,不是经过对照验证的团队方案。原文没有提供延迟、断线恢复、多人协作或长期稳定性数据;合盖测试也只覆盖一台 Mac 和约 16.5 小时。与只用 SSH 相比,它增加了手机审批能力,也增加了域名、隧道和配对管理成本。
安全描述尤其需要收紧理解:电脑不开放公网端口,不等于外部无法控制它。手机仍可通过出站隧道操作工作电脑上的 Agent,这本来就是目标功能。企业是否允许这种入口,不能由「连接方向朝外」决定。
原文声称 relay 流量端到端加密,Cloudflare 只能看到时序和帧大小,但没有展开协议和密钥实现。这里应作为作者的描述保留,不能替代安全审查。
能拿来做什么
- 如果经常等待 AI 编程审批,可以先在一台个人电脑上验证手机控制,并用插件
status和本机http://127.0.0.1:8375/readyz检查服务;后者就绪时返回200。 - 如果想从另一台电脑继续工作,先确认工具支持附着既有会话,再测试断开 SSH 后任务是否继续运行,避免重复启动同一对话。
- 如果用家用 Mac 长期运行 Agent,应分别验证空闲、合盖和重启后的状态,尤其确认 FileVault 是否要求现场解锁。
- 如果接入工作电脑,应先核对组织规则,并保留设备撤销路径。作者的手机丢失处理是撤销配对,再在工作电脑运行
stable-teardown,相关凭据也不能进入聊天或截图。