Ralph E2B 云沙箱执行指南:在云端隔离环境运行 Claude Code 自主循环
2026/9/16 0:32:19 网站建设 项目流程

Ralph E2B 云沙箱执行指南:在云端隔离环境运行 Claude Code 自主循环

【免费下载链接】ralph-claude-codeAutonomous AI development loop for Claude Code with intelligent exit detection项目地址: https://gitcode.com/GitHub_Trending/ra/ralph-claude-code

本篇技术指南围绕 Ralph 项目(Autonomous AI development loop for Claude Code)的 E2B 云沙箱能力展开,讲解如何通过ralph --sandbox e2b把 Claude Code CLI 的执行从本机迁移到 E2B 云端沙箱,从而卸载计算负载、获得一致的临时环境、并让自主执行完全脱离宿主机。读完本文,你将掌握 E2B 沙箱的整体架构、完整 CLI 与.ralphrc配置、凭据注入方式、文件双向同步机制、成本估算与预算控制,以及从启动到清理的完整生命周期与故障排查方法。

一、设计动机:为什么把执行搬到 E2B 云端

Ralph 的 Docker 沙箱(见 docs/DOCKER_SANDBOX.md)解决的是"本机容器隔离",而 E2B 沙箱解决的是另一类需求:执行环境完全不在你的机器上。使用 E2B 云沙箱的典型场景包括:

  • 卸载计算负载:Claude 每轮迭代的 CLI 运行在云端,宿主机只负责编排;
  • 一致的临时环境:每个 run 对应一个按秒计费的云沙箱,环境干净、可复制、用完即销毁;
  • 保持自主执行脱离宿主机:即便宿主机被干扰或需要严格控制网络/文件影响面,Claude 的工作目录、进程和产物都在云端。

从实现里程碑看,E2B 沙箱对应 Issue #75,是沙箱 epic #49(Phase 6.0)的第二个切片(首个切片是 Issue #74 的 Docker 沙箱)。daytonacloudflare两个 provider 明确不在计划内(Issue #79、#80),传入会被拒绝并给出清晰错误。

二、整体架构:编排留在主机,执行搬上云端

E2B 沙箱遵循与 Docker 沙箱一致的模型——Ralph 的编排(循环控制、限流、熔断、响应分析、退出检测、status.json)全部留在宿主机,只有 Claude 的执行移动位置。区别在于 E2B 没有 bind mount,因此项目文件需要在启动时上传一次、每轮迭代后下载变更文件回宿主机:

HOST E2B CLOUD SANDBOX (one per run) ralph_loop.sh ── lib/e2b_helper.py exec ───▶ claude -p "..." (per iteration) ├─ rate limiting / circuit breaker │ runs in /home/user/workspace ├─ response analysis / exit detection ▼ ├─ status.json (ralph-monitor) project copy ◀── upload at start ├─ cost tracking / --sandbox-max-cost changed files ── download after every loop ──▶ host └─ sandbox kill on exit / Ctrl+C

架构上有四个关键设计决策,均可在源码中找到依据:

  1. SDK 语言壁垒由 Python 薄封装打通。E2B 官方 SDK 只有 Python/JS 两种语言,而 Ralph 的主循环是 bash,因此所有 API 流量都经过 lib/e2b_helper.py(一个对官方e2bPython 包的薄 CLI 封装)。exec子命令会流式转发远端命令的 stdout/stderr 并原样传播远端退出码(见 lib/e2b_helper.py),所以--live(stream-json)与后台模式都无需改动即可工作。

  2. 一次 run 一个沙箱,跨迭代复用。E2B 按秒计费,若每轮迭代都新建沙箱,成本会成倍增长,还会丢失 Claude 在沙箱内的会话状态(会话连续性失效)。因此沙箱在启动时创建一次、被所有迭代复用;--sandbox-keep-alive可让它在退出后继续存活,供后续通过--sandbox-id复用。

  3. 文件同步替代 bind mount。项目(被跟踪与未被忽略的未跟踪文件,外加.ralph控制文件)在启动时上传一次;沙箱内被修改的文件在每一轮迭代结束后下载回宿主机。这样进度检测、熔断器、ralph-monitor全部照常工作在宿主机侧。删除与重命名也会回传:每次下载的归档中都携带一份沙箱当前文件的清单(manifest),宿主机中"之前已同步、但已从清单消失"的文件会被删除;宿主机独有文件、.git.ralph永远不会成为删除候选。同步内容可用--sync-include/--sync-exclude标志、项目根目录的.ralphignore文件和大文件策略过滤,详见 docs/SANDBOX_SYNC.md。

  4. 绝不静默降级。如果沙箱初始化失败(缺少 SDK、API key 无效、API 不可达),Ralph 直接报错退出,而不会在用户要求保护的主机上悄悄运行 Claude——init_e2b_sandboxstart_e2b_sandbox的任一失败都会中止整个 run(见 ralph_loop.sh)。

