← Voltar ao curso
Nível 3 — Automação e escala · Módulo 3.7 — Claude API e agentes sob medida

3.7.3 · Tool use

5 min de vídeo TEC

Objetivo: ao final, o consultor define uma tool com schema, executa o loop agêntico corretamente, conhece o tool runner do SDK como caminho padrão, e sabe distinguir ferramenta que roda no cliente de ferramenta que roda no servidor da Anthropic.

O que você precisa levar desta aula

  1. O Claude nunca executa a sua ferramenta — ele devolve um pedido com nome e argumentos, e quem executa é o seu código. A API conduz a conversa sobre a ferramenta, não a ferramenta.
  2. Dois erros quebram o loop: não devolver response.content inteiro ao histórico (perde o bloco tool_use e a próxima chamada é rejeitada) e separar os tool_result em mensagens diferentes (não dá erro — ensina o modelo a parar de pedir em paralelo).
  3. O tool runner do SDK cuida do laço e é hoje o caminho padrão; o laço manual ficou para quando você precisa de controle que o runner não expõe.

Definindo uma tool

tools = [
    {
        "name": "consultar_pedido",
        "description": (
            "Consulta a situação de um pedido de compra no MRD. "
            "Use quando a pergunta envolver um número de pedido específico — "
            "situação, bloqueio, fornecedor ou itens."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "numero_pedido": {
                    "type": "string",
                    "description": "Número do pedido de compra, 10 dígitos. Ex.: 4500012345",
                },
                "ambiente": {
                    "type": "string",
                    "enum": ["DEV", "QAS", "PRD"],
                    "description": "Ambiente do MRD a consultar. Padrão: QAS.",
                },
            },
            "required": ["numero_pedido"],
        },
    }
]

Três decisões nessa definição valem nota:

O loop agêntico, manual

messages = [{"role": "user", "content": "O pedido 4500012345 está bloqueado? Se estiver, por quê?"}]

while True:
    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=16000,
        tools=tools,
        messages=messages,
    )

    if response.stop_reason != "tool_use":
        break

    # 1) devolve a resposta INTEIRA ao histórico — inclusive os blocos tool_use
    messages.append({"role": "assistant", "content": response.content})

    # 2) executa TODAS as ferramentas pedidas
    resultados = []
    for bloco in response.content:
        if bloco.type == "tool_use":
            try:
                saida = executar(bloco.name, bloco.input)
                resultados.append({
                    "type": "tool_result",
                    "tool_use_id": bloco.id,
                    "content": saida,
                })
            except Exception as e:
                resultados.append({
                    "type": "tool_result",
                    "tool_use_id": bloco.id,
                    "content": f"Erro ao consultar: {e}",
                    "is_error": True,
                })

    # 3) TODOS os resultados numa ÚNICA mensagem de usuário
    messages.append({"role": "user", "content": resultados})

texto = next(b.text for b in response.content if b.type == "text")
Regra O que acontece se você violar
Devolver response.content inteiro A próxima chamada é rejeitada: falta o tool_use correspondente ao tool_result
Um tool_result por tool_use, com o tool_use_id certo A API rejeita a mensagem
Todos os tool_result numa única mensagem de usuário Não dá erro — o modelo aprende a não pedir mais em paralelo. Degradação silenciosa
Ferramenta que falhou volta com is_error: true Omitir o resultado quebra o pareamento; devolver o erro deixa o Claude se recuperar

A terceira linha é a que mais aparece em código de produção com desempenho pior do que deveria — e é invisível, porque nada falha.

O tool runner: o mesmo, sem o laço

import anthropic
from anthropic import beta_tool

client = anthropic.Anthropic()


@beta_tool
def consultar_pedido(numero_pedido: str, ambiente: str = "QAS") -> str:
    """Consulta a situação de um pedido de compra no MRD.

    Use quando a pergunta envolver um número de pedido específico.

    Args:
        numero_pedido: Número do pedido, 10 dígitos.
        ambiente: DEV, QAS ou PRD. Padrão QAS.
    """
    return consulta_real(numero_pedido, ambiente)


runner = client.beta.messages.tool_runner(
    model="claude-opus-5",
    max_tokens=16000,
    tools=[consultar_pedido],
    messages=[{"role": "user", "content": "O pedido 4500012345 está bloqueado?"}],
)

for message in runner:
    print(message)

preview — pode mudar · O tool runner é beta (client.beta.messages). O schema sai da assinatura e do docstring da função — o docstring é a description.

Quando ainda vale o laço manual: transporte próprio, formato de requisição que o SDK não monta, ou fluxo de controle que os ganchos por turno do runner não cobrem. Aprovação humana antes de executar não é motivo — dá para barrar dentro da própria função da tool, devolvendo "o usuário recusou" como resultado.

Ferramentas de servidor

Tipo Quem executa Exemplos
Tool sua Seu código Consulta ao MRD, leitura de arquivo, chamada a API interna
Tool de servidor Anthropic web_search_20260209, web_fetch_20260209, code_execution_20260521
Tool definida pela Anthropic, executada por você Seu código bash, editor de texto — schema fixo, execução sua
tools = [
    {"type": "web_search_20260209", "name": "web_search"},
    {"type": "code_execution_20260521", "name": "code_execution"},
]

Ferramenta de servidor não tem loop: você declara, e o resultado volta como bloco de conteúdo na mesma resposta. Dois pontos práticos:

