Claude 托管代理入门

创建您的第一个自主代理。


本指南将引导您创建代理、设置环境、启动会话和流式传输代理响应。

Tip

**更喜欢交互式演练?**在最新版本的 Claude Code 中运行 /claude-api managed-agents-onboard,获取引导式设置和交互式问答。

核心概念

概念描述
代理模型、系统提示、工具、MCP 服务器和技能
环境会话运行位置的配置:Anthropic 管理的云容器,或您自己基础设施上的自托管沙箱
会话环境中运行的代理实例,执行特定任务并生成输出
事件应用程序和代理之间交换的消息(用户轮次、工具结果、状态更新)

前提条件

安装 CLI

brew install anthropics/tap/ant

对于 Linux 环境,直接下载发布二进制文件。

VERSION=1.9.1
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
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 发布页面找到所有发布版本。

您也可以使用 go install 从源代码安装 CLI。需要 Go 1.22 或更高版本。

go install github.com/anthropics/anthropic-cli/cmd/ant@latest

二进制文件放在 $(go env GOPATH)/bin 中。如果尚未添加,请将其添加到您的 PATH

export PATH="$PATH:$(go env GOPATH)/bin"

检查安装:

ant --version

安装 SDK

pip install anthropic
npm install @anthropic-ai/sdk
implementation("com.anthropic:anthropic-java:2.33.0")
go get github.com/anthropics/anthropic-sdk-go
dotnet add package Anthropic
bundle add anthropic
composer require anthropic-ai/sdk

将您的 API 密钥设置为环境变量:

export ANTHROPIC_API_KEY="your-api-key-here"

创建您的第一个会话

Note