三、快速开始:最小可用配置

前置条件:宿主机已安装 Ralph,且 Python 环境可用(helper 默认使用python3)。三步即可启用 E2B 沙箱:

pip install e2b # 官方 E2B Python SDK export E2B_API_KEY="e2b_..." # 从 E2B 控制台获取 # —— 或者把密钥落盘存储: mkdir -p ~/.ralph ( umask 177 && echo "e2b_..." > ~/.ralph/e2b_api_key ) ralph --sandbox e2b

沙箱内必须有 Claude CLI。Ralph 使用的默认base模板在首次运行时会自动引导安装(npm install -g @anthropic-ai/claude-code);若希望启动更快,可以构建一个预装好 Claude CLI 的自定义 E2B 模板,并用--sandbox-template传入。

从源码看,lib/sandbox_e2b.sh 中的_ensure_claude_in_e2b会先探测claude --version;失败后再尝试npm install -g @anthropic-ai/claude-code;二次探测仍失败时,会把 npm 输出的最后几行作为诊断信息记录(用于区分"仓库不可达"与"模板缺 npm"),最终报错并提示构建自定义模板。第一次在普通模板上运行需要为这次 npm 引导付出计费成本,使用自定义模板可完全规避。

四、CLI 参考:E2B 子标志与校验规则

E2B 沙箱的全部开关都是--sandbox e2b的子标志,完整清单如下:

Flag默认值说明
--sandbox e2b(关闭)启用 E2B 云沙箱执行
--sandbox-template TbaseE2B 模板名(自定义模板可预装 claude)
--sandbox-id ID(新建沙箱)复用既有沙箱(与--sandbox-keep-alive搭配)
--sandbox-timeout SECS3600沙箱会话超时;过期沙箱会被自动重建并重新上传
--sandbox-keep-alive(关闭)退出时保留沙箱运行(计费继续!)
--sandbox-max-cost USD(无)估算成本达到该金额时优雅停止循环
--sandbox-cost-alert USD(无)估算成本达到该金额时只警告一次

标志归属是硬约束。Docker 子标志(--sandbox-image等)只配--sandbox docker,E2B 子标志只配--sandbox e2b,混用是启动期错误(见 ralph_loop.sh)。同理,--sync-include/--sync-exclude只对 e2b provider 有效——Docker 的 bind mount 实时共享一切,无需也不允许过滤(混用会报错,见 ralph_loop.sh)。

这些标志在提交给底层时还会经过严格校验(validate_e2b_sandbox_config,见 lib/sandbox_e2b.sh):

  • 模板名只允许字母数字加._-,且必须以字母数字开头——这一正则同时阻断了 shell 元字符进入远端命令行;
  • 沙箱 ID 只允许字母数字加_-
  • --sandbox-timeout必须是正整数(0也会被拒绝);
  • --sandbox-max-cost--sandbox-cost-alertSANDBOX_E2B_COST_PER_HOUR必须是合法的十进制数(如5.00)。

单元测试 tests/unit/test_sandbox_e2b.bats 对这些拒绝路径逐一有断言,包括恶意模板名evil;rm -rf /、非数字超时soon、零超时与非数字金额等。

五、.ralphrc 配置与优先级规则

与 CLI 标志等价的项目级配置如下(CLI 标志优先于.ralphrcAPI key 本身绝不写入.ralphrc):

