给 Agent 布置好任务,离开电脑后,它可能一直停在一个确认问题上。看进度、回答问题、确认下一步,这些操作在手机上就能完成。
这套方案把 Agent 和开发环境留在 NixOS 机器上:Herdr 管理终端会话,Collie 提供手机网页,Tailscale 连接两端。系统安装只做一次,用户首次完成登录与配对,之后直接打开手机入口。
为什么把 Agent 留在开发机
出口集中。 Agent 请求由开发机发出,手机切换 Wi-Fi 和蜂窝网络不会改变这条路径。使用相同路由或代理时,可以统一出口,减少账号网络环境频繁变化的因素。动态 IP 和分流仍可能影响出口;Tailscale 在这里仅负责网页访问,稳定出口也不保证降低封号风险。
一个页面管理多个 Agent。 Claude Code、Codex 等 CLI 保留各自的配置和账号,通过同一个页面查看与操作。普通终端操作通用;状态识别、对话历史和审批界面则取决于具体集成。
环境只维护一份。 仓库、凭据和项目的 flake.nix 都留在开发机。手机适合短暂接手,复杂 diff 和大规模修改仍留给桌面。
三个组件的分工
- Herdr:用工作区、标签页和 pane 管理终端;客户端脱离后,任务继续运行。
- Collie:提供手机网页、快捷按键,以及受支持 Agent 的会话视图。可以添加到主屏幕,也支持推送通知。
- Tailscale Serve:通过 tailnet 提供私有 HTTPS 入口,无需把 Collie 端口开放到公网。
手机浏览器 / 主屏幕应用
│ Tailscale + HTTPS
▼
Collie
│ Herdr socket
▼
Herdr
├─ Claude Code
└─ Codex / 其他终端程序
每位 Unix 用户使用自己的会话、Collie 实例和 Tailscale 身份。Agent 访问模型服务时,走的仍是开发机原有路由。
首次使用:四步
已有机器部署直接从这里开始,不用创建 .env,也不用手写服务文件。从零搭建的 NixOS 主机,先完成后面的系统配置。
手机安装 Tailscale,与开发机登录同一账号。tailnet 需启用 MagicDNS、HTTPS Certificates,完成节点审批,并允许手机访问节点的 TCP 443。Agent CLI 也应提前安装并登录。
1. 在 Herdr 里启动 Agent
直接 SSH 登录自己的普通用户,不用 sudo -iu 切换账号:
ssh alice@devbox
herdr
在 Herdr 的终端中进入项目,加载环境(如 nix develop),启动 claude 或 codex。需要并行任务时新建标签页或 pane。
按 Ctrl+B,松开后按 Q 返回外层 shell,任务继续在后台运行。Herdr 不会接管其他终端里已运行的 Agent。
2. 登录自己的 Tailscale
systemctl --user start collie-tailscaled
collie-tailscale up --hostname=devbox-alice
把节点名换成自己的名称,打开输出的授权链接登录。已登录的实例无需重复授权;这里使用 collie-tailscale,以连接当前用户的 daemon。
3. 启动 Collie
collie start
collie doctor
启动输出里的 tailnet HTTPS 地址就是手机入口,之后也能用 collie url 查询。不要在手机上打开 127.0.0.1。已有 Collie 安装、刚升级或修改过配置时,用 collie restart 代替 start。
首次尚未配对时,doctor 的配对告警是正常的,完成下一步即可。
4. 配对手机
collie pair
手机保持 Tailscale 在线,扫描二维码或打开配对链接,输入设备名称。配对码单次使用、10 分钟有效;配对后的设备凭据默认持续有效,直到撤销。
iPhone 用 Safari“添加到主屏幕”,Android 选择“安装应用”或“添加到主屏幕”。从新图标打开,确认能看到 Agent 并发送输入;如果未继承浏览器的配对状态,重新生成配对码,在主屏幕应用里配对一次。
配对手机拥有该 Unix 用户的终端操作权限,只给自己的设备配对。权限说明
之后只需要打开手机
保持手机 Tailscale 在线,点开主屏幕入口即可。无需每次 SSH 登录、重新授权或配对。桌面上执行 herdr,可以接回同一套终端。
退出 SSH 后继续使用需要开启 linger,下文的通用模块会自动设置。已有机器部署可用 loginctl show-user "$USER" -p Linger 检查;若为 no,由管理员按需开启。机器重启仍会结束 Agent 进程,需要回到 Herdr 中重新启动。
可选:让手机收到等待输入的通知
collie push-keys
collie restart
# 在手机端授权并订阅通知后:
collie push-test
iPhone 需 iOS 16.4 或更新版本,并从主屏幕应用使用 Web Push。推送密钥保留在用户目录,不放进系统 flake。
NixOS:管理员只配置一次
这里使用 my-nix-pkgs 的公开模块,适合接入现有系统 flake。模块封装了用户级 Tailscale、Collie 默认配置和 systemd 依赖,用户只执行前面的四步。
示例锁定提交 d9f545d,对应 Collie 1.23.0、Herdr 0.9.5、Tailscale 1.104.1。以下命令使用 Bash,配置目录假设为 ~/nixos,configuration.nix 已包含硬件配置和普通用户 alice。
导入模块
Nix 需已启用 nix-command 和 flakes。未启用时,先在原配置添加 nix.settings.experimental-features = [ "nix-command" "flakes" ]; 并按原有方式重建系统。
cd ~/nixos
COLLIE_PKGS_REV=d9f545d9ff3ce18c50a7749310f3219f51da53ea
curl --fail --location \
"https://raw.githubusercontent.com/LMMMMMJ/my-nix-pkgs/${COLLIE_PKGS_REV}/docs/examples/collie-mobile.nix" \
--output collie-mobile.nix
查看下载的模块后,将下面的输入和配置合并进现有 flake,保留原有系统模块。已有同名文件时先比较,避免覆盖。
完整 flake 配置(展开查看)
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
my-nix-pkgs.url =
"github:LMMMMMJ/my-nix-pkgs/d9f545d9ff3ce18c50a7749310f3219f51da53ea";
};
outputs = { nixpkgs, my-nix-pkgs, ... }: {
nixosConfigurations.devbox = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
./collie-mobile.nix
({ pkgs, ... }: {
environment.systemPackages = [ pkgs.python3 ];
services.collieMobile = {
enable = true;
colliePackage =
my-nix-pkgs.packages.${pkgs.stdenv.hostPlatform.system}.collie;
herdrPackage =
my-nix-pkgs.packages.${pkgs.stdenv.hostPlatform.system}.herdr;
tailscalePackage =
my-nix-pkgs.packages.${pkgs.stdenv.hostPlatform.system}.tailscale;
users.alice = {
port = 8787;
tailnetLogin = "alice@example.com";
};
};
})
];
};
};
}
替换 devbox、alice 和实际 Tailscale 登录名;ARM 主机将 system 改为 aarch64-linux。pkgs.python3 是 Herdr 的 Agent hooks 所需运行时,安装到系统才能同时供 Agent 终端和后台服务使用。多个用户分配不同本地端口即可。
重建系统
git add flake.nix collie-mobile.nix
nix flake lock
sudo nixos-rebuild build --flake .#devbox
sudo nixos-rebuild switch --flake .#devbox
保存 flake.lock。如果原来另装了 collie,移除重复安装项,确保命令使用模块的包装器;保留现有状态。部署后用户直接 SSH 登录,按前面的四步操作。
与已有 my-nix-machine 部署的区别
my-nix-machine 的 HomeServer 配置已提供按用户分配的端口和默认设置,不必再导入这份通用模块。它默认不预填 Tailscale 邮箱,用户在浏览器中选择账号;collie-tailscaled 按需启动,状态为 static 正常,linger 由管理员按需开启:
sudo loginctl enable-linger alice
本文的通用模块则由管理员填写 tailnetLogin,并自动启用 daemon 和 linger。两者的用户操作相同,但不能混用服务状态的验收标准。
排障与升级
部署后先从手机打开目标会话,在测试 shell 里执行 pwd,再退出全部 SSH 会话确认仍能操作。遇到问题先运行 collie doctor,无需每次逐项检查 systemd 和 socket。
常见问题与 Agent 集成
- 网页打不开:检查手机 Tailscale、节点审批、MagicDNS、HTTPS 和 TCP 443 策略。首次签发证书可能稍有等待。
- 无法配对或被拒绝:重新生成配对码;如配置了受信任身份,核对 Tailscale 登录名。
- 找不到 Agent:确认它运行在同一用户的 Herdr 内。
- 状态识别不正常:检查集成和
python3,只安装实际需要的集成:
herdr integration status
command -v python3
herdr integration install claude
# 使用 Codex 时:herdr integration install codex
安装会修改 Agent 用户配置,之后在 Herdr 内重启对应 Agent,并完成信任确认。仅查看普通终端和发送按键不要求安装全部集成。集成文档
需要进一步排查时查看日志:
journalctl --user -u collie -u collie-tailscaled -n 80 --no-pager
软件升级由管理员在 Nix 中完成。采用本文配置时,先修改 my-nix-pkgs.url 的固定提交、检查同版本模块变更,再执行:
nix flake update my-nix-pkgs
sudo nixos-rebuild build --flake .#devbox
sudo nixos-rebuild switch --flake .#devbox
之后每位用户执行 collie restart 和 collie doctor。重启会更新服务引用的 Nix store 路径,无需重新配对。更换手机时用 collie devices list 查找旧设备,再用 collie devices revoke old-phone 撤销。