E há uma decisão de dado embutida. web_search manda a consulta para fora. code_execution roda o código num contêiner da Anthropic. Nos dois casos, o que você mandar sai do seu ambiente — é a mesma análise que o módulo 3.1 fez para servidor MCP e que o 3.9 formaliza.

Regra Wayon Tool que escreve em sistema de cliente — cria, altera, libera, transporta — não é executada direto pelo agente: ela devolve uma proposta que um humano aprova, ou exige confirmação explícita no código antes de executar. Tool de leitura pode rodar automática. E ferramenta de servidor da Anthropic com dado de cliente segue a classificação do módulo 3.9 — o que sai do ambiente é decisão de política, não de conveniência.

📖 Tool use overview · Skills de verdade — módulo 2.4

Quiz — 5 questões

1.No loop de tool use, o que acontece se você acrescentar ao histórico apenas o texto da resposta do assistente, em vez de response.content inteiro?
  • a)Nada — o Claude reconstrói o contexto da ferramenta a partir do tool_result

    Não reconstrói: o pareamento é por tool_use_id, e sem o bloco original não há par.

  • b)A próxima chamada é rejeitada: falta o bloco tool_use que corresponde ao tool_result

    Correto. Todo tool_result precisa do tool_use correspondente no histórico.

  • c)O loop entra em repetição infinita, pedindo a mesma ferramenta sempre

    Não chega a repetir: a requisição é recusada antes.

Ver resposta e por quê
a) Não reconstrói: o pareamento é por tool_use_id, e sem o bloco original não há par.
b) Correto. Todo tool_result precisa do tool_use correspondente no histórico.
c) Não chega a repetir: a requisição é recusada antes.
2.O Claude pediu duas ferramentas na mesma resposta. Você devolve os dois resultados em duas mensagens de usuário separadas. O que acontece?
  • a)A API rejeita a segunda mensagem por falta de tool_use correspondente

    Os dois tool_use existem no histórico; a requisição passa.

  • b)O segundo resultado é ignorado e a ferramenta é pedida de novo

    Ele não é ignorado — a conversa segue normalmente, e é justamente isso que esconde o problema.

  • c)Não dá erro, mas o modelo aprende a parar de pedir ferramentas em paralelo — degradação silenciosa

    Correto. É o motivo de a regra ser "todos os tool_result numa única mensagem".

Ver resposta e por quê
a) Os dois tool_use existem no histórico; a requisição passa.
b) Ele não é ignorado — a conversa segue normalmente, e é justamente isso que esconde o problema.
c) Correto. É o motivo de a regra ser "todos os tool_result numa única mensagem".
3.Uma tool de consulta ao MRD lançou exceção. O que devolver ao Claude?
  • a)Um tool_result com o mesmo tool_use_id, a mensagem de erro e is_error: true

    Correto. Devolver o erro mantém o pareamento e deixa o Claude tentar outro caminho.

  • b)Nada — omitir o resultado e deixar o Claude perceber que a ferramenta falhou

    A omissão quebra o pareamento e a requisição é rejeitada.

  • c)Um tool_result com conteúdo vazio, para não induzir o modelo ao erro

    Conteúdo vazio faz o Claude tratar como resposta válida; a falha precisa ser explícita.

Ver resposta e por quê
a) Correto. Devolver o erro mantém o pareamento e deixa o Claude tentar outro caminho.
b) A omissão quebra o pareamento e a requisição é rejeitada.
c) Conteúdo vazio faz o Claude tratar como resposta válida; a falha precisa ser explícita.
4.Você quer que um humano aprove a execução de uma tool antes de ela rodar. Isso exige abandonar o tool runner e escrever o laço manual?
  • a)Sim — o runner executa toda tool pedida, sem ponto de intervenção

    Ele executa a sua função, e a sua função pode recusar; além disso o runner expõe ganchos por turno.

  • b)Não — a aprovação pode ser feita dentro da própria função da tool, devolvendo "o usuário recusou" como resultado

    Correto. Aprovação humana não é motivo para descer ao laço manual.

  • c)Sim, mas só quando houver mais de uma tool pedida na mesma resposta

    O número de tools não muda nada; a intervenção cabe na função em qualquer caso.

Ver resposta e por quê
a) Ele executa a sua função, e a sua função pode recusar; além disso o runner expõe ganchos por turno.
b) Correto. Aprovação humana não é motivo para descer ao laço manual.
c) O número de tools não muda nada; a intervenção cabe na função em qualquer caso.
5.Qual é a consequência prática de declarar web_search numa aplicação que processa chamados do Meridiano? ---
  • a)Nenhuma além do custo: a busca roda no contexto isolado do seu processo

    Ela roda na infraestrutura da Anthropic, não no seu processo.

  • b)O código passa a precisar de um loop de execução para a busca, como nas tools próprias

    Ferramenta de servidor não tem loop — o resultado volta na mesma resposta.

  • c)A consulta sai do seu ambiente, o que é decisão de classificação de dado, não de conveniência

    Correto. É a mesma análise feita para servidor MCP no módulo 3.1 e formalizada no 3.9.

Ver resposta e por quê
a) Ela roda na infraestrutura da Anthropic, não no seu processo.
b) Ferramenta de servidor não tem loop — o resultado volta na mesma resposta.
c) Correto. É a mesma análise feita para servidor MCP no módulo 3.1 e formalizada no 3.9.