---
title: Инструмент использования компьютера
url: https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool
description: Предоставьте Claude управление рабочим столом через снимки экрана, мышь и клавиатуру с помощью инструмента использования компьютера — клиентского набора инструментов computer_toolset_20260801.
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/ru/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124). Чтобы перейти с `computer_20250124`, см. [Перенесите использование компьютера на набор инструментов](https://platform.claude.com/docs/ru/models/haiku-5-5/migration-guide#computer-use-toolset) в руководстве по миграции на Claude Haiku 5.5.
    - В Amazon Bedrock модели Claude Opus 5.5, Claude Sonnet 5.5 и Claude Haiku 5.5 принимают более раннюю версию инструмента `computer_20251124` так же, как Claude Opus 5 и Claude Sonnet 5.
    - Claude Opus 4.7, Claude Opus 4.6, Claude Sonnet 4.6 и Claude Opus 4.5 поддерживают использование компьютера только через более раннюю версию инструмента `computer_20251124`, для которой требуется бета-заголовок; см. [Более ранние версии инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions).
    - Платформы, отличные от Claude API и Google Cloud, в настоящее время предлагают только [более ранние бета-версии инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions).
---

<Note>
  **Начните с наборов инструментов SDK:** для `computer_toolset_20260801` в SDK для Python и TypeScript есть класс набора инструментов компьютера (в бета-версии). Начните с [интеграции партнёра](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/browser-use-sdk#partner-integrations) или см. раздел [Набор инструментов компьютера](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/browser-use-sdk#computer-toolset) на странице наборов инструментов SDK. Используйте эту страницу как справочник по инструменту или в случае, когда вы обрабатываете вызовы инструментов самостоятельно.
</Note>

Claude может взаимодействовать с компьютерными средами через инструмент «computer use» (использование компьютера), который предоставляет возможности создания снимков экрана и управления мышью/клавиатурой для автономного взаимодействия с рабочим столом.

Инструмент использования компьютера — это определённый Anthropic [клиентский набор инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/tool-reference#client-toolsets) («client toolset»): одна запись `{"type": "computer_toolset_20260801"}` в `tools` даёт Claude 17 инструментов-членов, таких как `screenshot`, `left_click`, `type` и `zoom`, а ваше приложение выполняет каждый вызов в среде, которую вы контролируете. В настоящее время он недоступен в [Claude Managed Agents](https://platform.claude.com/docs/ru/managed-agents/tools). Вызовы Claude представляют собой блоки `tool_use`, у которых `name` — это имя члена и которые содержат `"toolset_name": "computer"`, часто по несколько за ход ([пакетное действие](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#batch-actions)).

Для задач, которые не выходят за пределы веб-страниц, лучше подходит [инструмент использования браузера](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/browser-use-tool): его инструменты-члены читают саму страницу и действуют на ней, и ему не нужна полноценная среда рабочего стола.

<Note>
  Использование компьютера доступно в Claude API и [Google Cloud](https://platform.claude.com/docs/ru/build-with-claude/claude-on-vertex-ai) в виде набора инструментов `computer_toolset_20260801`; поддерживаемые модели см. в разделе [Совместимость](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#compatibility).

  Существующие интеграции с `computer_20251124` продолжают работать на моделях, перечисленных для этой версии в разделе [Более ранние версии инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions), а более ранние версии инструмента остаются доступными в бета-режиме для моделей и платформ, которые не поддерживают набор инструментов. Чтобы выполнить обновление, см. [Миграция с `computer_20251124`](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124), а бета-заголовки см. в разделе [Более ранние версии инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions).
</Note>

## Соображения безопасности

Использование компьютера несёт уникальные риски, отличные от стандартных функций API. Эти риски возрастают при взаимодействии с интернетом.

<Warning>
  Чтобы минимизировать риски, рассмотрите такие меры предосторожности, как:

  1. Использование выделенной виртуальной машины или контейнера с минимальными привилегиями для предотвращения прямых атак на систему или случайных инцидентов.
  2. Отказ от предоставления модели доступа к конфиденциальным данным, таким как учётные данные для входа в аккаунты, для предотвращения кражи информации.
  3. Ограничение доступа в интернет списком разрешённых доменов для снижения воздействия вредоносного контента.
  4. Обращение к человеку для подтверждения решений, которые могут привести к значимым последствиям в реальном мире, а также любых задач, требующих явного согласия, таких как принятие файлов cookie, совершение финансовых транзакций или согласие с условиями обслуживания.
</Warning>

В некоторых обстоятельствах Claude будет следовать командам, найденным в контенте, даже если они противоречат вашим инструкциям. Например, инструкции на веб-страницах или содержащиеся в изображениях могут переопределить ваши инструкции или привести к ошибкам Claude. Примите меры предосторожности, чтобы изолировать Claude от конфиденциальных данных и действий во избежание рисков, связанных с «prompt injection» (инъекцией подсказок).

Anthropic обучила модель противостоять таким внедрениям подсказок и добавила дополнительный уровень защиты. Если вы используете инструменты использования компьютера, классификаторы будут автоматически сканировать то, что возвращают инструменты, например снимки экрана, чтобы выявлять потенциальные внедрения подсказок. Когда эти классификаторы обнаруживают потенциальное внедрение подсказки, они автоматически направляют модель проверить, действительно ли инструкция исходит от вас, прежде чем действовать в соответствии с ней.

Эта дополнительная защита подойдёт не для каждого сценария использования (например, для сценариев без участия человека в цикле), поэтому, если вы хотите отказаться от неё и отключить её, [обратитесь в службу поддержки](https://support.claude.com/en/). Описанные выше меры предосторожности остаются важными даже при наличии этих классификаторов.

Информируйте конечных пользователей о соответствующих рисках и получайте их согласие перед включением использования компьютера в ваших собственных продуктах.

## Быстрый старт

Добавьте набор инструментов использования компьютера в массив `tools` запроса [Messages API](https://platform.claude.com/docs/ru/api/messages/create) в виде `{"type": "computer_toolset_20260801"}`. Запросу не нужен бета-заголовок. В этом примере также объявляются [инструмент текстового редактора](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/text-editor-tool) и [инструмент bash](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/bash-tool), которые Claude обычно использует вместе с использованием компьютера:

<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` и содержит один или несколько блоков `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_result` на каждый блок `tool_use` и снова вызывает API; раздел [Как работает использование компьютера](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#how-computer-use-works) описывает этот цикл, а остальная часть этой страницы показывает, как его реализовать.

***

## Как работает использование компьютера

<Steps>
  <Step title="Предоставьте Claude инструмент использования компьютера и пользовательскую подсказку">
    * Добавьте набор инструментов использования компьютера (и, при необходимости, другие инструменты) в массив `tools` вашего запроса к API.
    * Включите пользовательскую подсказку, требующую взаимодействия с рабочим столом, например: «Сохрани картинку с котом на мой рабочий стол».
  </Step>

  <Step title="Claude отвечает вызовами инструментов-членов">
    * Claude оценивает, может ли действие на рабочем столе помочь с запросом пользователя.
    * Если да, Claude отвечает одним или несколькими блоками `tool_use` для членов набора, такими как `screenshot`, `left_click` или `type`, каждый из которых содержит `"toolset_name": "computer"`. Ответ с несколькими такими блоками — это [пакетное действие](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#batch-actions).
    * Ответ API имеет `stop_reason` со значением `tool_use`, что сигнализирует о запросе на использование инструментов.
  </Step>

  <Step title="Выполните вызовы по порядку и верните результаты">
    * Переберите все блоки `tool_use` в ответе по порядку. Для каждого из них выполните диспетчеризацию по `name` члена вместе с `toolset_name` и выполните это действие с `input` блока в вашем контейнере или виртуальной машине.
    * Продолжите диалог новым сообщением `user`, содержащим по одному блоку `tool_result` на каждый блок `tool_use`, сопоставленному по `tool_use_id` и повторяющему `"toolset_name": "computer"`. Для `screenshot` и `zoom` возвращайте изображение; для остальных действий достаточно короткого текста, например `OK`.
    * Если действие завершилось неудачей, верните `is_error: true` для этого блока и ответьте на остальную часть пакета, как описано в разделе [Пакетные действия](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#batch-actions).
  </Step>

  <Step title="Claude продолжает, пока задача не будет выполнена">
    * Claude анализирует результаты инструментов, чтобы определить, нужны ли дополнительные действия или задача выполнена.
    * Если Claude определяет, что нужны дополнительные действия, он отвечает с `stop_reason` со значением `tool_use`, и вам следует вернуться к шагу 3.
    * В противном случае он возвращает пользователю текстовый ответ.
  </Step>
</Steps>

Повторение шагов 3 и 4 без участия пользователя называется «agent loop» (агентным циклом) — то есть Claude отвечает запросом на использование инструментов, а ваше приложение отвечает Claude результатами выполнения этого запроса.

### Пакетные действия

Claude может спланировать короткую последовательность действий, например щёлкнуть, ввести текст, а затем сделать снимок экрана, и вернуть их вместе в одном ответе. Это называется «batch action» (пакетным действием); оно использует ту же форму ответа, что и [параллельное использование инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/parallel-tool-use), с одним отличием: вы выполняете блоки по порядку, а не одновременно.

Ответ с пакетом из трёх действий выглядит так:

```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_result` на каждый блок `tool_use`, сопоставленному по `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/ru/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`, поэтому агентный цикл, который читает только первый блок, завершится ошибкой при следующем вызове. Если ваше приложение просит человека подтверждать значимые действия, выполняйте эту проверку перед запуском каждого блока, поскольку пакет может завершить многошаговое действие в рамках одного хода.

Обычно Claude завершает пакет действием `screenshot`, чтобы увидеть результат, прежде чем решить, что делать дальше. Если пакет не заканчивается скриншотом, ваше приложение может прикрепить скриншот в виде дополнительного блока `image` к последнему результату в пакете, чтобы Claude всегда видел текущее состояние экрана; это экономит один цикл запроса-ответа по сравнению с ожиданием, пока Claude сам его запросит. Вы также можете попросить Claude в подсказке завершать каждый пакет скриншотом (см. [Оптимизация производительности модели с помощью подсказок](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#optimize-model-performance-with-prompting)).

### Вычислительная среда

Использование компьютера требует изолированной вычислительной среды (песочницы), в которой Claude может безопасно взаимодействовать с приложениями и вебом. Эта среда включает:

1. **Виртуальный дисплей:** виртуальный сервер дисплея X11 (с использованием Xvfb), который отрисовывает интерфейс рабочего стола, который Claude будет видеть через снимки экрана и которым будет управлять с помощью действий мыши/клавиатуры.

2. **Среда рабочего стола:** лёгкий пользовательский интерфейс с оконным менеджером (Mutter) и панелью (Tint2), работающий на Linux, который предоставляет Claude единообразный графический интерфейс для взаимодействия.

3. **Приложения:** предустановленные приложения Linux, такие как Firefox, LibreOffice, текстовые редакторы и файловые менеджеры, которые Claude может использовать для выполнения задач.

4. **Реализации инструментов:** интеграционный код, который преобразует абстрактные запросы инструментов Claude (такие как «переместить мышь» или «сделать снимок экрана») в реальные операции в виртуальной среде.

5. **Агентный цикл:** программа, которая обеспечивает связь между Claude и средой, отправляя действия Claude в среду и возвращая результаты (снимки экрана, вывод команд) обратно Claude.

Когда вы используете использование компьютера, Claude не подключается к этой среде напрямую. Вместо этого ваше приложение:

1. Получает запросы Claude на использование инструментов
2. Преобразует их в действия в вашей вычислительной среде
3. Фиксирует результаты (такие как снимки экрана и вывод команд)
4. Возвращает эти результаты Claude

Для безопасности и изоляции эталонная реализация запускает всё это внутри контейнера Docker с соответствующими сопоставлениями портов для просмотра среды и взаимодействия с ней.

***

## Как реализовать использование компьютера

Обновляете существующую интеграцию `computer_20251124`? Начните с раздела [Миграция с `computer_20251124`](https://platform.claude.com/docs/ru/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), [агентный цикл](https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/computer_use_demo/loop.py), который вызывает Claude API и запускает инструменты, а также веб-интерфейс для контейнера, цикла и инструментов.
</Tip>

### Понимание агентного цикла

Ядро использования компьютера — это «агентный цикл»: цикл, в котором Claude запрашивает действия инструментов, ваше приложение выполняет их и возвращает результаты Claude. Цикл использует клиент, созданный вами в разделе [Быстрый старт](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#quick-start), массив `tools`, объявляющий только набор инструментов использования компьютера, и вспомогательную функцию обработки вызовов инструментов из раздела [Реализация инструмента использования компьютера](https://platform.claude.com/docs/ru/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

          # Отправляем все результаты обратно 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[]> {
    // Выполнять цикл агента computer-use, пока Claude не перестанет запрашивать инструменты
    // или не будет достигнут лимит итераций.
    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
  )
  {
      // Запускаем цикл агента computer-use, пока Claude не перестанет запрашивать инструменты
      // или не будет достигнут лимит итераций.
      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
  		}

  		// Отправляем все результаты обратно 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
  # Выполняйте цикл агента computer-use, пока 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

      # Отправьте все результаты обратно 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. Некоторыми элементами интерфейса (такими как выпадающие списки и полосы прокрутки) Claude может быть сложно управлять с помощью движений мыши. Если вы столкнулись с этим, попробуйте попросить модель использовать сочетания клавиш.
4. Для повторяющихся задач или взаимодействий с интерфейсом включайте в подсказку примеры снимков экрана и вызовов инструментов с успешными результатами.
5. Если вам нужно, чтобы модель выполнила вход в систему, укажите ей имя пользователя и пароль в подсказке внутри XML-тегов, таких как `<robot_credentials>`. Использование компьютера в приложениях, требующих входа в систему, повышает риск неблагоприятных исходов в результате инъекции подсказок. Ознакомьтесь с разделом [Противодействие джейлбрейкам и инъекциям подсказок](https://platform.claude.com/docs/ru/test-and-evaluate/strengthen-guardrails/mitigate-jailbreaks), прежде чем предоставлять модели учётные данные для входа.
6. При формировании массива `content` пользовательского хода размещайте текст инструкции *перед* изображением снимка экрана. Предоставление описания цели до обработки изображения повышает точность щелчков.
7. Claude использует действие `zoom` для изучения области в полном разрешении, когда его спрашивают о мелком тексте или конкретных элементах интерфейса, которые неразборчивы при стандартном разрешении снимка экрана, например об именах файлов на боковой панели, заголовках вкладок, тексте строки состояния, номерах строк или надписях на кнопках. Если Claude не использует масштабирование, когда вы этого ожидаете, спрашивайте о конкретной области или элементе, а не об экране в целом.
8. Если вы хотите, чтобы каждое [пакетное действие](https://platform.claude.com/docs/ru/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>
  Для агентов, работающих в нескольких сеансах, выполняйте сквозную проверку в начале каждого сеанса, а не только после реализации. Проверки через браузер выявляют регрессии из предыдущих сеансов, которые пропускает одна лишь проверка на уровне кода. Подробности см. в статье [Эффективные обвязки для долго работающих агентов](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents).
</Tip>

### Системные подсказки

Когда вы включаете инструмент использования компьютера в запрос, API генерирует «system prompt» (системную подсказку), специфичную для использования компьютера. Она похожа на [системную подсказку использования инструментов](https://platform.claude.com/docs/ru/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 называет член в блоке `tool_use`, содержащем `"toolset_name": "computer"`, а `input` блока содержит только параметры этого члена, без поля `action`. Набор инструментов содержит 17 инструментов-членов:

| Член                                                          | Входные данные                                                                                                                                                                                                                    | Описание                                                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `screenshot`                                                  | Нет (`{}`)                                                                                                                                                                                                                        | Захватить весь дисплей и вернуть его в виде изображения.                                                                                                                                                                                                                                                                        |
| `zoom`                                                        | `region`: `[x0, y0, x1, y1]`, верхний левый и нижний правый углы изучаемой области                                                                                                                                                | Захватить только эту область дисплея в полном разрешении и вернуть её в виде изображения, масштабированного так, чтобы оно помещалось в ваши обычные размеры снимка экрана с сохранением соотношения сторон. Это позволяет Claude читать мелкий текст или плотный интерфейс, неразборчивый на уменьшенном полном снимке экрана. |
| `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/ru/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)).
* **Все члены включены по умолчанию, включая `zoom`.** Если ваша среда не может создавать изображения масштабирования, исключите этот член с помощью `configs` (см. [Параметры инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#tool-parameters)), а не оставляйте его включённым и возвращайте ошибки. Если Claude вызывает член, который вы исключили или не реализовали, верните `tool_result` с `is_error: true` для этого блока.
* **Выполняйте диспетчеризацию по паре (`toolset_name`, `name`).** Именно `toolset_name` помечает блок как действие компьютера: пользовательский инструмент в том же запросе может иметь то же имя, что и член, а более поздняя версия набора инструментов может добавить члены (см. [Клиентские наборы инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/tool-reference#client-toolsets)).

<Accordion title="Примеры действий">
  Каждый пример — это полный блок `tool_use` в том виде, в котором он появляется в ответе Claude.

  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]
    }
  }
  ```

  Прокрутка вниз на три щелчка колеса:

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

  Нажатие Tab четыре раза:

  ```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` принимает четыре параметра; правила, общие с набором инструментов использования браузера, перечислены в разделе [Клиентские наборы инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/tool-reference#client-toolsets).

| Параметр          | Обязательный | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`            | Да           | `computer_toolset_20260801`                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `configs`         | Нет          | Настройки для отдельных членов с ключами по имени члена; каждый член принимает `enabled` (по умолчанию `true` для всех 17, включая `zoom`) и `defer_loading` (по умолчанию `false`, для [поиска инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/tool-search-tool#deferred-tool-loading)), а опущенные вами члены сохраняют значения по умолчанию.                                                                                          |
| `cache_control`   | Нет          | Точка останова [кэширования подсказок](https://platform.claude.com/docs/ru/build-with-claude/prompt-caching) на определении набора инструментов; только для записи. Точка останова на любом блоке `tool_use` или `tool_result` в пакете вступает в силу в конце этого пакета; см. [Использование инструментов с кэшированием подсказок](https://platform.claude.com/docs/ru/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" }
}
```

Если ваш агентный цикл может выполнять только одно действие за цикл обмена, установите `disable_parallel_tool_use` в `true` в `tool_choice`; тогда Claude возвращает не более одного блока `tool_use` члена за ход (см. [Отключение параллельного использования инструментов](https://platform.claude.com/docs/ru/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`: масштабирование — это инструмент-член, которым вы управляете через `configs`.

Запись также нельзя объявлять в одном запросе с записью `computer_20251124` или другим инструментом с именем `computer`. Сведения о `strict`, `input_examples`, размещении `defer_loading`, `tool_choice`, потоковой передаче и ограничениях вызывающих сторон см. в разделе [Клиентские наборы инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/tool-reference#client-toolsets).

### Сочетание с размышлениями

Чтобы сочетать использование компьютера с размышлениями, см. [Размышления](https://platform.claude.com/docs/ru/build-with-claude/thinking).

<Tip>
  Для более раннего инструмента `computer_20251124` внутреннее тестирование на моделях, которые его используют, предлагает следующие настройки `effort`:

  * **Claude Opus 4.7:** используйте `high` по умолчанию; используйте `low` для высокопроизводительных или чувствительных к стоимости рабочих нагрузок.
  * **Claude Sonnet 4.6 и Claude Opus 4.6:** используйте `medium` по умолчанию (лучшее соотношение точности и стоимости). Избегайте `max`, который увеличивает расход токенов, не повышая точность в задачах с интерфейсом. На этих моделях `low` использует *меньше* выходных токенов, чем полное отключение размышлений (меньше ошибок означает меньше повторных попыток), что делает его хорошим вариантом для чувствительных к стоимости циклов.
</Tip>

### Дополнение использования компьютера другими инструментами

Чтобы добавить другие инструменты вместе с использованием компьютера, включите их в тот же массив `tools`. Раздел [Быстрый старт](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#quick-start) показывает этот шаблон с [инструментом bash](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/bash-tool) и [инструментом текстового редактора](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/text-editor-tool). Таким же образом вы можете добавить собственные [определения пользовательских инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/define-tools).

Для задач, которые не выходят за пределы веб-страниц, вы также можете [объявить инструмент использования браузера в том же запросе](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/browser-use-tool#combine-with-other-tools): два набора инструментов работают независимо, каждый в своей системе координат, а вызовы членов с одинаковыми именами, таких как `screenshot` или `key`, различаются по `toolset_name`.

### Создание собственной среды использования компьютера

[Эталонная реализация](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo) призвана помочь вам начать работу с использованием компьютера. Она включает все компоненты, необходимые для того, чтобы Claude использовал компьютер. Однако вы можете создать собственную среду для использования компьютера в соответствии со своими потребностями. Вам понадобятся:

* Виртуализированная или контейнеризованная среда, подходящая для использования компьютера с Claude
* Реализация действий инструмента использования компьютера
* Агентный цикл, который взаимодействует с Claude API и выполняет результаты `tool_use` с помощью ваших реализаций инструментов
* API или пользовательский интерфейс, позволяющий пользовательскому вводу запускать агентный цикл

### Реализация инструмента использования компьютера

Инструмент использования компьютера реализован как инструмент без схемы. При использовании этого инструмента вам не нужно предоставлять входную схему, как для других инструментов; схема встроена в модель 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 заменяет реальный снимок: исполнитель возвращает
      // экран в виде PNG-данных, закодированных в base64.
      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 формирует результат для одного действия компьютера. В отличие от
      // обычного результата инструмента, он должен повторять имя набора инструментов.
      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_result на каждый блок tool_use. После первой ошибки пропускает
      // остальные: 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_result на каждый блок tool_use. После первой ошибки пропустите остальные:
      # 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="Реализуйте агентный цикл">
    Оберните два предыдущих шага в цикл, который отправляет результаты обратно и повторяется, пока Claude не перестанет возвращать вызовы инструментов-членов; раздел [Понимание агентного цикла](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#understanding-the-agentic-loop) показывает этот цикл на каждом языке.
  </Step>
</Steps>

### Обработка ошибок

Сообщайте Claude о неудавшемся действии в виде `tool_result` с `is_error: true` и кратким описанием и включайте `"toolset_name": "computer"`, как и в любом другом результате члена. Если неудавшееся действие было частью [пакетного действия](https://platform.claude.com/docs/ru/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/ru/build-with-claude/vision#evaluate-image-size) вашей модели: набор инструментов не принимает размеры дисплея, а API не уменьшает изображения за вас, поэтому слишком большое изображение в `tool_result` отклоняется с ошибкой валидации. Поскольку Claude возвращает координаты в пиксельном пространстве изображения, которое он видит, сохраняйте использованный коэффициент масштабирования, чтобы можно было сопоставить эти координаты обратно с вашим экраном.

<Note>
  Ограничения различаются в зависимости от модели. Claude Opus 4.7 и более поздние модели, включая все модели, поддерживающие `computer_toolset_20260801`, принимают до 2576 пикселей по длинной стороне и 4784 визуальных токена в сумме (`⌈width / 28⌉ × ⌈height / 28⌉`, приблизительно 3,75 мегапикселя); более ранние модели принимают до 1568 пикселей по длинной стороне и приблизительно 1,15 мегапикселя в сумме (уровень каждой модели см. в разделе [Разрешение и стоимость в токенах](https://platform.claude.com/docs/ru/build-with-claude/vision#evaluate-image-size)). В следующем примере используются ограничения более ранних моделей: 1568 пикселей / 1,15 МП. Для модели уровня высокого разрешения подбирайте размер под ограничение визуальных токенов, а не под общее количество пикселей, например с помощью вспомогательной функции изменения размера из раздела [Измените размер изображения перед загрузкой](https://platform.claude.com/docs/ru/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 раза перед отправкой, либо делите пополам координаты, возвращаемые Claude, перед выполнением щелчка.
</Note>

Когда вы выбираете разрешение дисплея и возвращаете снимки экрана:

* Для общих задач рабочего стола используйте 1024x768 или 1280x720; для веб-приложений используйте 1280x800 или 1366x768.
* Избегайте разрешений выше 1920x1080, чтобы предотвратить проблемы с производительностью.
* Кодируйте снимки экрана в base64 PNG или JPEG и рассмотрите сжатие больших снимков экрана для повышения производительности.
* Включайте соответствующие метаданные, такие как временная метка или состояние дисплея.
* Если вы используете более высокие разрешения, убедитесь, что координаты точно масштабируются.

### Управление историей скриншотов

Длинные агентные циклы быстро накапливают скриншоты (примерно 1 000–1 800 входных токенов каждый). Также применяются [ограничения запросов](https://platform.claude.com/docs/ru/build-with-claude/vision#request-limits) API. Как только один запрос содержит более 20 изображений, к каждому изображению в нём применяется более строгое ограничение на размер стороны. Цикл, сохраняющий историю скриншотов, достигает этого количества за несколько десятков ходов, поэтому либо изменяйте размер каждого скриншота так, чтобы ни одна сторона не превышала 2000 px, либо удаляйте старые скриншоты, чтобы в запросе оставалось не более 20.

Чтобы [кэширование подсказок](https://platform.claude.com/docs/ru/build-with-claude/prompt-caching) (prompt caching) оставалось эффективным при ограничении контекста:

* Разместите одну точку останова («breakpoint») `cache_control` после системной подсказки и определений инструментов. Ещё до трёх точек разместите на последнем блоке `tool_result` каждого из самых последних ходов и сдвигайте их на каждом ходу. В рамках [пакетного действия](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#batch-actions) маркеры на нескольких блоках действуют как одна точка останова, но каждый из них всё равно учитывается в лимите из четырёх, поэтому используйте по одному маркеру на ход.
* Удаляйте старые снимки экрана *пакетами*, а не по одному на каждом ходу. Удаление снимка на каждом ходу каждый раз меняет префикс и делает кэш недействительным. Разумное значение по умолчанию — хранить последние три снимка и выполнять удаление каждые 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/ru/build-with-claude/thinking#preserved-in-conversation) в каждом запросе, который всё ещё содержит эти ходы. Вместо этого уменьшайте снимки экрана до 2000 px или меньше по каждой стороне. Для удаления старых снимков из контекста используйте серверную [очистку результатов инструментов](https://platform.claude.com/docs/ru/build-with-claude/context-editing#tool-result-clearing). Если удаление всё же необходимо, с этого момента держите установленным [`prefix_mismatch_behavior: "drop_block"`](https://platform.claude.com/docs/ru/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/ru/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)); на дисплеях macOS Retina учитывайте двукратное соотношение пикселей устройства |
| Клики попадают в нужную область, но мимо цели | Цель очень мала, детали потеряны при уменьшении источника 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` на набор инструментов необязателен. Модели, перечисленные для `computer_20251124` в разделе [Более ранние версии инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions), продолжают принимать его с соответствующим бета-заголовком, поэтому существующая интеграция работает, пока вы её не измените. Исключение составляют модели Claude 5.5 и более поздние в Claude API и Google Cloud: там они принимают только набор инструментов. Обновите интеграцию, прежде чем переводить её на одну из этих моделей. В 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. **Решите, оставлять ли zoom включённым.** В наборе инструментов zoom включён по умолчанию, тогда как `enable_zoom` по умолчанию равен `false`. Если ваша среда не реализует zoom, добавьте `"configs": {"zoom": {"enabled": false}}`, чтобы сохранить прежнее поведение; в противном случае реализуйте его (см. [Доступные действия](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#available-actions)).
4. **Обрабатывайте каждый блок в ходе.** Обновите ваш агентный цикл так, чтобы он перебирал каждый блок `tool_use` в ответе, а не читал только первый, и выполнял диспетчеризацию по `name` блока вместе с `toolset_name`, а не по `input.action`. Входные данные элементов больше не содержат поля `action`; остальные поля не изменились.
5. **Выполняйте блоки по порядку и используйте текст остановки.** Выполняйте блоки последовательно, останавливайтесь при первой ошибке и отвечайте на оставшиеся блоки текстом `Not executed: an earlier computer action in this turn failed.`, как описано в разделе [Пакетные действия](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#batch-actions). Если ваш цикл пока не может выполнять пакеты, в разделе [Параметры инструмента](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#tool-parameters) объясняется, как ограничить Claude одним действием за ход.
6. **Возвращайте `toolset_name` в результатах.** Добавьте `"toolset_name": "computer"` в каждый `tool_result`, отвечающий на вызов элемента. Результаты могут содержать только содержимое `text` и `image`.
7. **Поддерживайте `repeat` для `key`.** Элемент `key` принимает необязательный счётчик `repeat` от 1 до 100. Обработчик, игнорирующий нераспознанные поля, нажал бы клавишу один раз, поэтому сделайте так, чтобы ваш обработчик `key` учитывал `repeat`.
8. **Изменяйте размер скриншотов самостоятельно.** Набор инструментов отклоняет скриншот или изображение zoom, превышающее ограничения изображений модели, вместо того чтобы уменьшать его. Изменяйте размер перед возвратом изображения и продолжайте масштабировать координаты, как описано в разделе [Подбор размера скриншотов под ограничения изображений](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions).
9. **Удалите неподдерживаемые параметры.** Перенесите любой `defer_loading` из записи в `configs` с одинаковым значением для каждого включённого элемента. Остальные параметры, не поддерживаемые в записях набора инструментов, перечислены в разделе [Клиентские наборы инструментов](https://platform.claude.com/docs/ru/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` оставляет zoom выключенным, чтобы соответствовать прежней записи, в которой `enable_zoom` не задан; полностью опустите `configs`, чтобы принять значение по умолчанию и позволить Claude использовать zoom:

```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] }
}
```

## Более ранние версии инструмента

Две более ранние версии инструмента использования компьютера остаются доступными в бета-версии. Они предназначены для существующих интеграций, для моделей, не поддерживающих набор инструментов, и для платформ, где набор инструментов пока недоступен. Каждая из них требует своего [бета-заголовка](https://platform.claude.com/docs/ru/api/beta-headers) в каждом запросе. Их параметры описаны в [справочнике по бета-версии Messages API](https://platform.claude.com/docs/ru/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/ru/api/beta/messages/create) |
| `computer_20250124` | `computer-use-2025-01-24` | Claude Sonnet 4.5 ([устарела](https://platform.claude.com/docs/ru/about-claude/model-deprecations)), Claude Haiku 4.5, Claude Opus 4.1 ([выведена из эксплуатации, кроме Bedrock и Google Cloud](https://platform.claude.com/docs/ru/about-claude/model-deprecations)), Claude Sonnet 4 ([выведена из эксплуатации, кроме Bedrock и Google Cloud](https://platform.claude.com/docs/ru/about-claude/model-deprecations)) и Claude Opus 4 ([выведена из эксплуатации, кроме Google Cloud](https://platform.claude.com/docs/ru/about-claude/model-deprecations)) | [Справочник API](https://platform.claude.com/docs/ru/api/beta/messages/create) |

***

## Ограничения

1. **Задержка:** Текущая задержка использования компьютера при взаимодействии человека и ИИ может быть слишком велика по сравнению с обычными действиями на компьютере, выполняемыми человеком. Сосредоточьтесь на сценариях, где скорость не критична (например, фоновый сбор информации, автоматизированное тестирование программного обеспечения), в доверенных средах.
2. **Точность и надёжность компьютерного зрения:** Claude может ошибаться или галлюцинировать при выводе конкретных координат во время генерации действий. Вывод [суммаризированных размышлений](https://platform.claude.com/docs/ru/build-with-claude/thinking#summarized-thinking) Claude может помочь вам понять рассуждения модели и выявить потенциальные проблемы; установите `display: "summarized"` в конфигурации размышлений, поскольку модели, поддерживающие набор инструментов, по умолчанию опускают текст размышлений.
3. **Точность и надёжность выбора инструментов:** Claude может ошибаться или галлюцинировать при выборе инструментов во время генерации действий либо предпринимать неожиданные действия для решения проблем. Кроме того, надёжность может быть ниже при взаимодействии с нишевыми приложениями или несколькими приложениями одновременно. Тщательно формулируйте подсказки для модели при запросе сложных задач.
4. **Надёжность прокрутки:** Действие прокрутки поддерживает управление направлением (вверх, вниз, влево, вправо) и заданную величину. В приложениях, где прокрутка не срабатывает, могут помочь клавиатурные альтернативы, такие как Page Down.
5. **Взаимодействие с электронными таблицами:** Используйте действия точного управления мышью (`left_mouse_down`, `left_mouse_up`) и комбинации с клавишами-модификаторами для выбора отдельных ячеек. Сложные операции с электронными таблицами всё ещё могут требовать нескольких попыток.
6. **Создание учётных записей и генерация контента на социальных и коммуникационных платформах:** Хотя Claude посещает веб-сайты, его способность создавать учётные записи, генерировать и публиковать контент или иным образом выдавать себя за человека на сайтах и платформах социальных сетей ограничена.
7. **Уязвимости:** Джейлбрейки и инъекции подсказок могут влиять на использование компьютера, как и на любую передовую систему ИИ, в том числе через инструкции, встроенные в веб-страницы или изображения; применяйте меры предосторожности из раздела [Соображения безопасности](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/computer-use-tool#security-considerations).
8. **Неприемлемые или незаконные действия:** В соответствии с Условиями обслуживания Anthropic вы не должны применять использование компьютера для нарушения каких-либо законов или Политики допустимого использования.

Всегда внимательно просматривайте и проверяйте действия и журналы использования компьютера Claude. Не используйте Claude для задач, требующих идеальной точности или работы с конфиденциальной информацией пользователей, без контроля со стороны человека.

## Хранение данных

Использование компьютера — это клиентский инструмент. Все скриншоты, действия мыши, ввод с клавиатуры и любые файлы, задействованные в сеансе, захватываются и хранятся в вашей среде, а не Anthropic. Anthropic обрабатывает изображения скриншотов и запросы действий в реальном времени в рамках вызова API. Хранение этих запросов API регулируется документом [API и хранение данных](https://platform.claude.com/docs/ru/manage-claude/api-and-data-retention).

Поскольку ваше приложение контролирует, где и как хранятся данные использования компьютера, использование компьютера соответствует требованиям ZDR. Сведения о соответствии ZDR для всех функций см. в разделе [API и хранение данных](https://platform.claude.com/docs/ru/manage-claude/api-and-data-retention).

## Цены

Использование компьютера следует стандартному [ценообразованию на использование инструментов](https://platform.claude.com/docs/ru/agents-and-tools/tool-use/overview#pricing). При использовании инструмента для работы с компьютером:

**Накладные расходы на определение набора инструментов:** Объявление `computer_toolset_20260801` с его членами по умолчанию добавляет к запросу около 4 500 входных токенов (около 4 590 на Claude Sonnet 5 и около 4 520 на других поддерживаемых моделях), которые покрывают определения инструментов-членов и системную подсказку для использования инструментов. Отключение `zoom` с помощью `configs` убирает около 410 из этих токенов. Точное количество для запроса указывается в поле `usage` ответа, а заранее его можно оценить с помощью [конечной точки подсчёта токенов](https://platform.claude.com/docs/ru/build-with-claude/token-counting).

**Более ранние версии инструмента:** Следующие цифры относятся к версиям инструмента `computer_20251124` и `computer_20250124`, а не к `computer_toolset_20260801`:

* Накладные расходы на системную подсказку: 466–499 токенов, добавляемых к системной подсказке
* Определение инструмента: около 735 входных токенов на одно определение инструмента (измерено с `computer_20250124`)

**Дополнительное потребление токенов:**

* Снимки экрана и увеличенные изображения, возвращаемые в результатах инструментов, тарифицируются как входные изображения (см. [ценообразование Vision](https://platform.claude.com/docs/ru/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/ru/agents-and-tools/tool-use/browser-use-sdk#computer-toolset">
    Начните с драйвера партнёра или напишите собственный на Python или TypeScript. SDK выполняет цикл и переданный вами обратный вызов подтверждения.
  </Card>

  <Card title="Устранение неполадок при использовании инструментов" icon="wrench" href="https://platform.claude.com/docs/ru/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/ru/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/ru/agents-and-tools/tool-use/browser-use-tool">
    Позвольте Claude переходить по веб-страницам, читать их и взаимодействовать с ними в вашей собственной браузерной среде — для задач, которые не выходят за пределы браузера.
  </Card>
</CardGroup>