SANDBOX_PROVIDER="e2b" SANDBOX_E2B_TEMPLATE="base" SANDBOX_E2B_TIMEOUT="3600" SANDBOX_E2B_KEEP_ALIVE="false" SANDBOX_E2B_MAX_COST="5.00" SANDBOX_E2B_COST_ALERT="2.00" SANDBOX_E2B_COST_PER_HOUR="0.10"

这套变量的默认值同时定义在 lib/sandbox_e2b.sh 中,.ralphrc模板(templates/ralphrc.template)也保留了带注释的副本。三个层面的优先级是 Ralph 全项目统一的规则:CLI 标志 > 环境变量 >.ralphrc> 默认值。在 ralph_loop.sh 中,同名环境变量会在读取.ralphrc之后覆盖其值;随后命令行解析(ralph_loop.sh)再次覆盖。

另外,--monitor(tmux 模式)会把全部沙箱标志转发到循环窗格——只有非默认值会被转发,规则与 Docker provider 完全一致(见 ralph_loop.sh)。

六、凭据管理:两套互相独立的密钥

E2B 沙箱涉及两套密钥,两者都不会出现在命令行上(实现上e2b_helper.py从环境读取密钥、通过 stdin 传递文件内容,详见 lib/e2b_helper.py):

1. E2B API keysetup_e2b_credentials,见 lib/sandbox_e2b.sh),按序解析:

  1. E2B_API_KEY环境变量;
  2. ~/.ralph/e2b_api_key密钥文件(若权限不是chmod 600,会记录警告日志;密钥值会被剥离空白后读取,绝不进入日志)。

2. 沙箱内 Claude 的认证_seed_e2b_claude_credentials,与 Docker provider 的凭据处理互相镜像,见 lib/sandbox_e2b.sh),按序处理:

  1. 宿主机设置了ANTHROPIC_API_KEY——在创建沙箱时作为环境变量注入(helper 从自身环境读取,见 lib/e2b_helper.py);
  2. 宿主机存在~/.claude/.credentials.json——通过 stdin复制进沙箱 home(远端chmod 600,路径/home/user/.claude/.credentials.json)。宿主机原文件永不被修改;
  3. 两者皆无——记录警告并继续循环(适用于认证已内置在自定义模板中的场景)。

单测对凭据解析覆盖得很细(tests/unit/test_sandbox_e2b.bats):环境变量优先于密钥文件、644 权限会触发 chmod 600 提示、无密钥时报错信息同时包含E2B_API_KEYe2b_api_key两个线索。沙箱创建时若检测到ANTHROPIC_API_KEY,mock 还会额外记录"看到环境变量"的痕迹,并断言密钥值从未以 argv 形式出现(tests/unit/test_sandbox_e2b.bats)。

七、文件同步:上传一次、每轮回传、删除随清单传播

E2B 沙箱没有 bind mount,文件传输完全由同步层承担,其过滤逻辑在 lib/sync.sh 中实现、由 lib/sandbox_e2b.sh 驱动。完整规则见 docs/SANDBOX_SYNC.md,这里给出与 E2B 执行直接相关的要点。

上传方向upload_project_to_e2b,lib/sandbox_e2b.sh):上传清单由git ls-files -coz --exclude-standard构建(被跟踪 + 未被忽略的未跟踪文件,天然尊重.gitignore),再依次经过:

  1. SYNC_INCLUDE/--sync-include——若设置,仅匹配的文件上传;
  2. SYNC_EXCLUDE/--sync-exclude——匹配的文件被剔除;
  3. .ralphignore——项目根目录的额外排除模式;
  4. 大文件策略——超过SYNC_MAX_FILE_SIZE(默认 10MB)的文件默认警告保留(SYNC_LARGE_FILE_ACTION=warn),或直接丢弃(skip)。

其中.ralph控制文件(.ralphrcPROMPT.mdfix_plan.mdAGENT.mdspecs/永远上传,绕过一切过滤——循环绝不能让自己饿死(丢掉自己的提示词与计划)。反之,.ralph内部状态(.e2b_sandbox_statestatus.json、日志等)被整体排除,防止沙箱侧写入回传覆盖宿主机控制状态。

下载方向sync_e2b_artifacts_down,lib/sandbox_e2b.sh):只下载"上次同步后变更"的文件,过滤规则仅含SYNC_EXCLUDE+.ralphignore。有两个刻意的不对称:

  • include 模式不作用于下载——Claude 在 include 集合之外创建的产物(构建输出、报告)依然回传;想过滤用 exclude 模式;
  • 大文件策略仅限上传——沙箱侧文件在传输前无法测量大小。

