使用 Claude Code Sandbox

更新时间:
复制 MD 格式

Claude Code 是 Anthropic 的终端 AI 编程 Agent,可在沙箱内读代码、改文件、执行命令。本文聚焦真实任务场景:克隆仓库、连接 MCP、扩展 Skill、获取结构化输出与会话恢复。镜像地址、构建 Template、创建沙箱与基础运行见 Claude Code 模板。

首次使用请先完成 通过 SDK 创建第一个云沙箱 中的 SLR 授权、API Key 与 SDK 配置。

前置条件

  • 已完成 SDK 接入(E2B API Key、api_urldomain

  • 已按 Claude Code 模板 构建出状态为 ready 的模板,并创建沙箱、初始化 ~/.claude.json

  • 已准备模型 API Key,创建沙箱时通过 envs 注入 — 镜像内不预置

使用场景

以下示例假设已完成 Template 构建,sandbox 已创建且已初始化 ~/.claude.json

克隆仓库并执行任务

sandbox.git.clone(
    "https://github.com/your-org/your-repo.git",
    path="/home/user/repo",
    username="x-access-token",
    password="<your-github-token>",
    depth=1,
)

result = sandbox.commands.run(
    'cd /home/user/repo && claude --dangerously-skip-permissions < /dev/null '
    '-p "Add error handling to all API endpoints"',
    on_stdout=lambda data: print(data, end=""),
    timeout=0,
)

diff = sandbox.commands.run("cd /home/user/repo && git diff")
print(diff.stdout)

获取结构化 JSON 输出

import json

result = sandbox.commands.run(
    'claude --dangerously-skip-permissions --output-format json < /dev/null '
    '-p "List all files and describe each" 2>&1',
    timeout=0,
)

for line in reversed(result.stdout.strip().split("\n")):
    if line.startswith("{"):
        response = json.loads(line)
        break
else:
    raise RuntimeError("no JSON in output")

print(response.get("result") or response)

流式 JSONL 输出

import json

def handle_event(data):
    for line in data.strip().split("\n"):
        if line.startswith("{"):
            event = json.loads(line)
            if event["type"] == "assistant":
                usage = event.get("message", {}).get("usage", {})
                print(f"[assistant] tokens: {usage.get('output_tokens')}")
            elif event["type"] == "result":
                print(f"[done] {event['subtype']} in {event['duration_ms']}ms")

sandbox.commands.run(
    'claude --dangerously-skip-permissions --verbose --output-format stream-json < /dev/null '
    '-p "Find and fix all TODO comments" 2>&1',
    on_stdout=handle_event,
    timeout=0,
)

恢复会话

import json

initial = sandbox.commands.run(
    'claude --dangerously-skip-permissions --output-format json < /dev/null '
    '-p "Analyze the codebase and create a refactoring plan" 2>&1',
    timeout=0,
)

for line in reversed(initial.stdout.strip().split("\n")):
    if line.startswith("{"):
        session_id = json.loads(line)["session_id"]
        break
else:
    raise RuntimeError("no session_id in output")

sandbox.commands.run(
    f'claude --dangerously-skip-permissions --resume {session_id} < /dev/null '
    f'-p "Now implement step 1 of the plan"',
    on_stdout=lambda data: print(data, end=""),
    timeout=0,
)

自定义系统提示词

sandbox.files.write("/home/user/repo/CLAUDE.md", """
You are working on a Go microservice.
Always use structured logging with slog.
Follow the project's error handling conventions in pkg/errors.
""")

sandbox.commands.run(
    'cd /home/user/repo && claude --dangerously-skip-permissions < /dev/null '
    '-p "Add a /healthz endpoint"',
    timeout=0,
)

连接 MCP 工具

Claude Code 原生支持 MCP。可通过 claude mcp add 手动注册 MCP Server,沙箱具备出站网络。

stdio 本地进程(推荐):

sandbox.commands.run(
    "claude mcp add --transport stdio fs -- "
    "npx -y @modelcontextprotocol/server-filesystem /home/user",
    timeout=180,
)

result = sandbox.commands.run(
    'claude --dangerously-skip-permissions < /dev/null '
    '-p "Use the fs MCP tool to list /home/user and summarize top-level entries."',
    timeout=0,
)

HTTP 远程 Server:

sandbox.commands.run(
    "claude mcp add --transport http deepwiki https://mcp.deepwiki.com/mcp",
)

result = sandbox.commands.run(
    'claude --dangerously-skip-permissions < /dev/null '
    '-p "Use deepwiki MCP: what tools are available?"',
    timeout=0,
)

MCP 支持范围与限制见 Claude Code 模板中的“MCP 与 Skill 能力约定”。

使用 Skill 扩展能力

镜像不预装自定义 Skill。Skill 是 Claude Code 的文件系统约定:放入带 SKILL.md 的目录即可。详情见 Extend Claude with skills

作用域路径
个人(本沙箱内全局)/home/user/.claude/skills/<name>/SKILL.md
项目<项目>/.claude/skills/<name>/SKILL.md

触发方式:在 -p 提示词中写 /skill-name 显式调用,或描述匹配任务由模型自动加载。Claude Code 还自带 /debug/code-review 等 bundled skill,无需额外安装。

运行时写入个人 Skill:

sandbox.files.write(
    "/home/user/.claude/skills/summarize-changes/SKILL.md",
    """---
description: Summarizes uncommitted changes and flags risks. Use when reviewing diffs or writing commit messages.
---

## Instructions
1. Run `git diff HEAD` and summarize changes in 2–3 bullets.
2. List risks such as missing error handling or hardcoded values.
3. If the diff is empty, say there are no uncommitted changes.
""",
)

result = sandbox.commands.run(
    'claude --dangerously-skip-permissions < /dev/null '
    '-p "/summarize-changes"',
    timeout=0,
)
print(result.stdout)

项目内 Skill(随仓库 / 工作目录生效):

sandbox.files.write(
    "/home/user/repo/.claude/skills/api-conventions/SKILL.md",
    """---
description: API design conventions for this codebase. Use when adding or changing HTTP endpoints.
---

When writing API endpoints:
- Use RESTful naming
- Return consistent error formats
- Include request validation
""",
)

sandbox.commands.run(
    'cd /home/user/repo && claude --dangerously-skip-permissions < /dev/null '
    '-p "/api-conventions Add a /healthz endpoint"',
    timeout=0,
)

从本机上传多文件 Skill 目录:

若 Skill 含 scripts/references/ 等附属文件,用 files.write_files 一次批量写入,不必逐文件调用 files.write

from pathlib import Path

def upload_skill_dir(sandbox, local_dir: str, remote_root: str) -> None:
    local = Path(local_dir).resolve()
    entries = []
    for path in local.rglob("*"):
        if path.is_file():
            rel = path.relative_to(local).as_posix()
            entries.append({
                "path": f"{remote_root.rstrip('/')}/{rel}",
                "data": path.read_bytes(),
            })
    sandbox.files.write_files(entries)

# 本机目录结构示例:
# ./my-skills/echo-marker/SKILL.md
# ./my-skills/echo-marker/scripts/marker.txt
upload_skill_dir(
    sandbox,
    "./my-skills/echo-marker",
    "/home/user/.claude/skills/echo-marker",
)

result = sandbox.commands.run(
    'claude --dangerously-skip-permissions < /dev/null '
    '-p "/echo-marker"',
    timeout=0,
)
print(result.stdout)

项目作用域同理,把 remote_root 换成 /home/user/repo/.claude/skills/<name>。也可克隆已含 .claude/skills/ 的仓库后直接使用。

关于 Template.copy暂不支持Template.build 时用 .copy("local-dir", "/home/user/.claude/skills/...") 预置文件。自定义 Skill 请用上方运行时 files.write / files.write_files

计费说明

Sandbox 按 CPU、内存规格与运行时长计费;模型 API 调用费用由模型服务单独结算。详见 计费概述

常见问题

现象处理
报配置损坏echo '{}' > /home/user/.claude.json
Agent 无响应确认 envs 已注入模型 Key;中国站用百炼 envs 配置确认 已注入
构建失败确认 FROM_IMAGE 与地域匹配
name 'TEMPLATE_NAME' is not defined控制台获取模板名称并替换 TEMPLATE_NAME
其他 SDK / 构建问题模板管理

参考

  • Claude Code 模板(镜像地址、构建 Template、创建沙箱与基础运行、环境概览、MCP/Skill 能力约定)