---
title: Herramienta de uso de computadora
url: https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool
description: Dale a Claude control de capturas de pantalla, mouse y teclado de un entorno de escritorio con la herramienta de uso de computadora, el conjunto de herramientas de cliente 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:
    - En la Claude API y Google Cloud, los modelos Claude 5.5 y posteriores admiten el uso de computadora solo a través del conjunto de herramientas `computer_toolset_20260801` y devuelven un error para las versiones anteriores de la herramienta `computer_20251124` y `computer_20250124`. Para migrar una integración existente, consulta [Migrar desde `computer_20251124`](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124). Para migrar desde `computer_20250124`, consulta [Migra el uso de computadora al conjunto de herramientas](https://platform.claude.com/docs/es/models/haiku-5-5/migration-guide#computer-use-toolset) en la guía de migración de Claude Haiku 5.5.
    - En Amazon Bedrock, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5 aceptan la versión anterior de la herramienta `computer_20251124` tal como lo hacen Claude Opus 5 y Claude Sonnet 5.
    - Claude Opus 4.7, Claude Opus 4.6, Claude Sonnet 4.6 y Claude Opus 4.5 admiten el uso de computadora solo a través de la versión anterior de la herramienta `computer_20251124`, que requiere un encabezado beta; consulta [Versiones anteriores de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions).
    - Las plataformas distintas de la Claude API y Google Cloud actualmente ofrecen solo las [versiones beta anteriores de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions).
---

<Note>
  **Comienza con los conjuntos de herramientas del SDK:** Para `computer_toolset_20260801`, los SDK de Python y TypeScript tienen una clase de conjunto de herramientas de computadora, en beta. Comienza desde [la integración de un socio](https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-sdk#partner-integrations), o consulta la sección [conjunto de herramientas de computadora](https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-sdk#computer-toolset) de la página de conjuntos de herramientas del SDK. Usa esta página como referencia de la herramienta, o cuando manejes tú mismo las llamadas a herramientas.
</Note>

Claude puede interactuar con entornos de computadora a través de la herramienta de "computer use" (uso de computadora), que proporciona capacidades de captura de pantalla y control de mouse/teclado para la interacción autónoma con el escritorio.

La herramienta de uso de computadora es un [conjunto de herramientas de cliente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference#client-toolsets) ("client toolset") definido por Anthropic: una entrada `{"type": "computer_toolset_20260801"}` en `tools` le da a Claude 17 herramientas miembro como `screenshot`, `left_click`, `type` y `zoom`, y tu aplicación ejecuta cada llamada en un entorno que tú controlas. Actualmente no está disponible en [Claude Managed Agents](https://platform.claude.com/docs/es/managed-agents/tools). Las llamadas de Claude son bloques `tool_use` cuyo `name` es el miembro y que llevan `"toolset_name": "computer"`, a menudo varios por turno (una [acción por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions)).

Para tareas que permanecen dentro de páginas web, la [herramienta de uso de navegador](https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-tool) es la opción más adecuada: sus herramientas miembro leen y actúan sobre la página misma, y no necesita un entorno de escritorio completo.

<Note>
  El uso de computadora está disponible en la Claude API y [Google Cloud](https://platform.claude.com/docs/es/build-with-claude/claude-on-vertex-ai) como el conjunto de herramientas `computer_toolset_20260801`; consulta [Compatibilidad](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#compatibility) para ver los modelos compatibles.

  Las integraciones existentes de `computer_20251124` siguen funcionando en los modelos indicados para esa versión en [Versiones anteriores de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions), y las versiones anteriores de la herramienta siguen disponibles en beta para los modelos y plataformas que no admiten el conjunto de herramientas. Consulta [Migrar desde `computer_20251124`](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124) para actualizar, o [Versiones anteriores de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions) para ver los encabezados beta.
</Note>

## Consideraciones de seguridad

El uso de computadora tiene riesgos únicos distintos de las funciones estándar de la API. Estos riesgos aumentan al interactuar con internet.

<Warning>
  Para minimizar los riesgos, considera tomar precauciones como:

  1. Usar una máquina virtual o contenedor dedicado con privilegios mínimos para prevenir ataques directos al sistema o accidentes.
  2. Evitar dar al modelo acceso a datos sensibles, como información de inicio de sesión de cuentas, para prevenir el robo de información.
  3. Limitar el acceso a internet a una lista de dominios permitidos para reducir la exposición a contenido malicioso.
  4. Pedir a un humano que confirme las decisiones que puedan tener consecuencias significativas en el mundo real y cualquier tarea que requiera consentimiento afirmativo, como aceptar cookies, completar transacciones financieras o aceptar términos de servicio.
</Warning>

En algunas circunstancias, Claude seguirá comandos encontrados en el contenido incluso cuando entren en conflicto con tus instrucciones. Por ejemplo, las instrucciones en páginas web o contenidas en imágenes podrían anular tus instrucciones o hacer que Claude cometa errores. Toma precauciones para aislar a Claude de datos y acciones sensibles para evitar riesgos relacionados con la inyección de prompts.

Anthropic ha entrenado al modelo para resistir estas inyecciones de prompts y ha añadido una capa adicional de defensa. Si usas las herramientas de uso de computadora, unos clasificadores analizarán automáticamente lo que devuelven las herramientas, como las capturas de pantalla, para señalar posibles inyecciones de prompts. Cuando estos clasificadores identifican una posible inyección de prompts, guiarán automáticamente al modelo para que verifique si la instrucción realmente provino de ti antes de actuar en consecuencia.

Esta protección adicional no será ideal para todos los casos de uso (por ejemplo, casos de uso sin una persona en el ciclo), así que si deseas excluirte y desactivarla, [contacta a soporte](https://support.claude.com/en/). Las precauciones anteriores siguen siendo importantes incluso con estos clasificadores en funcionamiento.

Informa a los usuarios finales de los riesgos relevantes y obtén su consentimiento antes de habilitar el uso de computadora en tus propios productos.

## Inicio rápido

Agrega el conjunto de herramientas de uso de computadora al arreglo `tools` de una solicitud de la [Messages API](https://platform.claude.com/docs/es/api/messages/create) como `{"type": "computer_toolset_20260801"}`. La solicitud no necesita encabezado beta. Este ejemplo también declara la [herramienta de editor de texto](https://platform.claude.com/docs/es/agents-and-tools/tool-use/text-editor-tool) y la [herramienta bash](https://platform.claude.com/docs/es/agents-and-tools/tool-use/bash-tool), que Claude normalmente usa junto con el uso de computadora:

<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>

Cuando Claude actúa sobre el escritorio, la respuesta tiene un `stop_reason` de `tool_use` y contiene uno o más bloques `tool_use` de miembros, cada uno nombrando una herramienta miembro y llevando `"toolset_name": "computer"`. A mitad de esta tarea, después de que Claude ha visto una captura de pantalla del escritorio, una respuesta podría verse así:

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

Tu aplicación ejecuta cada llamada en orden en tu propio entorno, devuelve un bloque `tool_result` por cada bloque `tool_use` y llama a la API de nuevo; [Cómo funciona el uso de computadora](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#how-computer-use-works) describe ese ciclo, y el resto de esta página muestra cómo implementarlo.

***

## Cómo funciona el uso de computadora

<Steps>
  <Step title="Proporciona a Claude la herramienta de uso de computadora y un prompt de usuario">
    * Agrega el conjunto de herramientas de uso de computadora (y opcionalmente otras herramientas) al arreglo `tools` de tu solicitud a la API.
    * Incluye un prompt de usuario que requiera interacción con el escritorio, por ejemplo, "Guarda una imagen de un gato en mi escritorio."
  </Step>

  <Step title="Claude responde con llamadas a herramientas miembro">
    * Claude evalúa si actuar sobre el escritorio puede ayudar con la consulta del usuario.
    * Si es así, Claude responde con uno o más bloques `tool_use` de miembros, como `screenshot`, `left_click` o `type`, cada uno con `"toolset_name": "computer"`. Una respuesta con varios de estos bloques es una [acción por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions).
    * La respuesta de la API tiene un `stop_reason` de `tool_use`, lo que indica una solicitud de uso de herramientas.
  </Step>

  <Step title="Ejecuta las llamadas en orden y devuelve los resultados">
    * Itera sobre cada bloque `tool_use` de la respuesta, en orden. Para cada uno, despacha según el `name` del miembro junto con `toolset_name`, y realiza esa acción con el `input` del bloque en tu contenedor o máquina virtual.
    * Continúa la conversación con un nuevo mensaje `user` que contenga un bloque `tool_result` por cada bloque `tool_use`, emparejados por `tool_use_id` y cada uno repitiendo `"toolset_name": "computer"`. Devuelve una imagen para `screenshot` y `zoom`; un texto breve como `OK` es suficiente para las demás acciones.
    * Si una acción falla, devuelve `is_error: true` para ese bloque y responde el resto del lote como se describe en [Acciones por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions).
  </Step>

  <Step title="Claude continúa hasta completar la tarea">
    * Claude analiza los resultados de las herramientas para determinar si se necesitan más acciones o si la tarea se ha completado.
    * Si Claude determina que se necesitan más acciones, responde con otro `stop_reason` de `tool_use` y debes volver al paso 3.
    * De lo contrario, devuelve una respuesta de texto al usuario.
  </Step>
</Steps>

La repetición de los pasos 3 y 4 sin intervención del usuario se conoce como el "agent loop" (ciclo del agente), es decir, Claude respondiendo con una solicitud de uso de herramientas y tu aplicación respondiendo a Claude con los resultados de evaluar esa solicitud.

### Acciones por lotes

Claude puede planificar una secuencia corta de acciones, como hacer clic, escribir y luego tomar una captura de pantalla, y devolverlas juntas en una sola respuesta. Esto se llama una "batch action" (acción por lotes); usa la misma forma de respuesta que el [uso de herramientas en paralelo](https://platform.claude.com/docs/es/agents-and-tools/tool-use/parallel-tool-use) con una diferencia: ejecutas los bloques en orden en lugar de concurrentemente.

Una respuesta con un lote de tres acciones se ve así:

```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": {}
    }
  ]
}
```

Devuelve un bloque `tool_result` por cada bloque `tool_use`, emparejados por `tool_use_id`, todos en el siguiente mensaje `user`. Cada resultado de una herramienta miembro debe llevar `"toolset_name": "computer"`; un resultado que lo omita, o que nombre un conjunto de herramientas diferente al de su bloque `tool_use`, es rechazado. Solo los resultados de `screenshot` y `zoom` necesitan una imagen; para los demás miembros, un breve acuse de recibo en texto como `OK` es suficiente (`cursor_position` devuelve las coordenadas como texto):

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

**Ejecuta los bloques en orden y detente en el primer fallo.** Las acciones posteriores en un lote normalmente dependen de las anteriores: el `type` en este ejemplo introduce texto en lo que sea que el clic anterior haya enfocado. Ejecuta los bloques secuencialmente en el orden en que aparecen en `content`, y si uno falla, no ejecutes el resto. Cada bloque `tool_use` aún necesita un `tool_result`, así que responde el lote de la siguiente manera:

* Para cada acción que tuvo éxito, devuelve su resultado normal.
* Para la acción que falló, devuelve `is_error: true` con una descripción en texto de lo que salió mal.
* Para cada acción posterior en el lote, devuelve `is_error: true` con exactamente este texto (la herramienta de uso de navegador usa su propio [texto de detención](https://platform.claude.com/docs/es/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 entonces ve qué acciones tuvieron éxito, cuál falló y cuáles se omitieron, y replanifica en su siguiente turno. Una solicitud que deje sin responder cualquier bloque `tool_use` del lote es rechazada con un `invalid_request_error`, por lo que un ciclo del agente que lea solo el primer bloque falla en su siguiente llamada. Si tu aplicación pide a un humano que confirme acciones con consecuencias, haz esa verificación antes de que se ejecute cada bloque, porque un lote puede completar una acción de varios pasos dentro de un solo turno.

Claude normalmente termina un lote con `screenshot` para poder observar el resultado antes de decidir qué hacer a continuación. Cuando un lote no termina con una, tu aplicación puede adjuntar una captura de pantalla como un bloque `image` adicional en el último resultado del lote para que Claude siempre vea el estado actual de la pantalla, lo que ahorra un viaje de ida y vuelta en comparación con esperar a que Claude la pida. También puedes indicarle a Claude que termine cada lote con una captura de pantalla (consulta [Optimiza el rendimiento del modelo con prompts](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#optimize-model-performance-with-prompting)).

### El entorno de cómputo

El uso de computadora requiere un entorno de cómputo aislado (sandbox) donde Claude pueda interactuar de forma segura con aplicaciones y la web. Este entorno incluye:

1. **Pantalla virtual:** Un servidor de pantalla virtual X11 (usando Xvfb) que renderiza la interfaz de escritorio que Claude verá a través de capturas de pantalla y controlará con acciones de mouse/teclado.

2. **Entorno de escritorio:** Una interfaz de usuario ligera con gestor de ventanas (Mutter) y panel (Tint2) ejecutándose en Linux, que proporciona una interfaz gráfica consistente con la que Claude puede interactuar.

3. **Aplicaciones:** Aplicaciones Linux preinstaladas como Firefox, LibreOffice, editores de texto y gestores de archivos que Claude puede usar para completar tareas.

4. **Implementaciones de herramientas:** Código de integración que traduce las solicitudes abstractas de herramientas de Claude (como "mover el mouse" o "tomar captura de pantalla") en operaciones reales en el entorno virtual.

5. **Ciclo del agente:** Un programa que maneja la comunicación entre Claude y el entorno, enviando las acciones de Claude al entorno y devolviendo los resultados (capturas de pantalla, salidas de comandos) a Claude.

Cuando usas el uso de computadora, Claude no se conecta directamente a este entorno. En su lugar, tu aplicación:

1. Recibe las solicitudes de uso de herramientas de Claude
2. Las traduce en acciones en tu entorno de cómputo
3. Captura los resultados (como capturas de pantalla y salidas de comandos)
4. Devuelve estos resultados a Claude

Por seguridad y aislamiento, la implementación de referencia ejecuta todo esto dentro de un contenedor Docker con los mapeos de puertos apropiados para ver e interactuar con el entorno.

***

## Cómo implementar el uso de computadora

¿Estás actualizando una integración existente de `computer_20251124`? Comienza con [Migrar desde `computer_20251124`](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#migrate-from-computer-20251124); el resto de esta sección aplica tanto a integraciones nuevas como migradas.

<Tip>
  La [implementación de referencia de uso de computadora](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo) es un ejemplo funcional completo: un [entorno en contenedor](https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/Dockerfile) adecuado para el uso de computadora, implementaciones de [las herramientas de uso de computadora](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo/computer_use_demo/tools), un [ciclo del agente](https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/computer_use_demo/loop.py) que llama a la Claude API y ejecuta las herramientas, y una interfaz web para el contenedor, el ciclo y las herramientas.
</Tip>

### Comprende el ciclo del agente

El núcleo del uso de computadora es el "ciclo del agente": un ciclo donde Claude solicita acciones de herramientas, tu aplicación las ejecuta y devuelve los resultados a Claude. El ciclo usa el cliente que creaste en el [Inicio rápido](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#quick-start), un arreglo `tools` que declara solo el conjunto de herramientas de uso de computadora, y el ayudante de procesamiento de llamadas a herramientas de [Implementa la herramienta de uso de computadora](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#implement-the-computer-use-tool). Si también declaras otras herramientas, como las herramientas bash y de editor de texto del Inicio rápido, despacha sus bloques `tool_use` en la misma pasada; el ayudante responde solo las llamadas a miembros de uso de computadora, y el ciclo trata un turno sin llamadas respondidas como terminado. Aquí hay un ejemplo simplificado:

<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,
          )

          # Agrega la respuesta de Claude al historial de la conversación
          messages.append({"role": "assistant", "content": response.content})

          # Ejecuta las acciones que Claude solicitó, en orden, y recopila los resultados
          tool_results = process_tool_calls(response)
          if not tool_results:
              return messages  # No more tool use; task complete

          # Envía todos los resultados de vuelta a Claude en un solo mensaje de usuario
          messages.append({"role": "user", "content": tool_results})

      return messages
  ```

  ```typescript TypeScript
  async function samplingLoop(
    model: string,
    messages: Anthropic.MessageParam[],
    maxIterations = 10
  ): Promise<Anthropic.MessageParam[]> {
    // Ejecuta el bucle del agente de uso de computadora hasta que Claude deje de solicitar herramientas
    // o se alcance el límite de iteraciones.
    for (let i = 0; i < maxIterations; i++) {
      const response = await client.messages.create({
        model,
        max_tokens: 4096,
        messages,
        tools
      });

      // Agrega la respuesta de Claude al historial de la conversación
      messages.push({ role: "assistant", content: response.content });

      // Ejecuta las herramientas que Claude solicitó y recopila los resultados
      const toolResults = processToolCalls(response);
      if (toolResults.length === 0) {
        return messages; // No more tool use; task complete
      }

      // Envía los resultados de las herramientas de vuelta a Claude para la siguiente iteración
      messages.push({ role: "user", content: toolResults });
    }

    return messages;
  }
  ```

  ```csharp C#
  async Task<List<MessageParam>> SamplingLoop(
      Model model,
      List<MessageParam> messages,
      int maxIterations = 10
  )
  {
      // Ejecuta el bucle del agente de uso de computadora hasta que Claude deje de solicitar herramientas
      // o se alcance el límite de iteraciones.
      for (var i = 0; i < maxIterations; i++)
      {
          var response = await client.Messages.Create(
              new MessageCreateParams
              {
                  Model = model,
                  MaxTokens = 4096,
                  Messages = messages,
                  Tools = tools,
              }
          );

          // Agrega la respuesta de Claude al historial de la conversación
          messages.Add(
              new()
              {
                  Role = Role.Assistant,
                  Content = response
                      .Content.Select(block => new ContentBlockParam(block.Json))
                      .ToList(),
              }
          );

          // Ejecuta las herramientas que Claude solicitó y recopila los resultados
          var toolResults = ProcessToolCalls(response);
          if (toolResults.Count == 0)
          {
              return messages; // No more tool use; task complete
          }

          // Envía los resultados de las herramientas de vuelta a Claude para la siguiente iteración
          messages.Add(new() { Role = Role.User, Content = toolResults });
      }

      return messages;
  }
  ```

  ```go Go
  // samplingLoop ejecuta el bucle del agente de uso de computadora hasta que Claude deja de
  // solicitar herramientas o se alcanza el límite de iteraciones.
  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
  		}

  		// Agrega la respuesta de Claude al historial de la conversación
  		messages = append(messages, response.ToParam())

  		// Ejecuta en orden las acciones que Claude solicitó y recopila los resultados
  		toolResults := processToolCalls(response)
  		if len(toolResults) == 0 {
  			return messages, nil // No more tool use; task complete
  		}

  		// Envía todos los resultados de vuelta a Claude en un solo mensaje de usuario
  		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());

          // Agrega la respuesta de Claude al historial de la conversación
          messages.add(MessageParam.builder()
                  .role(MessageParam.Role.ASSISTANT)
                  .contentOfBlockParams(response.content().stream().map(ContentBlock::toParam).toList())
                  .build());

          // Ejecuta las herramientas que Claude solicitó y recopila los resultados
          List<ContentBlockParam> toolResults = processToolCalls(response);
          if (toolResults.isEmpty()) {
              return messages; // No more tool use; task complete
          }

          // Envía los resultados de las herramientas de vuelta a Claude para la siguiente iteración
          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,
          );

          // Agrega la respuesta de Claude al historial de la conversación
          $messages[] = MessageParam::with(role: Role::ASSISTANT, content: $response->content);

          // Ejecuta las herramientas que Claude solicitó y recopila los resultados
          $toolResults = processToolCalls($response);
          if ($toolResults === []) {
              return $messages; // No more tool use; task complete
          }

          // Envía los resultados de las herramientas de vuelta a Claude para la siguiente iteración
          $messages[] = MessageParam::with(role: Role::USER, content: $toolResults);
      }

      return $messages;
  }
  ```

  ```ruby Ruby
  # Ejecuta el bucle del agente de uso de computadora hasta que Claude deje de solicitar herramientas
  # o se alcance el límite de iteraciones.
  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
      )

      # Agrega la respuesta de Claude al historial de la conversación
      messages << { role: "assistant", content: response.content }

      # Ejecuta en orden las acciones que Claude solicitó y recopila los resultados
      tool_results = process_tool_calls(response)
      return messages if tool_results.empty? # No more tool use; task complete

      # Envía todos los resultados de vuelta a Claude en un solo mensaje de usuario
      messages << { role: "user", content: tool_results }
    end

    messages
  end
  ```
</CodeGroup>

El ciclo continúa hasta que Claude responde sin solicitar ninguna herramienta (tarea completada) o se alcanza el límite máximo de iteraciones. Esta protección previene posibles ciclos infinitos que podrían resultar en costos de API inesperados.

### Optimiza el rendimiento del modelo con prompts

1. Especifica tareas simples y bien definidas y proporciona instrucciones explícitas para cada paso.
2. Claude a veces asume los resultados de sus acciones sin verificarlos explícitamente. Para evitarlo, puedes indicarle a 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. Algunos elementos de la interfaz (como menús desplegables y barras de desplazamiento) pueden ser difíciles de manipular para Claude usando movimientos del mouse. Si experimentas esto, intenta indicarle al modelo que use atajos de teclado.
4. Para tareas o interacciones de interfaz repetibles, incluye en tu prompt capturas de pantalla de ejemplo y llamadas a herramientas de resultados exitosos.
5. Si necesitas que el modelo inicie sesión, proporciónale el nombre de usuario y la contraseña en tu prompt dentro de etiquetas XML como `<robot_credentials>`. Usar el uso de computadora dentro de aplicaciones que requieren inicio de sesión aumenta el riesgo de malos resultados como consecuencia de la inyección de prompts. Revisa [Mitigar jailbreaks e inyecciones de prompts](https://platform.claude.com/docs/es/test-and-evaluate/strengthen-guardrails/mitigate-jailbreaks) antes de proporcionar al modelo credenciales de inicio de sesión.
6. Al construir el arreglo `content` de un turno de usuario, coloca el texto de la instrucción *antes* de la imagen de la captura de pantalla. Proporcionar la descripción del objetivo antes de que se procese la imagen mejora la precisión de los clics.
7. Claude usa la acción `zoom` para inspeccionar una región a resolución completa cuando se le pregunta sobre texto pequeño o elementos específicos de la interfaz que no son legibles a la resolución predeterminada de la captura de pantalla, como nombres de archivos en una barra lateral, títulos de pestañas, texto de la barra de estado, números de línea o etiquetas de botones. Si Claude no hace zoom cuando lo esperas, pregunta sobre una región o elemento específico en lugar de la pantalla en su conjunto.
8. Si quieres que cada [acción por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions) termine con una captura de pantalla, dilo en la indicación del sistema, por ejemplo, `End each group of actions with a screenshot so you can verify the result before continuing.`

<Tip>
  Si encuentras repetidamente un conjunto claro de problemas o sabes de antemano las tareas que Claude necesitará completar, usa la indicación del sistema para proporcionar a Claude consejos o instrucciones explícitas sobre cómo realizar las tareas con éxito.
</Tip>

<Tip>
  Para agentes que abarcan múltiples sesiones, ejecuta una verificación de extremo a extremo al inicio de cada sesión, no solo después de la implementación. Las verificaciones basadas en navegador detectan regresiones de sesiones anteriores que la revisión a nivel de código por sí sola no detecta. Consulta [Arneses efectivos para agentes de larga duración](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents) para más detalles.
</Tip>

### Indicaciones del sistema

Cuando incluyes la herramienta de uso de computadora en una solicitud, la API genera una "system prompt" (indicación del sistema) específica para el uso de computadora. Es similar a la [indicación del sistema de uso de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/define-tools#tool-use-system-prompt) pero comienza con:

> 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.

Al igual que con el uso de herramientas regular, el parámetro `system` proporcionado por el usuario se sigue respetando y se usa en la construcción de la indicación del sistema combinada.

### Acciones disponibles

Cada acción es una herramienta miembro del conjunto de herramientas de uso de computadora: Claude nombra al miembro en un bloque `tool_use` que lleva `"toolset_name": "computer"`, y el `input` del bloque contiene solo los parámetros de ese miembro, sin campo `action`. El conjunto de herramientas tiene 17 herramientas miembro:

| Miembro                                                       | Entrada                                                                                                                                                                                                                | Descripción                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `screenshot`                                                  | Ninguna (`{}`)                                                                                                                                                                                                         | Captura la pantalla completa y la devuelve como imagen.                                                                                                                                                                                                                                                                                        |
| `zoom`                                                        | `region`: `[x0, y0, x1, y1]`, las esquinas superior izquierda e inferior derecha del área a inspeccionar                                                                                                               | Captura solo esa región de la pantalla a resolución completa y la devuelve como imagen, escalada para ajustarse a las dimensiones habituales de tus capturas de pantalla con su relación de aspecto preservada. Esto permite a Claude leer texto pequeño o interfaces densas que no son legibles en una captura de pantalla completa reducida. |
| `left_click`                                                  | `coordinate` (opcional): `[x, y]`; `text` (opcional): teclas modificadoras a mantener durante el clic: `shift`, `ctrl`, `alt`, `super` (la tecla Command o Windows), o una combinación unida con `+` como `ctrl+shift` | Hace clic con el botón izquierdo del mouse en `coordinate`, o en la posición actual del cursor cuando se omite `coordinate`.                                                                                                                                                                                                                   |
| `right_click`, `middle_click`, `double_click`, `triple_click` | Igual que `left_click`                                                                                                                                                                                                 | Otros botones del mouse y clics múltiples.                                                                                                                                                                                                                                                                                                     |
| `left_click_drag`                                             | `start_coordinate`: `[x, y]`; `coordinate`: `[x, y]`; `text` (opcional): teclas modificadoras                                                                                                                          | Presiona en `start_coordinate`, arrastra hasta `coordinate` y suelta.                                                                                                                                                                                                                                                                          |
| `mouse_move`                                                  | `coordinate`: `[x, y]`                                                                                                                                                                                                 | Mueve el cursor sin hacer clic, por ejemplo, para pasar por encima (hover).                                                                                                                                                                                                                                                                    |
| `left_mouse_down`, `left_mouse_up`                            | Ninguna (`{}`)                                                                                                                                                                                                         | Presiona o suelta el botón izquierdo del mouse en la posición actual del cursor, para arrastres que `left_click_drag` no puede expresar. Mueve el cursor con `mouse_move` primero.                                                                                                                                                             |
| `cursor_position`                                             | Ninguna (`{}`)                                                                                                                                                                                                         | Reporta la posición actual `[x, y]` del cursor como texto.                                                                                                                                                                                                                                                                                     |
| `scroll`                                                      | `scroll_direction`: `"up"`, `"down"`, `"left"` o `"right"`; `scroll_amount`: número de clics de la rueda de desplazamiento; `coordinate` (opcional): `[x, y]`; `text` (opcional): teclas modificadoras                 | Desplaza en `coordinate`, o en la posición actual del cursor.                                                                                                                                                                                                                                                                                  |
| `type`                                                        | `text`: la cadena a escribir                                                                                                                                                                                           | Escribe texto literal en el foco actual del teclado.                                                                                                                                                                                                                                                                                           |
| `key`                                                         | `text`: una tecla o una combinación unida con `+` como `"Return"`, `"ctrl+s"` o `"alt+Tab"`; `repeat` (opcional): 1 a 100, predeterminado 1                                                                            | Presiona una tecla o combinación de teclas, `repeat` veces.                                                                                                                                                                                                                                                                                    |
| `hold_key`                                                    | `text`: una tecla o combinación; `duration`: segundos, hasta 300                                                                                                                                                       | Mantiene una tecla presionada durante la duración dada.                                                                                                                                                                                                                                                                                        |
| `wait`                                                        | `duration`: segundos, hasta 300                                                                                                                                                                                        | Pausa antes de la siguiente acción, por ejemplo, mientras se carga una aplicación.                                                                                                                                                                                                                                                             |

Ten en cuenta lo siguiente al implementar los miembros:

* **Las coordenadas están en píxeles de la captura de pantalla.** Cada valor de `coordinate`, `start_coordinate` y `region`, y la posición que reporta `cursor_position`, está en el espacio de píxeles de las capturas de pantalla completas que devuelves, con el origen en la esquina superior izquierda. Las imágenes de zoom no cambian esto: después de un `zoom`, Claude sigue expresando las coordenadas en el espacio de la captura de pantalla completa, nunca relativas a la imagen ampliada. Si reduces las capturas de pantalla antes de devolverlas, escala las coordenadas de Claude de vuelta hacia arriba antes de aplicarlas a la pantalla real (consulta [Dimensiona las capturas de pantalla para ajustarse a los límites de imagen](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)).
* **Todos los miembros están habilitados por defecto, incluido `zoom`.** Si tu entorno no puede producir imágenes de zoom, retén el miembro con `configs` (consulta [Parámetros de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#tool-parameters)) en lugar de dejarlo habilitado y devolver errores. Si Claude llama a un miembro que has retenido o que no implementas, devuelve un `tool_result` con `is_error: true` para ese bloque.
* **Despacha según el par (`toolset_name`, `name`).** `toolset_name` es lo que marca un bloque como una acción de computadora: una herramienta personalizada en la misma solicitud puede compartir el nombre de un miembro, y una versión posterior del conjunto de herramientas puede agregar miembros (consulta [Conjuntos de herramientas de cliente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference#client-toolsets)).

<Accordion title="Acciones de ejemplo">
  Cada ejemplo es un bloque `tool_use` completo tal como aparece en la respuesta de Claude.

  Shift+clic en una posición, por ejemplo, para extender una selección. A diferencia de `hold_key`, `text` mantiene los modificadores solo durante la duración de ese clic o desplazamiento:

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

  Arrastrar de un punto a otro:

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

  Desplazar hacia abajo tres clics de la rueda:

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

  Presionar Tab cuatro veces:

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

  Hacer zoom para inspeccionar una región a resolución completa:

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

  Reportar la posición del cursor. Responde esta llamada con un resultado de texto corto que dé la posición en píxeles de la captura de pantalla, por ejemplo, `X=512, Y=384`:

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

### Parámetros de la herramienta

La entrada del conjunto de herramientas en el arreglo `tools` acepta cuatro parámetros; las reglas que comparten con el conjunto de herramientas de uso de navegador se enumeran en [Conjuntos de herramientas de cliente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference#client-toolsets).

| Parámetro         | Requerido | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`            | Sí        | `computer_toolset_20260801`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `configs`         | No        | Configuraciones por miembro indexadas por nombre de miembro; cada miembro acepta `enabled` (predeterminado `true` para los 17, incluido `zoom`) y `defer_loading` (predeterminado `false`, para la [búsqueda de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-search-tool#deferred-tool-loading)), y los miembros que omitas mantienen sus valores predeterminados.                                                                                                                            |
| `cache_control`   | No        | Punto de interrupción de [almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching) en la definición del conjunto de herramientas; solo en la entrada. Un punto de interrupción en cualquier bloque `tool_use` o `tool_result` de un lote tiene efecto al final de ese lote; consulta [Uso de herramientas con almacenamiento en caché de prompts](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-use-with-prompt-caching#cache-control-on-tool-definitions). |
| `allowed_callers` | No        | Solo `["direct"]`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

Por ejemplo, esta entrada retiene `zoom` para un entorno que no lo implementa y establece un punto de interrupción de caché en la definición del conjunto de herramientas:

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

Si tu ciclo del agente solo puede ejecutar una acción por viaje de ida y vuelta, establece `disable_parallel_tool_use` en `true` en `tool_choice`; Claude entonces devuelve como máximo un bloque `tool_use` de miembro por turno (consulta [Deshabilitar el uso de herramientas en paralelo](https://platform.claude.com/docs/es/agents-and-tools/tool-use/parallel-tool-use#disable-parallel-tool-use)).

La entrada rechaza estos parámetros de versiones anteriores de la herramienta, y una solicitud que incluya cualquiera de ellos devuelve un `invalid_request_error`:

* `name`: los nombres de los miembros están fijados por la versión del conjunto de herramientas.
* `display_width_px`, `display_height_px` y `display_number`: las coordenadas siempre están en el espacio de píxeles de las capturas de pantalla que devuelves.
* `enable_zoom`: zoom es una herramienta miembro que controlas a través de `configs`.

La entrada tampoco puede declararse en la misma solicitud que una entrada `computer_20251124` u otra herramienta llamada `computer`. Para `strict`, `input_examples`, la ubicación de `defer_loading`, `tool_choice`, streaming y restricciones de llamador, consulta [Conjuntos de herramientas de cliente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference#client-toolsets).

### Combinación con el pensamiento

Para combinar el uso de computadora con el pensamiento, consulta [Pensamiento](https://platform.claude.com/docs/es/build-with-claude/thinking).

<Tip>
  Para la herramienta anterior `computer_20251124`, las pruebas comparativas internas en los modelos que la usan sugieren estas configuraciones de `effort`:

  * **Claude Opus 4.7:** usa `high` como predeterminado; usa `low` para cargas de trabajo de alto rendimiento o sensibles al costo.
  * **Claude Sonnet 4.6 y Claude Opus 4.6:** usa `medium` como predeterminado (mejor relación precisión-costo). Evita `max`, que añade costo de tokens sin mejorar la precisión en tareas de interfaz. En estos modelos, `low` usa *menos* tokens de salida que deshabilitar el pensamiento por completo (menos errores significan menos reintentos), lo que lo convierte en una opción sólida para ciclos sensibles al costo.
</Tip>

### Aumentar el uso de computadora con otras herramientas

Para agregar otras herramientas junto con el uso de computadora, inclúyelas en el mismo arreglo `tools`. La sección de [Inicio rápido](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#quick-start) muestra este patrón con la [herramienta bash](https://platform.claude.com/docs/es/agents-and-tools/tool-use/bash-tool) y la [herramienta de editor de texto](https://platform.claude.com/docs/es/agents-and-tools/tool-use/text-editor-tool). Puedes agregar tus propias [definiciones de herramientas personalizadas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/define-tools) de la misma manera.

Para tareas que permanecen dentro de páginas web, también puedes [declarar la herramienta de uso de navegador en la misma solicitud](https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-tool#combine-with-other-tools): los dos conjuntos de herramientas funcionan de forma independiente, cada uno en su propio marco de coordenadas, y las llamadas a miembros que comparten nombre, como `screenshot` o `key`, se distinguen por `toolset_name`.

### Construye un entorno de uso de computadora personalizado

La [implementación de referencia](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo) está pensada para ayudarte a comenzar con el uso de computadora. Incluye todos los componentes necesarios para que Claude use una computadora. Sin embargo, puedes construir tu propio entorno para el uso de computadora que se adapte a tus necesidades. Necesitarás:

* Un entorno virtualizado o en contenedor adecuado para el uso de computadora con Claude
* Una implementación de las acciones de la herramienta de uso de computadora
* Un ciclo del agente que interactúe con la Claude API y ejecute los resultados de `tool_use` usando tus implementaciones de herramientas
* Una API o interfaz de usuario que permita la entrada del usuario para iniciar el ciclo del agente

### Implementa la herramienta de uso de computadora

La herramienta de uso de computadora se implementa como una herramienta sin esquema. Al usar esta herramienta, no necesitas proporcionar un esquema de entrada como con otras herramientas; el esquema está integrado en el modelo de Claude y no puede modificarse.

<Steps>
  <Step title="Configura tu entorno de cómputo">
    Crea una pantalla virtual o conéctate a una pantalla existente con la que Claude interactuará. Esto normalmente implica configurar Xvfb (X Virtual Framebuffer) o una tecnología similar.
  </Step>

  <Step title="Implementa los manejadores de acciones">
    Crea funciones para manejar cada tipo de acción que Claude podría solicitar:

    <CodeGroup exclude="shell">
      ```python Python
      # Datos de imagen de marcador de posición; un ejecutor real captura la pantalla y devuelve los bytes PNG
      PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="


      def capture_screenshot() -> list[ImageBlockParam]:
          # screenshot responde con un bloque de imagen en lugar de texto: devuelve la lista de contenido del resultado
          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 es opcional; sin él, haz clic donde ya está el cursor
                  return click(tool_input.get("coordinate"))
              case "type":
                  return type_text(tool_input["text"])
          # Maneja otras acciones según sea necesario
          raise ValueError(f"Unknown or unimplemented member: {name}")
      ```

      ```typescript TypeScript
      // Datos de imagen de marcador de posición; un ejecutor real captura la pantalla como bytes PNG
      const PLACEHOLDER_PNG =
        "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";

      function captureScreenshot(): Anthropic.ImageBlockParam[] {
        // screenshot responde con un bloque de imagen en lugar de texto
        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 es opcional en el conjunto de herramientas; sin ella, se hace clic en la posición del cursor
            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;
        }
        // Maneja otras acciones según sea necesario
        throw new Error(`Unknown or unimplemented member: ${action}`);
      }
      ```

      ```csharp C#
      // Datos de imagen de marcador de posición; un ejecutor real captura la pantalla y devuelve los bytes PNG
      const string PlaceholderPng = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";

      // screenshot responde con un bloque de imagen en lugar de texto: devuelve la lista de contenido del resultado
      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 es opcional en los miembros de click; sin él, haz clic donde esté el cursor
              "left_click" when input.TryGetValue("coordinate", out var xy) => ClickAt(
                  xy[0].GetInt32(),
                  xy[1].GetInt32()
              ),
              "left_click" => ClickAtCursor(),
              "type" => TypeText(input["text"].GetString()!),
              // Maneja otras acciones según sea necesario
              _ => throw new NotSupportedException($"Unknown or unimplemented member: {action}"),
          };
      ```

      ```go Go
      // placeholderPNG sustituye a una captura real: un ejecutor devuelve la
      // pantalla como datos PNG codificados en base64.
      const placeholderPNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="

      // captureScreenshot devuelve un bloque de imagen en lugar de texto.
      func captureScreenshot() []anthropic.ToolResultBlockParamContentUnion {
      	return []anthropic.ToolResultBlockParamContentUnion{{
      		OfImage: &anthropic.ImageBlockParam{
      			Source: anthropic.ImageBlockParamSourceUnion{
      				OfBase64: &anthropic.Base64ImageSourceParam{
      					MediaType: anthropic.Base64ImageSourceMediaTypeImagePNG,
      					Data:      placeholderPNG,
      				},
      			},
      		},
      	}}
      }

      // textContent envuelve texto como contenido de 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 es opcional; sin él, haz clic donde ya está el cursor
      		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
      		}
      	// Maneja otras acciones según sea necesario
      	default:
      		return nil, fmt.Errorf("unknown or unimplemented member: %s", action)
      	}
      	// Se alcanza cuando al input de un miembro le falta un campo o un campo tiene el tipo incorrecto
      	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());
              // Maneja otras acciones según sea necesario
              default -> throw new UnsupportedOperationException("Unknown or unimplemented member: " + action);
          };
          return ToolResultBlockParam.Content.ofString(output);
      }
      ```

      ```php PHP
      // Sustituto de bytes PNG reales; un ejecutor real captura la pantalla
      const PLACEHOLDER_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';

      function captureScreenshot(): array
      {
          // screenshot responde con un bloque de imagen en lugar de texto, así que devuelve la lista de contenido del resultado
          $image = [
              'type' => 'image',
              'source' => ['type' => 'base64', 'media_type' => 'image/png', 'data' => PLACEHOLDER_PNG],
          ];

          return [$image];
      }

      function clickAt(?array $coordinate): string
      {
          // left_click puede omitir coordinate, en cuyo caso el clic ocurre donde ya está el cursor
          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']),
              // Maneja otras acciones según sea necesario
              default => throw new \RuntimeException("Unknown or unimplemented member: {$name}"),
          };
      }
      ```

      ```ruby Ruby
      # Datos de imagen de relleno; un ejecutor real captura la pantalla como PNG.
      PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="

      # screenshot responde con un bloque de imagen en lugar de texto
      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 es opcional; sin él, haz clic donde ya está el cursor
          click(input[:coordinate])
        when "type"
          type_text(input[:text])
        # Maneja otras acciones según sea necesario
        else
          raise ArgumentError, "Unknown or unimplemented member: #{name}"
        end
      end
      ```
    </CodeGroup>
  </Step>

  <Step title="Procesa las llamadas a herramientas de Claude">
    Extrae y ejecuta las llamadas a herramientas de las respuestas de 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:
              # Solo se declara el conjunto de herramientas computer; enruta otras herramientas aquí si las agregas
              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:
                      # Una cadena, o una lista de bloques de contenido como la imagen de la captura de pantalla
                      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") {
            // Este ejemplo declara solo el conjunto de herramientas computer; enruta otras herramientas
            // aquí si las agregas.
            continue;
          }
          if (failed) {
            // Un lote se detiene en su primer fallo; responde las acciones posteriores como no ejecutadas
            toolResults.push(computerResult(block.id, HALT_TEXT, true));
            continue;
          }
          try {
            // Una cadena, o la lista de bloques de imagen que devuelve 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")
              {
                  // Este ejemplo declara solo el conjunto de herramientas de computadora; enruta otras herramientas
                  // aquí si las agregas.
                  continue;
              }

              if (failed)
              {
                  // Un lote se detiene en su primer fallo; responde las acciones posteriores sin ejecutarlas
                  toolResults.Add(
                      new ToolResultBlockParam(toolUse.ID)
                      {
                          Content = HaltText,
                          IsError = true,
                          ToolsetName = "computer",
                      }
                  );
                  continue;
              }

              try
              {
                  // Una cadena, o la lista de bloques de imagen que devuelve 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 construye el resultado de una acción de computadora. A diferencia de un
      // resultado de herramienta ordinario, debe repetir el nombre del toolset.
      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 ejecuta en orden las acciones de computadora de la respuesta de Claude y
      // construye un tool_result por cada bloque tool_use. Tras el primer fallo omite
      // el resto: Claude las planeó asumiendo que las acciones anteriores tuvieron éxito.
      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:
      			// Este ejemplo declara solo el toolset de computadora; enruta aquí otras herramientas si las agregas.
      			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 {
      				// Texto, o el bloque de imagen que devuelve 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()) {
              // Este ejemplo declara solo el conjunto de herramientas de computadora; enruta aquí otras herramientas si las agregas.
              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();
                      // Una cadena, o el bloque de imagen que devuelve 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) {
              // Este ejemplo declara solo el conjunto de herramientas computer; enruta otras herramientas aquí si las agregas.
              if (!($block instanceof \Anthropic\Messages\ToolUseBlock) || $block->toolsetName !== 'computer') {
                  continue;
              }
              $result = ['type' => 'tool_result', 'tool_use_id' => $block->id, 'toolset_name' => 'computer'];
              if ($failed) {
                  // Un lote se detiene en su primer fallo; las acciones restantes se responden sin ejecutarse
                  $toolResults[] = [...$result, 'content' => HALT_TEXT, 'is_error' => true];
                  continue;
              }
              try {
                  // Una cadena, o la lista de bloques de imagen que devuelve 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."

      # Ejecuta en orden las acciones de computadora de la respuesta de Claude y crea un
      # tool_result por cada bloque tool_use. Tras el primer fallo, omite el resto:
      # Claude las planificó asumiendo que las acciones anteriores tuvieron éxito.
      def process_tool_calls(response)
        tool_results = []
        failed = false
        response.content.each do |block|
          # Este ejemplo declara solo el conjunto de herramientas de computadora; enruta aquí otras herramientas
          # si las agregas.
          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
              # Un String, o los bloques de contenido de imagen que devuelve 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="Implementa el ciclo del agente">
    Envuelve los dos pasos anteriores en un ciclo que envíe los resultados de vuelta y se repita hasta que Claude no devuelva llamadas a herramientas miembro; [Comprende el ciclo del agente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#understanding-the-agentic-loop) muestra este ciclo en cada lenguaje.
  </Step>
</Steps>

### Maneja los errores

Reporta una acción fallida a Claude como un `tool_result` con `is_error: true` y una descripción corta, e incluye `"toolset_name": "computer"` como en cualquier otro resultado de miembro. Si la acción fallida era parte de una [acción por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions), responde los bloques restantes del lote con el texto de detención mostrado allí en lugar de ejecutarlos.

Por ejemplo, cuando falla la captura de pantalla:

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

Usa la misma forma para coordenadas fuera de los límites de la pantalla y para acciones que no logran ejecutarse, con un mensaje que diga qué salió mal.

### Dimensiona las capturas de pantalla para ajustarse a los límites de imagen

Las capturas de pantalla y las imágenes de zoom que devuelves al conjunto de herramientas de uso de computadora ya deben ajustarse a los [límites de tamaño de imagen](https://platform.claude.com/docs/es/build-with-claude/vision#evaluate-image-size) de tu modelo: el conjunto de herramientas no recibe dimensiones de pantalla y la API no reduce la escala por ti, por lo que una imagen de `tool_result` demasiado grande es rechazada con un error de validación. Dado que Claude devuelve coordenadas en el espacio de píxeles de la imagen que ve, conserva el factor de escala que usaste para poder mapear esas coordenadas de vuelta a tu pantalla.

<Note>
  Los límites varían según el modelo. Claude Opus 4.7 y modelos posteriores, incluidos todos los modelos que admiten `computer_toolset_20260801`, aceptan hasta 2576 píxeles en el lado largo y 4784 tokens visuales en total (`⌈width / 28⌉ × ⌈height / 28⌉`, aproximadamente 3.75 megapíxeles); los modelos anteriores aceptan hasta 1568 píxeles en el lado largo y aproximadamente 1.15 megapíxeles en total (consulta [Resolución y costo de tokens](https://platform.claude.com/docs/es/build-with-claude/vision#evaluate-image-size) para el nivel de cada modelo). El siguiente ejemplo usa los límites de 1568 px / 1.15 MP de los modelos anteriores. Para un modelo del nivel de alta resolución, dimensiona según el límite de tokens visuales en lugar de un total de píxeles, por ejemplo con el ayudante de redimensionamiento en [Redimensiona tu imagen antes de subirla](https://platform.claude.com/docs/es/build-with-claude/vision-coordinates#resize-your-image-before-uploading).
</Note>

Si tu pantalla es más grande que el límite, redimensiona cada captura de pantalla antes de devolverla y escala las coordenadas devueltas por Claude de vuelta al espacio original de la pantalla. Dado que el conjunto de herramientas no recibe dimensiones de pantalla, el redimensionamiento y el escalado de coordenadas en el código de tu aplicación son todo lo que necesitas:

<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)


  # Al capturar la captura de pantalla
  scale = get_scale_factor(screen_width, screen_height)
  scaled_width = int(screen_width * scale)
  scaled_height = int(screen_height * scale)

  # Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  screenshot = capture_and_resize(scaled_width, scaled_height)


  # Al manejar las coordenadas de Claude, vuelve a escalarlas hacia arriba
  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);
  }

  // Al capturar la captura de pantalla
  const scale = getScaleFactor(screenWidth, screenHeight);
  const scaledWidth = Math.floor(screenWidth * scale);
  const scaledHeight = Math.floor(screenHeight * scale);

  // Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  const screenshot = captureAndResize(scaledWidth, scaledHeight);

  // Al manejar las coordenadas de Claude, vuelve a escalarlas hacia arriba
  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)
  {
      // Calcula el factor de escala para cumplir con las restricciones de la 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));
  }

  // Al capturar una captura de pantalla
  double scale = GetScaleFactor(screenWidth, screenHeight);
  int scaledWidth = (int)(screenWidth * scale);
  int scaledHeight = (int)(screenHeight * scale);

  // Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  var screenshot = CaptureAndResize(scaledWidth, scaledHeight);

  // Al manejar las coordenadas de Claude, vuelve a escalarlas al tamaño original
  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

  	// Al capturar la pantalla
  	scale := getScaleFactor(screenWidth, screenHeight)
  	scaledWidth := int(float64(screenWidth) * scale)
  	scaledHeight := int(float64(screenHeight) * scale)

  	// Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  	screenshot := captureAndResize(scaledWidth, scaledHeight)

  	// Al manejar las coordenadas de Claude, vuelve a escalarlas hacia arriba
  	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;

      // Al capturar la pantalla
      double scale = getScaleFactor(screenWidth, screenHeight);
      int scaledWidth = (int)(screenWidth * scale);
      int scaledHeight = (int)(screenHeight * scale);

      // Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
      var screenshot = captureAndResize(scaledWidth, scaledHeight);

      // Al manejar las coordenadas de Claude, vuelve a escalarlas hacia arriba
      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;

  // Al capturar la captura de pantalla
  $scale = getScaleFactor($screenWidth, $screenHeight);
  $scaledWidth = (int)($screenWidth * $scale);
  $scaledHeight = (int)($screenHeight * $scale);

  // Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  $screenshot = captureAndResize($scaledWidth, $scaledHeight);

  // Al manejar las coordenadas de Claude, vuelve a escalarlas al tamaño original
  $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

  # Al capturar una captura de pantalla
  scale = get_scale_factor(screen_width, screen_height)
  scaled_width = (screen_width * scale).to_i
  scaled_height = (screen_height * scale).to_i

  # Redimensiona la imagen a las dimensiones escaladas antes de enviarla a Claude
  screenshot = capture_and_resize(scaled_width, scaled_height)

  # Al manejar las coordenadas de Claude, vuelve a escalarlas al tamaño original
  execute_click = ->(x, y) { perform_click(x / scale, y / scale) }
  ```
</CodeGroup>

<Note>
  **Las pantallas Retina de macOS** capturan las capturas de pantalla con una relación de píxeles del dispositivo de 2, por lo que la imagen tiene el doble de resolución que las coordenadas lógicas de la pantalla. Reduce la captura de pantalla 2x antes de enviarla, o divide a la mitad las coordenadas que Claude devuelve antes de emitir el clic.
</Note>

Cuando elijas una resolución de pantalla y devuelvas capturas de pantalla:

* Para tareas generales de escritorio, usa 1024x768 o 1280x720; para aplicaciones web, usa 1280x800 o 1366x768.
* Evita resoluciones superiores a 1920x1080 para prevenir problemas de rendimiento.
* Codifica las capturas de pantalla como PNG o JPEG en base64, y considera comprimir las capturas de pantalla grandes para mejorar el rendimiento.
* Incluye metadatos relevantes como la marca de tiempo o el estado de la pantalla.
* Si usas resoluciones más altas, asegúrate de que las coordenadas estén escaladas con precisión.

### Gestionar el historial de capturas de pantalla

Los bucles de agente largos acumulan capturas de pantalla rápidamente (aproximadamente entre 1,000 y 1,800 tokens de entrada cada una). También se aplican los [límites de solicitud](https://platform.claude.com/docs/es/build-with-claude/vision#request-limits) de la API. Una vez que una sola solicitud contiene más de 20 imágenes, cada imagen en ella queda sujeta a un límite por lado más estricto. Un bucle que conserva su historial de capturas de pantalla alcanza ese número en unas pocas docenas de turnos, así que redimensiona cada captura de pantalla para que ningún lado supere los 2000 px o elimina las capturas de pantalla más antiguas para mantener 20 o menos en la solicitud.

Para mantener efectivo el [almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching) mientras limitas el contexto:

* Coloca un punto de interrupción `cache_control` después de la indicación del sistema y las definiciones de herramientas, y hasta tres más en el último bloque `tool_result` de cada uno de los turnos más recientes, avanzándolos en cada turno. Dentro de una [acción por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions), los marcadores en varios bloques actúan como un único punto de interrupción, pero cada uno sigue contando para el límite de cuatro, así que usa uno por turno.
* Elimina las capturas de pantalla antiguas *por lotes*, no una en cada turno. Descartar una captura de pantalla en cada turno cambia el prefijo en cada turno e invalida la caché. Un valor predeterminado razonable es conservar las últimas tres capturas de pantalla y hacer la eliminación cada 25 turnos, de modo que el prefijo permanezca idéntico byte a byte entre eventos de eliminación; si tus capturas de pantalla superan los 2000 px en cualquiera de sus lados, elige un intervalo que mantenga cada solicitud en 20 imágenes o menos.
* En Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5, evita eliminar capturas en el cliente: quitar una captura de pantalla anterior [invalida todos los "thinking blocks" (bloques de pensamiento) posteriores](https://platform.claude.com/docs/es/build-with-claude/thinking#preserved-in-conversation) en cada solicitud que todavía contenga esos turnos. En su lugar, redimensiona las capturas de pantalla a 2000 px o menos por lado y usa la [eliminación de resultados de herramientas](https://platform.claude.com/docs/es/build-with-claude/context-editing#tool-result-clearing) del lado del servidor para quitar las antiguas del contexto. Si debes eliminarlas, mantén [`prefix_mismatch_behavior: "drop_block"`](https://platform.claude.com/docs/es/build-with-claude/thinking#preserved-thinking-controls) configurado a partir de ese momento; después de cada eliminación, Claude continúa sin el pensamiento producido desde la captura de pantalla eliminada, en esa solicitud y en todas las posteriores. En Claude Sonnet 5.5, `block_binding` funciona solo con `thinking: {"type": "adaptive"}`. Con `between_tools`, mantén el historial en modo de solo anexar, o quita los bloques de pensamiento desde el turno editado en adelante. En Claude Haiku 5.5, `block_binding` funciona solo con `thinking: {"type": "adaptive"}`; con `thinking: {"type": "disabled"}`, mantén el historial en modo de solo anexar, o quita los bloques de pensamiento desde el turno editado en adelante.

### Diagnosticar problemas de clics

Si los clics no aciertan en sus objetivos, la causa suele ser una de las siguientes:

| Síntoma                                                            | Causa probable                                                                                                                                                                | Prueba                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Los clics se desplazan consistentemente en una dirección           | Las coordenadas de Claude, que están en el espacio de píxeles de las capturas de pantalla que devuelves, se están aplicando a una pantalla de un tamaño diferente sin escalar | Escala cada coordenada por la proporción entre el tamaño de tu pantalla y el tamaño de tu captura de pantalla antes de hacer clic (consulta [Dimensionar capturas de pantalla para ajustarse a los límites de imagen](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions)); en pantallas Retina de macOS, ten en cuenta la proporción de píxeles del dispositivo de 2x |
| Los clics caen en el área correcta pero no aciertan en el objetivo | El objetivo es muy pequeño, se perdió detalle al reducir una fuente 4K+, o la relación de aspecto se distorsionó                                                              | Mantén habilitado el miembro `zoom` e impleméntalo para que Claude pueda inspeccionar la región a resolución completa; captura a un DPI más bajo o recorta a la región relevante; conserva la relación de aspecto al redimensionar                                                                                                                                                                                                                   |
| Claude hace clic en un elemento completamente equivocado           | Instrucción ambigua, o elementos visualmente similares cercanos                                                                                                               | Usa prompts posicionales ("el botón azul Submit en la esquina inferior derecha"); divide la interacción en pasos más pequeños                                                                                                                                                                                                                                                                                                                        |
| La precisión es consistentemente baja                              | Resolución demasiado baja                                                                                                                                                     | Prueba 1280x720 como línea base                                                                                                                                                                                                                                                                                                                                                                                                                      |

<Tip>
  **La elección del modelo afecta la precisión de los clics.** Entre los modelos que usan la herramienta anterior `computer_20251124`, Claude Sonnet 4.6 es mecánicamente más preciso al hacer clic que Claude Opus 4.6 y es más robusto cuando las capturas de pantalla requieren una reducción considerable. Claude Opus 4.7 reduce esa brecha: su precisión de clic es aproximadamente comparable a la de Sonnet 4.6, y su límite de resolución más alto significa que se necesita menos reducción.
</Tip>

### Seguir las mejores prácticas de implementación

<AccordionGroup>
  <Accordion title="Agregar retrasos entre acciones">
    Algunas aplicaciones necesitan tiempo para responder a las acciones:

    <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="Validar las acciones antes de ejecutarlas">
    Verifica que las acciones solicitadas sean seguras y válidas:

    <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="Registrar acciones para depuración">
    Mantén un registro de todas las acciones para la resolución de problemas:

    <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>

***

## Migrar desde `computer_20251124`

Actualizar de `computer_20251124` al conjunto de herramientas es opcional: los modelos listados para `computer_20251124` en [Versiones anteriores de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions) siguen aceptándola con su encabezado beta, así que una integración existente sigue funcionando hasta que la cambies. Claude 5.5 y los modelos posteriores son la excepción en la Claude API y Google Cloud: allí solo aceptan el conjunto de herramientas. Actualiza una integración antes de moverla a uno de ellos. En Amazon Bedrock, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5 aceptan `computer_20251124`. Para actualizar, realiza los siguientes cambios en conjunto:

1. **Elimina el encabezado beta.** Quita `anthropic-beta: computer-use-2025-11-24` de tus solicitudes. Con el SDK, elimina `betas` (csharp, go: `Betas`; java: `.addBeta()`) y llama a la Messages API a través del cliente estándar en lugar del espacio de nombres beta.
2. **Cambia la entrada de `tools`.** Establece `type` en `computer_toolset_20260801` y elimina `name`, `display_width_px`, `display_height_px`, `display_number` y `enable_zoom`. El conjunto de herramientas rechaza cada uno de estos campos.
3. **Elige si mantener el zoom habilitado.** El zoom está habilitado de forma predeterminada en el conjunto de herramientas, mientras que `enable_zoom` tiene como valor predeterminado `false`. Si tu entorno no implementa el zoom, agrega `"configs": {"zoom": {"enabled": false}}` para mantener el comportamiento anterior; de lo contrario, impleméntalo (consulta [Acciones disponibles](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#available-actions)).
4. **Maneja cada bloque en un turno.** Actualiza tu bucle de agente para iterar sobre cada bloque `tool_use` en una respuesta en lugar de leer solo el primero, y para despachar según el `name` del bloque junto con `toolset_name` en lugar de según `input.action`. Las entradas de los miembros ya no contienen un campo `action`; los campos restantes no cambian.
5. **Ejecuta los bloques en orden y usa el texto de detención.** Ejecuta los bloques secuencialmente, detente en el primer fallo y responde los bloques restantes con `Not executed: an earlier computer action in this turn failed.` como se describe en [Acciones por lotes](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#batch-actions). Si tu bucle aún no puede ejecutar lotes, [Parámetros de la herramienta](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#tool-parameters) explica cómo limitar a Claude a una acción por turno.
6. **Repite `toolset_name` en los resultados.** Agrega `"toolset_name": "computer"` a cada `tool_result` que responda a una llamada de miembro. Los resultados solo pueden contener contenido `text` e `image`.
7. **Admite `repeat` en `key`.** El miembro `key` acepta un conteo `repeat` opcional de 1 a 100. Un manejador que ignore los campos no reconocidos presionaría la tecla una sola vez, así que haz que tu manejador de `key` respete `repeat`.
8. **Redimensiona las capturas de pantalla tú mismo.** El conjunto de herramientas rechaza una captura de pantalla o imagen de zoom que supere los límites de imagen del modelo en lugar de reducirla. Redimensiona antes de devolver la imagen y sigue escalando las coordenadas como se describe en [Dimensionar capturas de pantalla para ajustarse a los límites de imagen](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#handle-coordinate-scaling-for-higher-resolutions).
9. **Elimina las opciones no admitidas.** Mueve cualquier `defer_loading` de la entrada a `configs`, con el mismo valor en cada miembro habilitado. Las demás opciones no admitidas en las entradas de conjuntos de herramientas se enumeran en [Conjuntos de herramientas del cliente](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference#client-toolsets).

Esta es la entrada de `tools` antes del cambio, enviada con el encabezado `anthropic-beta: computer-use-2025-11-24`:

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

Esta es la entrada de `tools` después del cambio, enviada sin encabezado beta. El objeto `configs` mantiene el zoom desactivado para coincidir con la entrada anterior, que no establece `enable_zoom`; omite `configs` por completo para aceptar el valor predeterminado y permitir que Claude haga zoom:

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

El siguiente par muestra un bloque `tool_use` antes y después del cambio. El nombre de la acción pasa de `input.action` a `name`, y el bloque adquiere `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] }
}
```

## Versiones anteriores de la herramienta

Dos versiones anteriores de la herramienta de uso de computadora siguen disponibles en beta para integraciones existentes, para modelos que no admiten el conjunto de herramientas y en plataformas donde el conjunto de herramientas no está disponible actualmente. Cada una requiere su [encabezado beta](https://platform.claude.com/docs/es/api/beta-headers) en cada solicitud, y sus parámetros están documentados en la [referencia de la Messages API beta](https://platform.claude.com/docs/es/api/beta/messages/create). Con el SDK, pasa el encabezado mediante `betas` (csharp, go: `Betas`; java: `.addBeta()`) y usa el espacio de nombres beta; solo la herramienta de uso de computadora necesita el encabezado, no las herramientas bash ni de editor de texto en la misma solicitud.

| Versión de la herramienta | Encabezado beta           | Usar con                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Parámetros                                                                           |
| ------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `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 y Claude Opus 4.5; en Amazon Bedrock, también Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5                                                                                                                                                                                                                                               | [Referencia de la API](https://platform.claude.com/docs/es/api/beta/messages/create) |
| `computer_20250124`       | `computer-use-2025-01-24` | Claude Sonnet 4.5 ([obsoleto](https://platform.claude.com/docs/es/about-claude/model-deprecations)), Claude Haiku 4.5, Claude Opus 4.1 ([retirado, excepto en Bedrock y Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations)), Claude Sonnet 4 ([retirado, excepto en Bedrock y Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations)) y Claude Opus 4 ([retirado, excepto en Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations)) | [Referencia de la API](https://platform.claude.com/docs/es/api/beta/messages/create) |

***

## Limitaciones

1. **Latencia:** La "latency" (latencia) actual del uso de computadora para interacciones entre humanos e IA podría ser demasiado lenta en comparación con las acciones de computadora habituales dirigidas por humanos. Enfócate en casos de uso donde la velocidad no sea crítica (por ejemplo, recopilación de información en segundo plano, pruebas de software automatizadas) en entornos de confianza.
2. **Precisión y confiabilidad de la visión por computadora:** Claude podría cometer errores o alucinar al generar coordenadas específicas mientras genera acciones. La salida de [pensamiento resumido](https://platform.claude.com/docs/es/build-with-claude/thinking#summarized-thinking) de Claude puede ayudarte a comprender el razonamiento del modelo e identificar posibles problemas; establece `display: "summarized"` en la configuración de pensamiento, porque los modelos que admiten el conjunto de herramientas omiten el texto de pensamiento de forma predeterminada.
3. **Precisión y confiabilidad de la selección de herramientas:** Claude podría cometer errores o alucinar al seleccionar herramientas mientras genera acciones, o tomar acciones inesperadas para resolver problemas. Además, la confiabilidad podría ser menor al interactuar con aplicaciones de nicho o con varias aplicaciones a la vez. Indica al modelo con cuidado cuando solicites tareas complejas.
4. **Confiabilidad del desplazamiento:** La acción de desplazamiento admite control de dirección (arriba, abajo, izquierda, derecha) y una cantidad especificada. En aplicaciones donde el desplazamiento no tiene efecto, las alternativas de teclado como Page Down pueden ayudar.
5. **Interacción con hojas de cálculo:** Usa las acciones de control fino del mouse (`left_mouse_down`, `left_mouse_up`) y combinaciones de teclas modificadoras para seleccionar celdas individuales. Las operaciones complejas en hojas de cálculo aún podrían requerir varios intentos.
6. **Creación de cuentas y generación de contenido en plataformas sociales y de comunicación:** Aunque Claude visita sitios web, su capacidad para crear cuentas, generar y compartir contenido, o de otro modo participar en la suplantación de humanos en sitios web y plataformas de redes sociales es limitada.
7. **Vulnerabilidades:** Los jailbreaks y la inyección de prompts pueden afectar el uso de computadora como pueden afectar a cualquier sistema de IA de frontera, incluso a través de instrucciones incrustadas en páginas web o imágenes; aplica las precauciones de [Consideraciones de seguridad](https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool#security-considerations).
8. **Acciones inapropiadas o ilegales:** Según los Términos de Servicio de Anthropic, no debes emplear el uso de computadora para violar ninguna ley ni la Política de Uso Aceptable.

Revisa y verifica siempre con cuidado las acciones y registros de uso de computadora de Claude. No uses Claude para tareas que requieran precisión perfecta o información sensible de usuarios sin supervisión humana.

## Retención de datos

El uso de computadora es una herramienta del lado del cliente. Todas las capturas de pantalla, acciones del mouse, entradas de teclado y cualquier archivo involucrado en una sesión se capturan y almacenan en tu entorno, no por Anthropic. Anthropic procesa las imágenes de capturas de pantalla y las solicitudes de acciones en tiempo real como parte de la llamada a la API. La retención de esas solicitudes de API se rige por [API y retención de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention).

Dado que tu aplicación controla dónde y cómo se almacenan los datos de uso de computadora, el uso de computadora es elegible para ZDR. Para la elegibilidad de ZDR en todas las funciones, consulta [API y retención de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention).

## Precios

El uso de computadora sigue los [precios estándar de uso de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/overview#pricing). Al usar la herramienta de uso de computadora:

**Sobrecarga de la definición del conjunto de herramientas:** Declarar `computer_toolset_20260801` con sus miembros predeterminados agrega aproximadamente 4,500 tokens de entrada a una solicitud (aproximadamente 4,590 en Claude Sonnet 5 y aproximadamente 4,520 en los demás modelos compatibles), lo que cubre las definiciones de las herramientas miembro y la indicación del sistema de uso de herramientas. Deshabilitar `zoom` con `configs` elimina aproximadamente 410 de esos tokens. El recuento exacto de una solicitud se informa en el campo `usage` de la respuesta, y puedes estimarlo de antemano con el [endpoint de conteo de tokens](https://platform.claude.com/docs/es/build-with-claude/token-counting).

**Versiones anteriores de la herramienta:** Las siguientes cifras se aplican a las versiones de herramienta `computer_20251124` y `computer_20250124`, no a `computer_toolset_20260801`:

* Sobrecarga de la indicación del sistema: 466–499 tokens agregados a la indicación del sistema
* Definición de la herramienta: aproximadamente 735 tokens de entrada por definición de herramienta (medido con `computer_20250124`)

**Consumo adicional de tokens:**

* Imágenes de capturas de pantalla y de zoom devueltas en los resultados de herramientas, facturadas como entrada de imagen (consulta [Precios de visión](https://platform.claude.com/docs/es/build-with-claude/vision#evaluate-image-size))
* Resultados de ejecución de herramientas devueltos a Claude

<Note>
  Si también estás usando las herramientas bash o de editor de texto junto con el uso de computadora, esas herramientas tienen sus propios costos de tokens, como se documenta en sus respectivas páginas.
</Note>

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Conjunto de herramientas de computadora en los SDK" icon="code" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-sdk#computer-toolset">
    Comienza con el controlador de un socio, o escribe el tuyo en Python o TypeScript. El SDK ejecuta el bucle y el callback de aprobación que le pases.
  </Card>

  <Card title="Solución de problemas del uso de herramientas" icon="wrench" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/troubleshooting-tool-use">
    Corrige los errores más comunes del uso de herramientas con tablas de diagnóstico de síntoma a solución.
  </Card>

  <Card title="Implementación de referencia" icon="github-logo" href="https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo">
    Comienza con la implementación completa basada en Docker
  </Card>

  <Card title="Uso de herramientas con Claude" icon="tool" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/overview">
    Conecta Claude a herramientas y API externas. Descubre dónde se ejecutan las herramientas, cuándo las llama Claude y qué herramienta se adapta a tu tarea.
  </Card>

  <Card title="Mejores prácticas en detalle" icon="book" href="https://claude.com/blog/best-practices-for-computer-and-browser-use-with-claude">
    Recomendaciones evaluadas con benchmarks sobre resolución, esfuerzo de pensamiento y gestión del contexto
  </Card>

  <Card title="Herramienta de uso del navegador" icon="browser" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-tool">
    Permite que Claude navegue, lea e interactúe con páginas web en tu propio entorno de navegador, para tareas que se mantienen dentro del navegador.
  </Card>
</CardGroup>
