在 Linux sandbox 中运行 Claude Code ↗,根据提示编辑 GitHub 仓库,然后将其更改作为 diff 读取。Claude Code 通过 AI Gateway 调用 Anthropic 模型。你的 Worker 会为这些请求添加 gateway token,且 sandbox 只能访问你的 gateway 和 github.com。
- 来自 构建编程 Agent runner 的
sandbox-coding-agent项目。该教程使用 Claude Code 构建 runner。在运行其他 Agent 之后,可使用本页切回 Claude Code,或更改其设置。 - AI Gateway 中的 Anthropic 凭据,可以是 Unified Billing 额度,或作为 provider key 存储的 Anthropic API key。
-
替换
Dockerfile:Dockerfiledockerfile FROM node:24-trixie-slim RUN apt-get update \ && apt-get install -y --no-install-recommends bash ca-certificates git ripgrep \ && rm -rf /var/lib/apt/lists/* RUN npm install --global @anthropic-ai/[email protected] COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim WORKDIR /workspace CMD ["sleep", "infinity"]Claude Code 软件包的安装脚本会放入其原生二进制文件。镜像会固定版本,因为 Claude Code 的标志和事件格式可能在版本之间变化。
-
在
wrangler.jsonc中,将MODEL设为你的 gateway 可以提供的 Anthropic 模型 ID:{ "vars": { "AI_GATEWAY_ACCOUNT_ID": "<ACCOUNT_ID>", "AI_GATEWAY_ID": "default", "MODEL": "claude-sonnet-5", }, }[vars] AI_GATEWAY_ACCOUNT_ID = "<ACCOUNT_ID>" AI_GATEWAY_ID = "default" MODEL = "claude-sonnet-5" -
在
src/outbound.ts中,确保Outboundentrypoint 在添加 gateway token 之前删除x-api-keyheader:src/outbound.tsts const headers = new Headers(request.headers); headers.delete("x-api-key"); headers.set("cf-aig-authorization", `Bearer ${this.env.AI_GATEWAY_TOKEN}`);Claude Code 会发送占位 API key。如果
x-api-keyheader 保留,AI Gateway 会将其转发给 Anthropic,模型请求会因Invalid API key失败。 -
在
src/sandbox.ts中,将ResultEvent常量替换为 Claude Code 最终事件的 schema:src/sandbox.tsts const ResultEvent = z.object({ type: z.literal("result"), subtype: z.string(), is_error: z.boolean(), result: z.string().optional(), }); -
替换
agentCommand()和agentEnv()方法:src/sandbox.tsts private agentCommand(prompt: string): string[] { return [ "claude", "--print", "--output-format", "stream-json", "--verbose", "--dangerously-skip-permissions", "--no-session-persistence", "--model", this.env.MODEL, "--", prompt, ]; } private agentEnv(): Record<string, string> { return { ANTHROPIC_BASE_URL: `https://gateway.ai.cloudflare.com/v1/${this.env.AI_GATEWAY_ACCOUNT_ID}/${this.env.AI_GATEWAY_ID}/anthropic`, ANTHROPIC_API_KEY: "provided-by-worker", CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1", IS_SANDBOX: "1", }; }--print在没有交互式终端的情况下运行 Claude Code。--output-format stream-json --verbose每行写入一个 JSON 事件,包括最终的result事件。--dangerously-skip-permissions允许 Claude Code 在不询问的情况下运行命令和编辑文件。container 会限制其命令可以访问的范围。Claude Code 要求IS_SANDBOX=1才能以root允许此行为。ANTHROPIC_BASE_URL将模型请求发送到 gateway 的 Anthropic 端点。ANTHROPIC_API_KEY是占位符,因为没有 API key 时 Claude Code 不会启动。CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC会关闭更新检查、遥测和错误报告,因此 Claude Code 只会调用你的 gateway。
如果仓库有
CLAUDE.md文件,Claude Code 会读取它,因此该文件中的说明会应用于任务。 -
替换
outcome()方法:src/sandbox.tsts export class AgentSandbox extends DurableObject<Env> { // ... private async outcome(exitCode: number): Promise<TaskStatus> { let result: z.infer<typeof ResultEvent> | undefined; const events = await this.files.readFile(eventsPath); for await (const line of readLines(events.body)) { const parsed = ResultEvent.safeParse(parseJson(line)); if (parsed.success) { result = parsed.data; } } if (result === undefined) { const stderr = (await this.readOptionalText(stderrPath)) ?? ""; return { state: "failed", error: `claude exited with ${exitCode}: ${stderr.slice(-2000)}`, }; } if (result.is_error) { return { state: "failed", error: result.result ?? result.subtype }; } return { state: "succeeded", result: result.result ?? "" }; } }即使模型请求失败,Claude Code 也会以成功状态退出,因此结果来自最终
result事件的is_error字段,而不是退出码。Claude Code 会对失败的模型请求重试 10 次。被拒绝的 gateway token 大约三分钟后会以Failed to authenticate. API Error: 401 Unauthorized使任务失败。 -
部署你的 Worker:
npx wrangler deployyarn wrangler deploypnpm wrangler deploy正在运行的 container 会保留启动时使用的镜像,因此请为 Claude Code 使用新的 sandbox 名称。
-
将仓库克隆到名为
claude-1的 sandbox:curl "$WORKER_URL/sandboxes/claude-1/repository" \ --json '{"url": "https://github.com/octocat/Hello-World"}' -
启动任务:
curl "$WORKER_URL/sandboxes/claude-1/task" \ --data "Add a file NOTES.md with a one-sentence summary of this repository. Do not commit." -
检查任务,直到其状态为
succeeded或failed:curl "$WORKER_URL/sandboxes/claude-1/task"succeeded任务会包含 Claude Code 的最终回复。 -
读取更改:
curl "$WORKER_URL/sandboxes/claude-1/diff"diff 会显示新的
NOTES.md文件。
- 构建编程 Agent runner:runner 如何启动 sandbox、运行任务并读取 diff。
- Claude Code 示例 ↗:可单独部署、用于运行 Claude Code 的 Worker。
- AI Gateway 中的 Claude Code:在其他环境中通过 AI Gateway 路由 Claude Code。