删除与重命名传播download子命令生成的归档里含一个.ralph_e2b_manifest成员,记录沙箱当前全部文件(见 lib/e2b_helper.py);宿主机以.ralph/.e2b_synced_files为删除基线(删除同步基线),用comm求出"基线有、清单无"的候选集后再删除(lib/sandbox_e2b.sh)。安全护栏包括:.git.ralph、绝对路径、含..的路径即使基线被污染也绝不删除;匹配排除模式的主机文件永不是删除候选;被下载过滤掉的文件不进入删除基线(避免同名主机文件因沙箱删除副本而遭殃)。

ack 机制保证至少一次投递:同步标记(sync marker)位于工作区之外/home/下,不会被误打包进上传/下载内容),且只在宿主机成功解包并完成删除扫描后才由ack-download推进(见 lib/e2b_helper.py)。若 ack 丢失,下一轮迭代会重新投递同样的变更——重新解包是幂等覆盖。测试断言了"download 成功才 ack、失败绝不 ack"(tests/unit/test_sandbox_e2b.bats),以及.git内容永远不被解包(tests/unit/test_sandbox_e2b.bats)。

同步过程会输出人类可读的进度摘要,任何丢弃都不会静默发生:

Uploading 412 file(s) (2.3MB compressed) to E2B sandbox... Uploaded 412 file(s) to E2B workspace /home/user/workspace Synced 7 changed file(s) (18.2KB) from the E2B sandbox Filtered 3 file(s) from sandbox download (SYNC_EXCLUDE / .ralphignore patterns) Large file in sync: data/fixtures.bin (24.0MB > 10.0MB limit; SYNC_LARGE_FILE_ACTION=skip to drop)

八、成本跟踪:按秒估算、跨重建累计、预算硬停

E2B 按沙箱运行秒数计费。Ralph 把估算花费计算为所有沙箱时段之和(当前激活时段 + 会话过期后重建的既往时段)×SANDBOX_E2B_COST_PER_HOUR(默认$0.10/h,请根据模板规格对照 E2B 定价页调整)。这个费率仅用于成本估算与限额执行。

关键实现细节(update_e2b_costcheck_e2b_cost_limits,见 lib/sandbox_e2b.sh):

  • 被替换沙箱的已产生成本会在纪元(epoch)重置前折叠进accrued_cost(状态文件.ralph/.e2b_sandbox_state中的字段),所以--sandbox-max-cost覆盖的是整个 run 的累计花费,而不是当前沙箱时段——一个反复过期/重建的 run 不会从零重新计预算。单测专门验证了这一跨重建累计(tests/unit/test_sandbox_e2b.bats)。
  • 实时估算值出现在status.jsonsandbox.estimated_cost字段与ralph-monitor的 Sandbox 面板中(get_e2b_sandbox_status输出providersandbox_idstatusestimated_cost)。
  • --sandbox-cost-alert到达阈值时只记录一次警告(状态文件中的cost_alerted字段防止重复提醒)。
  • --sandbox-max-cost到达时优雅停止循环:先做最终产物同步,再杀沙箱,退出原因为e2b_cost_limit(见 ralph_loop.sh)。
  • 每次 run 结束都会向.ralph/logs/e2b_cost.log追加一行汇总(时间戳、沙箱 ID、运行秒数、估算成本)。

需要强调的是,这是预算控制用的估算值,不是账单——实际用量请以 E2B 控制台为准。

九、生命周期与故障处理

