为什么应在一次性 VM 中运行编码代理
一次性 VM 将编码代理的影响范围限制在可销毁的环境中,支持每任务干净状态、快照回滚和低价 VPS;小型服务器每月仅需几美元。
为什么一次性 VM 优于您的笔记本电脑
为编码代理提供一个一次性 VM,它最坏的结果也只是摧毁一台您可以在十分钟内重建的计算机。代理仍然可以获得 root 权限、安装软件包,并运行测试套件,而不必为每一步都请求许可。区别在于损害发生在哪里。在笔记本电脑上,代理会与您的主目录共享 SSH 密钥、浏览器配置文件、.env 文件,以及您曾经克隆过的所有其他代码仓库。在一次性服务器上,它只有 shell、一个检出目录,以及没有其他值得窃取的内容。
这就是全部理由。这里讨论的是不对称性,而不是概率。即使在笔记本电脑上使用谨慎的代理,几乎每次也不会出问题。但一旦出问题,代价就不只是一次错误提交。如果您有备份,还需要从备份恢复。
先明确影响范围,再讨论它
影响范围是指某个进程能够访问的一组对象。对于以普通用户身份在普通计算机上运行的代理,其影响范围通常比大多数人设想的更大。
其中包括 ~/.ssh/id_ed25519。它通常未加密,因为您不想反复输入密码短语。还包括 ~/.aws/credentials 和 ~/.config/gh/hosts.yml,它们本来就以纯文本形式存在。它包括 ~/code 下的所有同级仓库,包括那些在本地 env 文件中包含生产环境连接字符串的仓库。它还包括 shell 历史记录,其中可能保存着您曾经粘贴过的令牌。此外,它还包括笔记本电脑所连接的网络。该网络通常是家庭或办公网络,其中可能运行着无需身份验证的服务。
这些情况都不需要恶意代理。只需要一条自信但错误的命令即可。例如,rm -rf 中未设置的变量展开为 /;在错误目录中执行 git clean -xfd;执行会连同本地数据库一起删除的 docker system prune -af --volumes;或者在主目录上执行看似有帮助的 chmod -R 777。代理所接受训练的互联网,与教会其他人使用这些命令的互联网相同。
真正保护您的不是代理的判断力,而是保存损害对象的那台计算机本来就是您愿意失去的计算机。
成本计算很枯燥,但重点就在这里
一台小型 VPS 每月只需几美元。恢复开发者笔记本电脑需要一天时间,而这还是理想情况:您能立即发现问题,并且有备份。
使用您自己的数字计算。将您的时薪乘以以下操作所需的小时数:重新安装操作系统、恢复主目录、轮换 SSH 密钥、轮换个人访问令牌,以及重新克隆 20 个存储库。然后将结果与您的服务提供商销售的最小规格服务器 12 个月的费用进行比较。几年内只需避免发生一次事件,节省的成本就能超过服务器费用;而且事件不必造成灾难性后果。一整个下午因本地环境损坏而损失的时间,已经足以支付一年的服务器费用。
计算的另一部分是快照。在执行高风险操作前创建快照,可以将糟糕结果从“恢复整个工作环境”变成“回滚,然后尝试其他提示词”。您正在使用的笔记本电脑无法提供这个选项,因为您不能在把机器作为工作桌面使用时对其创建快照。
截至2026年7月的方案
对于“agent 应该在哪里运行”,有三种可靠答案。它们都在权衡两点:边界强度,以及您愿意接受多少配置工作。
本地微型 VM。 此类工具会在您的硬件上启动真正的虚拟机,将代码仓库挂载到虚拟机中,并允许 agent 在其中使用 root。clawk 是当前的示例,其定位正是本文的核心观点:为编码 agent 提供一次性的 Linux VM,而不是您的笔记本电脑。截至2026年7月,它支持 Apple silicon 上的 macOS 14 及更高版本,并通过 Firecracker 实验性支持 Linux;使用 brew install clawkwork/tap/clawk 安装。在代码仓库中运行 clawk 可启动沙箱并连接 agent,运行 clawk down 可停止沙箱,运行 clawk destroy 可将其删除。其边界由 hypervisor 提供,强度较高。限制在于,VM 运行在您随身携带的设备上,会占用设备内存,并且您合上笔记本电脑盖子后它也会停止。
容器。 Docker 是大多数人已经安装的方案,而且确实很有用。
docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash--rm 会在退出时删除容器,--network none 则完全禁用容器的网络连接,这对于构建或测试运行来说是很好的默认设置。但要明确其无法做到的事情:容器共享宿主机内核,因此内核漏洞可能成为逃逸路径;一旦添加 --privileged,或挂载 /var/run/docker.sock 让 agent 能够“使用 Docker”,该边界就会消失。将 Docker socket 挂载到容器中,相当于向该容器授予宿主机上的 root 权限。
可重建的普通 VPS。 不需要新工具,具有真正的内核边界,支持提供商快照,并且您关闭笔记本电脑后它仍会继续运行。本指南其余部分介绍的就是这种模式。它也最适合长时间运行的 agent,因为一个需要四小时的任务不会因为您回家而中断。
VPS 模式:为代理创建专用用户
从已加固的服务器开始。新 VPS 的前 10 分钟介绍了与代理无关的部分:更新、非 root 登录、仅使用密钥的 SSH 和防火墙。
然后创建一个仅供代理使用的账户。这样,即使账户内发生错误,也不会影响服务器上的其他内容。
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。真正的域名允许列表要求流量经过能够读取请求主机名的代理。对于大多数单人开发环境来说,这需要的组件过多。只声明实际具备的能力:在一台你已做好丢失准备的机器上,控制端口级别的出站访问。
在任务之间重置为干净状态
每个任务使用干净状态,这是一个常被低估的好处。某个代理花了三个小时处理上一个工单,留下了已安装的软件包、部分应用的迁移、过时的 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会介绍每个权限级别实际阻止的操作。如果您的工作仅涉及一个代码仓库,并且计算机上没有任何生产环境凭据,那么潜在影响范围已经很小。如果您的代理会话时间较短,并且有人监督,暴露窗口也会相应缩短。
一旦您跳过提示,情况就会改变。无人值守运行、夜间任务,以及批准计划后离开的任何工作流,都会移除原本负责控制影响范围的人工检查。这时必须由计算机代替人工完成控制。如果扩大代理的访问范围,情况也一样,包括同时跨多个代码仓库在 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 可以使用转发的套接字。因此,在与其他人共享的机器上,应使用限定仓库范围的部署密钥。
代理需要多大配置的 VPS?
代理工作主要包括编辑文件、运行构建和运行测试,因此应根据构建需求而不是模型需求确定机器规格。托管模型运行在提供商的硬件上,只会增加网络流量,几乎不会增加本地负载。脚本工作可从 2 GB RAM 开始;如果仓库需要构建容器或编译较大的项目,则提高到 8 GB。
应多久销毁并重建一次机器?
当机器状态无法再解释清楚时应进行重建;如果服务器上的凭据可能已暴露,则至少应立即重建。在不同任务之间使用全新检出可以处理日常状态漂移;在代理首次运行前创建快照,则可以获得一个干净的系统映像,以便恢复。如果重建成本很高,说明有重要数据或状态存放在一台你称为一次性机器的设备上。