所有托管代理 API 请求都需要 managed-agents-2026-04-01 beta 头。SDK 会自动设置该 beta 头。

  1. 创建代理

    创建一个定义模型、系统提示和可用工具的代理。

    set -euo pipefail
    
    agent=$(
      curl -sS --fail-with-body https://api.anthropic.com/v1/agents \
        -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 @- <<'EOF'
    {
      "name": "Coding Assistant",
      "model": "claude-opus-4-7",
      "system": "You are a helpful coding assistant. Write clean, well-documented code.",
      "tools": [
        {"type": "agent_toolset_20260401"}
      ]
    }
    EOF
    )
    
    AGENT_ID=$(jq -er '.id' <<<"$agent")
    AGENT_VERSION=$(jq -er '.version' <<<"$agent")
    
    echo "Agent ID: $AGENT_ID, version: $AGENT_VERSION"
    
    ant beta:agents create \
      --name "Coding Assistant" \
      --model '{id: claude-opus-4-7}' \
      --system "You are a helpful coding assistant. Write clean, well-documented code." \
      --tool '{type: agent_toolset_20260401}'
    
    from anthropic import Anthropic
    
    client = Anthropic()
    
    agent = client.beta.agents.create(
        name="Coding Assistant",
        model="claude-opus-4-7",
        system="You are a helpful coding assistant. Write clean, well-documented code.",
        tools=[
            {"type": "agent_toolset_20260401"},
        ],
    )
    
    print(f"Agent ID: \{agent.id\}, version: \{agent.version\}")
    
    import Anthropic from "@anthropic-ai/sdk";
    
    const client = new Anthropic();
    
    const agent = await client.beta.agents.create({
      name: "Coding Assistant",
      model: "claude-opus-4-7",
      system: "You are a helpful coding assistant. Write clean, well-documented code.",
      tools: [
        { type: "agent_toolset_20260401" },
      ],
    });
    
    console.log(`Agent ID: ${agent.id}, version: ${agent.version}`);
    
    using Anthropic;
    using Anthropic.Models.Beta.Agents;
    using Anthropic.Models.Beta.Environments;
    using Anthropic.Models.Beta.Sessions;
    using Anthropic.Models.Beta.Sessions.Events;
    
    var client = new AnthropicClient();
    
    var agent = await client.Beta.Agents.Create(new()
    {
        Name = "Coding Assistant",
        Model = BetaManagedAgentsModel.ClaudeOpus4_7,
        System = "You are a helpful coding assistant. Write clean, well-documented code.",
        Tools =
        [
            new BetaManagedAgentsAgentToolset20260401Params
            {
                Type = "agent_toolset_20260401",
            },
        ],
    });
    
    Console.WriteLine({{CONTENT}}quot;Agent ID: \{agent.ID\}, version: \{agent.Version\}");
    
    package main
    
    import (
    	"context"
    	"fmt"
    
    	"github.com/anthropics/anthropic-sdk-go"
    )
    
    func main() {
    	client := anthropic.NewClient()
    	ctx := context.Background()
    
    	agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
    		Name: "Coding Assistant",
    		Model: anthropic.BetaManagedAgentsModelConfigParams{
    			ID: anthropic.BetaManagedAgentsModelClaudeOpus4_7,
    		},
    		System: anthropic.String("You are a helpful coding assistant. Write clean, well-documented code."),
    		Tools: []anthropic.BetaAgentNewParamsToolUnion{{
    			OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
    				Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
    			},
    		}},
    	})
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Printf("Agent ID: %s, version: %d\n", agent.ID, agent.Version)
    
    import com.anthropic.client.okhttp.AnthropicOkHttpClient;
    import com.anthropic.models.beta.agents.AgentCreateParams;
    import com.anthropic.models.beta.agents.BetaManagedAgentsAgentToolset20260401Params;
    import com.anthropic.models.beta.agents.BetaManagedAgentsModel;
    import com.anthropic.models.beta.environments.BetaCloudConfigParams;
    import com.anthropic.models.beta.environments.EnvironmentCreateParams;
    import com.anthropic.models.beta.environments.BetaUnrestrictedNetwork;
    import com.anthropic.models.beta.sessions.SessionCreateParams;
    import com.anthropic.models.beta.sessions.events.BetaManagedAgentsUserMessageEventParams;
    import com.anthropic.models.beta.sessions.events.EventSendParams;
    import com.anthropic.models.beta.sessions.events.BetaManagedAgentsStreamSessionEvents;
    
    void main() {
        var client = AnthropicOkHttpClient.fromEnv();
    
        var agent = client.beta().agents().create(AgentCreateParams.builder()
            .name("Coding Assistant")
            .model(BetaManagedAgentsModel.CLAUDE_OPUS_4_7)
            .system("You are a helpful coding assistant. Write clean, well-documented code.")
            .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
                .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
                .build())
            .build());
    
        IO.println("Agent ID: " + agent.id() + ", version: " + agent.version());
    
    use Anthropic\Client;
    
    $client = new Client();
    
    $agent = $client->beta->agents->create(
        name: 'Coding Assistant',
        model: 'claude-opus-4-7',
        system: 'You are a helpful coding assistant. Write clean, well-documented code.',
        tools: [
            ['type' => 'agent_toolset_20260401'],
        ],
    );
    
    echo "Agent ID: {$agent->id}, version: {$agent->version}\n";
    
    require "anthropic"
    
    client = Anthropic::Client.new
    
    agent = client.beta.agents.create(
      name: "Coding Assistant",
      model: "claude-opus-4-7",
      system_: "You are a helpful coding assistant. Write clean, well-documented code.",
      tools: [{type: "agent_toolset_20260401"}]
    )
    
    puts "Agent ID: #\{agent.id\}, version: #\{agent.version\}"
    

    agent_toolset_20260401 工具类型启用完整的预构建代理工具集(bash、文件操作、网络搜索等)。请参阅工具了解完整列表和每个工具的配置选项。

    保存返回的 agent.id。您将在创建的每个会话中引用它。

  2. 创建环境

    环境定义了代理运行的容器。

    environment=$(
      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 @- <<'EOF'
    {
      "name": "quickstart-env",
      "config": {
        "type": "cloud",
        "networking": {"type": "unrestricted"}
      }
    }
    EOF
    )
    
    ENVIRONMENT_ID=$(jq -er '.id' <<<"$environment")
    
    echo "Environment ID: $ENVIRONMENT_ID"
    
    ant beta:environments create \
      --name "quickstart-env" \
      --config '{type: cloud, networking: {type: unrestricted}}'
    
    environment = client.beta.environments.create(
        name="quickstart-env",
        config={
            "type": "cloud",
            "networking": {"type": "unrestricted"},
        },
    )
    
    print(f"Environment ID: \{environment.id\}")
    
    const environment = await client.beta.environments.create({
      name: "quickstart-env",
      config: {
        type: "cloud",
        networking: { type: "unrestricted" },
      },
    });
    
    console.log(`Environment ID: ${environment.id}`);
    
    var environment = await client.Beta.Environments.Create(new()
    {
        Name = "quickstart-env",
        Config = new BetaCloudConfigParams { Networking = new BetaUnrestrictedNetwork() },
    });
    
    Console.WriteLine({{CONTENT}}quot;Environment ID: \{environment.ID\}");
    
    environment, err := client.Beta.Environments.New(ctx, anthropic.BetaEnvironmentNewParams{
    	Name: "quickstart-env",
    	Config: anthropic.BetaEnvironmentNewParamsConfigUnion{
    		OfCloud: &anthropic.BetaCloudConfigParams{
    			Networking: anthropic.BetaCloudConfigParamsNetworkingUnion{
    				OfUnrestricted: &anthropic.BetaUnrestrictedNetworkParam{},
    			},
    		},
    	},
    })
    if err != nil {
    	panic(err)
    }
    
    fmt.Printf("Environment ID: %s\n", environment.ID)
    
    var environment = client.beta().environments().create(EnvironmentCreateParams.builder()
        .name("quickstart-env")
        .config(BetaCloudConfigParams.builder()
            .networking(BetaUnrestrictedNetwork.builder().build())
            .build())
        .build());
    
    IO.println("Environment ID: " + environment.id());
    
    $environment = $client->beta->environments->create(
        name: 'quickstart-env',
        config: ['type' => 'cloud', 'networking' => ['type' => 'unrestricted']],
    );
    
    echo "Environment ID: {$environment->id}\n";
    
    environment = client.beta.environments.create(
      name: "quickstart-env",
      config: {type: "cloud", networking: {type: "unrestricted"}}
    )
    
    puts "Environment ID: #\{environment.id\}"
    

    保存返回的 environment.id。您将在创建的每个会话中引用它。

    Tip
    要在您自己的基础设施上运行沙箱而不是云容器,请参阅自托管沙箱
  3. 启动会话

    创建引用您的代理和环境的会话。

    session=$(
      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 @- <<EOF
    {
      "agent": "$AGENT_ID",
      "environment_id": "$ENVIRONMENT_ID",
      "title": "Quickstart session"
    }
    EOF
    )
    
    SESSION_ID=$(jq -er '.id' <<<"$session")
    
    echo "Session ID: $SESSION_ID"
    
    session = client.beta.sessions.create(
        agent=agent.id,
        environment_id=environment.id,
        title="Quickstart session",
    )
    
    print(f"Session ID: \{session.id\}")
    
    const session = await client.beta.sessions.create({
      agent: agent.id,
      environment_id: environment.id,
      title: "Quickstart session",
    });
    
    console.log(`Session ID: ${session.id}`);
    
    var session = await client.Beta.Sessions.Create(new()
    {
        Agent = agent.ID,
        EnvironmentID = environment.ID,
        Title = "Quickstart session",
    });
    
    Console.WriteLine({{CONTENT}}quot;Session ID: \{session.ID\}");
    
    session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
    	Agent:         anthropic.BetaSessionNewParamsAgentUnion{OfString: anthropic.String(agent.ID)},
    	EnvironmentID: environment.ID,
    	Title:         anthropic.String("Quickstart session"),
    })
    if err != nil {
    	panic(err)
    }
    
    fmt.Printf("Session ID: %s\n", session.ID)
    
    var session = client.beta().sessions().create(SessionCreateParams.builder()
        .agent(agent.id())
        .environmentId(environment.id())
        .title("Quickstart session")
        .build());
    
    IO.println("Session ID: " + session.id());
    
    $session = $client->beta->sessions->create(
        agent: $agent->id,
        environmentID: $environment->id,
        title: 'Quickstart session',
    );
    
    echo "Session ID: {$session->id}\n";
    
    session = client.beta.sessions.create(
      agent: agent.id,
      environment_id: environment.id,
      title: "Quickstart session"
    )
    
    puts "Session ID: #\{session.id\}"
    
  4. 发送消息并流式传输响应

    打开流,发送用户事件,然后在事件到达时处理它们:

    # Send the user message first; the API buffers events until the stream attaches
    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 @- >/dev/null <<'EOF'
    {
      "events": [
        {
          "type": "user.message",
          "content": [
            {
              "type": "text",
              "text": "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt"
            }
          ]
        }
      ]
    }
    EOF
    
    # Open the SSE stream and process events as they arrive
    while IFS= read -r line; do
      [[ $line == data:* ]] || continue
      json=${line#data: }
      case $(jq -r '.type' <<<"$json") in
        agent.message)
          jq -j '.content[] | select(.type == "text") | .text' <<<"$json"
          ;;
        agent.tool_use)
          printf '\n[Using tool: %s]\n' "$(jq -r '.name' <<<"$json")"
          ;;
        session.status_idle)
          printf '\n\nAgent finished.\n'
          break
          ;;
      esac
    done < <(
      curl -sS -N --fail-with-body \
        "https://api.anthropic.com/v1/sessions/$SESSION_ID/stream" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "Accept: text/event-stream"
    )
    
    with client.beta.sessions.events.stream(session.id) as stream:
        # Send the user message after the stream opens
        client.beta.sessions.events.send(
            session.id,
            events=[
                {
                    "type": "user.message",
                    "content": [
                        {
                            "type": "text",
                            "text": "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
                        },
                    ],
                },
            ],
        )
    
        # Process streaming events
        for event in stream:
            match event.type:
                case "agent.message":
                    for block in event.content:
                        print(block.text, end="")
                case "agent.tool_use":
                    print(f"\n[Using tool: \{event.name\}]")
                case "session.status_idle":
                    print("\n\nAgent finished.")
                    break
    
    const stream = await client.beta.sessions.events.stream(session.id);
    
    // Send the user message after the stream opens
    await client.beta.sessions.events.send(session.id, {
      events: [
        {
          type: "user.message",
          content: [
            {
              type: "text",
              text: "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
            },
          ],
        },
      ],
    });
    
    // Process streaming events
    for await (const event of stream) {
      if (event.type === "agent.message") {
        for (const block of event.content) {
          process.stdout.write(block.text);
        }
      } else if (event.type === "agent.tool_use") {
        console.log(`\n[Using tool: ${event.name}]`);
      } else if (event.type === "session.status_idle") {
        console.log("\n\nAgent finished.");
        break;
      }
    }
    
    var stream = client.Beta.Sessions.Events.StreamStreaming(session.ID);
    
    // Send the user message after the stream opens
    await client.Beta.Sessions.Events.Send(session.ID, new()
    {
        Events =
        [
            new BetaManagedAgentsUserMessageEventParams
            {
                Type = "user.message",
                Content =
                [
                    new BetaManagedAgentsTextBlock
                    {
                        Type = "text",
                        Text = "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
                    },
                ],
            },
        ],
    });
    
    // Process streaming events
    await foreach (var ev in stream)
    {
        if (ev.Value is BetaManagedAgentsAgentMessageEvent message)
        {
            foreach (var block in message.Content)
            {
                Console.Write(block.Text);
            }
        }
        else if (ev.Value is BetaManagedAgentsAgentToolUseEvent toolUse)
        {
            Console.WriteLine({{CONTENT}}quot;\n[Using tool: \{toolUse.Name\}]");
        }
        else if (ev.Value is BetaManagedAgentsSessionStatusIdleEvent)
        {
            Console.WriteLine("\n\nAgent finished.");
            break;
        }
    }
    
    	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{})
    	defer stream.Close()
    
    	// Send the user message after the stream opens
    	_, err = client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
    		Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
    			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
    				Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
    				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
    					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
    						Type: anthropic.BetaManagedAgentsTextBlockTypeText,
    						Text: "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
    					},
    				}},
    			},
    		}},
    	})
    	if err != nil {
    		panic(err)
    	}
    
    	// Process streaming events
    loop:
    	for stream.Next() {
    		switch event := stream.Current().AsAny().(type) {
    		case anthropic.BetaManagedAgentsAgentMessageEvent:
    			for _, block := range event.Content {
    				fmt.Print(block.Text)
    			}
    		case anthropic.BetaManagedAgentsAgentToolUseEvent:
    			fmt.Printf("\n[Using tool: %s]\n", event.Name)
    		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
    			fmt.Print("\n\nAgent finished.\n")
    			break loop
    		}
    	}
    	if err := stream.Err(); err != nil {
    		panic(err)
    	}
    
    try (var stream = client.beta().sessions().events().streamStreaming(session.id())) {
        // Send the user message after the stream opens
        client.beta().sessions().events().send(session.id(), EventSendParams.builder()
            .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
                .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
                .addTextContent("Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt")
                .build())
            .build());
    
        // Process streaming events
        for (var event : (Iterable<BetaManagedAgentsStreamSessionEvents>) stream.stream()::iterator) {
            if (event.isAgentMessage()) {
                event.asAgentMessage().content().forEach(block -> IO.print(block.text()));
            } else if (event.isAgentToolUse()) {
                IO.println("\n[Using tool: " + event.asAgentToolUse().name() + "]");
            } else if (event.isSessionStatusIdle()) {
                IO.println("\n\nAgent finished.");
                break;
            }
        }
    }
    
    $stream = $client->beta->sessions->events->streamStream($session->id);
    
    // Send the user message after the stream opens
    $client->beta->sessions->events->send(
        $session->id,
        events: [
            [
                'type' => 'user.message',
                'content' => [
                    ['type' => 'text', 'text' => 'Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt'],
                ],
            ],
        ],
    );
    
    // Process streaming events
    foreach ($stream as $event) {
        match ($event->type) {
            'agent.message' => print(implode('', array_map(fn($block) => $block->text, $event->content))),
            'agent.tool_use' => print("\n[Using tool: {$event->name}]\n"),
            'session.status_idle' => print("\n\nAgent finished.\n"),
            default => null,
        };
        if ($event->type === 'session.status_idle') {
            break;
        }
    }
    
    stream = client.beta.sessions.events.stream_events(session.id)
    
    # Send the user message after the stream opens
    client.beta.sessions.events.send_(
      session.id,
      events: [{
        type: "user.message",
        content: [{type: "text", text: "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt"}]
      }]
    )
    
    # Process streaming events
    stream.each do |event|
      case event.type
      in :"agent.message"
        event.content.each { print it.text }
      in :"agent.tool_use"
        puts "\n[Using tool: #\{event.name\}]"
      in :"session.status_idle"
        puts "\n\nAgent finished."
        break
      else
        # ignore other event types
      end
    end
    

    代理将编写一个 Python 脚本,在容器中执行它,并验证输出文件是否已创建。您的输出将类似于:

    I'll create a Python script that generates the first 20 Fibonacci numbers and saves them to a file.
    [Using tool: write]
    [Using tool: bash]
    The script ran successfully. Let me verify the output file.
    [Using tool: bash]
    fibonacci.txt contains the first 20 Fibonacci numbers (0 through 4181).
    
    Agent finished.
    

工作原理

当您发送用户事件时,Claude 托管代理:

  1. **配置容器:**您的环境配置决定了它如何构建。
  2. **运行代理循环:**Claude 根据您的消息决定使用哪些工具
  3. **执行工具:**文件写入、bash 命令和其他工具调用在容器内运行
  4. **流式传输事件:**您在代理工作时接收实时更新
  5. **变为空闲:**当代理没有更多任务时,发出 session.status_idle 事件

后续步骤