---
title: コンピューター使用ツール
url: https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool
description: コンピューター使用ツール（`computer_toolset_20260801` クライアントツールセット）を使用して、Claudeにデスクトップ環境のスクリーンショット、マウス、キーボードの制御を与えます。
featureMetadata:
  status: ga
  zdr:
    eligibility: eligible
    note: Excludes [Covered Models](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#model-specific-data-retention-requirements).
  supportedModels:
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-opus-5-5
    - claude-opus-5
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-opus-4-8
    - claude-haiku-5-5
  supportedPlatforms:
    Claude API: ga
    Claude Platform on AWS: beta
    Amazon Bedrock: beta
    Google Cloud: ga
    Microsoft Foundry: beta
  details:
    - Claude APIおよびGoogle Cloudでは、Claude 5.5以降のモデルは`computer_toolset_20260801`ツールセットを通じてのみコンピューター使用をサポートし、以前の`computer_20251124`および`computer_20250124`ツールバージョンに対してはエラーを返します。既存の統合を移行するには、[`computer_20251124`からの移行](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124)を参照してください。`computer_20250124`から移行するには、Claude Haiku 5.5移行ガイドの[コンピュータ使用をツールセットに移行する](https://platform.claude.com/docs/ja/models/haiku-5-5/migration-guide#computer-use-toolset)を参照してください。
    - Amazon Bedrockでは、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5は、Claude Opus 5およびClaude Sonnet 5と同様に、以前の`computer_20251124`ツールバージョンを受け付けます。
    - Claude Opus 4.7、Claude Opus 4.6、Claude Sonnet 4.6、Claude Opus 4.5は、ベータヘッダーを必要とする以前の`computer_20251124`ツールバージョンを通じてのみコンピューター使用をサポートします。[以前のツールバージョン](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions)を参照してください。
    - Claude APIおよびGoogle Cloud以外のプラットフォームでは、現在[以前のベータツールバージョン](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions)のみが提供されています。
---

<Note>
  **SDKツールセットから始めましょう：** `computer_toolset_20260801`については、PythonおよびTypeScript SDKにコンピューターツールセットクラスがベータ版で用意されています。[パートナー統合](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-sdk#partner-integrations)から始めるか、SDKツールセットページの[コンピュータツールセット](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-sdk#computer-toolset)セクションを参照してください。このページは、ツールリファレンスとして、またはツール呼び出しを自分で処理する場合に使用してください。
</Note>

Claudeは、「computer use tool」（コンピューター使用ツール）を通じてコンピューター環境と対話できます。このツールは、自律的なデスクトップ操作のためのスクリーンショット機能とマウス/キーボード制御を提供します。

コンピューター使用ツールは、Anthropicが定義する[「client toolset」（クライアントツールセット）](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference#client-toolsets)です。`tools`内の1つの`{"type": "computer_toolset_20260801"}`エントリにより、Claudeは`screenshot`、`left_click`、`type`、`zoom`などの17個のメンバーツールを利用できるようになり、アプリケーションはすべての呼び出しを自身が管理する環境で実行します。現在、[Claude Managed Agents](https://platform.claude.com/docs/ja/managed-agents/tools)では利用できません。Claudeの呼び出しは、`name`がメンバー名であり`"toolset_name": "computer"`を持つ`tool_use`ブロックで、多くの場合1ターンに複数含まれます（[「batch action」（バッチアクション）](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)）。

Webページ内で完結するタスクには、[ブラウザ使用ツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-tool)の方が適しています。そのメンバーツールはページ自体を読み取って操作し、完全なデスクトップ環境を必要としません。

<Note>
  コンピューター使用は、Claude APIおよび[Google Cloud](https://platform.claude.com/docs/ja/build-with-claude/claude-on-vertex-ai)で`computer_toolset_20260801`ツールセットとして利用できます。サポートされているモデルについては[互換性](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#compatibility)を参照してください。

  既存の`computer_20251124`統合は、[以前のツールバージョン](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions)でそのバージョン向けに記載されているモデルで引き続き動作し、以前のツールバージョンは、ツールセットをサポートしていないモデルおよびプラットフォーム向けにベータ版として引き続き利用できます。アップグレードするには[`computer_20251124`からの移行](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124)を、ベータヘッダーについては[以前のツールバージョン](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions)を参照してください。
</Note>

## セキュリティに関する考慮事項

コンピューター使用には、標準的なAPI機能とは異なる固有のリスクがあります。これらのリスクは、インターネットと対話する場合に高まります。

<Warning>
  リスクを最小限に抑えるために、次のような予防措置を検討してください。

  1. 直接的なシステム攻撃や事故を防ぐために、最小限の権限を持つ専用の仮想マシンまたはコンテナを使用する。
  2. 情報の盗難を防ぐために、アカウントのログイン情報などの機密データへのアクセスをモデルに与えないようにする。
  3. 悪意のあるコンテンツへの露出を減らすために、インターネットアクセスをドメインの許可リストに制限する。
  4. 現実世界に重大な影響を及ぼす可能性のある判断や、Cookieの受け入れ、金融取引の完了、利用規約への同意など、明示的な同意を必要とするタスクについては、人間に確認を求める。
</Warning>

状況によっては、Claudeはコンテンツ内で見つけたコマンドが指示と矛盾する場合でも、それに従うことがあります。たとえば、Webページ上の指示や画像に含まれる指示が、あなたの指示を上書きしたり、Claudeに誤りを犯させたりする可能性があります。「prompt injection」（プロンプトインジェクション）に関連するリスクを回避するために、Claudeを機密データや機密性の高い操作から隔離する予防措置を講じてください。

Anthropicは、これらのプロンプトインジェクションに抵抗するようにモデルを訓練し、追加の防御層を設けています。コンピューター使用ツールを使用する場合、分類器がスクリーンショットなどツールが返す内容を自動的にスキャンし、潜在的なプロンプトインジェクションにフラグを立てます。これらの分類器が潜在的なプロンプトインジェクションを特定すると、指示に基づいて行動する前に、その指示が本当にあなたからのものかどうかを確認するよう、モデルを自動的に誘導します。

この追加の保護は、すべてのユースケース（たとえば、人間が介在しないユースケース）に最適とは限らないため、オプトアウトして無効にしたい場合は[サポートにお問い合わせください](https://support.claude.com/en/)。これらの分類器が導入されていても、上記の予防措置は引き続き重要です。

自社製品でコンピューター使用を有効にする前に、エンドユーザーに関連するリスクを通知し、同意を得てください。

## クイックスタート

[Messages API](https://platform.claude.com/docs/ja/api/messages/create)リクエストの`tools`配列に、コンピューター使用ツールセットを`{"type": "computer_toolset_20260801"}`として追加します。リクエストにベータヘッダーは必要ありません。この例では、Claudeがコンピューター使用と併せて一般的に使用する[テキストエディタツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/text-editor-tool)と[bashツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/bash-tool)も宣言しています。

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "tools": [
        {
          "type": "computer_toolset_20260801"
        },
        {
          "type": "text_editor_20250728",
          "name": "str_replace_based_edit_tool"
        },
        {
          "type": "bash_20250124",
          "name": "bash"
        }
      ],
      "messages": [
        {
          "role": "user",
          "content": "Save a picture of a cat to my desktop."
        }
      ]
    }'
  ```

  ```bash CLI
  ant messages create <<'YAML'
  model: claude-opus-5-5
  max_tokens: 1024
  tools:
    - type: computer_toolset_20260801
    - type: text_editor_20250728
      name: str_replace_based_edit_tool
    - type: bash_20250124
      name: bash
  messages:
    - role: user
      content: Save a picture of a cat to my desktop.
  YAML
  ```

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

  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=[
          {"type": "computer_toolset_20260801"},
          {"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"},
          {"type": "bash_20250124", "name": "bash"},
      ],
      messages=[{"role": "user", "content": "Save a picture of a cat to my desktop."}],
  )
  print(response)
  ```

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

  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [
      {
        type: "computer_toolset_20260801"
      },
      {
        type: "text_editor_20250728",
        name: "str_replace_based_edit_tool"
      },
      {
        type: "bash_20250124",
        name: "bash"
      }
    ],
    messages: [{ role: "user", content: "Save a picture of a cat to my desktop." }]
  });

  console.log(response);
  ```

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

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools =
      [
          new ComputerToolset20260801(),
          new ToolTextEditor20250728(),
          new ToolBash20250124(),
      ],
      Messages =
      [
          new MessageParam
          {
              Role = Role.User,
              Content = "Save a picture of a cat to my desktop.",
          },
      ],
  };

  var response = await client.Messages.Create(parameters);
  Console.WriteLine(response);
  ```

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

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Tools: []anthropic.ToolUnionParam{
  		{OfComputerToolset20260801: &anthropic.ComputerToolset20260801Param{}},
  		{OfTextEditor20250728: &anthropic.ToolTextEditor20250728Param{}},
  		{OfBashTool20250124: &anthropic.ToolBash20250124Param{}},
  	},
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Save a picture of a cat to my desktop.")),
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response.RawJSON())
  ```

  ```java Java
  import com.anthropic.models.messages.ComputerToolset20260801;
  // ...
  import com.anthropic.models.messages.ToolBash20250124;
  import com.anthropic.models.messages.ToolTextEditor20250728;

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

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(ComputerToolset20260801.builder().build())
          .addTool(ToolTextEditor20250728.builder().build())
          .addTool(ToolBash20250124.builder().build())
          .addUserMessage("Save a picture of a cat to my desktop.")
          .build();

      Message response = client.messages().create(params);
      IO.println(response);
  }
  ```

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

  $response = $client->messages->create(
      maxTokens: 1024,
      messages: [
          ['role' => 'user', 'content' => 'Save a picture of a cat to my desktop.'],
      ],
      model: 'claude-opus-5-5',
      tools: [
          ['type' => 'computer_toolset_20260801'],
          [
              'type' => 'text_editor_20250728',
              'name' => 'str_replace_based_edit_tool',
          ],
          [
              'type' => 'bash_20250124',
              'name' => 'bash',
          ],
      ],
  );

  echo $response;
  ```

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

  response = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [
      { type: "computer_toolset_20260801" },
      {
        type: "text_editor_20250728",
        name: "str_replace_based_edit_tool"
      },
      {
        type: "bash_20250124",
        name: "bash"
      }
    ],
    messages: [
      { role: "user", content: "Save a picture of a cat to my desktop." }
    ]
  )

  puts response
  ```
</CodeGroup>

Claudeがデスクトップ上で操作を行う場合、レスポンスの`stop_reason`は`tool_use`となり、1つ以上のメンバー`tool_use`ブロックが含まれます。各ブロックはメンバーツールを指定し、`"toolset_name": "computer"`を持ちます。このタスクの途中で、Claudeがデスクトップのスクリーンショットを確認した後のレスポンスは、次のようになる場合があります。

```json Output
{
  "id": "msg_01UZ3bXcQH8mTqNhVfL9eK2p",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5-5",
  "content": [
    {
      "type": "text",
      "text": "I'll open the web browser to find a picture of a cat."
    },
    {
      "type": "tool_use",
      "id": "toolu_01WkoTUvSHDzTBu2xnGk8Ep8",
      "name": "left_click",
      "toolset_name": "computer",
      "input": { "coordinate": [512, 742] }
    },
    {
      "type": "tool_use",
      "id": "toolu_017nJn3RgSCkTMwuZDb4uUov",
      "name": "screenshot",
      "toolset_name": "computer",
      "input": {}
    }
  ],
  "stop_reason": "tool_use",
  "stop_sequence": null
}
```

アプリケーションは各呼び出しを自身の環境で順番に実行し、`tool_use`ブロックごとに1つの`tool_result`ブロックを返して、再度APIを呼び出します。[コンピューター使用の仕組み](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#how-computer-use-works)ではこのループについて説明し、このページの残りの部分ではその実装方法を示します。

***

## コンピューター使用の仕組み

<Steps>
  <Step title="Claudeにコンピューター使用ツールとユーザープロンプトを提供する">
    * APIリクエストの`tools`配列に、コンピューター使用ツールセット（および必要に応じて他のツール）を追加します。
    * デスクトップ操作を必要とするユーザープロンプトを含めます。たとえば、「猫の画像をデスクトップに保存して」などです。
  </Step>

  <Step title="Claudeがメンバーツールの呼び出しで応答する">
    * Claudeは、デスクトップ上での操作がユーザーのクエリに役立つかどうかを評価します。
    * 役立つ場合、Claudeは`screenshot`、`left_click`、`type`などの1つ以上のメンバー`tool_use`ブロックで応答し、各ブロックには`"toolset_name": "computer"`が含まれます。これらのブロックを複数含むレスポンスは[バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)です。
    * APIレスポンスの`stop_reason`は`tool_use`となり、ツール使用リクエストであることを示します。
  </Step>

  <Step title="呼び出しを順番に実行して結果を返す">
    * レスポンス内のすべての`tool_use`ブロックを順番に反復処理します。各ブロックについて、メンバーの`name`と`toolset_name`に基づいてディスパッチし、ブロックの`input`を使用してコンテナまたは仮想マシン上でそのアクションを実行します。
    * `tool_use`ブロックごとに1つの`tool_result`ブロックを含む新しい`user`メッセージで会話を続けます。各ブロックは`tool_use_id`で対応付けられ、それぞれ`"toolset_name": "computer"`を返します。`screenshot`と`zoom`には画像を返し、その他のアクションには`OK`などの短いテキストで十分です。
    * アクションが失敗した場合は、そのブロックに`is_error: true`を返し、バッチの残りについては[バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)で説明されているとおりに応答します。
  </Step>

  <Step title="タスクが完了するまでClaudeが続行する">
    * Claudeはツールの結果を分析し、さらにアクションが必要か、タスクが完了したかを判断します。
    * さらにアクションが必要だとClaudeが判断した場合、再び`tool_use`の`stop_reason`で応答するため、ステップ3に戻る必要があります。
    * それ以外の場合は、ユーザーにテキストレスポンスを返します。
  </Step>
</Steps>

ユーザー入力なしでステップ3と4を繰り返すことを、「agent loop」（エージェントループ）と呼びます（つまり、Claudeがツール使用リクエストで応答し、アプリケーションがそのリクエストを評価した結果でClaudeに応答することです）。

### バッチアクション

Claudeは、クリック、入力、スクリーンショットの取得といった短い一連のアクションを計画し、1つのレスポンスでまとめて返すことができます。これをバッチアクションと呼びます。これは[並列ツール使用](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/parallel-tool-use)と同じレスポンス形式を使用しますが、1つ違いがあります。ブロックを同時にではなく、順番に実行します。

3つのアクションからなるバッチを含むレスポンスは、次のようになります。

```json
{
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01HqCF3nJ4Vzr8sTkPZ2wxYA",
      "name": "left_click",
      "toolset_name": "computer",
      "input": { "coordinate": [640, 60] }
    },
    {
      "type": "tool_use",
      "id": "toolu_01Ppr3sZ3TnE9m6VUu4RyH2K",
      "name": "type",
      "toolset_name": "computer",
      "input": { "text": "pictures of cats" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01Xf5W1sD8Q9aBcJ7kLmN2pQ",
      "name": "screenshot",
      "toolset_name": "computer",
      "input": {}
    }
  ]
}
```

`tool_use`ブロックごとに1つの`tool_result`ブロックを`tool_use_id`で対応付けて、すべて次の`user`メッセージで返します。メンバーツールに対するすべての結果は`"toolset_name": "computer"`を持つ必要があります。これを省略した結果や、対応する`tool_use`ブロックとは異なるツールセットを指定した結果は拒否されます。画像が必要なのは`screenshot`と`zoom`の結果のみで、その他のメンバーには`OK`などの短いテキストによる確認応答で十分です（`cursor_position`は座標をテキストで返します）。

```json
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01HqCF3nJ4Vzr8sTkPZ2wxYA",
      "toolset_name": "computer",
      "content": [{ "type": "text", "text": "OK" }]
    },
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01Ppr3sZ3TnE9m6VUu4RyH2K",
      "toolset_name": "computer",
      "content": [{ "type": "text", "text": "OK" }]
    },
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01Xf5W1sD8Q9aBcJ7kLmN2pQ",
      "toolset_name": "computer",
      "content": [
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/png",
            "data": "iVBORw0KGgo..."
          }
        }
      ]
    }
  ]
}
```

**ブロックを順番に実行し、最初の失敗で停止します。** バッチ内の後続のアクションは、通常、前のアクションに依存しています。この例の`type`は、直前のクリックでフォーカスされた場所にテキストを入力します。ブロックを`content`に現れる順序で逐次実行し、いずれかが失敗した場合は残りを実行しないでください。すべての`tool_use`ブロックには引き続き`tool_result`が必要なため、バッチには次のように応答します。

* 成功した各アクションについては、通常の結果を返します。
* 失敗したアクションについては、何が問題だったかを説明するテキストとともに`is_error: true`を返します。
* バッチ内のそれ以降のすべてのアクションについては、正確に次のテキストとともに`is_error: true`を返します（ブラウザ使用ツールは独自の[停止テキスト](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-tool#batch-actions)を使用します）。

```json
{
  "type": "tool_result",
  "tool_use_id": "toolu_01Xf5W1sD8Q9aBcJ7kLmN2pQ",
  "toolset_name": "computer",
  "is_error": true,
  "content": "Not executed: an earlier computer action in this turn failed."
}
```

これによりClaudeは、どのアクションが成功し、どれが失敗し、どれがスキップされたかを把握し、次のターンで計画を立て直します。バッチ内のいずれかの`tool_use`ブロックに応答していないリクエストは`invalid_request_error`で拒否されるため、最初のブロックのみを読み取るエージェントループは次の呼び出しで失敗します。アプリケーションが重大なアクションについて人間に確認を求める場合は、各ブロックの実行前にその確認を行ってください。バッチは1ターン内で複数ステップのアクションを完了できるためです。

Claudeは通常、次に何をすべきかを判断する前に結果を確認できるよう、バッチを`screenshot`で終えます。バッチがスクリーンショットで終わらない場合、アプリケーションはバッチの最後の結果に追加の`image`ブロックとしてスクリーンショットを添付できます。これにより、Claudeは常に画面の現在の状態を確認でき、Claudeが要求するのを待つ場合と比べて往復を1回節約できます。また、すべてのバッチをスクリーンショットで終えるようClaudeにプロンプトで指示することもできます（[プロンプトによるモデルパフォーマンスの最適化](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#optimize-model-performance-with-prompting)を参照）。

### コンピューティング環境

コンピューター使用には、Claudeがアプリケーションやウェブと安全に対話できるサンドボックス化されたコンピューティング環境が必要です。この環境には次のものが含まれます。

1. **仮想ディスプレイ：** デスクトップインターフェースをレンダリングする仮想X11ディスプレイサーバー（Xvfbを使用）。Claudeはこれをスクリーンショットを通じて確認し、マウス/キーボードアクションで制御します。

2. **デスクトップ環境：** Linux上で動作するウィンドウマネージャー（Mutter）とパネル（Tint2）を備えた軽量UI。Claudeが対話するための一貫したグラフィカルインターフェースを提供します。

3. **アプリケーション：** Firefox、LibreOffice、テキストエディタ、ファイルマネージャーなど、Claudeがタスクを完了するために使用できるプリインストールされたLinuxアプリケーション。

4. **ツール実装：** Claudeの抽象的なツールリクエスト（「マウスを移動する」や「スクリーンショットを撮る」など）を、仮想環境での実際の操作に変換する統合コード。

5. **エージェントループ：** Claudeと環境間の通信を処理するプログラム。Claudeのアクションを環境に送信し、結果（スクリーンショット、コマンド出力）をClaudeに返します。

コンピューター使用を利用する場合、Claudeはこの環境に直接接続しません。代わりに、アプリケーションが次のことを行います。

1. Claudeのツール使用リクエストを受け取る
2. それらをコンピューティング環境でのアクションに変換する
3. 結果（スクリーンショットやコマンド出力など）を取得する
4. これらの結果をClaudeに返す

セキュリティと隔離のため、リファレンス実装では、環境の表示と操作のための適切なポートマッピングを備えたDockerコンテナ内でこれらすべてを実行します。

***

## コンピューター使用の実装方法

既存の`computer_20251124`統合をアップグレードする場合は、[`computer_20251124`からの移行](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124)から始めてください。このセクションの残りの部分は、新規の統合と移行済みの統合の両方に適用されます。

<Tip>
  [コンピューター使用のリファレンス実装](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo)は、完全に動作する例です。コンピューター使用に適した[コンテナ化された環境](https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/Dockerfile)、[コンピューター使用ツール](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo/computer_use_demo/tools)の実装、Claude APIを呼び出してツールを実行する[エージェントループ](https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/computer_use_demo/loop.py)、そしてコンテナ、ループ、ツールのためのWebインターフェースが含まれています。
</Tip>

### エージェントループを理解する

コンピューター使用の中核は「エージェントループ」です。これは、Claudeがツールアクションを要求し、アプリケーションがそれを実行して、結果をClaudeに返すサイクルです。このループは、[クイックスタート](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#quick-start)で作成したクライアント、コンピューター使用ツールセットのみを宣言する`tools`配列、および[コンピューター使用ツールを実装する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#implement-the-computer-use-tool)にあるツール呼び出し処理ヘルパーを使用します。クイックスタートのbashツールやテキストエディタツールなど、他のツールも宣言する場合は、それらの`tool_use`ブロックも同じパスでディスパッチしてください。ヘルパーはコンピューター使用のメンバー呼び出しにのみ応答し、ループは応答した呼び出しがないターンを完了として扱います。以下は簡略化した例です。

<CodeGroup exclude="shell">
  ```python Python
  def sampling_loop(model: str, messages: list[MessageParam], max_iterations: int = 10):
      """
      Run the computer-use agent loop until Claude stops requesting tools
      or the iteration limit is reached.
      """
      for _ in range(max_iterations):
          response = client.messages.create(
              model=model,
              max_tokens=4096,
              messages=messages,
              tools=TOOLS,
          )

          # Claudeの応答を会話履歴に追加します
          messages.append({"role": "assistant", "content": response.content})

          # Claudeが要求したアクションを順番に実行し、結果を収集します
          tool_results = process_tool_calls(response)
          if not tool_results:
              return messages  # No more tool use; task complete

          # すべての結果を1つのユーザーメッセージでClaudeに送り返します
          messages.append({"role": "user", "content": tool_results})

      return messages
  ```

  ```typescript TypeScript
  async function samplingLoop(
    model: string,
    messages: Anthropic.MessageParam[],
    maxIterations = 10
  ): Promise<Anthropic.MessageParam[]> {
    // Claudeがツールの要求をやめるか、反復回数の上限に達するまで
    // computer-useエージェントループを実行します。
    for (let i = 0; i < maxIterations; i++) {
      const response = await client.messages.create({
        model,
        max_tokens: 4096,
        messages,
        tools
      });

      // Claudeの応答を会話履歴に追加します
      messages.push({ role: "assistant", content: response.content });

      // Claudeが要求したツールを実行し、結果を収集します
      const toolResults = processToolCalls(response);
      if (toolResults.length === 0) {
        return messages; // No more tool use; task complete
      }

      // 次の反復のためにツール結果をClaudeに送り返します
      messages.push({ role: "user", content: toolResults });
    }

    return messages;
  }
  ```

  ```csharp C#
  async Task<List<MessageParam>> SamplingLoop(
      Model model,
      List<MessageParam> messages,
      int maxIterations = 10
  )
  {
      // Claudeがツールの要求をやめるか、反復回数の上限に達するまで
      // computer-useエージェントループを実行します。
      for (var i = 0; i < maxIterations; i++)
      {
          var response = await client.Messages.Create(
              new MessageCreateParams
              {
                  Model = model,
                  MaxTokens = 4096,
                  Messages = messages,
                  Tools = tools,
              }
          );

          // Claudeの応答を会話履歴に追加します
          messages.Add(
              new()
              {
                  Role = Role.Assistant,
                  Content = response
                      .Content.Select(block => new ContentBlockParam(block.Json))
                      .ToList(),
              }
          );

          // Claudeが要求したツールを実行し、結果を収集します
          var toolResults = ProcessToolCalls(response);
          if (toolResults.Count == 0)
          {
              return messages; // No more tool use; task complete
          }

          // 次の反復のためにツール結果をClaudeに送り返します
          messages.Add(new() { Role = Role.User, Content = toolResults });
      }

      return messages;
  }
  ```

  ```go Go
  // samplingLoop は、Claude がツールの要求を停止するか
  // 反復回数の上限に達するまで、コンピュータ使用エージェントループを実行します。
  func samplingLoop(ctx context.Context, model anthropic.Model, messages []anthropic.MessageParam, maxIterations int) ([]anthropic.MessageParam, error) {
  	for range maxIterations {
  		response, err := client.Messages.New(ctx, anthropic.MessageNewParams{
  			Model:     model,
  			MaxTokens: 4096,
  			Messages:  messages,
  			Tools:     tools,
  		})
  		if err != nil {
  			return nil, err
  		}

  		// Claude の応答を会話履歴に追加します
  		messages = append(messages, response.ToParam())

  		// Claude が要求したアクションを順に実行し、結果を収集します
  		toolResults := processToolCalls(response)
  		if len(toolResults) == 0 {
  			return messages, nil // No more tool use; task complete
  		}

  		// すべての結果を1つのユーザーメッセージで Claude に返します
  		messages = append(messages, anthropic.NewUserMessage(toolResults...))
  	}
  	return messages, nil
  }
  ```

  ```java Java
  /**
   * Run the computer-use agent loop until Claude stops requesting tools
   * or the iteration limit is reached.
   */
  List<MessageParam> samplingLoop(Model model, List<MessageParam> messages, int maxIterations) {
      for (int i = 0; i < maxIterations; i++) {
          Message response = client.messages().create(MessageCreateParams.builder()
                  .model(model)
                  .maxTokens(4096)
                  .messages(messages)
                  .addTool(COMPUTER_TOOLSET)
                  .build());

          // Claudeの応答を会話履歴に追加します
          messages.add(MessageParam.builder()
                  .role(MessageParam.Role.ASSISTANT)
                  .contentOfBlockParams(response.content().stream().map(ContentBlock::toParam).toList())
                  .build());

          // Claudeが要求したツールを実行し、結果を収集します
          List<ContentBlockParam> toolResults = processToolCalls(response);
          if (toolResults.isEmpty()) {
              return messages; // No more tool use; task complete
          }

          // 次のイテレーションのためにツール結果をClaudeに送り返します
          messages.add(MessageParam.builder()
                  .role(MessageParam.Role.USER)
                  .contentOfBlockParams(toolResults)
                  .build());
      }
      return messages;
  }
  ```

  ```php PHP
  /**
   * Run the computer-use agent loop until Claude stops requesting tools
   * or the iteration limit is reached.
   */
  function samplingLoop(string $model, array $messages, int $maxIterations = 10): array
  {
      global $client, $tools;

      for ($i = 0; $i < $maxIterations; $i++) {
          $response = $client->messages->create(
              model: $model,
              maxTokens: 4096,
              messages: $messages,
              tools: $tools,
          );

          // Claudeの応答を会話履歴に追加します
          $messages[] = MessageParam::with(role: Role::ASSISTANT, content: $response->content);

          // Claudeが要求したツールを実行し、結果を収集します
          $toolResults = processToolCalls($response);
          if ($toolResults === []) {
              return $messages; // No more tool use; task complete
          }

          // 次のイテレーションのためにツール結果をClaudeに送り返します
          $messages[] = MessageParam::with(role: Role::USER, content: $toolResults);
      }

      return $messages;
  }
  ```

  ```ruby Ruby
  # Claudeがツールの要求をやめるか、反復回数の上限に達するまで
  # コンピュータ使用のエージェントループを実行します。
  def sampling_loop(model, messages, max_iterations: 10)
    max_iterations.times do
      response = CLIENT.messages.create(
        model: model,
        max_tokens: 4096,
        messages: messages,
        tools: TOOLS
      )

      # Claudeの応答を会話履歴に追加します
      messages << { role: "assistant", content: response.content }

      # Claudeが要求したアクションを順に実行し、結果を収集します
      tool_results = process_tool_calls(response)
      return messages if tool_results.empty? # No more tool use; task complete

      # すべての結果を1つのユーザーメッセージでClaudeに返します
      messages << { role: "user", content: tool_results }
    end

    messages
  end
  ```
</CodeGroup>

ループは、Claudeがツールを要求せずに応答する（タスク完了）か、最大反復回数に達するまで続きます。この安全策により、予期しないAPIコストにつながる可能性のある無限ループを防ぎます。

### プロンプトによるモデルパフォーマンスの最適化

1. シンプルで明確に定義されたタスクを指定し、各ステップについて明示的な指示を提供します。
2. Claudeは、アクションの結果を明示的に確認せずに、その結果を想定してしまうことがあります。これを防ぐには、Claudeに`After each step, take a screenshot and carefully evaluate if you have achieved the right outcome. State in one sentence what the screenshot shows and whether the step succeeded. If it didn't, try again. Only when you confirm a step was executed correctly should you move on to the next one.`とプロンプトで指示できます。
3. 一部のUI要素（ドロップダウンやスクロールバーなど）は、Claudeがマウス操作で扱うのが難しい場合があります。このような問題が発生した場合は、キーボードショートカットを使用するようモデルにプロンプトで指示してみてください。
4. 繰り返し可能なタスクやUI操作については、成功した結果のスクリーンショットとツール呼び出しの例をプロンプトに含めます。
5. モデルにログインさせる必要がある場合は、`<robot_credentials>`などのXMLタグ内でユーザー名とパスワードをプロンプトに含めて提供します。ログインが必要なアプリケーション内でコンピューター使用を利用すると、プロンプトインジェクションによって悪い結果が生じるリスクが高まります。モデルにログイン認証情報を提供する前に、[ジェイルブレイクとプロンプトインジェクションの軽減](https://platform.claude.com/docs/ja/test-and-evaluate/strengthen-guardrails/mitigate-jailbreaks)を確認してください。
6. ユーザーターンの`content`配列を構築する際は、指示テキストをスクリーンショット画像の*前*に配置します。画像が処理される前にターゲットの説明を提供することで、クリックの精度が向上します。
7. Claudeは、サイドバー内のファイル名、タブのタイトル、ステータスバーのテキスト、行番号、ボタンのラベルなど、スクリーンショットのデフォルト解像度では判読できない小さなテキストや特定のUI要素について尋ねられた場合、`zoom`アクションを使用して領域をフル解像度で確認します。期待どおりにClaudeがズームしない場合は、画面全体ではなく特定の領域や要素について尋ねてください。
8. すべての[バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)をスクリーンショットで終えたい場合は、システムプロンプトでその旨を伝えます。たとえば、`End each group of actions with a screenshot so you can verify the result before continuing.`のように指示します。

<Tip>
  明確な一連の問題に繰り返し遭遇する場合や、Claudeが完了する必要のあるタスクが 事前にわかっている場合は、システムプロンプトを使用して、タスクを正常に実行する方法に関する 明示的なヒントや指示をClaudeに提供してください。
</Tip>

<Tip>
  複数のセッションにまたがるエージェントでは、実装後だけでなく、各セッションの開始時にも エンドツーエンドの検証を実行してください。ブラウザベースのチェックは、 コードレベルのレビューだけでは見逃してしまう、以前のセッションからのリグレッションを検出します。詳細については、 [Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents) を参照してください。
</Tip>

### システムプロンプト

リクエストにコンピューター使用ツールを含めると、APIはコンピューター使用専用のシステムプロンプトを生成します。これは[ツール使用のシステムプロンプト](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/define-tools#tool-use-system-prompt)に似ていますが、次の文で始まります。

> You have access to a set of functions you can use to answer the user's question. This includes access to a sandboxed computing environment. You do NOT currently have the ability to inspect files or interact with external resources, except by invoking the below functions.

通常のツール使用と同様に、ユーザーが指定した`system`パラメータは引き続き尊重され、結合されたシステムプロンプトの構築に使用されます。

### 利用可能なアクション

各アクションはコンピューター使用ツールセットのメンバーツールです。Claudeは`"toolset_name": "computer"`を持つ`tool_use`ブロックでメンバーを指定し、ブロックの`input`にはそのメンバーのパラメータのみが含まれ、`action`フィールドはありません。ツールセットには17個のメンバーツールがあります。

| メンバー                                                       | 入力                                                                                                                                          | 説明                                                                                                                                                |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `screenshot`                                               | なし（`{}`）                                                                                                                                    | ディスプレイ全体をキャプチャし、画像として返します。                                                                                                                        |
| `zoom`                                                     | `region`：`[x0, y0, x1, y1]`、確認する領域の左上隅と右下隅                                                                                                  | ディスプレイのその領域のみをフル解像度でキャプチャし、アスペクト比を維持したまま通常のスクリーンショットの寸法に収まるようにスケーリングして、画像として返します。これにより、Claudeは縮小されたフルスクリーンショットでは判読できない小さなテキストや密集したUIを読み取ることができます。 |
| `left_click`                                               | `coordinate`（省略可）：`[x, y]`、`text`（省略可）：クリック中に押し続ける修飾キー。`shift`、`ctrl`、`alt`、`super`（CommandキーまたはWindowsキー）、または`ctrl+shift`のような`+`で結合した組み合わせ | `coordinate`の位置、または`coordinate`が省略された場合は現在のカーソル位置で、マウスの左ボタンをクリックします。                                                                              |
| `right_click`、`middle_click`、`double_click`、`triple_click` | `left_click`と同じ                                                                                                                             | その他のマウスボタンおよび複数回クリック。                                                                                                                             |
| `left_click_drag`                                          | `start_coordinate`：`[x, y]`、`coordinate`：`[x, y]`、`text`（省略可）：修飾キー                                                                          | `start_coordinate`で押下し、`coordinate`までドラッグして離します。                                                                                                  |
| `mouse_move`                                               | `coordinate`：`[x, y]`                                                                                                                       | クリックせずにカーソルを移動します。たとえば、ホバーするために使用します。                                                                                                             |
| `left_mouse_down`、`left_mouse_up`                          | なし（`{}`）                                                                                                                                    | `left_click_drag`では表現できないドラッグのために、現在のカーソル位置でマウスの左ボタンを押下または解放します。先に`mouse_move`でカーソルを移動してください。                                                     |
| `cursor_position`                                          | なし（`{}`）                                                                                                                                    | カーソルの現在の`[x, y]`位置をテキストで報告します。                                                                                                                    |
| `scroll`                                                   | `scroll_direction`：`"up"`、`"down"`、`"left"`、または`"right"`、`scroll_amount`：スクロールホイールのクリック数、`coordinate`（省略可）：`[x, y]`、`text`（省略可）：修飾キー        | `coordinate`の位置、または現在のカーソル位置でスクロールします。                                                                                                            |
| `type`                                                     | `text`：入力する文字列                                                                                                                              | 現在のキーボードフォーカスにリテラルテキストを入力します。                                                                                                                     |
| `key`                                                      | `text`：キー、または`"Return"`、`"ctrl+s"`、`"alt+Tab"`のような`+`で結合した組み合わせ、`repeat`（省略可）：1〜100、デフォルトは1                                                 | キーまたはキーの組み合わせを`repeat`回押します。                                                                                                                      |
| `hold_key`                                                 | `text`：キーまたは組み合わせ、`duration`：秒数、最大300                                                                                                       | 指定された時間、キーを押し続けます。                                                                                                                                |
| `wait`                                                     | `duration`：秒数、最大300                                                                                                                         | 次のアクションの前に一時停止します。たとえば、アプリケーションの読み込み中に使用します。                                                                                                      |

メンバーを実装する際は、次の点に留意してください。

* **座標はスクリーンショットのピクセル単位です。** すべての`coordinate`、`start_coordinate`、`region`の値、および`cursor_position`が報告する位置は、返すフルディスプレイのスクリーンショットのピクセル空間におけるもので、原点は左上です。ズーム画像はこれを変更しません。`zoom`の後も、Claudeは座標をズーム画像に対する相対位置ではなく、常にフルスクリーンショットの空間で表現します。スクリーンショットを縮小してから返す場合は、実際のディスプレイに適用する前にClaudeの座標を拡大し直してください（[画像の制限に合わせてスクリーンショットのサイズを調整する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)を参照）。
* **`zoom`を含むすべてのメンバーはデフォルトで有効です。** 環境でズーム画像を生成できない場合は、有効のままにしてエラーを返すのではなく、`configs`でそのメンバーを無効にしてください（[ツールパラメータ](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#tool-parameters)を参照）。無効にしたメンバーや実装していないメンバーをClaudeが呼び出した場合は、そのブロックに対して`is_error: true`を含む`tool_result`を返してください。
* **（`toolset_name`、`name`）の組み合わせに基づいてディスパッチします。** ブロックをコンピューターアクションとして識別するのは`toolset_name`です。同じリクエスト内のカスタムツールがメンバーと同じ名前を持つことがあり、また後のツールセットバージョンでメンバーが追加される可能性があります（[クライアントツールセット](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference#client-toolsets)を参照）。

<Accordion title="アクションの例">
  各例は、Claudeのレスポンスに現れる完全な`tool_use`ブロックです。

  ある位置でShift+クリックします。たとえば、選択範囲を拡張する場合です。`hold_key`とは異なり、`text`はそのクリックまたはスクロールの間だけ修飾キーを押し続けます。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Qg8m3XqC5aRy7tD2eS4jUg",
    "name": "left_click",
    "toolset_name": "computer",
    "input": { "coordinate": [500, 300], "text": "shift" }
  }
  ```

  ある地点から別の地点へドラッグします。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Ed6j9VnA3yPw5rB8cQ2gSe",
    "name": "left_click_drag",
    "toolset_name": "computer",
    "input": {
      "start_coordinate": [200, 300],
      "coordinate": [600, 300]
    }
  }
  ```

  ホイールを3クリック分下にスクロールします。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Yc5h8UmZ2xNv4qA7bP9fRd",
    "name": "scroll",
    "toolset_name": "computer",
    "input": {
      "coordinate": [500, 400],
      "scroll_direction": "down",
      "scroll_amount": 3
    }
  }
  ```

  Tabキーを4回押します。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Sb4g7TkY9wLu3pX6zM8eQc",
    "name": "key",
    "toolset_name": "computer",
    "input": { "text": "Tab", "repeat": 4 }
  }
  ```

  ズームインして領域をフル解像度で確認します。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Kf7k2WpB4zQx6sC9dR3hTf",
    "name": "zoom",
    "toolset_name": "computer",
    "input": { "region": [100, 200, 400, 350] }
  }
  ```

  カーソル位置を報告します。この呼び出しには、スクリーンショットのピクセル単位で位置を示す短いテキスト結果（たとえば`X=512, Y=384`）で応答します。

  ```json
  {
    "type": "tool_use",
    "id": "toolu_01Ekh3vqB6yTs2mNc4Rw8pLd",
    "name": "cursor_position",
    "toolset_name": "computer",
    "input": {}
  }
  ```
</Accordion>

### ツールパラメータ

`tools`配列内のツールセットエントリは4つのパラメータを受け付けます。ブラウザ使用ツールセットと共通するルールは、[クライアントツールセット](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference#client-toolsets)に記載されています。

| パラメータ             | 必須  | 説明                                                                                                                                                                                                                                                                                                                                                       |
| ----------------- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`            | はい  | `computer_toolset_20260801`                                                                                                                                                                                                                                                                                                                              |
| `configs`         | いいえ | メンバー名をキーとするメンバーごとの設定です。各メンバーは`enabled`（`zoom`を含む17個すべてでデフォルトは`true`）と`defer_loading`（デフォルトは`false`、[ツール検索](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-search-tool#deferred-tool-loading)用）を受け付け、省略したメンバーはデフォルト値を維持します。                                                                                                           |
| `cache_control`   | いいえ | ツールセット定義における[プロンプトキャッシング](https://platform.claude.com/docs/ja/build-with-claude/prompt-caching)のブレークポイントです（エントリのみ）。バッチ内の任意の`tool_use`または`tool_result`ブロックに設定したブレークポイントは、そのバッチの末尾で有効になります。[プロンプトキャッシングを使用したツール使用](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-use-with-prompt-caching#cache-control-on-tool-definitions)を参照してください。 |
| `allowed_callers` | いいえ | `["direct"]`のみ。                                                                                                                                                                                                                                                                                                                                          |

たとえば、次のエントリは、`zoom`を実装していない環境向けにそれを無効にし、ツールセット定義にキャッシュブレークポイントを設定します。

```json
{
  "type": "computer_toolset_20260801",
  "configs": {
    "zoom": { "enabled": false }
  },
  "cache_control": { "type": "ephemeral" }
}
```

エージェントループが1回の往復で1つのアクションしか実行できない場合は、`tool_choice`で`disable_parallel_tool_use`を`true`に設定します。これにより、Claudeは1ターンあたり最大1つのメンバー`tool_use`ブロックを返します（[並列ツール使用を無効にする](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/parallel-tool-use#disable-parallel-tool-use)を参照）。

エントリは以前のツールバージョンの次のパラメータを拒否し、これらのいずれかを含むリクエストは`invalid_request_error`を返します。

* `name`：メンバー名はツールセットバージョンによって固定されています。
* `display_width_px`、`display_height_px`、`display_number`：座標は常に、返すスクリーンショットのピクセル空間におけるものです。
* `enable_zoom`：zoomは`configs`で制御するメンバーツールです。

また、このエントリは、`computer_20251124`エントリや`computer`という名前の別のツールと同じリクエスト内で宣言することはできません。`strict`、`input_examples`、`defer_loading`の配置、`tool_choice`、ストリーミング、および呼び出し元の制限については、[クライアントツールセット](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference#client-toolsets)を参照してください。

### 思考との組み合わせ

コンピューター使用と思考を組み合わせるには、[思考](https://platform.claude.com/docs/ja/build-with-claude/thinking)を参照してください。

<Tip>
  以前の`computer_20251124`ツールについて、それを使用するモデルでの内部ベンチマークでは、次の`effort`設定が推奨されています。

  * **Claude Opus 4.7：** デフォルトとして`high`を使用します。高スループットまたはコスト重視のワークロードには`low`を使用します。
  * **Claude Sonnet 4.6およびClaude Opus 4.6：** デフォルトとして`medium`を使用します（精度対コスト比が最も優れています）。`max`は、UIタスクの精度を向上させずにトークンコストを増加させるため、避けてください。これらのモデルでは、`low`は思考を完全に無効にするよりも*少ない*出力トークンを使用するため（ミスが少ないほど再試行も少なくなります）、コスト重視のループに適した選択肢です。
</Tip>

### 他のツールによるコンピューター使用の拡張

コンピューター使用と併せて他のツールを追加するには、それらを同じ`tools`配列に含めます。[クイックスタート](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#quick-start)セクションでは、[bashツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/bash-tool)と[テキストエディタツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/text-editor-tool)を使用してこのパターンを示しています。独自の[カスタムツール定義](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/define-tools)も同じ方法で追加できます。

Webページ内で完結するタスクについては、[同じリクエストでブラウザ使用ツールを宣言する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-tool#combine-with-other-tools)こともできます。2つのツールセットはそれぞれ独自の座標系で独立して動作し、`screenshot`や`key`など同じ名前を持つメンバーへの呼び出しは`toolset_name`によって区別されます。

### カスタムのコンピューター使用環境を構築する

[リファレンス実装](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo)は、コンピューター使用を始めるのに役立つことを目的としています。Claudeにコンピューターを使用させるために必要なすべてのコンポーネントが含まれています。ただし、ニーズに合わせてコンピューター使用のための独自の環境を構築することもできます。次のものが必要です。

* Claudeによるコンピューター使用に適した仮想化またはコンテナ化された環境
* コンピューター使用ツールのアクションの実装
* Claude APIと対話し、ツール実装を使用して`tool_use`の結果を実行するエージェントループ
* ユーザー入力によってエージェントループを開始できるAPIまたはUI

### コンピューター使用ツールを実装する

コンピューター使用ツールは、スキーマレスツールとして実装されています。このツールを使用する場合、他のツールのように入力スキーマを提供する必要はありません。スキーマはClaudeのモデルに組み込まれており、変更することはできません。

<Steps>
  <Step title="コンピューティング環境をセットアップする">
    Claudeが対話する仮想ディスプレイを作成するか、既存のディスプレイに接続します。これには通常、Xvfb（X Virtual Framebuffer）または同様の技術のセットアップが含まれます。
  </Step>

  <Step title="アクションハンドラーを実装する">
    Claudeが要求する可能性のある各アクションタイプを処理する関数を作成します。

    <CodeGroup exclude="shell">
      ```python Python
      # プレースホルダーの画像データ。実際のエグゼキューターは画面をキャプチャしてPNGバイトを返します
      PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="


      def capture_screenshot() -> list[ImageBlockParam]:
          # screenshotはテキストではなく画像ブロックで応答するため、結果のコンテンツリストを返します
          return [
              {
                  "type": "image",
                  "source": {
                      "type": "base64",
                      "media_type": "image/png",
                      "data": PLACEHOLDER_PNG,
                  },
              }
          ]


      def click(coordinate=None):
          if coordinate is None:
              return "clicked at current cursor"
          x, y = coordinate
          return f"clicked at ({x}, {y})"


      def type_text(text):
          return f"typed: {text}"


      def handle_computer_action(name, tool_input):
          match name:
              case "screenshot":
                  return capture_screenshot()
              case "left_click":
                  # coordinate は省略可能です。指定がない場合は現在のカーソル位置をクリックします
                  return click(tool_input.get("coordinate"))
              case "type":
                  return type_text(tool_input["text"])
          # 必要に応じて他のアクションを処理します
          raise ValueError(f"Unknown or unimplemented member: {name}")
      ```

      ```typescript TypeScript
      // プレースホルダーの画像データ。実際のエグゼキューターは画面をPNGバイトとしてキャプチャします
      const PLACEHOLDER_PNG =
        "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";

      function captureScreenshot(): Anthropic.ImageBlockParam[] {
        // screenshotはテキストではなく画像ブロックで応答します
        return [
          {
            type: "image",
            source: {
              type: "base64",
              media_type: "image/png",
              data: PLACEHOLDER_PNG
            }
          }
        ];
      }

      function clickAt(x: number, y: number): string {
        return `clicked at (${x}, ${y})`;
      }

      function clickAtCursor(): string {
        return "clicked at the current cursor position";
      }

      function typeText(text: string): string {
        return `typed: ${text}`;
      }

      function handleComputerAction(
        action: string,
        input: unknown
      ): string | Anthropic.ImageBlockParam[] {
        const params: object = typeof input === "object" && input !== null ? input : {};
        switch (action) {
          case "screenshot":
            return captureScreenshot();
          case "left_click":
            // coordinate はツールセットでは省略可能です。指定がない場合はカーソル位置でクリックします
            if ("coordinate" in params && Array.isArray(params.coordinate)) {
              const [x, y] = params.coordinate;
              return clickAt(x, y);
            }
            return clickAtCursor();
          case "type":
            if ("text" in params) {
              return typeText(String(params.text));
            }
            break;
        }
        // 必要に応じて他のアクションを処理します
        throw new Error(`Unknown or unimplemented member: ${action}`);
      }
      ```

      ```csharp C#
      // プレースホルダーの画像データ。実際のエグゼキューターは画面をキャプチャしてPNGバイトを返します
      const string PlaceholderPng = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";

      // screenshotはテキストではなく画像ブロックで応答します。結果のコンテンツリストを返します
      List<Block> CaptureScreenshot() =>
          [
              new ImageBlockParam(
                  new Base64ImageSource { Data = PlaceholderPng, MediaType = MediaType.ImagePng }
              ),
          ];

      string ClickAt(int x, int y) => $"clicked at ({x}, {y})";

      string ClickAtCursor() => "clicked at the current cursor position";

      string TypeText(string text) => $"typed: {text}";

      ToolResultBlockParamContent HandleComputerAction(
          string action,
          IReadOnlyDictionary<string, JsonElement> input
      ) =>
          action switch
          {
              "screenshot" => CaptureScreenshot(),
              // coordinateはclickメンバーでは省略可能です。指定がない場合はカーソル位置でクリックします
              "left_click" when input.TryGetValue("coordinate", out var xy) => ClickAt(
                  xy[0].GetInt32(),
                  xy[1].GetInt32()
              ),
              "left_click" => ClickAtCursor(),
              "type" => TypeText(input["text"].GetString()!),
              // 必要に応じて他のアクションを処理します
              _ => throw new NotSupportedException($"Unknown or unimplemented member: {action}"),
          };
      ```

      ```go Go
      // placeholderPNG は実際のキャプチャの代わりです。エグゼキュータは
      // 画面を base64 エンコードされた PNG データとして返します。
      const placeholderPNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="

      // captureScreenshot はテキストではなく画像ブロックを返します。
      func captureScreenshot() []anthropic.ToolResultBlockParamContentUnion {
      	return []anthropic.ToolResultBlockParamContentUnion{{
      		OfImage: &anthropic.ImageBlockParam{
      			Source: anthropic.ImageBlockParamSourceUnion{
      				OfBase64: &anthropic.Base64ImageSourceParam{
      					MediaType: anthropic.Base64ImageSourceMediaTypeImagePNG,
      					Data:      placeholderPNG,
      				},
      			},
      		},
      	}}
      }

      // textContent はテキストを tool_result のコンテンツとしてラップします。
      func textContent(text string) []anthropic.ToolResultBlockParamContentUnion {
      	return []anthropic.ToolResultBlockParamContentUnion{
      		{OfText: &anthropic.TextBlockParam{Text: text}},
      	}
      }

      func clickAt(x, y int) string {
      	return fmt.Sprintf("clicked at (%d, %d)", x, y)
      }

      func clickAtCursor() string {
      	return "clicked at the current cursor position"
      }

      func typeText(text string) string {
      	return fmt.Sprintf("typed: %s", text)
      }

      func handleComputerAction(action string, params map[string]any) ([]anthropic.ToolResultBlockParamContentUnion, error) {
      	switch action {
      	case "screenshot":
      		return captureScreenshot(), nil
      	case "left_click":
      		// coordinate は省略可能です。省略時はカーソルの現在位置でクリックします
      		coord, ok := params["coordinate"].([]any)
      		if !ok {
      			return textContent(clickAtCursor()), nil
      		}
      		if len(coord) == 2 {
      			x, xok := coord[0].(float64)
      			y, yok := coord[1].(float64)
      			if xok && yok {
      				return textContent(clickAt(int(x), int(y))), nil
      			}
      		}
      	case "type":
      		if text, ok := params["text"].(string); ok {
      			return textContent(typeText(text)), nil
      		}
      	// 必要に応じて他のアクションを処理します
      	default:
      		return nil, fmt.Errorf("unknown or unimplemented member: %s", action)
      	}
      	// メンバーの入力にフィールドが欠けているか、フィールドの型が誤っている場合に到達します
      	return nil, fmt.Errorf("invalid input for %s", action)
      }
      ```

      ```java Java
      /** Placeholder pixels; a real executor captures the screen and base64-encodes the PNG. */
      static final String PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";

      ToolResultBlockParam.Content captureScreenshot() {
          ImageBlockParam image = ImageBlockParam.builder()
                  .source(Base64ImageSource.builder()
                          .mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
                          .data(PLACEHOLDER_PNG)
                          .build())
                  .build();
          return ToolResultBlockParam.Content.ofBlocks(
                  List.of(ToolResultBlockParam.Content.Block.ofImage(image)));
      }

      String clickAt(long x, long y) {
          return "clicked at (" + x + ", " + y + ")";
      }

      String clickAtCursor() {
          return "clicked at current cursor";
      }

      String typeText(String text) {
          return "typed: " + text;
      }

      /** Runs one computer toolset member; {@code action} is the tool_use block's name. */
      ToolResultBlockParam.Content handleComputerAction(String action, Map<String, JsonValue> input) {
          if (action.equals("screenshot")) {
              return captureScreenshot(); // the one member here that answers with an image block
          }
          String output = switch (action) {
              case "left_click" -> {
                  JsonValue coordinate = input.get("coordinate"); // optional on the toolset
                  if (coordinate == null) {
                      yield clickAtCursor();
                  }
                  List<JsonValue> point = (List<JsonValue>) coordinate.asArray().get();
                  long x = ((Number) point.get(0).asNumber().get()).longValue();
                  long y = ((Number) point.get(1).asNumber().get()).longValue();
                  yield clickAt(x, y);
              }
              case "type" -> typeText(input.get("text").asStringOrThrow());
              // 必要に応じて他のアクションを処理します
              default -> throw new UnsupportedOperationException("Unknown or unimplemented member: " + action);
          };
          return ToolResultBlockParam.Content.ofString(output);
      }
      ```

      ```php PHP
      // 実際のPNGバイトの代用。実際のエグゼキュータは画面をキャプチャします
      const PLACEHOLDER_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';

      function captureScreenshot(): array
      {
          // screenshotはテキストではなく画像ブロックで応答するため、結果のコンテンツリストを返します
          $image = [
              'type' => 'image',
              'source' => ['type' => 'base64', 'media_type' => 'image/png', 'data' => PLACEHOLDER_PNG],
          ];

          return [$image];
      }

      function clickAt(?array $coordinate): string
      {
          // left_clickはcoordinateを省略可能で、その場合は現在のカーソル位置でクリックされます
          if ($coordinate === null) {
              return 'clicked at current cursor';
          }
          [$x, $y] = $coordinate;

          return "clicked at ({$x}, {$y})";
      }

      function typeText(string $text): string
      {
          return "typed: {$text}";
      }

      function handleComputerAction(string $name, array $input): string|array
      {
          return match ($name) {
              'screenshot' => captureScreenshot(),
              'left_click' => clickAt($input['coordinate'] ?? null),
              'type' => typeText($input['text']),
              // 必要に応じて他のアクションを処理します
              default => throw new \RuntimeException("Unknown or unimplemented member: {$name}"),
          };
      }
      ```

      ```ruby Ruby
      # 仮の画像データ。実際のエグゼキュータは画面をPNGとしてキャプチャします。
      PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="

      # screenshotはテキストではなく画像ブロックで応答します
      def capture_screenshot
        [
          {
            type: "image",
            source: { type: "base64", media_type: "image/png", data: PLACEHOLDER_PNG }
          }
        ]
      end

      def click(coordinate = nil)
        return "clicked at current cursor" if coordinate.nil?

        x, y = coordinate
        "clicked at (#{x}, #{y})"
      end

      def type_text(text)
        "typed: #{text}"
      end

      def handle_computer_action(name, input)
        case name
        when "screenshot"
          capture_screenshot
        when "left_click"
          # coordinateは省略可能。指定しない場合はカーソルの現在位置でクリックします
          click(input[:coordinate])
        when "type"
          type_text(input[:text])
        # 必要に応じて他のアクションを処理します
        else
          raise ArgumentError, "Unknown or unimplemented member: #{name}"
        end
      end
      ```
    </CodeGroup>
  </Step>

  <Step title="Claudeのツール呼び出しを処理する">
    Claudeのレスポンスからツール呼び出しを抽出して実行します。

    <CodeGroup exclude="shell">
      ```python Python
      NOT_EXECUTED = "Not executed: an earlier computer action in this turn failed."


      def process_tool_calls(response: Message) -> list[ToolResultBlockParam]:
          """
          Run the computer actions in Claude's response in order and answer each
          one. After the first failure the rest are skipped, because Claude planned
          them assuming the earlier actions succeeded.
          """
          tool_results: list[ToolResultBlockParam] = []
          failed = False
          for block in response.content:
              # 宣言されているのはcomputerツールセットのみ。他のツールを追加する場合はここでルーティングします
              if block.type != "tool_use" or block.toolset_name != "computer":
                  continue
              result: ToolResultBlockParam = {
                  "type": "tool_result",
                  "tool_use_id": block.id,
                  "toolset_name": "computer",
              }
              if failed:
                  result["content"] = NOT_EXECUTED
                  result["is_error"] = True
              else:
                  try:
                      # 文字列、またはスクリーンショット画像などのコンテンツブロックのリスト
                      result["content"] = handle_computer_action(block.name, block.input)
                  except Exception as err:
                      result["content"] = f"Error: {err}"
                      result["is_error"] = True
                      failed = True
              tool_results.append(result)
          return tool_results
      ```

      ```typescript TypeScript
      const HALT_TEXT = "Not executed: an earlier computer action in this turn failed.";

      function computerResult(
        toolUseId: string,
        content: string | Anthropic.ImageBlockParam[],
        isError?: boolean
      ): Anthropic.ToolResultBlockParam {
        return {
          type: "tool_result",
          tool_use_id: toolUseId,
          toolset_name: "computer",
          content,
          is_error: isError
        };
      }

      function processToolCalls(response: Anthropic.Message): Anthropic.ToolResultBlockParam[] {
        const toolResults: Anthropic.ToolResultBlockParam[] = [];
        let failed = false;
        for (const block of response.content) {
          if (block.type !== "tool_use") {
            continue;
          }
          if (block.toolset_name !== "computer") {
            // この例ではcomputerツールセットのみを宣言しています。他のツールを追加する場合は
            // ここでルーティングしてください。
            continue;
          }
          if (failed) {
            // バッチは最初の失敗で停止します。以降のアクションには未実行として応答します
            toolResults.push(computerResult(block.id, HALT_TEXT, true));
            continue;
          }
          try {
            // 文字列、またはscreenshotが返す画像ブロックのリスト
            const result = handleComputerAction(block.name, block.input);
            toolResults.push(computerResult(block.id, result));
          } catch (error) {
            failed = true;
            const message = error instanceof Error ? error.message : String(error);
            toolResults.push(computerResult(block.id, `Error: ${message}`, true));
          }
        }
        return toolResults;
      }
      ```

      ```csharp C#
      const string HaltText = "Not executed: an earlier computer action in this turn failed.";

      List<ContentBlockParam> ProcessToolCalls(Message response)
      {
          List<ContentBlockParam> toolResults = [];
          var failed = false;
          foreach (var block in response.Content)
          {
              if (!block.TryPickToolUse(out var toolUse))
              {
                  continue;
              }

              if (toolUse.ToolsetName != "computer")
              {
                  // この例ではcomputerツールセットのみを宣言しています。他のツールを追加する場合は
                  // ここでルーティングしてください。
                  continue;
              }

              if (failed)
              {
                  // バッチは最初の失敗で停止します。以降のアクションは実行せずに応答します
                  toolResults.Add(
                      new ToolResultBlockParam(toolUse.ID)
                      {
                          Content = HaltText,
                          IsError = true,
                          ToolsetName = "computer",
                      }
                  );
                  continue;
              }

              try
              {
                  // 文字列、またはscreenshotが返す画像ブロックのリスト
                  var result = HandleComputerAction(toolUse.Name, toolUse.Input);
                  toolResults.Add(
                      new ToolResultBlockParam(toolUse.ID) { Content = result, ToolsetName = "computer" }
                  );
              }
              catch (Exception e)
              {
                  failed = true;
                  toolResults.Add(
                      new ToolResultBlockParam(toolUse.ID)
                      {
                          Content = $"Error: {e.Message}",
                          IsError = true,
                          ToolsetName = "computer",
                      }
                  );
              }
          }
          return toolResults;
      }
      ```

      ```go Go
      const notExecuted = "Not executed: an earlier computer action in this turn failed."

      // computerToolResult は1つのコンピュータアクションの結果を構築します。
      // 通常のツール結果とは異なり、ツールセット名をエコーする必要があります。
      func computerToolResult(toolUseID string, content []anthropic.ToolResultBlockParamContentUnion, isError bool) anthropic.ContentBlockParamUnion {
      	result := anthropic.ToolResultBlockParam{
      		ToolUseID:   toolUseID,
      		ToolsetName: anthropic.String("computer"),
      		Content:     content,
      	}
      	if isError {
      		result.IsError = anthropic.Bool(true)
      	}
      	return anthropic.ContentBlockParamUnion{OfToolResult: &result}
      }

      // processToolCalls は Claude の応答内のコンピュータアクションを順に実行し、
      // tool_use ブロックごとに1つの tool_result を構築します。最初の失敗以降は残りをスキップします。
      // Claude は先行アクションの成功を前提に計画しているためです。
      func processToolCalls(response *anthropic.Message) []anthropic.ContentBlockParamUnion {
      	var toolResults []anthropic.ContentBlockParamUnion
      	failed := false
      	for _, block := range response.Content {
      		switch variant := block.AsAny().(type) {
      		case anthropic.ToolUseBlock:
      			// この例では computer ツールセットのみを宣言しています。他のツールを追加する場合はここでルーティングしてください。
      			if variant.ToolsetName != "computer" {
      				continue
      			}
      			if failed {
      				toolResults = append(toolResults, computerToolResult(variant.ID, textContent(notExecuted), true))
      				continue
      			}
      			var input map[string]any
      			var content []anthropic.ToolResultBlockParamContentUnion
      			err := json.Unmarshal(variant.Input, &input)
      			if err == nil {
      				// テキスト、または screenshot が返す画像ブロック
      				content, err = handleComputerAction(variant.Name, input)
      			}
      			if err != nil {
      				failed = true
      				content = textContent("Error: " + err.Error())
      			}
      			toolResults = append(toolResults, computerToolResult(variant.ID, content, err != nil))
      		}
      	}
      	return toolResults
      }
      ```

      ```java Java
      /** The exact text the toolset contract prescribes for member calls skipped after a failure. */
      static final String HALT_TEXT = "Not executed: an earlier computer action in this turn failed.";

      /** Every result answering a computer toolset member echoes toolset_name. */
      ToolResultBlockParam.Builder computerResult(ToolUseBlock toolUse) {
          return ToolResultBlockParam.builder()
                  .toolUseId(toolUse.id())
                  .toolsetName("computer");
      }

      /**
       * Run the computer actions in Claude's response in order and build one
       * tool_result per tool_use block. After the first failure, skip the rest:
       * Claude planned them assuming the earlier actions succeeded.
       */
      List<ContentBlockParam> processToolCalls(Message response) {
          List<ContentBlockParam> toolResults = new ArrayList<>();
          boolean failed = false;
          for (ContentBlock block : response.content()) {
              // この例ではcomputerツールセットのみを宣言しています。他のツールを追加する場合はここでルーティングしてください。
              if (!block.isToolUse() || !block.asToolUse().toolsetName().equals(Optional.of("computer"))) {
                  continue;
              }
              ToolUseBlock toolUse = block.asToolUse();
              ToolResultBlockParam result;
              if (failed) {
                  result = computerResult(toolUse).content(HALT_TEXT).isError(true).build();
              } else {
                  try {
                      Map<String, JsonValue> input =
                              (Map<String, JsonValue>) toolUse._input().asObject().get();
                      // 文字列、またはscreenshotが返す画像ブロック
                      ToolResultBlockParam.Content output = handleComputerAction(toolUse.name(), input);
                      result = computerResult(toolUse).content(output).build();
                  } catch (RuntimeException e) {
                      failed = true;
                      result = computerResult(toolUse).content("Error: " + e.getMessage()).isError(true).build();
                  }
              }
              toolResults.add(ContentBlockParam.ofToolResult(result));
          }
          return toolResults;
      }
      ```

      ```php PHP
      const HALT_TEXT = 'Not executed: an earlier computer action in this turn failed.';

      function processToolCalls(Message $response): array
      {
          $toolResults = [];
          $failed = false;
          foreach ($response->content as $block) {
              // この例ではcomputerツールセットのみを宣言しています。他のツールを追加する場合はここでルーティングしてください。
              if (!($block instanceof \Anthropic\Messages\ToolUseBlock) || $block->toolsetName !== 'computer') {
                  continue;
              }
              $result = ['type' => 'tool_result', 'tool_use_id' => $block->id, 'toolset_name' => 'computer'];
              if ($failed) {
                  // バッチは最初の失敗で停止し、残りのアクションは実行されずに応答されます
                  $toolResults[] = [...$result, 'content' => HALT_TEXT, 'is_error' => true];
                  continue;
              }
              try {
                  // 文字列、またはscreenshotが返す画像ブロックのリスト
                  $toolResults[] = [...$result, 'content' => handleComputerAction($block->name, $block->input)];
              } catch (\Throwable $e) {
                  $failed = true;
                  $toolResults[] = [...$result, 'content' => 'Error: ' . $e->getMessage(), 'is_error' => true];
              }
          }

          return $toolResults;
      }
      ```

      ```ruby Ruby
      NOT_EXECUTED = "Not executed: an earlier computer action in this turn failed."

      # Claudeの応答に含まれるコンピュータアクションを順に実行し、
      # tool_useブロックごとに1つのtool_resultを作成します。最初の失敗以降は残りをスキップします。
      # Claudeは先行するアクションが成功した前提で計画しているためです。
      def process_tool_calls(response)
        tool_results = []
        failed = false
        response.content.each do |block|
          # この例ではcomputerツールセットのみを宣言しています。他のツールを追加する場合は
          # ここでルーティングしてください。
          next unless block.type == :tool_use && block.toolset_name == "computer"

          result = { type: "tool_result", tool_use_id: block.id, toolset_name: "computer" }
          if failed
            result.update(content: NOT_EXECUTED, is_error: true)
          else
            begin
              # String、またはscreenshotが返す画像コンテンツブロック
              result[:content] = handle_computer_action(block.name, block.input)
            rescue => e
              result.update(content: "Error: #{e.message}", is_error: true)
              failed = true
            end
          end
          tool_results << result
        end
        tool_results
      end
      ```
    </CodeGroup>
  </Step>

  <Step title="エージェントループを実装する">
    前の2つのステップを、結果を送り返し、Claudeがメンバーツール呼び出しを返さなくなるまで繰り返すループで囲みます。[エージェントループを理解する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#understanding-the-agentic-loop)では、各言語でのこのループを示しています。
  </Step>
</Steps>

### エラーを処理する

失敗したアクションは、`is_error: true`と短い説明を含む`tool_result`としてClaudeに報告し、他のメンバーの結果と同様に`"toolset_name": "computer"`を含めます。失敗したアクションが[バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)の一部であった場合は、バッチ内の残りのブロックを実行せず、そこに示されている停止テキストで応答します。

たとえば、スクリーンショットのキャプチャが失敗した場合は次のようになります。

```json
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "toolset_name": "computer",
      "content": "Error: Failed to capture screenshot. Display may be locked or unavailable.",
      "is_error": true
    }
  ]
}
```

ディスプレイの範囲外の座標や、実行に失敗したアクションについても、何が問題だったかを示すメッセージとともに同じ形式を使用します。

### 画像の制限に合わせてスクリーンショットのサイズを調整する

コンピューター使用ツールセットに返すスクリーンショットとズーム画像は、あらかじめモデルの[画像サイズの制限](https://platform.claude.com/docs/ja/build-with-claude/vision#evaluate-image-size)内に収まっている必要があります。ツールセットはディスプレイの寸法を受け取らず、APIも縮小を行わないため、サイズが大きすぎる`tool_result`画像は検証エラーで拒否されます。Claudeは自身が見ている画像のピクセル空間で座標を返すため、使用したスケール係数を保持しておき、それらの座標を画面にマッピングし直せるようにしてください。

<Note>
  制限はモデルによって異なります。`computer_toolset_20260801`をサポートするすべてのモデルを含むClaude Opus 4.7以降のモデルは、長辺最大2576ピクセル、合計4784ビジュアルトークン（`⌈width / 28⌉ × ⌈height / 28⌉`、約3.75メガピクセル）まで受け付けます。それ以前のモデルは、長辺最大1568ピクセル、合計約1.15メガピクセルまで受け付けます（各モデルのティアについては[解像度とトークンコスト](https://platform.claude.com/docs/ja/build-with-claude/vision#evaluate-image-size)を参照）。次の例では、以前のモデルの1568 px / 1.15 MPの制限を使用しています。高解像度ティアのモデルでは、ピクセル総数ではなくビジュアルトークンの制限に合わせてサイズを調整してください。たとえば、[アップロード前に画像のサイズを変更する](https://platform.claude.com/docs/ja/build-with-claude/vision-coordinates#resize-your-image-before-uploading)のリサイズヘルパーを使用できます。
</Note>

画面が制限より大きい場合は、各スクリーンショットを返す前にリサイズし、Claudeが返した座標を元の画面空間にスケーリングし直します。ツールセットはディスプレイの寸法を受け取らないため、アプリケーションコードでのリサイズと座標のスケーリングだけで十分です。

<CodeGroup exclude="shell">
  ```python Python
  import math

  screen_width, screen_height = 1512, 982


  def get_scale_factor(width, height):
      """Calculate scale factor to meet API constraints."""
      long_edge = max(width, height)
      total_pixels = width * height

      long_edge_scale = 1568 / long_edge
      total_pixels_scale = math.sqrt(1_150_000 / total_pixels)

      return min(1.0, long_edge_scale, total_pixels_scale)


  # スクリーンショットをキャプチャする場合
  scale = get_scale_factor(screen_width, screen_height)
  scaled_width = int(screen_width * scale)
  scaled_height = int(screen_height * scale)

  # Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  screenshot = capture_and_resize(scaled_width, scaled_height)


  # Claude の座標を処理する場合は、元のスケールに拡大し直します
  def execute_click(x, y):
      screen_x = x / scale
      screen_y = y / scale
      perform_click(screen_x, screen_y)
  ```

  ```typescript TypeScript
  const screenWidth = 1512;
  const screenHeight = 982;
  const MAX_LONG_EDGE = 1568;
  const MAX_PIXELS = 1_150_000;

  function getScaleFactor(width: number, height: number): number {
    const longEdge = Math.max(width, height);
    const totalPixels = width * height;

    const longEdgeScale = MAX_LONG_EDGE / longEdge;
    const totalPixelsScale = Math.sqrt(MAX_PIXELS / totalPixels);

    return Math.min(1.0, longEdgeScale, totalPixelsScale);
  }

  // スクリーンショットをキャプチャする場合
  const scale = getScaleFactor(screenWidth, screenHeight);
  const scaledWidth = Math.floor(screenWidth * scale);
  const scaledHeight = Math.floor(screenHeight * scale);

  // Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  const screenshot = captureAndResize(scaledWidth, scaledHeight);

  // Claude の座標を処理する場合は、元のスケールに戻します
  function executeClick(x: number, y: number): void {
    const screenX = x / scale;
    const screenY = y / scale;
    performClick(screenX, screenY);
  }
  ```

  ```csharp C#
  int screenWidth = 1512, screenHeight = 982;

  double GetScaleFactor(int width, int height)
  {
      // API の制約を満たすためのスケール係数を計算します。
      int longEdge = Math.Max(width, height);
      int totalPixels = width * height;

      double longEdgeScale = 1568.0 / longEdge;
      double totalPixelsScale = Math.Sqrt(1_150_000.0 / totalPixels);

      return Math.Min(1.0, Math.Min(longEdgeScale, totalPixelsScale));
  }

  // スクリーンショットをキャプチャする際
  double scale = GetScaleFactor(screenWidth, screenHeight);
  int scaledWidth = (int)(screenWidth * scale);
  int scaledHeight = (int)(screenHeight * scale);

  // Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  var screenshot = CaptureAndResize(scaledWidth, scaledHeight);

  // Claude の座標を処理する際は、元のスケールに拡大して戻します
  void ExecuteClick(int x, int y)
  {
      double screenX = x / scale;
      double screenY = y / scale;
      PerformClick(screenX, screenY);
  }
  ```

  ```go Go
  func getScaleFactor(width, height int) float64 {
  	longest := float64(max(width, height))
  	area := float64(width * height)
  	return min(1.0, 1568/longest, math.Sqrt(1_150_000/area))
  }

  // ...
  	screenWidth, screenHeight := 1512, 982

  	// スクリーンショットをキャプチャする場合
  	scale := getScaleFactor(screenWidth, screenHeight)
  	scaledWidth := int(float64(screenWidth) * scale)
  	scaledHeight := int(float64(screenHeight) * scale)

  	// Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  	screenshot := captureAndResize(scaledWidth, scaledHeight)

  	// Claude の座標を処理する場合は、元のスケールに拡大して戻します
  	executeClick := func(x, y int) {
  		performClick(float64(x)/scale, float64(y)/scale)
  	}
  ```

  ```java Java
  static double getScaleFactor(int width, int height) {
      return Math.min(
          1.0,
          Math.min(
              1568.0 / Math.max(width, height),
              Math.sqrt(1_150_000.0 / (width * height))
          )
      );
  }

  void main() {
      int screenWidth = 1512, screenHeight = 982;

      // スクリーンショットをキャプチャする場合
      double scale = getScaleFactor(screenWidth, screenHeight);
      int scaledWidth = (int)(screenWidth * scale);
      int scaledHeight = (int)(screenHeight * scale);

      // Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
      var screenshot = captureAndResize(scaledWidth, scaledHeight);

      // Claude から返された座標を処理する際は、元のスケールに戻します
      BiConsumer<Integer, Integer> executeClick =
          (x, y) -> performClick(x / scale, y / scale);
  // ...
  }
  ```

  ```php PHP
  function getScaleFactor(int $width, int $height): float
  {
      return min(
          1.0,
          1568 / max($width, $height),
          sqrt(1_150_000 / ($width * $height)),
      );
  }

  $screenWidth = 1512;
  $screenHeight = 982;

  // スクリーンショットをキャプチャする場合
  $scale = getScaleFactor($screenWidth, $screenHeight);
  $scaledWidth = (int)($screenWidth * $scale);
  $scaledHeight = (int)($screenHeight * $scale);

  // Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  $screenshot = captureAndResize($scaledWidth, $scaledHeight);

  // Claude が返した座標を処理する場合は、元のスケールに拡大して戻します
  $executeClick = fn(int $x, int $y) => performClick($x / $scale, $y / $scale);
  ```

  ```ruby Ruby
  def get_scale_factor(width, height)
    [1.0, 1568.0 / [width, height].max, Math.sqrt(1_150_000.0 / (width * height))].min
  end

  screen_width, screen_height = 1512, 982

  # スクリーンショットをキャプチャする場合
  scale = get_scale_factor(screen_width, screen_height)
  scaled_width = (screen_width * scale).to_i
  scaled_height = (screen_height * scale).to_i

  # Claude に送信する前に、画像をスケーリング後のサイズにリサイズします
  screenshot = capture_and_resize(scaled_width, scaled_height)

  # Claude の座標を処理する場合は、元のスケールに拡大して戻します
  execute_click = ->(x, y) { perform_click(x / scale, y / scale) }
  ```
</CodeGroup>

<Note>
  **macOSのRetinaディスプレイ**は、デバイスピクセル比2でスクリーンショットをキャプチャするため、画像は論理的な画面座標の2倍の解像度になります。送信前にスクリーンショットを2分の1に縮小するか、クリックを実行する前にClaudeが返した座標を半分にしてください。
</Note>

ディスプレイ解像度を選択してスクリーンショットを返す際は、次の点に注意してください。

* 一般的なデスクトップタスクには1024x768または1280x720を、Webアプリケーションには1280x800または1366x768を使用します。
* パフォーマンスの問題を防ぐために、1920x1080を超える解像度は避けます。
* スクリーンショットはbase64のPNGまたはJPEGとしてエンコードし、パフォーマンス向上のために大きなスクリーンショットの圧縮を検討します。
* タイムスタンプやディスプレイの状態など、関連するメタデータを含めます。
* より高い解像度を使用する場合は、座標が正確にスケーリングされていることを確認します。

### スクリーンショット履歴を管理する

長いエージェントループでは、スクリーンショットがすぐに蓄積されます（1枚あたりおよそ1,000〜1,800入力トークン）。APIの[リクエスト制限](https://platform.claude.com/docs/ja/build-with-claude/vision#request-limits)も適用されます。1つのリクエストに20枚を超える画像が含まれると、そのリクエスト内のすべての画像に、より厳しい1辺あたりの制限が適用されます。スクリーンショット履歴を保持するループは数十ターン以内にこの枚数に達します。そのため、各スクリーンショットをどちらの辺も2000 pxを超えないようにリサイズするか、古いスクリーンショットを削除してリクエスト内の枚数を20枚以下に保ってください。

コンテキストを制限しながら[「prompt caching」（プロンプトキャッシング）](https://platform.claude.com/docs/ja/build-with-claude/prompt-caching)の効果を維持するには、次のようにします。

* 「system prompt」（システムプロンプト）とツール定義の後に`cache_control`ブレークポイントを1つ配置し、直近の各ターンの最後の`tool_result`ブロックに最大3つまで追加で配置して、ターンごとにそれらを進めます。[バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)内では、複数のブロックに付けたマーカーは1つのブレークポイントとして機能しますが、それぞれが4つという上限にカウントされるため、1ターンにつき1つを使用してください。
* 古いスクリーンショットは、毎ターン1枚ずつではなく*まとめて*削除します。毎ターンスクリーンショットを削除すると、毎ターンプレフィックスが変わり、キャッシュが無効になります。妥当なデフォルトは、直近3枚のスクリーンショットを保持し、25ターンごとに削除することです。これにより、削除のタイミングの間でプレフィックスがバイト単位で同一に保たれます。スクリーンショットのいずれかの辺が2000 pxを超える場合は、各リクエストの画像が20枚以下に収まる間隔を選択してください。
* Claude Fable 5.1、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5では、クライアント側での削除は避けてください。以前のスクリーンショットを削除すると、それらのターンをまだ含むすべてのリクエストで、[それ以降のすべての思考ブロックが無効になります](https://platform.claude.com/docs/ja/build-with-claude/thinking#preserved-in-conversation)。代わりに、スクリーンショットを1辺あたり2000 px以下にリサイズし、サーバー側の「[tool result clearing](https://platform.claude.com/docs/ja/build-with-claude/context-editing#tool-result-clearing)」（ツール結果のクリア）を使用して古いものをコンテキストから削除してください。どうしても削除する必要がある場合は、それ以降 [`prefix_mismatch_behavior: "drop_block"`](https://platform.claude.com/docs/ja/build-with-claude/thinking#preserved-thinking-controls) を設定したままにしてください。削除のたびに、Claudeはそのリクエストおよびそれ以降のすべてのリクエストで、削除されたスクリーンショット以降に生成された思考なしで処理を続行します。Claude Sonnet 5.5では、`block_binding` は `thinking: {"type": "adaptive"}` の場合にのみ機能します。`between_tools` を使用する場合は、履歴を追記のみに保つか、編集したターン以降の思考ブロックを取り除いてください。Claude Haiku 5.5では、`block_binding` は `thinking: {"type": "adaptive"}` の場合にのみ機能します。`thinking: {"type": "disabled"}` を使用する場合は、履歴を追記のみに保つか、編集したターン以降の思考ブロックを取り除いてください。

### クリックの問題を診断する

クリックが対象から外れる場合、原因は通常次のいずれかです。

| 症状                     | 考えられる原因                                                           | 試すこと                                                                                                                                                                                                                                                        |
| ---------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| クリックが一貫して一方向にずれる       | 返したスクリーンショットのピクセル空間におけるClaudeの座標が、スケーリングされずに異なるサイズのディスプレイに適用されている | クリックする前に、各座標を画面サイズとスクリーンショットサイズの比率でスケーリングします（[画像制限に合わせてスクリーンショットのサイズを調整する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)を参照）。macOSのRetinaディスプレイでは、2倍のデバイスピクセル比を考慮してください |
| クリックは正しい領域に着地するが対象を外す  | 対象が非常に小さい、4K以上のソースを縮小した際に詳細が失われた、またはアスペクト比が歪んでいる                  | `zoom`メンバーを有効にしたまま実装し、Claudeがその領域をフル解像度で確認できるようにします。より低いDPIでキャプチャするか、関連する領域に切り抜きます。リサイズ時にはアスペクト比を維持してください                                                                                                                                                   |
| Claudeがまったく別の要素をクリックする | 指示があいまい、または近くに視覚的に似た要素がある                                         | 位置を示すプロンプト（「右下の青いSubmitボタン」）を使用します。操作をより小さなステップに分割します                                                                                                                                                                                                       |
| 精度が一貫して低い              | 解像度が低すぎる                                                          | ベースラインとして1280x720を試してください                                                                                                                                                                                                                                   |

<Tip>
  **モデルの選択はクリックの精度に影響します。** 以前の`computer_20251124`ツールを使用するモデルの中では、Claude Sonnet 4.6はClaude Opus 4.6よりもクリックの機械的な精度が高く、スクリーンショットの大幅な縮小が必要な場合にもより堅牢です。Claude Opus 4.7はその差を縮めています。そのクリック精度はSonnet 4.6とほぼ同等であり、より高い解像度制限により必要な縮小が少なくて済みます。
</Tip>

### 実装のベストプラクティスに従う

<AccordionGroup>
  <Accordion title="アクションの遅延を追加する">
    一部のアプリケーションでは、アクションに応答するまでに時間が必要です。

    <CodeGroup exclude="shell">
      ```python Python
      def click_and_wait(x, y, wait_time=0.5):
          click_at(x, y)
          time.sleep(wait_time)  # Allow UI to update
      ```

      ```typescript TypeScript
      async function clickAndWait(x: number, y: number, waitMs = 500): Promise<void> {
        clickAt(x, y);
        await setTimeout(waitMs); // Allow UI to update
      }
      ```

      ```csharp C#
      static void ClickAndWait(int x, int y, double waitSeconds = 0.5)
      {
          ClickAt(x, y);
          Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));  // Allow UI to update
      }
      ```

      ```go Go
      func clickAndWaitFor(x, y int, wait time.Duration) {
      	clickAt(x, y)
      	time.Sleep(wait) // Allow UI to update
      }

      func clickAndWait(x, y int) {
      	clickAndWaitFor(x, y, 500*time.Millisecond)
      }
      ```

      ```java Java
      void clickAndWait(int x, int y) throws InterruptedException {
          clickAndWait(x, y, 500);
      }

      void clickAndWait(int x, int y, long waitTimeMillis) throws InterruptedException {
          clickAt(x, y);
          Thread.sleep(waitTimeMillis);  // Allow UI to update
      }
      ```

      ```php PHP
      function clickAndWait(int $x, int $y, float $waitSeconds = 0.5): void
      {
          clickAt($x, $y);
          usleep((int) ($waitSeconds * 1_000_000));  // Allow UI to update
      }
      ```

      ```ruby Ruby
      def click_and_wait(x, y, wait_time: 0.5)
        click_at(x, y)
        sleep(wait_time) # Allow UI to update
      end
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="実行前にアクションを検証する">
    要求されたアクションが安全かつ有効であることを確認します。

    <CodeGroup exclude="shell">
      ```python Python
      display_width, display_height = 1024, 768


      def validate_action(action_type, params):
          if action_type == "left_click" and "coordinate" in params:
              x, y = params["coordinate"]
              if not (0 <= x < display_width and 0 <= y < display_height):
                  return False, "Coordinates out of bounds"
          return True, None
      ```

      ```typescript TypeScript
      const displayWidth = 1024;
      const displayHeight = 768;

      interface ActionParams {
        coordinate?: [number, number];
      }

      function validateAction(actionType: string, params: ActionParams): [boolean, string | null] {
        if (actionType === "left_click" && params.coordinate) {
          const [x, y] = params.coordinate;
          if (!(x >= 0 && x < displayWidth && y >= 0 && y < displayHeight)) {
            return [false, "Coordinates out of bounds"];
          }
        }
        return [true, null];
      }
      ```

      ```csharp C#
      const int DisplayWidth = 1024;
      const int DisplayHeight = 768;
      // ...
      static (bool IsValid, string? Error) ValidateAction(string actionType, IReadOnlyDictionary<string, JsonElement> parameters)
      {
          if (actionType == "left_click" && parameters.TryGetValue("coordinate", out JsonElement coordinate))
          {
              int x = coordinate[0].GetInt32();
              int y = coordinate[1].GetInt32();
              if (x is < 0 or >= DisplayWidth || y is < 0 or >= DisplayHeight)
              {
                  return (false, "Coordinates out of bounds");
              }
          }
          return (true, null);
      }
      ```

      ```go Go
      const (
      	displayWidth  = 1024
      	displayHeight = 768
      )

      func validateAction(actionType string, params map[string]any) (bool, string) {
      	raw, hasCoordinate := params["coordinate"]
      	if actionType == "left_click" && hasCoordinate {
      		coord, ok := raw.([]any)
      		if !ok || len(coord) != 2 {
      			return false, "Invalid coordinate"
      		}
      		x, y := int(coord[0].(float64)), int(coord[1].(float64))
      		if !(0 <= x && x < displayWidth && 0 <= y && y < displayHeight) {
      			return false, "Coordinates out of bounds"
      		}
      	}
      	return true, ""
      }
      ```

      ```java Java
      static final int DISPLAY_WIDTH = 1024;
      static final int DISPLAY_HEIGHT = 768;

      record Validation(boolean valid, String error) {}

      Validation validateAction(String actionType, Map<String, JsonValue> params) {
          if (actionType.equals("left_click") && params.containsKey("coordinate")) {
              List<JsonValue> coord = (List<JsonValue>) params.get("coordinate").asArray().get();
              long x = ((Number) coord.get(0).asNumber().get()).longValue();
              long y = ((Number) coord.get(1).asNumber().get()).longValue();
              if (!(0 <= x && x < DISPLAY_WIDTH && 0 <= y && y < DISPLAY_HEIGHT)) {
                  return new Validation(false, "Coordinates out of bounds");
              }
          }
          return new Validation(true, null);
      }
      ```

      ```php PHP
      const DISPLAY_WIDTH = 1024;
      const DISPLAY_HEIGHT = 768;

      /** @return array{bool, ?string} */
      function validateAction(string $actionType, array $params): array
      {
          if ($actionType === 'left_click' && isset($params['coordinate'])) {
              [$x, $y] = $params['coordinate'];
              if (!(0 <= $x && $x < DISPLAY_WIDTH && 0 <= $y && $y < DISPLAY_HEIGHT)) {
                  return [false, 'Coordinates out of bounds'];
              }
          }
          return [true, null];
      }
      ```

      ```ruby Ruby
      DISPLAY_WIDTH = 1024
      DISPLAY_HEIGHT = 768

      def validate_action(action_type, params)
        if action_type == "left_click" && params.key?(:coordinate)
          x, y = params[:coordinate]
          unless (0...DISPLAY_WIDTH).cover?(x) && (0...DISPLAY_HEIGHT).cover?(y)
            return [false, "Coordinates out of bounds"]
          end
        end
        [true, nil]
      end
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="デバッグのためにアクションをログに記録する">
    トラブルシューティングのために、すべてのアクションのログを保持します。

    <CodeGroup exclude="shell">
      ```python Python
      import logging


      def log_action(action_type, params, result):
          logging.info(f"Action: {action_type}, Params: {params}, Result: {result}")
      ```

      ```typescript TypeScript
      function logAction(actionType: string, params: unknown, result: unknown): void {
        console.error(
          `Action: ${actionType}, Params: ${JSON.stringify(params)}, Result: ${JSON.stringify(
            result
          )}`
        );
      }
      ```

      ```csharp C#
      static void LogAction(string actionType, object? parameters, object? result)
      {
          Console.Error.WriteLine($"Action: {actionType}, Params: {parameters}, Result: {result}");
      }
      ```

      ```go Go
      func logAction(actionType string, params map[string]any, result any) {
      	log.Printf("Action: %s, Params: %v, Result: %v", actionType, params, result)
      }
      ```

      ```java Java
      import static java.lang.System.Logger.Level.INFO;

      static final System.Logger LOGGER = System.getLogger("computer-use");

      void logAction(String actionType, Object params, Object result) {
          LOGGER.log(INFO, "Action: {0}, Params: {1}, Result: {2}", actionType, params, result);
      }
      ```

      ```php PHP
      function logAction(string $actionType, array $params, mixed $result): void
      {
          error_log(sprintf(
              'Action: %s, Params: %s, Result: %s',
              $actionType,
              json_encode($params),
              json_encode($result),
          ));
      }
      ```

      ```ruby Ruby
      require "logger"

      LOGGER = Logger.new($stderr)

      def log_action(action_type, params, result)
        LOGGER.info("Action: #{action_type}, Params: #{params}, Result: #{result}")
      end
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

***

## `computer_20251124`から移行する

`computer_20251124`からツールセットへのアップグレードは任意です。[以前のツールバージョン](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions)で`computer_20251124`向けに記載されているモデルは、そのベータヘッダーとともに引き続きこれを受け付けるため、既存の統合は変更するまで動作し続けます。例外はClaude APIおよびGoogle Cloud上のClaude 5.5以降のモデルで、これらはツールセットのみを受け付けます。統合をそれらのモデルに移行する前にアップグレードしてください。Amazon Bedrockでは、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5は`computer_20251124`を受け付けます。アップグレードするには、次の変更をまとめて行います。

1. **ベータヘッダーを削除します。** リクエストから `anthropic-beta: computer-use-2025-11-24` を削除します。SDKでは、`betas` (csharp, go: `Betas`; java: `.addBeta()`) を削除し、ベータ名前空間ではなく標準クライアントを通じてMessages APIを呼び出します。
2. **`tools`エントリを変更します。** `type`を`computer_toolset_20260801`に設定し、`name`、`display_width_px`、`display_height_px`、`display_number`、`enable_zoom`を削除します。ツールセットはこれらの各フィールドを拒否します。
3. **ズームを有効のままにするかどうかを選択します。** ツールセットではズームがデフォルトで有効ですが、`enable_zoom`のデフォルトは`false`です。環境がズームを実装していない場合は、`"configs": {"zoom": {"enabled": false}}`を追加して以前の動作を維持してください。そうでない場合は、ズームを実装してください（[利用可能なアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#available-actions)を参照）。
4. **ターン内のすべてのブロックを処理します。** エージェントループを更新し、最初のブロックだけを読み取るのではなく、レスポンス内のすべての`tool_use`ブロックを反復処理するようにし、`input.action`ではなくブロックの`name`と`toolset_name`に基づいてディスパッチするようにします。メンバーの入力には`action`フィールドが含まれなくなりました。残りのフィールドは変更されていません。
5. **ブロックを順番に実行し、停止テキストを使用します。** [バッチアクション](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#batch-actions)で説明されているように、ブロックを順番に実行し、最初の失敗で停止し、残りのブロックには`Not executed: an earlier computer action in this turn failed.`で応答します。ループがまだバッチを実行できない場合は、[ツールパラメータ](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#tool-parameters)で、Claudeを1ターンにつき1アクションに制限する方法を説明しています。
6. **結果に`toolset_name`をエコーします。** メンバー呼び出しに応答するすべての`tool_result`に`"toolset_name": "computer"`を追加します。結果には`text`および`image`コンテンツのみを含めることができます。
7. **`key`で`repeat`をサポートします。** `key`メンバーは、1から100までのオプションの`repeat`回数を受け付けます。認識されないフィールドを無視するハンドラーはキーを1回しか押さないため、`key`ハンドラーが`repeat`に従うようにしてください。
8. **スクリーンショットを自分でリサイズします。** ツールセットは、モデルの画像制限を超えるスクリーンショットやズーム画像を縮小せずに拒否します。画像を返す前にリサイズし、[画像制限に合わせてスクリーンショットのサイズを調整する](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)で説明されているように座標のスケーリングを続けてください。
9. **サポートされていないオプションを削除します。** `defer_loading`がある場合はエントリから`configs`に移動し、有効なすべてのメンバーで同じ値を設定します。ツールセットエントリでサポートされていないその他のオプションは、[クライアントツールセット](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference#client-toolsets)に記載されています。

以下は変更前の`tools`エントリで、`anthropic-beta: computer-use-2025-11-24`ヘッダーとともに送信されます。

```json
{
  "type": "computer_20251124",
  "name": "computer",
  "display_width_px": 1024,
  "display_height_px": 768,
  "display_number": 1
}
```

以下は変更後の`tools`エントリで、ベータヘッダーなしで送信されます。`configs`オブジェクトは、`enable_zoom`を設定していない以前のエントリに合わせてズームをオフにしています。デフォルトを受け入れてClaudeにズームさせる場合は、`configs`を完全に省略してください。

```json
{
  "type": "computer_toolset_20260801",
  "configs": {
    "zoom": { "enabled": false }
  }
}
```

次のペアは、変更前と変更後の`tool_use`ブロックを示しています。アクション名は`input.action`から`name`に移動し、ブロックに`toolset_name`が追加されます。

```json
{
  "type": "tool_use",
  "id": "toolu_01A9r5kQm2LxWc7vT3nZ4bJs",
  "name": "computer",
  "input": { "action": "left_click", "coordinate": [500, 300] }
}
```

```json
{
  "type": "tool_use",
  "id": "toolu_01A9r5kQm2LxWc7vT3nZ4bJs",
  "name": "left_click",
  "toolset_name": "computer",
  "input": { "coordinate": [500, 300] }
}
```

## 以前のツールバージョン

コンピューター使用ツールの以前の2つのバージョンは、既存の統合、ツールセットをサポートしていないモデル、およびツールセットが現在利用できないプラットフォーム向けに、引き続きベータ版として利用できます。それぞれ、すべてのリクエストで対応する[ベータヘッダー](https://platform.claude.com/docs/ja/api/beta-headers)が必要であり、そのパラメータは[ベータ版Messages APIリファレンス](https://platform.claude.com/docs/ja/api/beta/messages/create)に記載されています。SDKでは、`betas` (csharp, go: `Betas`; java: `.addBeta()`) を通じてヘッダーを渡し、ベータ名前空間を使用します。ヘッダーが必要なのはコンピューター使用ツールのみで、同じリクエスト内のbashツールやテキストエディタツールには必要ありません。

| ツールバージョン            | ベータヘッダー                   | 使用するモデル                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | パラメータ                                                                     |
| ------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `computer_20251124` | `computer-use-2025-11-24` | Claude Fable 5.1、Claude Mythos 5.1、Claude Fable 5、Claude Mythos 5、Claude Opus 5、Claude Sonnet 5、Claude Opus 4.8、Claude Opus 4.7、Claude Opus 4.6、Claude Sonnet 4.6、Claude Opus 4.5。Amazon Bedrockでは、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5も対象                                                                                                                                                                                                                | [APIリファレンス](https://platform.claude.com/docs/ja/api/beta/messages/create) |
| `computer_20250124` | `computer-use-2025-01-24` | Claude Sonnet 4.5（[非推奨](https://platform.claude.com/docs/ja/about-claude/model-deprecations)）、Claude Haiku 4.5、Claude Opus 4.1（[廃止済み、BedrockおよびGoogle Cloudを除く](https://platform.claude.com/docs/ja/about-claude/model-deprecations)）、Claude Sonnet 4（[廃止済み、BedrockおよびGoogle Cloudを除く](https://platform.claude.com/docs/ja/about-claude/model-deprecations)）、Claude Opus 4（[廃止済み、Google Cloudを除く](https://platform.claude.com/docs/ja/about-claude/model-deprecations)） | [APIリファレンス](https://platform.claude.com/docs/ja/api/beta/messages/create) |

***

## 制限事項

1. **「latency」（レイテンシ）：** 人間とAIのインタラクションにおける現在のコンピューター使用のレイテンシは、人間が直接行う通常のコンピューター操作と比べて遅すぎる場合があります。信頼できる環境で、速度が重要ではないユースケース（たとえば、バックグラウンドでの情報収集、自動化されたソフトウェアテスト）に焦点を当ててください。
2. **コンピュータービジョンの精度と信頼性：** Claudeは、アクションを生成する際に特定の座標を出力するときに、誤りを犯したり「hallucination」（ハルシネーション）を起こしたりする可能性があります。Claudeの[要約された思考](https://platform.claude.com/docs/ja/build-with-claude/thinking#summarized-thinking)の出力は、モデルの推論を理解し、潜在的な問題を特定するのに役立ちます。ツールセットをサポートするモデルはデフォルトで思考テキストを省略するため、思考の設定で`display: "summarized"`を設定してください。
3. **ツール選択の精度と信頼性：** Claudeは、アクションを生成する際にツールを選択するときに誤りを犯したりハルシネーションを起こしたりする可能性があり、また問題を解決するために予期しないアクションを取る可能性があります。さらに、ニッチなアプリケーションや複数のアプリケーションを同時に操作する場合、信頼性が低下する可能性があります。複雑なタスクを依頼する場合は、モデルに慎重にプロンプトを与えてください。
4. **スクロールの信頼性：** スクロールアクションは、方向の制御（上、下、左、右）と指定した量をサポートしています。スクロールが効かないアプリケーションでは、Page Downなどのキーボードによる代替手段が役立つ場合があります。
5. **スプレッドシートの操作：** 個々のセルを選択するには、きめ細かなマウス制御アクション（`left_mouse_down`、`left_mouse_up`）と修飾キーの組み合わせを使用してください。複雑なスプレッドシート操作では、依然として複数回の試行が必要になる場合があります。
6. **ソーシャルおよびコミュニケーションプラットフォームでのアカウント作成とコンテンツ生成：** Claudeはウェブサイトにアクセスしますが、ソーシャルメディアのウェブサイトやプラットフォーム全体でアカウントを作成したり、コンテンツを生成・共有したり、その他の方法で人間になりすましたりする能力は制限されています。
7. **脆弱性：** 「jailbreak」（ジェイルブレイク）や「prompt injection」（プロンプトインジェクション）は、あらゆる最先端のAIシステムと同様に、ウェブページや画像に埋め込まれた指示を通じたものも含め、コンピューター使用に影響を与える可能性があります。[セキュリティに関する考慮事項](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/computer-use-tool#security-considerations)の予防措置を適用してください。
8. **不適切または違法なアクション：** Anthropicの利用規約に基づき、法律または利用ポリシーに違反するためにコンピューター使用を利用してはなりません。

Claudeのコンピューター使用のアクションとログは、常に慎重に確認・検証してください。人間による監督なしに、完全な精度を必要とするタスクや機密性の高いユーザー情報を扱うタスクにClaudeを使用しないでください。

## データ保持

コンピューター使用はクライアント側のツールです。セッションに関わるすべてのスクリーンショット、マウス操作、キーボード入力、およびファイルは、Anthropicではなくお客様の環境でキャプチャおよび保存されます。Anthropicは、API呼び出しの一部として、スクリーンショット画像とアクションリクエストをリアルタイムで処理します。これらのAPIリクエストの保持については、[APIとデータ保持](https://platform.claude.com/docs/ja/manage-claude/api-and-data-retention)に従います。

コンピューター使用のデータをどこにどのように保存するかはお客様のアプリケーションが制御するため、コンピューター使用はZDRの対象となります。すべての機能におけるZDRの対象については、[APIとデータ保持](https://platform.claude.com/docs/ja/manage-claude/api-and-data-retention)を参照してください。

## 料金

コンピュータ使用は標準の[ツール使用の料金](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/overview#pricing)に従います。コンピュータ使用ツールを使用する場合：

**ツールセット定義のオーバーヘッド：** `computer_toolset_20260801` をデフォルトのメンバーで宣言すると、リクエストに約4,500入力トークンが追加されます（Claude Sonnet 5では約4,590、その他のサポート対象モデルでは約4,520）。これには、メンバーツールの定義とツール使用のシステムプロンプトが含まれます。`configs` で `zoom` を無効にすると、そのうち約410トークンが削減されます。リクエストの正確なトークン数はレスポンスの `usage` で報告されます。また、[トークンカウントエンドポイント](https://platform.claude.com/docs/ja/build-with-claude/token-counting)を使用して事前に見積もることもできます。

**以前のツールバージョン：** 以下の数値は `computer_20251124` および `computer_20250124` ツールバージョンに適用され、`computer_toolset_20260801` には適用されません：

* システムプロンプトのオーバーヘッド：システムプロンプトに466〜499トークンが追加されます
* ツール定義：ツール定義ごとに約735入力トークン（`computer_20250124` で測定）

**追加のトークン消費：**

* ツール結果で返されるスクリーンショットおよびズーム画像。画像入力として課金されます（[ビジョンの料金](https://platform.claude.com/docs/ja/build-with-claude/vision#evaluate-image-size)を参照）
* Claudeに返されるツール実行結果

<Note>
  コンピュータ使用と併せてbashツールやテキストエディタツールも使用している場合、それらのツールにはそれぞれのページに記載されている独自のトークンコストがあります。
</Note>

## 次のステップ

<CardGroup cols={2}>
  <Card title="SDKのコンピューターツールセット" icon="code" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-sdk#computer-toolset">
    パートナーのドライバーから始めるか、PythonまたはTypeScriptで独自に作成してください。SDKがループと、渡した承認コールバックを実行します。
  </Card>

  <Card title="ツール使用のトラブルシューティング" icon="wrench" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/troubleshooting-tool-use">
    症状から修正方法を導く診断表を使って、最も一般的なツール使用のエラーを修正します。
  </Card>

  <Card title="リファレンス実装" icon="github-logo" href="https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo">
    Dockerベースの完全な実装で始めましょう
  </Card>

  <Card title="Claudeでのツール使用" icon="tool" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/overview">
    Claudeを外部ツールやAPIに接続します。ツールがどこで実行されるか、Claudeがいつそれらを呼び出すか、どのツールがタスクに適しているかを確認できます。
  </Card>

  <Card title="ベストプラクティスの詳細" icon="book" href="https://claude.com/blog/best-practices-for-computer-and-browser-use-with-claude">
    解像度、思考の労力、コンテキスト管理に関するベンチマークに基づく推奨事項
  </Card>

  <Card title="ブラウザ使用ツール" icon="browser" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/browser-use-tool">
    ブラウザ内で完結するタスクのために、Claudeがお客様自身のブラウザ環境でWebページを移動、閲覧、操作できるようにします。
  </Card>
</CardGroup>
