Por padrão, Claude pode chamar várias ferramentas em uma única resposta. Esta página aborda como executar essas chamadas, como formatar o histórico de mensagens para que o paralelismo continue funcionando e como desabilitar o uso de ferramentas em paralelo quando necessário. Para o fluxo de chamada única, consulte Lidar com chamadas de ferramentas.
Quando Claude chama ferramentas, a resposta tem um stop_reason de tool_use e pode conter vários blocos tool_use em um único turno do assistente. Como você executa essas chamadas é decisão sua. A API não prescreve uma ordem de execução: você pode executar as chamadas de forma concorrente (Promise.all, asyncio.gather), sequencialmente na ordem em que aparecem, ou em qualquer combinação que se adeque às suas ferramentas.
Escolha a estratégia com base no que suas ferramentas fazem. Operações independentes e somente leitura geralmente são seguras para executar em paralelo para obter menor "latency" (latência). Ferramentas com efeitos colaterais, estado compartilhado ou requisitos de ordenação podem ser melhor executadas sequencialmente.
Qualquer que seja a estratégia usada, retorne um tool_result para cada bloco tool_use, todos juntos na próxima mensagem do usuário. Associe cada resultado à sua chamada com tool_use_id, e coloque todos os blocos tool_result antes de qualquer conteúdo de texto nessa mensagem. Consulte Lidar com chamadas de ferramentas para as regras completas de formatação. Se você optar por não executar uma chamada específica (por exemplo, porque executou o lote sequencialmente e uma chamada anterior falhou), ainda assim retorne um tool_result para ela com is_error: true e uma breve explicação.
{
"type": "tool_result",
"tool_use_id": "toolu_02",
"is_error": true,
"content": "Not executed: the preceding write_file call failed."
}O script a seguir envia uma solicitação que deve acionar chamadas de ferramentas em paralelo, verifica se a resposta as contém e formata os resultados das ferramentas para que o paralelismo continue funcionando. Execute-o com ANTHROPIC_API_KEY definido em seu ambiente:
As linhas de resumo no final reafirmam as duas regras de formatação que mantêm o paralelismo funcionando: todos os resultados de ferramentas retornam em uma única mensagem do usuário, e nenhum conteúdo de texto aparece antes dos resultados das ferramentas nessa mensagem.
Os modelos Claude 4 e posteriores fazem chamadas de ferramentas em paralelo por padrão quando uma solicitação se beneficia de várias ferramentas. Para todos os modelos, você pode aumentar a probabilidade de chamadas de ferramentas em paralelo com prompts direcionados:
O uso de ferramentas em paralelo está ativado por padrão. Para desativá-lo, defina disable_parallel_tool_use: true dentro do objeto tool_choice. Ele não é um parâmetro de nível superior da solicitação. O efeito depende do tipo de tool_choice.
Quando o tipo de tool_choice é auto (o padrão), definir disable_parallel_tool_use: true significa que Claude chama no máximo uma ferramenta por resposta. Claude ainda pode responder em texto simples sem chamar nenhuma ferramenta. As linhas destacadas são a única mudança em relação a uma solicitação padrão de uso de ferramentas:
Quando o tipo de tool_choice é any ou tool, definir disable_parallel_tool_use: true significa que Claude chama exatamente uma ferramenta. O exemplo a seguir usa any. O mesmo campo funciona com tool:
Se Claude não estiver fazendo chamadas de ferramentas em paralelo quando esperado, verifique estes problemas comuns:
1. Formatação incorreta dos resultados das ferramentas
O problema mais comum é formatar os resultados das ferramentas incorretamente no histórico da conversa. Isso "ensina" Claude a evitar chamadas em paralelo.
Especificamente para o uso de ferramentas em paralelo:
// Wrong: separate user messages reduce parallel tool use
[
{"role": "assistant", "content": [tool_use_1, tool_use_2]},
{"role": "user", "content": [tool_result_1]},
{"role": "user", "content": [tool_result_2]} // Separate message
]
// Correct: one user message with all results maintains parallel tool use
[
{"role": "assistant", "content": [tool_use_1, tool_use_2]},
{"role": "user", "content": [tool_result_1, tool_result_2]} // Single message
]Consulte Lidar com chamadas de ferramentas para outras regras de formatação.
2. Prompting fraco
O prompting padrão pode não ser suficiente. Use o prompt do sistema mais forte de Maximizando o uso de ferramentas em paralelo.
3. Medindo o uso de ferramentas em paralelo
Para verificar se as chamadas de ferramentas em paralelo estão funcionando:
4. Chamadas em um lote parecem depender umas das outras
A ordem de execução é escolha sua. Se suas ferramentas têm dependências de ordenação, executar o lote sequencialmente e parar na primeira falha é uma estratégia válida: retorne is_error: true para qualquer chamada que você não executou. Se você executar em paralelo e uma chamada falhar porque seu pré-requisito não havia sido concluído, retorne is_error: true com a mensagem de erro natural. Claude reemitirá a chamada no próximo turno. Para reduzir a ocorrência de chamadas dependentes aparecendo juntas, adicione isto ao seu prompt do sistema: "Only batch tool calls that are independent of each other."
Use a abstração Tool Runner do SDK para lidar com o loop agêntico, o encapsulamento de erros e a segurança de tipos automaticamente.
Analise blocos tool_use, formate respostas tool_result e trate erros com is_error.
Especifique esquemas de ferramentas, escreva descrições eficazes e controle quando Claude chama suas ferramentas.
Was this page helpful?
client = Anthropic()
# Define as ferramentas
tools = [
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
},
{
"name": "get_time",
"description": "Get the current time in a given timezone",
"input_schema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "The timezone, e.g. America/New_York",
}
},
"required": ["timezone"],
},
},
]
# Testa a conversa com chamadas de ferramentas em paralelo
messages = [
{
"role": "user",
"content": "What's the weather in SF and NYC, and what time is it there?",
}
]
# Faz a requisição inicial
print("Requesting parallel tool calls...")
response = client.messages.create(
model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)
# Verifica chamadas de ferramentas em paralelo
tool_uses = [block for block in response.content if block.type == "tool_use"]
print(f"\n✓ Claude made {len(tool_uses)} tool calls")
if len(tool_uses) > 1:
print("✓ Parallel tool calls detected!")
for tool in tool_uses:
print(f" - {tool.name}: {tool.input}")
else:
print("✗ No parallel tool calls detected")
# Simula a execução das ferramentas e formata os resultados corretamente
tool_results = []
for tool_use in tool_uses:
if tool_use.name == "get_weather":
if "San Francisco" in str(tool_use.input):
result = "San Francisco: 68°F, partly cloudy"
else:
result = "New York: 45°F, clear skies"
else: # get_time
if "Los_Angeles" in str(tool_use.input):
result = "2:30 PM PST"
else:
result = "5:30 PM EST"
tool_results.append(
{"type": "tool_result", "tool_use_id": tool_use.id, "content": result}
)
# Continua a conversa com os resultados das ferramentas
messages.extend(
[
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}, # All results in one message!
]
)
# Obtém a resposta final
print("\nGetting final response...")
final_response = client.messages.create(
model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)
final_text = next(
block.text for block in final_response.content if block.type == "text"
)
print(f"\nClaude's response:\n{final_text}")
# Verifica a formatação
print("\n--- Verification ---")
print(f"✓ Tool results sent in single user message: {len(tool_results)} results")
print("✓ No text before tool results in content array")
print("✓ Conversation formatted correctly for future parallel tool use")client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
],
tool_choice={"type": "auto", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
],
tool_choice={"type": "any", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)messages = [] # Message objects returned by client.messages.create across your run
tool_call_messages = [
msg for msg in messages if any(block.type == "tool_use" for block in msg.content)
]
total_tool_calls = sum(
len([block for block in msg.content if block.type == "tool_use"])
for msg in tool_call_messages
)
avg_tools_per_message = (
total_tool_calls / len(tool_call_messages) if tool_call_messages else 0.0
)
print(f"Average tools per message: {avg_tools_per_message}")
# Deve ser > 1.0 se as chamadas paralelas estiverem funcionando