E2B 沙箱的完整生命周期由 lib/sandbox_e2b.sh 中的函数编排:

  • 启动init_e2b_sandbox(配置校验 → SDK 可用性 → API key 解析,并写入初始状态文件,见 lib/sandbox_e2b.sh)→start_e2b_sandbox(创建沙箱或--sandbox-id连接、凭据注入、项目上传、claude 引导检查)。任一失败都中止 run。
  • 每轮迭代:构建好的 Claude 命令数组被包装为python3 lib/e2b_helper.py exec --sandbox-id <id> --cwd /home/user/workspace -- claude ...build_e2b_exec_args,lib/sandbox_e2b.sh);每次迭代后(无论成功、失败还是超时),都会先下载变更文件并执行删除扫描,再进入进度检测。注意 SDK 侧timeout=0表示禁用 SDK 内建限制,迭代预算完全由宿主机侧的portable_timeout掌控(退出码 124)。
  • 会话过期:E2B 会在会话超时后杀掉沙箱。每轮迭代执行前的存活探测(ensure_e2b_sandbox调用info子命令)会发现这一情况,并自动启动替代沙箱(全新创建 + 重新上传)。值得注意的降级策略:get_info失败不会误判存活的沙箱为死亡,避免每轮都重建一个活得好好的沙箱(见 lib/e2b_helper.py)。
  • 超时(exit 124):宿主机侧超时只杀掉本地 helper 客户端;沙箱内残留的claude进程会在下一轮迭代前被远端pkill清理(handle_e2b_sandbox_timeout,lib/sandbox_e2b.sh)。
  • 退出:先做最终产物同步,再杀掉沙箱(计费停止)——覆盖优雅完成、熔断停机、成本上限、错误与 SIGINT/SIGTERM 所有路径。若开了--sandbox-keep-alive,则保留沙箱并记录其 ID 供复用。清理是幂等的(重复调用不会重复 kill,见 tests/unit/test_sandbox_e2b.bats)。
  • 状态.ralph/.e2b_sandbox_state(JSON,通过 temp 文件 +mv原子写入)记录模板、沙箱 ID、状态、estimated_costaccrued_cost(重建时并入既往时段成本)等;.ralph/.e2b_synced_files是删除同步基线(沙箱中已知存在的项目路径集合)。

十、已知限制

  1. 沙箱内的 git 提交不会同步回来。同步基于文件内容,.git在双向都被排除(沙箱侧 git 状态绝不能覆盖宿主机仓库)。Claude 的变更以宿主工作区的未提交修改形式到达;请在宿主机侧提交,或交给下一个宿主机侧工具处理。
  2. 网络限制不可配置。E2B 沙箱默认具备出网能力(Claude API 本来也需要出网),安全策略属于 Issue #78 的范畴。
  3. 首次引导成本:普通模板首次运行要支付npm install -g引导成本;用自定义模板可规避。

十一、故障排查

症状修复
E2B SDK unavailable ... pip install e2bpip install e2b(安装到 Ralph 使用的 python3 环境)
E2B API key not foundexport E2B_API_KEY=...,或创建~/.ralph/e2b_api_key(chmod 600)
Claude Code CLI is unavailable in the E2B sandbox构建预装@anthropic-ai/claude-code的自定义 E2B 模板,并传入--sandbox-template
沙箱内 Claude 认证错误导出ANTHROPIC_API_KEY,或先在宿主机登录使~/.claude/.credentials.json存在
循环以e2b_cost_limit停止符合预期——调高--sandbox-max-cost,或按模板实际费率修正SANDBOX_E2B_COST_PER_HOUR
硬杀(kill -9)后残留沙箱它会在--sandbox-timeout时自动过期;也可从 E2B 控制台提前终止

十二、与 Docker 沙箱的选择

若你的场景需要本机容器隔离与实时文件共享(bind mount、零同步开销、会话状态随容器存活),选择--sandbox docker(详见 docs/DOCKER_SANDBOX.md);若需要完全脱离宿主机、按秒计费、用完即销毁的云端临时环境,选择--sandbox e2b。两者共享同一套"编排留宿主机、执行进沙箱、失败不静默降级"的架构理念,区别只在于文件传输模型(Docker 实时 bind mount vs E2B 快照上传 + 每轮迭代回传)与成本模型(Docker 常驻容器 vs E2B 按秒计费 + 可配预算硬停)。选择 E2B 时,建议结合 docs/SANDBOX_SYNC.md 的过滤规则规划项目文件,并用--sandbox-max-cost守住预算底线。

【免费下载链接】ralph-claude-codeAutonomous AI development loop for Claude Code with intelligent exit detection项目地址: https://gitcode.com/GitHub_Trending/ra/ralph-claude-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询