Pular para o conteúdo principal

Anthropic Tool Use

Definição

Anthropic Tool Use (às vezes chamado de "function calling") é o mecanismo nativo do Claude para interagir com sistemas externos de forma estruturada e confiável. Em vez de pedir ao Claude para produzir texto que você analisa para encontrar um nome de função e argumentos, você descreve suas ferramentas como esquemas JSON na requisição da API e o Claude retorna um bloco tool_use estruturado com o nome exato da ferramenta e um objeto JSON de argumentos validados. Seu código executa a ferramenta, envolve o resultado em um bloco tool_result e o envia de volta ao Claude como o próximo turno da conversa — um loop que continua até que o Claude produza uma resposta de texto final.

A filosofia de design é um minimalismo intencional: Anthropic Tool Use é uma capacidade da API do modelo, não um framework. Não há camada de orquestração, sem memória embutida, sem loop de agente — você os escreve. Isso fornece controle máximo e overhead mínimo de abstração. Para casos de uso simples a médios, o resultado é limpo, legível e fácil de depurar. Para sistemas multi-agente complexos, você normalmente combinaria o Anthropic Tool Use com um framework como LangGraph ou um orquestrador personalizado.

Os modelos Claude foram especificamente treinados no uso de ferramentas, o que significa que exibem forte desempenho para decidir quando chamar uma ferramenta (sem chamar desnecessariamente), como preencher argumentos corretamente a partir de linguagem natural, e como lidar com solicitações ambíguas ou subespecificadas pedindo esclarecimentos em vez de alucinar argumentos. Chamadas de ferramentas paralelas (múltiplos blocos tool_use em uma única resposta) e uso de ferramentas em múltiplos turnos (várias rodadas de chamadas de ferramentas antes de uma resposta final) são ambos suportados nativamente.

Como funciona

Definições de ferramentas: JSON Schema

Cada ferramenta é descrita como um objeto JSON com três campos obrigatórios: name (um identificador de string), description (uma explicação em linguagem natural do que a ferramenta faz e quando usá-la — este é o campo mais importante para orientar a decisão do Claude) e input_schema (um objeto JSON Schema definindo os argumentos esperados). O input_schema segue o rascunho padrão do JSON Schema, suportando tipos string, número, booleano, array e objeto, campos obrigatórios, valores enum e esquemas aninhados. O Claude lê as descrições das ferramentas para decidir qual ferramenta chamar; descrições mais precisas levam a uma seleção de ferramentas mais precisa.

Tipos de mensagem tool_use e tool_result

Quando o Claude decide usar uma ferramenta, ele retorna uma resposta com stop_reason: "tool_use" e um array content contendo um ou mais blocos tool_use. Cada bloco tem um id (uma string única como "toulu_01abc..."), um name (correspondendo a uma das definições de ferramenta) e um input (um objeto JSON com os argumentos validados). Sua aplicação extrai esses blocos, executa cada chamada de ferramenta e constrói uma nova mensagem com role: "user" cujo conteúdo é uma lista de blocos tool_result — um por chamada de ferramenta, correspondendo por tool_use_id. Esse vai e vem continua até que o Claude retorne stop_reason: "end_turn" com uma resposta de texto simples.

Chamadas de ferramentas paralelas

O Claude pode emitir múltiplos blocos tool_use em uma única resposta quando determina que várias ferramentas podem ser chamadas simultaneamente — por exemplo, pesquisar em dois bancos de dados diferentes ou buscar o clima de três cidades de uma vez. Sua aplicação deve detectar múltiplos blocos tool_use e executá-los em paralelo (por exemplo, com asyncio.gather ou um pool de threads) antes de construir a resposta tool_result. Chamadas paralelas reduzem significativamente a latência total em comparação com rodadas sequenciais de chamada única.

Uso de ferramentas em múltiplos turnos

Tarefas complexas frequentemente requerem várias rodadas de chamadas de ferramentas antes que o Claude possa produzir uma resposta final: buscar uma entidade, depois buscar detalhes sobre ela, depois calcular algo a partir desses detalhes. Cada rodada adiciona uma mensagem de assistente (com blocos tool_use) e uma mensagem de usuário (com blocos tool_result) ao histórico da conversa. O histórico da conversa é sempre enviado completo em cada chamada de API, dando ao Claude contexto completo sobre o que foi tentado e quais foram os resultados. Este design sem estado significa que você é responsável por manter e aparar a lista de mensagens — não há memória embutida ou gerenciamento de estado.

Quando usar / Quando NÃO usar

Usar quandoEvitar quando
Você quer controle direto sobre o loop de chamadas de ferramentas sem overhead de frameworkVocê precisa de uma camada de coordenação multi-agente — Anthropic Tool Use é para agente único
Você precisa da integração mais estreita com recursos específicos do Claude (streaming, extended thinking)Você precisa de conveniências de framework como memória automática, bibliotecas de ferramentas embutidas ou gerenciamento de papéis
Seu caso de uso tem 1–10 ferramentas e um fluxo de conversa bem definidoSeu conjunto de ferramentas é muito grande e você precisa de seleção semântica de ferramentas em escala
Você está construindo um sistema de produção e quer dependências mínimasVocê quer prototipagem rápida com integrações pré-construídas (use LangChain ou CrewAI)
Você precisa de portabilidade máxima — apenas o SDK Anthropic e seu próprio códigoSua equipe prefere configuração declarativa de agentes a escrever código de orquestração

Comparações

