Claude Code 是 Anthropic 的终端 AI 编程 Agent,可在沙箱内读代码、改文件、执行命令。本文聚焦真实任务场景:克隆仓库、连接 MCP、扩展 Skill、获取结构化输出与会话恢复。镜像地址、构建 Template、创建沙箱与基础运行见 Claude Code 模板。
首次使用请先完成 通过 SDK 创建第一个云沙箱 中的 SLR 授权、API Key 与 SDK 配置。
前置条件
已完成 SDK 接入(E2B API Key、
api_url、domain)已按 Claude Code 模板 构建出状态为
ready的模板,并创建沙箱、初始化~/.claude.json已准备模型 API Key,创建沙箱时通过
envs注入 — 镜像内不预置中国站:百炼控制台 获取 API Key(
sk-开头)国际站:Anthropic Console 获取
ANTHROPIC_API_KEY
使用场景
以下示例假设已完成 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 能力约定)