---
title: 自托管沙箱
url: https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes
description: 在自托管沙箱中运行 Claude Managed Agents 会话，将工具执行、文件和网络出口流量保留在您自己的基础设施中。
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

"Self-hosted sandboxes"（自托管沙箱）将智能体的工具执行从 Anthropic 托管的云沙箱迁移到您控制的基础设施中，而 Anthropic 继续运行智能体本身。要了解这意味着什么并判断它是否适合您的智能体，请参阅[选择智能体环境](https://platform.claude.com/docs/zh-CN/managed-agents/choosing-an-environment)。

## 工作原理

`self_hosted` 环境充当一个工作队列。您运行一个 **environment worker**（环境工作进程），这是在您自己的基础设施上为该队列提供服务的进程：

1. 您创建一个以该环境为目标的[会话](https://platform.claude.com/docs/zh-CN/managed-agents/sessions)。Anthropic 将该会话作为工作项加入队列。
2. 您的工作进程认领该工作项，并下载智能体的 [skills](https://platform.claude.com/docs/zh-CN/managed-agents/skills) 和会话的 [memory stores](https://platform.claude.com/docs/zh-CN/managed-agents/memory)。
3. Claude 在 Anthropic 一侧运行并请求工具调用。您的工作进程在本地运行每个调用，并将结果回传。

工具的输入和输出仍会流向 Anthropic 的控制平面，以便模型能够看到结果并决定下一步操作。Anthropic 存储 skills 和 memory stores。您的沙箱为该会话保存一份副本。有关完整的数据流边界，请参阅[安全模型](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-security)。

自托管沙箱支持 Managed Agents 中可用的所有 Claude 模型。模型是在智能体上配置的，而不是在环境上。

`ant` CLI 以及 Python、TypeScript 和 Go SDK 都附带预构建的工作进程。Cloudflare、Daytona 和 Modal 等沙箱提供商也发布了各自的[平台指南](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes#platform-guides)。

## 快速入门

本快速入门使用 `ant` CLI 运行一个常驻工作进程，向其发送一个会话，并确认智能体的工具调用在您的主机上运行。

### 前提条件

* **一个智能体：** 如果您还没有，请先完成 [Claude Managed Agents 入门](https://platform.claude.com/docs/zh-CN/managed-agents/quickstart)，并记下智能体 ID。
* **一台 Linux 主机：** 主机需要在该确切路径下有 `/bin/bash`。工作进程只需要出站 HTTPS。
* **一个 Claude API 密钥：** 您在自己的机器上使用它来创建会话和读取队列统计信息。不要将其放在工作进程主机上，因为智能体的工具调用可能会读取到它。
* **您自己机器上的 `ant` CLI 或 SDK：** 本快速入门中的统计和会话步骤在您自己的机器上运行，而不是在工作进程主机上。按照[安装步骤](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes#run-your-first-session)为工作进程安装 CLI 的相同方式安装 CLI，或安装 [SDK](https://platform.claude.com/docs/zh-CN/cli-sdks-libraries/overview)。

<Note>
  在 [Claude Platform on AWS](https://platform.claude.com/docs/zh-CN/build-with-claude/claude-platform-on-aws) 上，工作进程使用 AWS IAM（SigV4）或[在 AWS Console 中生成的 API 密钥](https://platform.claude.com/docs/zh-CN/build-with-claude/claude-platform-on-aws#api-key-authentication)进行身份验证，而不是使用环境密钥。请将 [`AnthropicSelfHostedEnvironmentAccess`](https://platform.claude.com/docs/zh-CN/api/claude-platform-on-aws-iam-actions#managed-policies) 托管策略附加到运行工作进程的 IAM 主体上。在 Claude Console 中生成的环境密钥不适用于 Claude Platform on AWS 端点。
</Note>

### 运行您的第一个会话

<Steps>
  <Step title="创建自托管环境">
    在 Claude Console 中，前往 [Environments](https://platform.claude.com/environments) 页面（`platform.claude.com/environments`），点击 **Create environment**，然后在 **Hosting** 下选择 **Self-hosted**。

    或通过 API：

    <CodeGroup defaultLanguage="CLI">
      ```bash cURL
      curl -sS --fail-with-body https://api.anthropic.com/v1/environments \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        -d '{
          "name": "self-hosted",
          "config": {"type": "self_hosted"}
        }'
      ```

      <CodeGroupItem>
        ```bash CLI
        ant apply environment.yaml
        ```

        <File filename="environment.yaml">
          ```yaml
          # yaml-language-server: $schema=https://platform.claude.com/schemas/ant/beta/environment.json
          name: self-hosted
          config:
            type: self_hosted
          ```
        </File>
      </CodeGroupItem>

      ```python Python
      client = anthropic.Anthropic()

      environment = client.beta.environments.create(
          name="self-hosted", config={"type": "self_hosted"}
      )
      print(environment.id)
      ```

      ```typescript TypeScript
      const client = new Anthropic();

      const environment = await client.beta.environments.create({
        name: "self-hosted",
        config: { type: "self_hosted" }
      });
      console.log(environment.id);
      ```

      ```csharp C#
      using Anthropic.Models.Beta.Environments;

      var client = new AnthropicClient();

      var environment = await client.Beta.Environments.Create(
          new EnvironmentCreateParams
          {
              Name = "self-hosted",
              Config = new BetaSelfHostedConfigParams(),
          }
      );
      Console.WriteLine(environment.ID);
      ```

      ```go Go
      client := anthropic.NewClient()

      environment, err := client.Beta.Environments.New(context.Background(), anthropic.BetaEnvironmentNewParams{
      	Name: "self-hosted",
      	Config: anthropic.BetaEnvironmentNewParamsConfigUnion{
      		OfSelfHosted: &anthropic.BetaSelfHostedConfigParams{},
      	},
      })
      if err != nil {
      	panic(err)
      }
      fmt.Println(environment.ID)
      ```

      ```java Java
      import com.anthropic.models.beta.environments.BetaSelfHostedConfigParams;
      import com.anthropic.models.beta.environments.EnvironmentCreateParams;

      void main() {
          var client = AnthropicOkHttpClient.fromEnv();

          var environment = client.beta().environments().create(
              EnvironmentCreateParams.builder()
                  .name("self-hosted")
                  .config(BetaSelfHostedConfigParams.builder().build())
                  .build()
          );
          IO.println(environment.id());
      }
      ```

      ```php PHP
      $client = new \Anthropic\Client();

      $environment = $client->beta->environments->create(
          name: 'self-hosted',
          config: ['type' => 'self_hosted'],
      );
      echo $environment->id, PHP_EOL;
      ```

      ```ruby Ruby
      client = Anthropic::Client.new

      environment = client.beta.environments.create(
        name: "self-hosted",
        config: {type: :self_hosted}
      )
      puts environment.id
      ```
    </CodeGroup>
  </Step>

  <Step title="生成环境密钥">
    在 Console 中，打开该环境并点击 **Generate environment key**。环境密钥用于向工作进程的队列验证其身份。您只能在 Console 中生成环境密钥，即使是通过 API 创建的环境也是如此。

    在工作进程主机上导出环境 ID 和密钥：

    ```bash
    export ANTHROPIC_ENVIRONMENT_KEY="sk-ant-oat01-..."
    export ANTHROPIC_ENVIRONMENT_ID="env_..."
    ```
  </Step>

  <Step title="安装 ant CLI">
    在工作进程主机上运行此操作。

    <Tabs>
      <Tab title="curl (Linux/WSL)">
        对于 Linux 环境，直接下载发布版二进制文件。

        ```bash
        VERSION=1.42.0
        OS=$(uname -s | tr '[:upper:]' '[:lower:]')
        case $(uname -m) in
          x86_64) ARCH=amd64 ;;
          aarch64) ARCH=arm64 ;;
        esac
        curl -fsSL "https://github.com/anthropics/anthropic-cli/releases/download/v${VERSION}/ant_${VERSION}_${OS}_${ARCH}.tar.gz" \
          | sudo tar -xz -C /usr/local/bin ant
        ```

        您可以在 [GitHub 发布页面](https://github.com/anthropics/anthropic-cli/releases)上找到所有版本。
      </Tab>

      <Tab title="Homebrew (macOS)">
        ```bash
        brew install anthropics/tap/ant
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="启动工作进程">
    创建工作目录，然后启动工作进程。`--workdir` 默认为当前目录，因此请传入 `/workspace` 以匹配系统默认值。

    ```bash
    sudo mkdir -p /workspace && sudo chown "$USER" /workspace
    ant beta:worker poll --workdir /workspace
    ```

    工作进程会读取您导出的两个变量，并持续轮询，直到您停止它。
  </Step>

  <Step title="验证工作进程已连接">
    在您自己的机器上，将 `ANTHROPIC_API_KEY` 设置为您的 Claude API 密钥（而不是环境密钥），并将 `ANTHROPIC_ENVIRONMENT_ID` (python, ruby: `environment_id`; typescript, java, csharp: `environmentId`; go: `environmentID`; php: `$environmentId`) 设置为环境 ID。确认 `workers_polling` (java, php: `workersPolling`; csharp, go: `WorkersPolling`) 至少为 1：

    <CodeGroup>
      ```bash cURL
      curl -sS --fail-with-body "https://api.anthropic.com/v1/environments/$ANTHROPIC_ENVIRONMENT_ID/work/stats" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01"
      ```

      ```bash CLI
      ant beta:environments:work stats --environment-id "$ANTHROPIC_ENVIRONMENT_ID"
      ```

      ```python Python
      client = anthropic.Anthropic()

      stats = client.beta.environments.work.stats(environment_id)
      print(f"workers_polling={stats.workers_polling}")
      ```

      ```typescript TypeScript
      const client = new Anthropic();

      const stats = await client.beta.environments.work.stats(environmentId);

      console.log(`workers_polling=${stats.workers_polling}`);
      ```

      ```csharp C#
      var client = new AnthropicClient();

      var stats = await client.Beta.Environments.Work.Stats(environmentId);

      Console.WriteLine($"workers_polling={stats.WorkersPolling}");
      ```

      ```go Go
      client := anthropic.NewClient()

      stats, err := client.Beta.Environments.Work.Stats(
      	context.Background(),
      	environmentID,
      	anthropic.BetaEnvironmentWorkStatsParams{},
      )
      if err != nil {
      	panic(err)
      }

      fmt.Printf("workers_polling=%d\n", stats.WorkersPolling)
      ```

      ```java Java
      var client = AnthropicOkHttpClient.fromEnv();

      var stats = client.beta().environments().work().stats(environmentId);

      IO.println("workers_polling=" + stats.workersPolling().orElse(null));
      ```

      ```php PHP
      $client = new Client();

      $stats = $client->beta->environments->work->stats($environmentId);

      printf("workers_polling=%d\n", $stats->workersPolling);
      ```

      ```ruby Ruby
      client = Anthropic::Client.new

      stats = client.beta.environments.work.stats(environment_id)

      puts "workers_polling=#{stats.workers_polling}"
      ```
    </CodeGroup>

    如果 `workers_polling` (java, php: `workersPolling`; csharp, go: `WorkersPolling`) 一直为 0，请参阅[故障排除](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-operations#troubleshooting)。
  </Step>

  <Step title="启动会话">
    将 `AGENT_ID` (python, ruby: `agent_id`; typescript, java, csharp: `agentId`; go: `agentID`; php: `$agentId`) 设置为您的智能体 ID。创建一个以该环境为目标的会话，然后向其发送任务：

    <CodeGroup>
      ```bash cURL
      SESSION_ID=$(curl -sS --fail-with-body https://api.anthropic.com/v1/sessions \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        -d '{
          "agent": "'"$AGENT_ID"'",
          "environment_id": "'"$ANTHROPIC_ENVIRONMENT_ID"'"
        }' | jq -er '.id'
      )

      curl -sS --fail-with-body "https://api.anthropic.com/v1/sessions/$SESSION_ID/events" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        -d '{
          "events": [
            {
              "type": "user.message",
              "content": [
                {
                  "type": "text",
                  "text": "Write the output of \"uname -a\" to hello.txt in your working directory."
                }
              ]
            }
          ]
        }'
      ```

      ```bash CLI
      SESSION_ID=$(ant beta:sessions create \
        --agent "$AGENT_ID" \
        --environment-id "$ANTHROPIC_ENVIRONMENT_ID" \
        --transform id --raw-output)

      ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
      events:
        - type: user.message
          content:
            - type: text
              text: Write the output of "uname -a" to hello.txt in your working directory.
      YAML
      ```

      ```python Python
      session = client.beta.sessions.create(
          agent=agent_id,
          environment_id=environment_id,
      )

      client.beta.sessions.events.send(
          session.id,
          events=[
              {
                  "type": "user.message",
                  "content": [
                      {
                          "type": "text",
                          "text": 'Write the output of "uname -a" to hello.txt in your working directory.',
                      },
                  ],
              },
          ],
      )
      ```

      ```typescript TypeScript
      const session = await client.beta.sessions.create({
        agent: agentId,
        environment_id: environmentId
      });

      await client.beta.sessions.events.send(session.id, {
        events: [
          {
            type: "user.message",
            content: [
              {
                type: "text",
                text: 'Write the output of "uname -a" to hello.txt in your working directory.'
              }
            ]
          }
        ]
      });
      ```

      ```csharp C#
      var session = await client.Beta.Sessions.Create(new()
      {
          Agent = agentId,
          EnvironmentID = environmentId,
      });

      await client.Beta.Sessions.Events.Send(session.ID, new()
      {
          Events =
          [
              new BetaManagedAgentsUserMessageEventParams
              {
                  Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
                  Content =
                  [
                      new BetaManagedAgentsTextBlock
                      {
                          Type = BetaManagedAgentsTextBlockType.Text,
                          Text = "Write the output of \"uname -a\" to hello.txt in your working directory.",
                      },
                  ],
              },
          ],
      });
      ```

      ```go Go
      session, err := client.Beta.Sessions.New(context.Background(), anthropic.BetaSessionNewParams{
      	Agent:         anthropic.BetaSessionNewParamsAgentUnion{OfString: anthropic.String(agentID)},
      	EnvironmentID: environmentID,
      })
      if err != nil {
      	panic(err)
      }

      _, err = client.Beta.Sessions.Events.Send(context.Background(), session.ID, anthropic.BetaSessionEventSendParams{
      	Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
      		OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
      			Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
      			Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
      				OfText: &anthropic.BetaManagedAgentsTextBlockParam{
      					Type: anthropic.BetaManagedAgentsTextBlockTypeText,
      					Text: "Write the output of \"uname -a\" to hello.txt in your working directory.",
      				},
      			}},
      		},
      	}},
      })
      if err != nil {
      	panic(err)
      }
      ```

      ```java Java
      var session = client.beta().sessions().create(SessionCreateParams.builder()
          .agent(agentId)
          .environmentId(environmentId)
          .build());

      client.beta().sessions().events().send(
          session.id(),
          EventSendParams.builder()
              .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
                  .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
                  .addTextContent("Write the output of \"uname -a\" to hello.txt in your working directory.")
                  .build())
              .build());
      ```

      ```php PHP
      $session = $client->beta->sessions->create(
          agent: $agentId,
          environmentID: $environmentId,
      );

      $client->beta->sessions->events->send(
          $session->id,
          events: [
              [
                  'type' => 'user.message',
                  'content' => [['type' => 'text', 'text' => 'Write the output of "uname -a" to hello.txt in your working directory.']],
              ],
          ],
      );
      ```

      ```ruby Ruby
      session = client.beta.sessions.create(
        agent: agent_id,
        environment_id: environment_id
      )

      client.beta.sessions.events.send_(
        session.id,
        events: [
          {
            type: :"user.message",
            content: [{type: :text, text: 'Write the output of "uname -a" to hello.txt in your working directory.'}]
          }
        ]
      )
      ```
    </CodeGroup>

    会话会在环境的队列中等待，直到有工作进程认领它。如果没有连接任何工作进程，会话将保持排队状态，而不会失败。
  </Step>

  <Step title="确认工具在您的主机上运行">
    在工作进程主机上，读取智能体写入的文件：

    ```bash
    cat /workspace/hello.txt
    ```

    该文件描述的是您自己主机的内核，因此智能体的工具调用是在那里运行的。要实时跟踪智能体的工作，请参阅[会话事件流](https://platform.claude.com/docs/zh-CN/managed-agents/events-and-streaming)。
  </Step>
</Steps>

## 会话资源

自托管沙箱仅支持 `memory_store` 资源。在自托管环境上包含 `file` 或 `github_repository` 资源的会话会被拒绝，并返回 400 错误：

```text wrap
Environment env_... is a self-hosted environment. `resources` are not supported with self-hosted environments.
```

以自托管环境为目标的[部署](https://platform.claude.com/docs/zh-CN/managed-agents/scheduled-deployments)遵循相同的规则。要为会话提供其自己的输入文件，请参阅[为会话暂存文件](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-workers#stage-files-for-a-session)。

## 自托管沙箱与 MCP 隧道

自托管控制的是*智能体代码在何处执行*。[MCP 隧道](https://platform.claude.com/docs/zh-CN/agents-and-tools/mcp-tunnels/overview)控制的是 *Anthropic 如何访问您网络中的 MCP 服务器*。两者相互独立：

* 在 Anthropic 云沙箱中的会话可以通过隧道访问私有 MCP 服务器。例如，私有 MCP 服务器可能部署在您防火墙后的数据库或内部 API 前面。
* 自托管会话可以使用经隧道连接的 MCP 服务器或公共 MCP 服务器。

当您希望执行和工具访问都保留在您的边界内时，请同时使用两者。要跳过隧道，请[将 MCP 服务器封装为自定义工具](https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-custom-tools#wrap-an-mcp-server-as-custom-tools)，由您的工作进程提供服务。

## 平台指南

这些页面介绍了如何在任何沙箱平台上构建工作进程。此外还提供以下特定平台的指南：

* [AWS Lambda MicroVMs](https://docs.aws.amazon.com/lambda/latest/dg/microvms-integrations-claude-managed-agents.html)
* [Blaxel](https://docs.blaxel.ai/Tutorials/Claude-Managed-Agents)
* [Cloudflare](https://developers.cloudflare.com/sandbox/claude-managed-agents/)
* [Daytona](https://www.daytona.io/docs/en/guides/claude/claude-managed-agents)
* [E2B](https://e2b.dev/docs/agents/claude-managed-agents)
* [Fly.io](https://docs.sprites.dev/integrations/claude-managed-agents/)
* [GKE Agent Sandbox](https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/tree/main/ai-ml/anthropic-agent-sandbox)
* [Modal](https://github.com/modal-labs/claude-managed-agents-modal-sandbox)
* [Namespace](https://namespace.so/docs/integrations/claude)
* [Superserve](https://docs.superserve.ai/integrations/managed-agents/claude-managed-agents)
* [Vercel](https://vercel.com/kb/guide/run-claude-managed-agent-tools-with-vercel-sandbox)

## 后续步骤

<CardGroup cols={2}>
  <Card title="部署工作进程" icon="play" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-workers">
    运行 SDK 工作进程、通过 webhook 触发工作进程，或为每个会话提供独立的沙箱。
  </Card>

  <Card title="Memory stores" icon="brain" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-memory">
    准备主机、配置同步，并处理只读存储和冲突。
  </Card>

  <Card title="自定义工具和 MCP 服务器" icon="tool" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-custom-tools">
    从工作进程提供您自己的工具，包括来自您网络内 MCP 服务器的工具。
  </Card>

  <Card title="监控和故障排除" icon="lightning" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-operations">
    读取队列深度、干净地停止会话和工作进程，并修复常见故障。
  </Card>

  <Card title="工作进程参考" icon="book" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-reference">
    CLI 标志、环境变量、文件系统路径和 SDK 辅助选项。
  </Card>

  <Card title="安全模型" icon="lock" href="https://platform.claude.com/docs/zh-CN/managed-agents/self-hosted-sandboxes-security">
    自托管沙箱环境的责任共担模型。
  </Card>
</CardGroup>