CritérioAnthropic Tool UseOpenAI Function Calling
Formato de esquemaJSON Schema com campos name, description, input_schemaJSON Schema com campos name, description, parameters — estrutura quase idêntica
Streaming de chamadas de ferramentasSuportado: eventos input_json_delta transmitem tokens de argumentos em tempo realSuportado: streaming de argumentos function_call via eventos delta
Chamadas de ferramentas paralelasSuportado: múltiplos blocos tool_use em uma única respostaSuportado: múltiplas entradas tool_calls em uma única resposta
Confiabilidade / precisão de argumentosForte: modelos Claude são especificamente treinados para uso preciso de ferramentasForte: modelos classe GPT-4 têm chamada de função robusta
Suporte a modelosFamília Claude 3 e superior (Haiku, Sonnet, Opus)GPT-3.5-turbo, GPT-4, GPT-4o e superior
Formato do resultado da ferramentaBloco de conteúdo tool_result com referência tool_use_idMensagem com papel tool com referência tool_call_id
Recursos estendidosFerramentas de uso do computador (beta), ferramentas de documentosInterpretador de código, busca de arquivos (Assistants API)

Exemplos de código

import anthropic
import json
from typing import Any

# Initialize the Anthropic client
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from environment

# --- Tool definitions using JSON Schema ---
# The 'description' field is critical: Claude uses it to decide when to call each tool.
# The 'input_schema' defines the expected arguments with types and required fields.

tools = [
{
"name": "get_weather",
"description": (
"Get current weather information for a specific city. "
"Use this when the user asks about weather conditions, temperature, or forecasts."
),
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name, e.g. 'London' or 'New York'",
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit. Defaults to celsius.",
},
},
"required": ["city"],
},
},
{
"name": "search_knowledge_base",
"description": (
"Search an internal knowledge base for information on AI topics. "
"Use this when the user asks a factual question about AI frameworks, models, or concepts."
),
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query string",
},
"max_results": {
"type": "integer",
"description": "Maximum number of results to return. Default: 3.",
"minimum": 1,
"maximum": 10,
},
},
"required": ["query"],
},
},
{
"name": "create_summary",
"description": (
"Create a structured summary of provided content. "
"Use this to format research findings or information into a clean summary."
),
"input_schema": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The content to summarize",
},
"format": {
"type": "string",
"enum": ["bullet_points", "paragraph", "table"],
"description": "Output format for the summary",
},
},
"required": ["content", "format"],
},
},
]

# --- Tool execution functions ---
# In production, these would call real APIs. Here they return simulated results.

def get_weather(city: str, units: str = "celsius") -> dict:
"""Simulated weather API call."""
return {
"city": city,
"temperature": 22 if units == "celsius" else 72,
"units": units,
"condition": "partly cloudy",
"humidity": "65%",
}

def search_knowledge_base(query: str, max_results: int = 3) -> list[dict]:
"""Simulated knowledge base search."""
return [
{"title": f"Result {i+1} for '{query}'", "snippet": f"Relevant information about {query}..."}
for i in range(min(max_results, 3))
]

def create_summary(content: str, format: str) -> str:
"""Simulated summary creation."""
if format == "bullet_points":
return f"• Key point from: {content[:50]}...\n• Additional insight\n• Conclusion"
return f"Summary: {content[:100]}..."

def execute_tool(tool_name: str, tool_input: dict) -> Any:
"""Dispatch tool calls to the appropriate function."""
if tool_name == "get_weather":
return get_weather(**tool_input)
elif tool_name == "search_knowledge_base":
return search_knowledge_base(**tool_input)
elif tool_name == "create_summary":
return create_summary(**tool_input)
else:
return {"error": f"Unknown tool: {tool_name}"}

# --- Multi-turn tool use loop ---

def run_agent(user_message: str) -> str:
"""
Run a multi-turn tool use loop until Claude produces a final answer.
Returns the final text response.
"""
messages = [{"role": "user", "content": user_message}]

while True:
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=4096,
tools=tools,
messages=messages,
system=(
"You are a helpful AI assistant with access to weather data, "
"a knowledge base, and a summary tool. "
"Use tools when needed to answer questions accurately."
),
)

# Append the assistant's response to the conversation history
messages.append({"role": "assistant", "content": response.content})

# Check if we're done
if response.stop_reason == "end_turn":
# Extract the final text from the response content
for block in response.content:
if hasattr(block, "text"):
return block.text
return "No text response found."

# Handle tool use: execute all tool_use blocks
if response.stop_reason == "tool_use":
tool_results = []

for block in response.content:
if block.type == "tool_use":
print(f" Calling tool: {block.name}({json.dumps(block.input)})")

# Execute the tool and get the result
result = execute_tool(block.name, block.input)

# Wrap result in a tool_result block
# The tool_use_id links this result to the specific tool call
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result), # serialize to string
})

# Add tool results as a user message to continue the conversation
messages.append({"role": "user", "content": tool_results})

else:
# Unexpected stop reason — return what we have
break

return "Agent loop ended unexpectedly."

# --- Run examples ---

print("Example 1: Weather + Knowledge base (potential parallel calls)")
answer = run_agent(
"What is the weather in Paris right now, and also search for information about LangGraph?"
)
print("Answer:", answer)

print("\nExample 2: Multi-turn tool use")
answer = run_agent(
"Search for information about CrewAI and then create a bullet-point summary of the results."
)
print("Answer:", answer)

Recursos práticos

Veja também