为什么编码代理应该运行在一次性 VM 中
将编码代理放入可销毁的 VM,限制 SSH 密钥、浏览器配置、令牌和其他代码仓库的影响范围;小型 VPS 每月只需几美元,并支持快照回滚。
为什么一次性 VM 比你的笔记本电脑更合适
为编码代理提供一次性 VM 后,它最坏也只能摧毁一台你可以在十分钟内重建的机器。代理仍然可以获得 root 权限、安装软件包,并在无需为每一步都请求许可的情况下运行测试套件。区别在于损害发生在哪里。在笔记本电脑上,代理可以访问与你的 SSH 密钥、浏览器配置文件、.env 文件以及你曾经克隆过的所有其他代码仓库共享的主目录。在一次性服务器上,它只有一个 shell、一个代码检出目录,以及其他没有价值可供窃取的内容。
这就是全部理由。这个理由关注的是不对称性,而不是发生概率。即使是在配置完善的笔记本电脑上,谨慎的代理几乎每次也都不会出问题。但一旦出问题,代价就不只是一次错误提交。如果你有备份,还需要从备份恢复。
在争论影响范围前,先明确它有多大
影响范围是指一个进程能够访问的对象集合。对于以普通用户身份在普通计算机上运行的 agent,这个集合通常比大多数人想象的更大。
其中包括 ~/.ssh/id_ed25519。它通常未加密,因为您不想反复输入口令。还包括 ~/.aws/credentials 和 ~/.config/gh/hosts.yml,它们在设计上就是纯文本。还包括 ~/code 下的所有同级存储库,包括那些在本地 env 文件中包含生产环境连接字符串的存储库。还包括 shell 历史记录,其中可能保存着您曾粘贴过一次的令牌。它还包括笔记本电脑所连接的网络,该网络通常是家庭或办公网络,其中可能运行着无需身份验证的服务。
这一切都不需要恶意 agent。只需要一条看似正确但实际错误的命令。例如,rm -rf 中未设置的变量展开为 /;在错误目录中执行 git clean -xfd;执行会连同本地数据库一起删除的 docker system prune -af --volumes;或在主目录中执行看似有帮助的 chmod -R 777。训练 agent 所使用的互联网,也教会了其他人使用这些命令。
真正保护您的不是 agent 的判断力,而是承载损害的那台机器本来就是您愿意放弃的机器。
成本计算很无聊,但这正是重点
一台小型 VPS 每月只需几美元。恢复一台开发者笔记本电脑需要一天时间;这还是较理想的情况,因为你能立即发现问题,并且已有备份。
用你自己的数字计算。将你的时薪乘以以下操作所需的小时数:重新安装操作系统、恢复主目录、轮换 SSH 密钥、轮换个人访问令牌,以及重新克隆 20 个代码仓库。然后将结果与供应商提供的最小规格服务器 12 个月的费用进行比较。几年内只要避免发生 1 次事故,成本通常就能达到盈亏平衡;而且事故不必造成灾难性后果。一台本地环境损坏,导致你损失一个下午的时间,就已经足以抵消一整年的费用。
计算的另一部分是快照。在执行高风险操作前创建快照,可以将糟糕的结果从“恢复我的全部工作环境”变成“回滚,然后尝试不同的提示词”。你正在使用的笔记本电脑无法提供这个选项,因为你不能在把电脑当作工作台使用时创建整机快照。
截至 2026 年 7 月的现状
对于“agent 应该运行在哪里”这个问题,有 3 个可靠答案。它们都需要在同样的两点之间权衡:隔离边界的强度,以及你能接受多少配置工作。
本地微型 VM。此类工具会在本机硬件上启动真正的虚拟机,将代码仓库挂载到虚拟机中,并允许 agent 在其中使用 root。clawk 是当前的示例,其核心理念正是本文的观点:为 coding agent 提供一次性的 Linux VM,而不是使用你的笔记本电脑。截至 2026 年 7 月,它面向 Apple silicon 上的 macOS 14 及更高版本,并通过 Firecracker 提供实验性 Linux 支持;使用 brew install clawkwork/tap/clawk 安装。在代码仓库中运行 clawk 可启动 sandbox 并连接 agent,运行 clawk down 可停止它,运行 clawk destroy 可将其删除。其隔离边界由 hypervisor 提供,强度较高。限制在于,VM 位于你随身携带的设备上,因此会占用本机内存;关闭笔记本电脑时,VM 也会停止。
容器。Docker 是大多数人已经安装的方案,而且确实很有用。
docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash--rm 会在退出时删除容器,--network none 则完全禁用网络连接,这对于构建或测试运行来说是不错的默认设置。但要明确它的局限:容器与宿主机共享 kernel,因此 kernel 漏洞可能成为越界路径;一旦添加 --privileged,或挂载 /var/run/docker.sock 让 agent 可以“使用 Docker”,隔离边界就会消失。将 Docker socket 挂载到容器中,等同于向该容器授予宿主机上的 root 权限。
可重建的普通 VPS。无需引入新工具,拥有真正的 kernel 隔离边界,支持云服务商快照,并且在你关闭笔记本电脑后仍会继续运行。本指南其余部分介绍的就是这种模式。它也最适合运行时间较长的 agent,因为耗时 4 小时的任务不会因为你下班回家而停止。
VPS 模式:为智能体创建专用用户
从加固后的服务器开始。新 VPS 的前十分钟涵盖与智能体无关的基础工作:更新系统、创建非 root 登录、仅允许密钥登录,以及配置防火墙。
然后创建一个仅供智能体使用的账户。这样,即使该账户中的操作出错,也无法影响服务器上的其他内容。
sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/work
sudo -u agent -H bash -lc 'id; ls -la ~'--disabled-password表示没有可供猜测的密码。您可以使用 sudo -u agent 或 SSH 密钥登录该账户。请注意,agent有意不属于 sudo 组。拥有 sudo 的智能体即拥有 root 权限,而 root 可以读取其他所有用户的文件,因此刚才建立的隔离就只是表面上的。如果智能体确实需要安装软件包,这说明它应使用一台完全由其管理的服务器,而不是在共享服务器上授予它 sudo。相关通用规则请参阅VPS 上 Linux 用户的最小权限原则。
在信任该边界前先进行检查。以 agent 用户身份,尝试读取属于该用户自己的文件:
sudo -u agent cat /home/you/.ssh/id_ed25519您应看到 cat: /home/you/.ssh/id_ed25519: Permission denied。如果看到的是密钥材料,说明主目录的权限模式为 755,隔离尚未真正生效。使用 sudo chmod 700 /home/you 修复。
完全不要将凭据放在该机器上
如果将生产环境的机密复制到一次性机器上,就失去了使用一次性机器的意义。规则很简单:该机器上的任何内容都不应是你不愿意在今天下午轮换的凭据。
对于 git,应转发 SSH agent,而不是复制密钥。私钥保留在你的笔记本电脑上,连接中只传递签名请求。
ssh -A agent@203.0.113.10
ssh -T git@github.com第二条命令应返回 Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.。这证明 git push 在服务器上没有密钥文件的情况下也能正常工作。随后在该机器上运行 ls -la ~/.ssh,确认其中不存在私钥。
Agent 转发有一个必须明确说明的实际风险:在你连接期间,任何拥有该服务器 root 权限的人都可以使用转发的套接字,以你的身份进行身份验证。如果服务器上的其他用户只有你自己,这种权衡可以接受。在共享服务器上则不可接受,此时最好使用限定为单个仓库的部署密钥。相关选项见 SSH 密钥管理基础。
对于 API 密钥,应为 agent 单独创建一个密钥,并设置独立的消费限额。将密钥存储在由 agent 用户拥有、权限为 mode 600 的文件中。销毁机器时,应撤销该密钥,而不是猜测它是否已经泄露。按密钥单独查看模型消费,也是让 VPS 上的 AI agent 成本控制中的数字保持可预测的方式。
限制代理在网络上的访问范围
文件系统隔离只是边界的一半。另一半是出站流量控制,即限制进程可以连接哪些目标。Linux 可以按照创建进程的用户过滤出站流量,这正好适用于此模式。
sudo iptables -A OUTPUT -m owner --uid-owner agent -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -j REJECT规则按顺序读取,因此最后的 REJECT 会匹配前面规则未允许的所有流量。以该代理的身份进行测试:
sudo -u agent curl -sS -m 5 http://example.com该命令应因 curl: (7) Failed to connect to example.com port 80: Connection refused 而失败,因为 reject 规则会立即返回响应,而不是让连接一直挂起。对同一主机发起 HTTPS 请求仍应成功。
有两个需要明确的限制。第一,除非使用 sudo apt install -y iptables-persistent 保存规则,再通过 sudo netfilter-persistent save 恢复,否则这些规则会在下次重启后丢失。第二,这些规则过滤的是端口和地址,而不是域名。允许访问 443 端口,就等于允许访问互联网上所有 HTTPS 主机;这既足以访问模型 API,也足以访问 pastebin。真正的域名允许列表需要让流量经过能够读取请求主机名的代理,但对于大多数单人开发环境来说,这需要额外的复杂配置。只能声明实际实现的能力:在一台已经做好丢失准备的机器上,提供基于端口的出站流量控制。
在任务之间恢复到干净状态
每个任务都使用干净状态,是一个常被低估的好处。某个代理处理上一个工单时运行了 3 个小时,留下了已安装的软件包、只完成一半的迁移、过期的 node_modules,以及一个包含未审核更改的 Git 工作树。下一个任务会继承全部这些内容,而您需要消耗审核时间来判断哪些问题属于哪次运行。更受限的代理一开始就会留下更少的内容,因此,将一次性机器与促使代理采用最小可行更改的技能结合,可以让差异和残留状态都保持在易于审核的范围内。
最简单的方法是为每个任务创建一个全新的检出副本。
sudo -u agent -H bash -lc 'rm -rf ~/work/repo && git clone git@github.com:you/repo.git ~/work/repo'更可靠的方法是在机器设置完成后、任何代理使用它之前,创建一次提供商快照。恢复该快照后,整个系统(包括软件包)都会回到已知状态。大多数提供商通过控制面板或 API 提供此功能,而不是将其作为机器上的命令,因此具体步骤取决于您的提供商。关键是要在机器仍处于未使用状态时创建快照。
需要保留的内容都不要放在一次性机器上。通常,这意味着推送分支,而不是将其长期保存在本地。如果机器上确实保存了您不希望丢失的内容,请使用VPS 上的 restic 备份正确备份。只有在销毁机器确实不会引发问题时,一台可以销毁的机器才真正有用。
如果您希望拥有多个隔离环境,但不想为多个服务器付费,可以让一台配置更高的 VPS 直接托管客户机 VM。VPS 上的嵌套虚拟化介绍了具体实现方式,包括如何检查您的提供商是否允许此功能。隔离在这里也有两面性。如果您希望同一台机器上的两个代理彼此协调,而不是完全隔离,那么可以使用一个 Claude Code 会话直接向另一个会话发送文本,无需让每次交接都经过您。
真正适合使用笔记本电脑的情况
对此应保持客观,因为过度宣传隔离效果会让人不再信任这些建议。
如果您会在每条命令执行前进行检查,使用笔记本电脑没有问题。权限提示确实是一项有效的控制措施,而在服务器上安全运行 Claude Code会说明每个权限级别实际阻止了哪些操作。如果您的工作只涉及一个代码仓库,并且这台机器上没有任何生产环境凭据,那么潜在影响范围已经很小。如果您的代理会话时间较短,并且始终有人监督,暴露窗口也会相应缩短。
一旦跳过这些提示,情况就会改变。现在尤其应考虑这一点,因为auto mode 将在 2026 年 8 月 14 日成为 Claude Code 的默认模式,全新安装后,Claude Code 不再在修改文件或运行命令前询问。无人值守运行、夜间任务,以及批准计划后离开的工作流,都会移除原本负责限制影响范围的人工检查。这时必须由机器来执行限制。同样,任何扩大代理访问范围的做法也适用,包括在 VPS 上运行代码代理并同时处理多个代码仓库。
这个决定实际上与您有多信任模型无关,而取决于模型出错时,旁边还有哪些系统和数据。
FAQ
容器是否足以为编码代理提供隔离?
对于大多数工作来说,足够,但必须满足两个条件。容器不能以 --privileged 运行,也不能将 /var/run/docker.sock 挂载到容器中,因为这两种情况都会为进程提供一条获取主机 root 权限的路径。容器与主机共享内核,因此其隔离边界弱于虚拟机。如果代理运行的是从互联网获取的不受信任代码,优先使用真正的虚拟机或独立服务器。
代理是否需要服务器上的 sudo 权限?
不需要。授予 sudo 会破坏已建立的隔离,因为 root 可以读取该主机上的所有其他账户。创建代理用户时不要授予 sudo,只允许它写入自己的工作目录。如果任务确实需要安装软件包,应为代理提供一台由它独占的整机,而不是让它在共享机器上获得 root 权限。
如何让代理推送到 git,同时不把我的 SSH 密钥放到服务器上?
连接时使用 ssh -A 转发 SSH agent。签名请求会通过连接传输,而私钥保留在你的笔记本电脑上,因此 ssh -T git@github.com 可以完成身份验证,git push 也能正常工作,服务器上无需保存私钥。需要注意的是,在你连接期间,该服务器上的 root 可以使用转发的 socket。因此,在与其他人共享的机器上,应使用限定仓库范围的 deploy key。
代理需要多大规格的 VPS?
代理的工作主要是编辑文件、运行构建和运行测试,因此应根据构建需求而不是模型需求确定机器规格。托管模型运行在提供商的硬件上,只会产生网络流量,几乎不会增加本地负载。脚本任务可以从 2 GB RAM 开始;如果仓库会构建容器或编译大型项目,则提升到 8 GB。
应多久销毁并重建一次机器?
当机器状态无法再解释清楚时,应重建;只要服务器上的凭据可能已暴露,也至少应重建一次。任务之间使用全新检出的代码可以处理日常状态漂移;在首次运行代理前创建快照,则可获得一个干净的系统镜像,以便恢复。如果重建的成本让你觉得过高,说明某些重要数据正在一台被称为可丢弃的机器上持续存在。