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

El "tool use" (uso de herramientas), también llamado "function calling" (llamada de funciones), permite que Claude llame a funciones que tú defines o que Anthropic proporciona. Claude determina cuándo llamar a una herramienta según la solicitud del usuario y la descripción de la herramienta. Luego devuelve una llamada estructurada que tu aplicación ejecuta (herramientas de cliente) o que Anthropic ejecuta (herramientas de servidor).

Aquí tienes un ejemplo mínimo que usa una herramienta de servidor, la [herramienta de búsqueda web](https://platform.claude.com/docs/es/agents-and-tools/tool-use/web-search-tool), que Anthropic ejecuta por ti:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "tools": [{"type": "web_search_20260209", "name": "web_search"}],
      "messages": [{"role": "user", "content": "What'\''s the latest on the Mars rover?"}]
    }'
  ```

  ```bash CLI
  ant messages create --transform content --format yaml \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --tool '{type: web_search_20260209, name: web_search}' \
    --message '{role: user, content: "What is the latest on the Mars rover?"}'
  ```

  ```python Python
  client = anthropic.Anthropic()
  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=[{"type": "web_search_20260209", "name": "web_search"}],
      messages=[{"role": "user", "content": "What's the latest on the Mars rover?"}],
  )
  print(response.content)
  ```

  ```typescript TypeScript
  const client = new Anthropic();
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [{ type: "web_search_20260209", name: "web_search" }],
    messages: [{ role: "user", content: "What's the latest on the Mars rover?" }]
  });
  console.log(response.content);
  ```

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

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = [new ToolUnion(new WebSearchTool20260209())],
      Messages = [new() { Role = Role.User, Content = "What's the latest on the Mars rover?" }]
  };

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

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

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Tools: []anthropic.ToolUnionParam{
  		{OfWebSearchTool20260209: &anthropic.WebSearchTool20260209Param{}},
  	},
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("What's the latest on the Mars rover?")),
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response.Content)
  ```

  ```java Java
  import com.anthropic.models.messages.WebSearchTool20260209;

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

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(WebSearchTool20260209.builder().build())
          .addUserMessage("What's the latest on the Mars rover?")
          .build();

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

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

  $message = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: [
          ['type' => 'web_search_20260209', 'name' => 'web_search'],
      ],
      messages: [
          ['role' => 'user', 'content' => "What's the latest on the Mars rover?"],
      ],
  );

  echo $message;
  ```

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

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [{ type: "web_search_20260209", name: "web_search" }],
    messages: [{ role: "user", content: "What's the latest on the Mars rover?" }]
  )
  puts message.content
  ```
</CodeGroup>

Claude ejecuta la búsqueda en la infraestructura de Anthropic y devuelve los resultados citados en la misma respuesta. Para que Claude llame a una función que tú defines, pasa una herramienta con un `input_schema` y luego ejecuta la llamada cuando Claude devuelva un bloque `tool_use`. [Cómo funciona el uso de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/overview#how-tool-use-works) muestra ese ciclo de ida y vuelta de principio a fin. Obtén más información sobre cómo [definir herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/define-tools) y [manejar llamadas a herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/handle-tool-calls).

## Cómo funciona el uso de herramientas

Las herramientas se diferencian principalmente por dónde se ejecuta el código. Las **herramientas de cliente** (incluidas las herramientas definidas por el usuario y las herramientas con esquemas definidos por Anthropic, como `bash` y `text_editor`) se ejecutan en tu aplicación. Claude responde con `stop_reason: "tool_use"` y uno o más bloques `tool_use`. Tu código ejecuta la operación y envía de vuelta un `tool_result`. Las **herramientas de servidor** (como `web_search`, `web_fetch`, `code_execution` y `tool_search`) se ejecutan en la infraestructura de Anthropic: ves los resultados directamente sin manejar la ejecución, a menos que Claude llame a la herramienta en el mismo grupo de llamadas paralelas a herramientas que una de tus herramientas de cliente (consulta [Razones de detención y respaldo](https://platform.claude.com/docs/es/build-with-claude/handling-stop-reasons#tool-use)).

Aquí tienes ese ciclo de ida y vuelta completo para una herramienta de cliente. La primera solicitud define una herramienta `get_weather`, y Claude responde la pregunta llamándola: la respuesta contiene un bloque `tool_use`, tu código ejecuta la consulta y una segunda solicitud envía el resultado de vuelta en un bloque `tool_result` para que Claude pueda responder con la respuesta.

<CodeGroup>
  ```bash cURL
  # Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  TOOLS='[
    {
      "name": "get_weather",
      "description": "Get the current weather for a given location.",
      "input_schema": {
        "type": "object",
        "properties": {
          "location": {"type": "string", "description": "City and state, e.g. San Francisco, CA"}
        },
        "required": ["location"]
      }
    }
  ]'
  USER_MSG="What's the weather in San Francisco?"
  RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "$(jq -n --argjson tools "$TOOLS" --arg msg "$USER_MSG" '{
      model: "claude-opus-5-5",
      max_tokens: 1024,
      tools: $tools,
      # Solicita como máximo una llamada a herramienta por turno.
      tool_choice: {type: "auto", disable_parallel_tool_use: true},
      messages: [{role: "user", content: $msg}]
    }')")
  TOOL_USE=$(echo "$RESPONSE" | jq '.content[] | select(.type == "tool_use")')
  echo "Claude called $(echo "$TOOL_USE" | jq -r '.name') with $(echo "$TOOL_USE" | jq -c '.input')"

  # Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  # Claude usa el resultado para responder la pregunta original.
  WEATHER="15 degrees Celsius, partly cloudy"
  curl -s https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "$(jq -n \
      --argjson tools "$TOOLS" \
      --arg msg "$USER_MSG" \
      --argjson assistant "$(echo "$RESPONSE" | jq '.content')" \
      --arg tool_use_id "$(echo "$TOOL_USE" | jq -r '.id')" \
      --arg weather "$WEATHER" \
      '{
        model: "claude-opus-5-5",
        max_tokens: 1024,
        tools: $tools,
        tool_choice: {type: "auto", disable_parallel_tool_use: true},
        messages: [
          {role: "user", content: $msg},
          {role: "assistant", content: $assistant},
          {role: "user", content: [
            {type: "tool_result", tool_use_id: $tool_use_id, content: $weather}
          ]}
        ]
      }')"
  ```

  ```bash CLI
  # ant lee el cuerpo de la solicitud como YAML desde stdin; jq lleva el estado de la conversación
  # a la segunda solicitud.
  USER_MSG="What's the weather in San Francisco?"
  MESSAGES=$(jq -n --arg msg "$USER_MSG" '[{role: "user", content: $msg}]')
  call_api() {
    {
      cat <<'YAML'
  model: claude-opus-5-5
  max_tokens: 1024
  # Pide como máximo una llamada a herramienta por turno.
  tool_choice: {type: auto, disable_parallel_tool_use: true}
  tools:
    - name: get_weather
      description: Get the current weather for a given location.
      input_schema:
        type: object
        properties:
          location: {type: string, description: "City and state, e.g. San Francisco, CA"}
        required: [location]
  YAML
      printf 'messages: %s\n' "$MESSAGES"
    } | ant messages create --format json
  }

  # Claude responde con un bloque tool_use que nombra la herramienta y sus argumentos.
  RESPONSE=$(call_api)
  TOOL_USE=$(jq '.content[] | select(.type == "tool_use")' <<<"$RESPONSE")
  echo "Claude called $(jq -r '.name' <<<"$TOOL_USE") with $(jq -c '.input' <<<"$TOOL_USE")"

  # Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  WEATHER="15 degrees Celsius, partly cloudy"
  MESSAGES=$(jq \
    --argjson assistant "$(jq '.content' <<<"$RESPONSE")" \
    --arg tool_use_id "$(jq -r '.id' <<<"$TOOL_USE")" \
    --arg weather "$WEATHER" \
    '. + [
      {role: "assistant", content: $assistant},
      {role: "user", content: [
        {type: "tool_result", tool_use_id: $tool_use_id, content: $weather}
      ]}
    ]' <<<"$MESSAGES")

  # Claude usa el resultado para responder la pregunta original.
  call_api
  ```

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

  tools = [
      {
          "name": "get_weather",
          "description": "Get the current weather for a given location.",
          "input_schema": {
              "type": "object",
              "properties": {
                  "location": {
                      "type": "string",
                      "description": "City and state, e.g. San Francisco, CA",
                  }
              },
              "required": ["location"],
          },
      }
  ]
  messages = [{"role": "user", "content": "What's the weather in San Francisco?"}]

  # Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=tools,
      # Solicita como máximo una llamada a herramienta por turno.
      tool_choice={"type": "auto", "disable_parallel_tool_use": True},
      messages=messages,
  )
  tool_use = next(block for block in response.content if block.type == "tool_use")
  print(f"Claude called {tool_use.name} with {json.dumps(tool_use.input)}")

  # Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  weather = "15 degrees Celsius, partly cloudy"  # your weather lookup goes here
  messages += [
      {"role": "assistant", "content": response.content},
      {
          "role": "user",
          "content": [
              {"type": "tool_result", "tool_use_id": tool_use.id, "content": weather}
          ],
      },
  ]
  followup = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=tools,
      tool_choice={"type": "auto", "disable_parallel_tool_use": True},
      messages=messages,
  )

  # Claude usa el resultado para responder la pregunta original.
  final_text = next(block for block in followup.content if block.type == "text")
  print(final_text.text)
  ```

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

  const tools: Anthropic.Tool[] = [
    {
      name: "get_weather",
      description: "Get the current weather for a given location.",
      input_schema: {
        type: "object",
        properties: {
          location: { type: "string", description: "City and state, e.g. San Francisco, CA" }
        },
        required: ["location"]
      }
    }
  ];
  const messages: Anthropic.MessageParam[] = [
    { role: "user", content: "What's the weather in San Francisco?" }
  ];

  // Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools,
    // Solicita como máximo una llamada a herramienta por turno.
    tool_choice: { type: "auto", disable_parallel_tool_use: true },
    messages
  });
  const toolUse = response.content.find(
    (block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
  )!;
  console.log(`Claude called ${toolUse.name} with ${JSON.stringify(toolUse.input)}`);

  // Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  const weather = "15 degrees Celsius, partly cloudy"; // your weather lookup goes here
  messages.push(
    { role: "assistant", content: response.content },
    {
      role: "user",
      content: [{ type: "tool_result", tool_use_id: toolUse.id, content: weather }]
    }
  );
  const followup = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools,
    tool_choice: { type: "auto", disable_parallel_tool_use: true },
    messages
  });

  // Claude usa el resultado para responder la pregunta original.
  const finalText = followup.content.find(
    (block): block is Anthropic.TextBlock => block.type === "text"
  )!;
  console.log(finalText.text);
  ```

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

  List<ToolUnion> tools =
  [
      new ToolUnion(new Tool()
      {
          Name = "get_weather",
          Description = "Get the current weather for a given location.",
          InputSchema = new InputSchema()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["location"] = JsonSerializer.SerializeToElement(new
                  {
                      type = "string",
                      description = "City and state, e.g. San Francisco, CA",
                  }),
              },
              Required = ["location"],
          },
      }),
  ];

  // Solicita como máximo una llamada a herramienta por turno.
  var toolChoice = new ToolChoice(new ToolChoiceAuto { DisableParallelToolUse = true });

  const string userPrompt = "What's the weather in San Francisco?";

  // Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  var response = await client.Messages.Create(new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = tools,
      ToolChoice = toolChoice,
      Messages = [new() { Role = Role.User, Content = userPrompt }],
  });
  ToolUseBlock? toolUse = null;
  foreach (var block in response.Content)
  {
      if (block.TryPickToolUse(out var picked))
      {
          toolUse = picked;
          break;
      }
  }
  Console.WriteLine($"Claude called {toolUse!.Name} with {JsonSerializer.Serialize(toolUse.Input)}");

  // Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  var weather = "15 degrees Celsius, partly cloudy";
  List<ContentBlockParam> toolResults =
  [
      new ContentBlockParam(new ToolResultBlockParam()
      {
          ToolUseID = toolUse.ID,
          Content = weather,
      }),
  ];
  var followup = await client.Messages.Create(new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = tools,
      ToolChoice = toolChoice,
      Messages =
      [
          new() { Role = Role.User, Content = userPrompt },
          new() { Role = Role.Assistant, Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList() },
          new() { Role = Role.User, Content = new MessageParamContent(toolResults) },
      ],
  });

  // Claude usa el resultado para responder la pregunta original.
  foreach (var block in followup.Content)
  {
      if (block.TryPickText(out var text))
      {
          Console.WriteLine(text.Text);
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()
  ctx := context.Background()

  tools := []anthropic.ToolUnionParam{
  	{OfTool: &anthropic.ToolParam{
  		Name:        "get_weather",
  		Description: anthropic.String("Get the current weather for a given location."),
  		InputSchema: anthropic.ToolInputSchemaParam{
  			Properties: map[string]any{
  				"location": map[string]any{
  					"type":        "string",
  					"description": "City and state, e.g. San Francisco, CA",
  				},
  			},
  			Required: []string{"location"},
  		},
  	}},
  }
  // Solicita como máximo una llamada a herramienta por turno.
  toolChoice := anthropic.ToolChoiceUnionParam{
  	OfAuto: &anthropic.ToolChoiceAutoParam{DisableParallelToolUse: anthropic.Bool(true)},
  }
  messages := []anthropic.MessageParam{
  	anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in San Francisco?")),
  }

  // Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  response, err := client.Messages.New(ctx, anthropic.MessageNewParams{
  	Model:      anthropic.ModelClaudeOpus5_5,
  	MaxTokens:  1024,
  	Tools:      tools,
  	ToolChoice: toolChoice,
  	Messages:   messages,
  })
  if err != nil {
  	log.Fatal(err)
  }
  var toolUse anthropic.ContentBlockUnion
  for _, block := range response.Content {
  	if block.Type == "tool_use" {
  		toolUse = block
  		break
  	}
  }
  fmt.Printf("Claude called %s with %s\n", toolUse.Name, string(toolUse.Input))

  // Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  weather := "15 degrees Celsius, partly cloudy"
  var assistantContent []anthropic.ContentBlockParamUnion
  for _, block := range response.Content {
  	assistantContent = append(assistantContent, block.ToParam())
  }
  messages = append(messages,
  	anthropic.NewAssistantMessage(assistantContent...),
  	anthropic.NewUserMessage(anthropic.NewToolResultBlock(toolUse.ID, weather, false)),
  )
  followup, err := client.Messages.New(ctx, anthropic.MessageNewParams{
  	Model:      anthropic.ModelClaudeOpus5_5,
  	MaxTokens:  1024,
  	Tools:      tools,
  	ToolChoice: toolChoice,
  	Messages:   messages,
  })
  if err != nil {
  	log.Fatal(err)
  }

  // Claude usa el resultado para responder la pregunta original.
  for _, block := range followup.Content {
  	if block.Type == "text" {
  		fmt.Println(block.Text)
  	}
  }
  ```

  ```java Java
  import com.anthropic.core.JsonValue;
  import com.anthropic.models.messages.ContentBlockParam;
  // ...
  import com.anthropic.models.messages.Tool;
  import com.anthropic.models.messages.Tool.InputSchema;
  import com.anthropic.models.messages.ToolChoiceAuto;
  import com.anthropic.models.messages.ToolResultBlockParam;
  import com.anthropic.models.messages.ToolUseBlock;
  // ...

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

      Tool weatherTool = Tool.builder()
          .name("get_weather")
          .description("Get the current weather for a given location.")
          .inputSchema(InputSchema.builder()
              .properties(JsonValue.from(Map.of(
                  "location", Map.of(
                      "type", "string",
                      "description", "City and state, e.g. San Francisco, CA"
                  )
              )))
              .required(List.of("location"))
              .build())
          .build();

      // Solicita como máximo una llamada a herramienta por turno.
      ToolChoiceAuto toolChoice = ToolChoiceAuto.builder()
          .disableParallelToolUse(true)
          .build();

      String userPrompt = "What's the weather in San Francisco?";

      // Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
      Message response = client.messages().create(MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(weatherTool)
          .toolChoice(toolChoice)
          .addUserMessage(userPrompt)
          .build());
      ToolUseBlock toolUse = response.content().stream()
          .flatMap(block -> block.toolUse().stream())
          .findFirst()
          .orElseThrow();
      IO.println("Claude called " + toolUse.name() + " with " + toolUse._input());

      // Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
      String weather = "15 degrees Celsius, partly cloudy";
      Message followup = client.messages().create(MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(weatherTool)
          .toolChoice(toolChoice)
          .addUserMessage(userPrompt)
          .addMessage(response)
          .addUserMessageOfBlockParams(List.of(ContentBlockParam.ofToolResult(
              ToolResultBlockParam.builder()
                  .toolUseId(toolUse.id())
                  .content(weather)
                  .build())))
          .build());

      // Claude usa el resultado para responder la pregunta original.
      followup.content().stream()
          .flatMap(block -> block.text().stream())
          .forEach(textBlock -> IO.println(textBlock.text()));
  }
  ```

  ```php PHP
  use Anthropic\Messages\ToolChoiceAuto;

  $client = new Client();

  $tools = [
      [
          'name' => 'get_weather',
          'description' => 'Get the current weather for a given location.',
          'input_schema' => [
              'type' => 'object',
              'properties' => [
                  'location' => [
                      'type' => 'string',
                      'description' => 'City and state, e.g. San Francisco, CA',
                  ],
              ],
              'required' => ['location'],
          ],
      ],
  ];
  $userMessage = ['role' => 'user', 'content' => "What's the weather in San Francisco?"];

  // Solicita como máximo una llamada a herramienta por turno.
  $toolChoice = ToolChoiceAuto::with(disableParallelToolUse: true);

  // Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  $response = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: $tools,
      toolChoice: $toolChoice,
      messages: [$userMessage],
  );
  $toolUse = null;
  foreach ($response->content as $block) {
      if ($block->type === 'tool_use') {
          $toolUse = $block;
          break;
      }
  }
  printf("Claude called %s with %s\n", $toolUse->name, json_encode($toolUse->input));

  // Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  $weather = '15 degrees Celsius, partly cloudy';
  $followup = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: $tools,
      toolChoice: $toolChoice,
      messages: [
          $userMessage,
          ['role' => 'assistant', 'content' => $response->content],
          [
              'role' => 'user',
              'content' => [
                  [
                      'type' => 'tool_result',
                      'tool_use_id' => $toolUse->id,
                      'content' => $weather,
                  ],
              ],
          ],
      ],
  );

  // Claude usa el resultado para responder la pregunta original.
  foreach ($followup->content as $block) {
      if ($block->type === 'text') {
          echo $block->text, "\n";
      }
  }
  ```

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

  tools = [
    {
      name: "get_weather",
      description: "Get the current weather for a given location.",
      input_schema: {
        type: "object",
        properties: {
          location: {type: "string", description: "City and state, e.g. San Francisco, CA"}
        },
        required: ["location"]
      }
    }
  ]
  messages = [{role: "user", content: "What's the weather in San Francisco?"}]

  # Claude responde con un bloque tool_use que indica la herramienta y sus argumentos.
  response = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: tools,
    # Solicita como máximo una llamada a herramienta por turno.
    tool_choice: {type: "auto", disable_parallel_tool_use: true},
    messages: messages
  )
  tool_use = response.content.find { |block| block.type == :tool_use }
  puts "Claude called #{tool_use.name} with #{JSON.generate(tool_use.input)}"

  # Ejecuta la herramienta y luego envía el resultado en un bloque tool_result.
  weather = "15 degrees Celsius, partly cloudy"
  messages += [
    {role: "assistant", content: response.content},
    {
      role: "user",
      content: [
        {type: "tool_result", tool_use_id: tool_use.id, content: weather}
      ]
    }
  ]
  followup = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: tools,
    tool_choice: {type: "auto", disable_parallel_tool_use: true},
    messages: messages
  )

  # Claude usa el resultado para responder la pregunta original.
  final_text = followup.content.find { |block| block.type == :text }
  puts final_text.text
  ```
</CodeGroup>

```text Output wrap
Claude called get_weather with {"location": "San Francisco, CA"}
The current weather in San Francisco is 15 degrees Celsius with partly cloudy skies.
```

[Manejar llamadas a herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/handle-tool-calls) cubre cada paso en detalle, incluido el formato de los resultados y la señalización de errores; [Uso de herramientas en paralelo](https://platform.claude.com/docs/es/agents-and-tools/tool-use/parallel-tool-use) cubre las respuestas que llaman a varias herramientas a la vez. Para no tener que escribir este ciclo tú mismo, usa [Tool Runner](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-runner): el SDK ejecuta tus herramientas y envía los resultados de vuelta automáticamente.

Para conocer el modelo conceptual completo, incluido el bucle agéntico y cuándo elegir cada enfoque, consulta [Cómo funciona el uso de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/how-tool-use-works).

Para conectarte a servidores de Model Context Protocol (MCP), consulta el [conector MCP](https://platform.claude.com/docs/es/agents-and-tools/mcp-connector). Para crear tu propio cliente MCP, consulta la guía de Model Context Protocol para [crear un cliente MCP](https://modelcontextprotocol.io/docs/develop/build-client).

## Cuándo Claude usa herramientas

Con el `tool_choice` predeterminado de `{"type": "auto"}`, Claude determina en cada turno si llamar a una herramienta o responder directamente. Llama a una herramienta cuando la solicitud corresponde a la capacidad descrita de esa herramienta y la respuesta no está ya en el contexto. Responde directamente para conocimiento estable, tareas creativas y turnos conversacionales.

Este límite se puede ajustar mediante tu indicación del sistema. Si Claude no llama a las herramientas cuando lo esperas, una instrucción ligera como `"Use the tools to investigate before responding."` aumenta el uso de herramientas. Una forma más fuerte como `"Always call a tool first before responding."` empuja aún más. Por el contrario, `"Use your judgment about whether to call a tool or respond directly."` mantiene conservador el comportamiento de activación.

Para exigir una llamada a herramienta en lugar de depender del prompting, configura [`tool_choice`](https://platform.claude.com/docs/es/agents-and-tools/tool-use/define-tools#forcing-tool-use).

<Tip>
  **Garantiza la conformidad con el esquema mediante el uso estricto de herramientas**

  Agrega `strict: true` a tus definiciones de herramientas personalizadas para asegurar que las llamadas a herramientas de Claude siempre coincidan exactamente con tu esquema. Consulta [Uso estricto de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/strict-tool-use).
</Tip>

La página de cada herramienta de servidor describe su propio límite de activación con más detalle.

<Accordion title="Cuando faltan parámetros obligatorios">
  Si el prompt del usuario no incluye suficiente información para completar todos los parámetros obligatorios de una herramienta, es mucho más probable que Claude Opus reconozca que falta un parámetro y lo solicite. Claude Sonnet podría preguntar, especialmente cuando se le indica que piense antes de emitir una solicitud de herramienta. Pero también podría inferir un valor razonable.

  Por ejemplo, dada una herramienta `get_weather` que requiere un parámetro `location`, si le preguntas a Claude "¿Cómo está el clima?" sin especificar una ubicación, Claude (particularmente Claude Sonnet) podría adivinar valores que no proporcionaste:

  ```json JSON
  {
    "type": "tool_use",
    "id": "toolu_01A09q90qw90lq917835lq9",
    "name": "get_weather",
    "input": { "location": "New York, NY", "unit": "fahrenheit" }
  }
  ```

  Este comportamiento no está garantizado, especialmente para prompts más ambiguos y para modelos menos capaces.
</Accordion>

## Elige una herramienta

Para las cadenas `type`, versiones y encabezados beta, consulta la [Referencia de herramientas](https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference).

### Tus propias herramientas

Para las herramientas que tú defines, escribes el esquema y tu aplicación ejecuta cada llamada.

<CardGroup cols={2}>
  <Card title="Definir herramientas" icon="hammer" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/define-tools">
    Especifica esquemas de herramientas, escribe descripciones y controla cuándo Claude llama a tus herramientas.
  </Card>

  <Card title="Manejar llamadas a herramientas" icon="arrows-left-right" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/handle-tool-calls">
    Analiza bloques `tool_use`, da formato a respuestas `tool_result` y maneja errores.
  </Card>
</CardGroup>

### Herramientas de cliente con esquema de Anthropic

Anthropic publica el esquema y entrena a Claude con él. Tu aplicación sigue ejecutando cada llamada y devuelve el `tool_result`.

<CardGroup cols={2}>
  <Card title="Herramienta de memoria" icon="brain" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/memory-tool">
    Almacena y recupera información entre conversaciones en archivos que tú controlas.
  </Card>

  <Card title="Herramienta Bash" icon="terminal" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/bash-tool">
    Ejecuta comandos de shell en una sesión persistente que mantiene el estado.
  </Card>

  <Card title="Herramienta de editor de texto" icon="edit" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/text-editor-tool">
    Visualiza y modifica archivos de texto para depurar, corregir y mejorar código.
  </Card>

  <Card title="Herramienta de uso de computadora" icon="computer" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/computer-use-tool">
    Toma capturas de pantalla y controla el mouse y el teclado en un entorno de escritorio.
  </Card>

  <Card title="Herramienta de uso de navegador" icon="browser" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/browser-use-tool">
    Navega, lee e interactúa con páginas web en tu propio entorno de navegador.
  </Card>
</CardGroup>

### Herramientas de servidor

Las herramientas de servidor se ejecutan en la infraestructura de Anthropic, sin código de manejo en tu aplicación. Consulta [Herramientas de servidor](https://platform.claude.com/docs/es/agents-and-tools/tool-use/server-tools) para conocer la mecánica que comparten.

<CardGroup cols={2}>
  <Card title="Herramienta de búsqueda web" icon="magnifying-glass" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/web-search-tool">
    Busca en la web información más allá de la fecha de corte de conocimiento, con fuentes citadas.
  </Card>

  <Card title="Herramienta de obtención web" icon="download" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/web-fetch-tool">
    Recupera el contenido completo de páginas web y documentos PDF especificados.
  </Card>

  <Card title="Herramienta de ejecución de código" icon="code" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/code-execution-tool">
    Ejecuta código Python y bash en un contenedor aislado para analizar datos y generar archivos.
  </Card>

  <Card title="Herramienta de asesor" icon="lightbulb" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/advisor-tool">
    Permite que un modelo ejecutor más rápido consulte a un modelo asesor de mayor inteligencia a mitad de la generación.
  </Card>

  <Card title="Herramienta de búsqueda de herramientas" icon="library" href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-search-tool">
    Trabaja con miles de herramientas descubriéndolas y cargándolas bajo demanda.
  </Card>

  <Card title="Conector MCP" icon="link" href="https://platform.claude.com/docs/es/agents-and-tools/mcp-connector">
    Conéctate a servidores MCP remotos desde la API de Messages sin un cliente MCP separado.
  </Card>
</CardGroup>

<Note>
  [Claude Managed Agents](https://platform.claude.com/docs/es/managed-agents/overview) proporciona un conjunto de herramientas integrado que Claude usa de forma autónoma dentro de una sesión. Para ese conjunto de herramientas y la forma de Managed Agents de agregar herramientas personalizadas, consulta su página de [Herramientas](https://platform.claude.com/docs/es/managed-agents/tools).
</Note>

## Precios

Las solicitudes de "tool use" (uso de herramientas) se cobran en función de:

1. El número total de tokens de entrada enviados al modelo (incluidos los del parámetro `tools`)
2. El número de tokens de salida generados
3. Para las herramientas del lado del servidor, precios adicionales basados en el uso (por ejemplo, la búsqueda web cobra por cada búsqueda realizada)

Las herramientas del lado del cliente tienen el mismo precio que cualquier otra solicitud a la Claude API, aunque las herramientas del lado del servidor pueden generar cargos adicionales según su uso específico.

Los tokens adicionales del uso de herramientas provienen de:

* El parámetro `tools` en las solicitudes a la API (nombres, descripciones y esquemas de las herramientas)
* Los bloques de contenido `tool_use` en las solicitudes y respuestas de la API
* Los bloques de contenido `tool_result` en las solicitudes a la API

Cuando usas `tools`, la API también incluye automáticamente un "system prompt" (indicación del sistema) especial para el modelo que habilita el uso de herramientas. El número de tokens de uso de herramientas requeridos para cada modelo se indica en la siguiente tabla (sin incluir los tokens adicionales mencionados anteriormente). Ten en cuenta que la tabla asume que se proporciona al menos 1 herramienta. Si no se proporcionan `tools`, entonces una elección de herramienta de `none` usa 0 tokens adicionales de indicación del sistema.

| Model                                                                                                                                | Tool use system prompt tokens: auto, none | Tool use system prompt tokens: any, tool |
| :----------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- | :--------------------------------------- |
| Claude Opus 5.5                                                                                                                      | 286 tokens                                |                                          |
| Claude Opus 5                                                                                                                        | 286 tokens                                | 406 tokens                               |
| Claude Opus 4.8                                                                                                                      | 290 tokens                                | 410 tokens                               |
| Claude Opus 4.7                                                                                                                      | 675 tokens                                | 804 tokens                               |
| Claude Opus 4.6                                                                                                                      | 497 tokens                                | 589 tokens                               |
| Claude Opus 4.5                                                                                                                      | 496 tokens                                | 588 tokens                               |
| Claude Opus 4.1 ([retired, except on Bedrock and Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations)) | 313 tokens                                | 315 tokens                               |
| Claude Opus 4 ([retired, except on Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations))               | 313 tokens                                | 315 tokens                               |
| Claude Sonnet 5.5                                                                                                                    | 286 tokens                                |                                          |
| Claude Sonnet 5                                                                                                                      | 354 tokens                                | 474 tokens                               |
| Claude Sonnet 4.6                                                                                                                    | 497 tokens                                | 589 tokens                               |
| Claude Sonnet 4.5                                                                                                                    | 496 tokens                                | 588 tokens                               |
| Claude Sonnet 4 ([retired, except on Bedrock and Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations)) | 313 tokens                                | 315 tokens                               |
| Claude Haiku 5.5                                                                                                                     | 286 tokens                                | 406 tokens                               |
| Claude Haiku 4.5                                                                                                                     | 496 tokens                                | 588 tokens                               |
| Claude Haiku 3.5 ([retired, except on Google Cloud](https://platform.claude.com/docs/es/about-claude/model-deprecations))            | 264 tokens                                | 355 tokens                               |

* **auto, none:** The count when tool\_choice is auto or none.
* **any, tool:** The count when tool\_choice is any or tool.
* **Retired:** May still be available on other cloud platforms. See [Model deprecations](https://platform.claude.com/docs/es/about-claude/model-deprecations) for more.

Estas cantidades de tokens se suman a tus tokens normales de entrada y salida para calcular el costo total de una solicitud.

Consulta la tabla de [Descripción general de modelos](https://platform.claude.com/docs/es/models/overview#latest-models-comparison) para ver los precios actuales por modelo.

Cuando envías un prompt de uso de herramientas, al igual que con cualquier otra solicitud a la API, la respuesta incluye los recuentos de tokens de entrada y de salida en las métricas `usage` reportadas.

Algunas herramientas de servidor agregan cargos basados en el uso además de los tokens: consulta la [Herramienta de búsqueda web](https://platform.claude.com/docs/es/agents-and-tools/tool-use/web-search-tool#usage-and-pricing) y la [Herramienta de ejecución de código](https://platform.claude.com/docs/es/agents-and-tools/tool-use/code-execution-tool#usage-and-pricing) para conocer sus tarifas.

## Próximos pasos

<CardGroup cols={3}>
  <Card href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/how-tool-use-works" title="Cómo funciona el uso de herramientas" icon="compass">
    Comprende el bucle de uso de herramientas, dónde se ejecutan las herramientas y cuándo usar herramientas en lugar de prosa.
  </Card>

  <Card href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/build-a-tool-using-agent" title="Tutorial: Crea un agente que usa herramientas" icon="graduation-cap">
    Un recorrido guiado desde una sola llamada a herramienta hasta un bucle agéntico listo para producción.
  </Card>

  <Card href="https://platform.claude.com/docs/es/agents-and-tools/tool-use/tool-reference" title="Referencia de herramientas" icon="book">
    Directorio de herramientas proporcionadas por Anthropic y referencia de las propiedades opcionales de definición de herramientas.
  </Card>
</CardGroup>
