在沙箱中运行 Claude Code 风格的或托管的编码代理,为每个代理分配一个限定范围的工作空间、明确文件权限、受控的 Shell 执行、网络与包策略、清晰的密钥边界、持久化日志、捕获的工件,以及在合并或发布更改前的人工审查。代理仍然可以读取代码、编辑文件、安装依赖、运行测试并生成补丁,但其周围环境会决定它能够接触什么、获取什么、看到哪些凭据,以及何时需要人工批准下一步操作。
需要隔离的内容
编码代理不仅仅是附加到仓库的聊天机器人。一旦它能够编辑文件和运行命令,它就类似于一个带有语言模型推理能力的初级构建工作者。该工作者可能会运行 npm test、检查生成的文件、启动开发服务器,或根据错误提示尝试安装包。如果工作空间是你的笔记本电脑、共享 CI 运行器或长期存在的类生产 VM,爆炸半径就太大了。
隔离目标涵盖整个代理工作循环:
- 代理可以读取或修改的仓库检出和分支。
- 代理可以写入的文件系统路径。
- 它可以自动运行的命令。
- 需要批准的命令。
- 它可以访问的包注册表、域名和 API。
- 暴露给会话的凭据。
- 为审查而保留的日志、差异、测试输出、截图和工件。
- 成功、失败或超时后的清理行为。
Claude Code 和其他托管编码代理产品可能包含自己的权限系统。例如,Anthropic 的 Claude Code 文档描述了允许和禁止工具、批准行为以及本地使用沙箱指导的权限设置。将这些控制视为一层,而非整个边界。更强大的设计是将代理置于隔离运行时内部,然后在该运行时内应用工具权限。
参考架构
一个实用的沙箱化代理工作流程包含四个层次:
| 层级 | 目的 | 典型控制 |
|---|---|---|
| 代理控制器 | 决定任务计划和工具调用 | 模型/工具权限、批准模式、任务提示 |
| 沙箱运行时 | 托管命令执行的工作空间 | 隔离文件系统、进程限制、生命周期控制 |
| 策略网关 | 决定允许哪些操作 | 命令规则、网络出口规则、包策略、密钥范围 |
| 审查界面 | 让人类检查结果 | 差异、日志、测试结果、工件、拉取请求 |
保持这些层次分离。如果代理控制器因提示注入而受损,沙箱运行时和策略网关仍应限制发生的情况。如果包安装拉取了意外代码,网络和工件日志应使其可见。如果代理生成了看似合理的补丁,审查界面仍应准确显示更改了什么以及运行了哪些测试。
一个概念性的策略对象可能如下所示:
workspace:
mode: ephemeral
repo_ref: pull-request-branch
writable_paths:
- /workspace/project
readonly_paths:
- /workspace/reference
commands:
auto_allow:
- git status
- npm test
- npm run lint
- pytest
require_approval:
- npm install
- pip install
- docker build
- git push
deny:
- rm -rf /
- curl ... | sh
network:
default: deny
allow:
- registry.npmjs.org
- pypi.org
- files.pythonhosted.org
secrets:
expose:
- READ_ONLY_PACKAGE_TOKEN
deny:
- PRODUCTION_DATABASE_URL
- CLOUD_ADMIN_TOKEN
artifacts:
capture:
- git diff
- test-results/
- screenshots/
- command-log.jsonl
这并非刻意作为 SDK 示例。确切的策略格式取决于你的代理框架和沙箱提供商。重点在于,权限应在模型自由形式的推理之外表达,然后由运行时或编排层强制执行。
工作空间与仓库设置
每个代理运行都从干净的工作空间开始。托管代理不应继承开发者的 shell 历史、SSH 代理、点文件、云 CLI 登录或未跟踪的本地文件,除非有刻意的理由。
对于仓库工作,使用专用检出:
- 仅克隆或挂载任务所需的仓库。
- 检出新的任务分支,而非编辑默认分支。
- 固定基础提交,以便审查可以重现起点。
- 将依赖缓存与可写源代码路径分开。
- 除非生成的文件是预期差异的一部分,否则将生成的工件存储在源代码树之外。
分支隔离很重要,因为编码代理在确定最终方案前通常会尝试多种方法。干净的任务分支为审查者提供正常的 PR 差异,而不是包含临时实验的混合工作空间。如果代理需要与参考实现进行比较,请以只读方式挂载该参考。
对于长期运行的托管代理,决定沙箱是临时性的、暂停的还是快照的。临时工作空间更易于推理。快照和暂停/恢复对于长时间作业、浏览器会话和昂贵的设置步骤很有用,但它们仍应保留清晰的审计线索:何时创建快照、存在哪些文件以及哪些凭据可用。
文件系统权限
文件系统范围应比“代理可以读取整个机器”更窄。大多数编码任务需要:
- 对仓库工作空间的读写访问。
- 对选定任务上下文、夹具或文档的只读访问。
- 用于构建输出和临时文件的临时目录。
- 无权访问主机主目录、无关仓库、云凭据、浏览器配置文件或生产数据转储。
写入权限需要特别关注。可以编辑仓库的编码代理也可以编辑脚本、测试、锁文件、CI 配置和部署文件。这可能是任务所要求的,但应在审查中可见。对于敏感路径,例如 .github/workflows/、部署清单或包发布配置,需要更强的批准步骤或最终人工审查。
当任务范围狭窄时,使用文件允许列表。例如,文档代理可能只需要 docs/ 和生成的预览目录。依赖升级代理可能需要 package.json、锁文件和测试快照。广泛的代码重构需要更大的访问权限,但审查应预期更大的差异和更完整的测试。
Shell 执行策略
Shell 访问是编码代理变得有用且危险的地方。它们需要命令执行来运行测试、格式化代码、检查构建错误和验证修复。它们不需要不受限制的权限来无停顿地运行每个命令。
良好的 Shell 策略包含三个桶:
| 桶 | 示例 | 为何重要 |
|---|---|---|
| 自动允许 | git status、npm test、pytest、go test ./...、npm run lint |
保持正常的编辑-测试循环快速 |
| 需要批准 | 包安装、迁移、长时间运行的服务、外部 CLI、git push |
在状态、成本或网络风险发生变化的地方增加摩擦 |
| 拒绝 | 破坏性主机命令、凭据转储、不安全的 Shell 管道、在工作空间外写入 | 阻止不应委托的操作 |
不要仅依赖命令文本匹配。代理可以通过脚本、包管理器钩子或嵌套 Shell 运行命令。对于高风险环境,将命令策略与运行时级别的文件系统边界、资源限制和网络控制结合起来。
长时间运行的命令需要超时行为。测试服务器、浏览器自动化运行或构建监视器可能在代理继续执行后仍保持活动状态。捕获进程 ID、stdout、stderr、退出状态、运行时间和终止原因。如果命令打开了预览端口,记录端口映射并在清理期间关闭它。
包安装与网络出口
包安装是代理工作空间最有用的功能之一,也是风险最容易进入的地方之一。编码代理可能因为 Stack Overflow 答案、README 或模型生成的计划而安装包。这可能会改变依赖图、执行安装脚本并访问外部注册表。
对于实现指南和生产工作流程,从默认拒绝的网络姿态开始,然后允许任务所需的内容:
- 包注册表,如 npm 或 PyPI,最好通过注册表镜像或缓存。
- 仓库和子模块所需的源主机。
- 任务所需的文档域名。
- 仅当沙箱具有正确数据分类时才允许内部 API。
避免默认赋予每个代理广泛的出站互联网访问。如果研究或浏览器自动化需要广泛访问,请将该运行与修改代码的运行分开,并相应标记工件。
对于包安装,记录:
- 包管理器命令。
- 注册表主机。
- 锁文件更改。
- 下载的包名称和版本(如果可用)。
- 运行的任何安装脚本。
- 是否有人工批准了安装。
这并不能使任意包变得安全。它使更改可审查。
密钥边界
密钥应限定于任务范围、短暂存在,并默认不出现。最安全的沙箱不是承诺模型永远不会泄露密钥的沙箱,而是除非任务确实需要,否则密钥不存在的沙箱。
使用以下默认值:
- 代理工作空间中不包含生产数据库凭据。
- 不包含云管理员令牌。
- 不包含个人 SSH 密钥或开发者机器凭据。
- 尽可能使用只读凭据。
- 为包读取、测试夹具或仅暂存 API 使用单独的令牌。
- 在共享工件之前,对日志中的密钥进行脱敏。
如果代理必须调用外部服务,请提供窄范围令牌并记录哪个工具或命令使用了它。避免将广泛凭据放在代理可以编辑的文件中。环境变量很方便,但它们仍可能被命令打印、包含在日志中或复制到生成的文件中。将它们视为暴露给代理进程。
日志、工件与审计线索
只有当审查者能够看到发生了什么时,人工审查才有用。沙箱化编码代理的运行应保留比最终补丁更多的信息。
至少捕获:
- 任务提示或指令摘要。
- 基础提交和分支。
- 当工具能够记录时,读取和写入的文件。
- 运行的命令,包含时间戳、工作目录、退出状态、stdout 和 stderr。
- 包安装和网络访问摘要。
- 测试和构建结果。
- 生成的文件、截图、报告或预览链接。
- 最终差异。
将日志存储在比沙箱更持久的审查界面中。如果沙箱在运行后立即销毁,证据仍应在 PR、CI 工件存储或代理平台记录中可用。
对于使用托管代理的团队,此审计线索还有助于比较代理性能。你可以查看失败是否源于缺少依赖、被拒绝的命令、不清晰的提示、不稳定的测试或真正的代码问题。
清理与重置
沙箱清理是安全性和成本控制,而不仅仅是整理。在运行结束时:
- 停止后台进程。
- 关闭暴露的端口。
- 撤销任务范围的令牌。
- 导出必要的工件。
- 删除不属于审查的临时文件。
- 根据运行类型销毁、暂停或快照沙箱。
临时重置是未经验证或探索性工作的最干净默认值。对于长期运行的代理,仅在已知良好的设置步骤之后进行快照,而不是在任意代理活动之后。如果失败运行需要调查,请保留沙箱或快照,并设置明确的过期时间。
Novita Agent Sandbox 的定位
Novita Agent Sandbox 专为 AI 代理执行工作流设计,其中代码在隔离的云工作空间中运行,而不是在开发者笔记本电脑或共享主机上。Novita 的 Sandbox 文档描述了与本指南中模式相匹配的核心原语:沙箱生命周期管理、文件系统操作、命令执行、模板和代理工作负载的运行时管理。
这使得 Novita 适合构建编码代理、数据分析、浏览器代理、评估或需要执行环境以及模型 API 的长期运行代理工作流的团队。不过,请保持边界清晰:本文是 Claude Code 风格和托管编码代理的通用实现模式。它不声称与 Claude Code 正式集成、存在合作伙伴关系或与每个托管代理产品普遍兼容。
如果你正在设计基于 Novita 的工作流,请使用产品文档获取确切的已发布 API,并保持策略层明确。沙箱可以提供隔离的执行工作空间;你的应用程序仍应决定命令批准、网络策略、密钥范围、工件保留和人工审查关卡。
安全审查清单
在允许编码代理在玩具仓库之外运行之前,请使用此清单:
| 问题 | 检查内容 |
|---|---|
| 隔离边界是什么? | 专用工作空间、进程限制、文件系统隔离以及明确的提供商文档 |
| 代理可以读取什么? | 默认仅仓库访问,无主机主目录,无无关仓库 |
| 代理可以写入什么? | 可写源路径明确;敏感配置路径需要额外审查 |
| 哪些命令自动运行? | 允许测试和格式化命令;状态更改命令需要批准 |
| 哪些网络访问存在? | 默认拒绝或限定出口;包注册表和文档域是有意为之 |
| 如何处理包安装? | 锁文件更改、注册表主机和安装脚本均被记录 |
| 存在哪些密钥? | 仅限任务范围、短暂、最小权限凭据 |
| 日志如何处理? | 命令、输出、差异和工件在沙箱清理后仍存在 |
| 如何强制执行清理? | 后台进程、端口、令牌和临时文件被关闭或撤销 |
| 谁批准合并或发布? | 人工审查者检查代码、测试、安全敏感文件和生成的工件 |
最重要的规则很简单:不要混淆“代理请求了权限”与“系统强制执行了边界”。模型可以帮助解释它想要做什么。运行时和策略层应决定它被允许做什么。
常见问题
可以在沙箱中运行 Claude Code 吗?
是的,如果你的设置将 Claude Code 风格的代理置于限定范围的工作空间内,并围绕它强制执行文件系统、Shell、网络、密钥、日志和审查策略。不要假设本地权限提示对于生产或敏感仓库就已足够。
容器对于编码代理隔离足够吗?
有时候,但答案取决于你的威胁模型。容器对于可重复构建和依赖分离很有用,但安全敏感的工作负载应在将容器视为完整沙箱边界之前评估内核边界、主机挂载、网络默认值、运行时权限和提供商文档。
应该允许代理安装包吗?
可以,但包安装应作为受控的供应链事件处理。首选注册表允许列表或镜像、锁文件审查、安装脚本记录,以及新依赖或获取并执行远程代码的命令的批准。
人工审查者在合并前应检查什么?
审查最终差异、运行的命令、执行的测试、包和锁文件更改、修改的 CI/部署文件、生成的工件,以及任何被拒绝或需要批准的操作。对于安全敏感的仓库,应将沙箱策略本身作为更改的一部分进行审查。
Novita Agent Sandbox 是否与 Claude Code 正式集成?
本文不声称这一点。Novita Agent Sandbox 为代理工作流提供隔离执行原语,而 Claude Code 和托管代理产品有自己的产品特定接口和权限模型。在发布可运行命令之前,请根据当前产品文档验证确切的集成路径。
