Domínio 2 — Tool Design & MCP Integration · Lição 4 de 6

Ferramentas server-side, programmatic tool calling e tool search

Objetivos de aprendizagem

Server-side vs client-side

FerramentaLadoQuem executa
Custom (suas tools), bash, text editor, memory, computer use (self-hosted)ClientSeu harness executa e devolve tool_result
web_search, web_fetch, code_executionServerAnthropic executa; você só declara em tools, sem função para implementar

Declarações atuais (server-side não têm input_schema — só type versionado e name):

[
  { "type": "web_search_20260209", "name": "web_search" },
  { "type": "web_fetch_20260209", "name": "web_fetch" },
  { "type": "code_execution_20260120", "name": "code_execution" }
]

Quando o loop server-side atinge o limite de iterações, a resposta vem com stop_reason: "pause_turn". Para continuar: reenvie a mensagem do usuário + a resposta do assistant e faça novo request — o servidor retoma de onde parou. Não adicione uma mensagem extra "Continue". Limite as continuações (ex.: 5) para evitar loop infinito.

Programmatic tool calling (beta)

No tool use padrão, cada chamada é um round trip: chamada → resultado no contexto → raciocínio → próxima chamada. Com PTC, o modelo escreve um script que roda no container de code execution; quando o script invoca uma ferramenta, o container pausa, a chamada executa e o resultado volta para o código em execução — não para o contexto do modelo. Loops, filtros e agregações acontecem em código, e só a saída final retorna ao modelo.

Para permitir que uma ferramenta custom seja chamada de dentro do container, marque-a com allowed_callers apontando para a ferramenta de code execution (recurso beta):

{
  "name": "get_order",
  "description": "Retorna um pedido pelo ID.",
  "input_schema": {
    "type": "object",
    "properties": { "order_id": { "type": "string" } },
    "required": ["order_id"]
  },
  "allowed_callers": ["code_execution_20260120"]
}

Quando usar: muitas chamadas encadeadas, ou resultados intermediários grandes que devem ser filtrados antes de chegar ao contexto (ex.: iterar 500 pedidos e devolver só o agregado). O custo de tokens escala com a saída final, não com os intermediários.

flowchart TD
    M[Modelo] -->|escreve script| CE[Container de code execution]
    CE -->|invoca get_order em loop| T[Ferramenta client-side]
    T -->|resultado volta ao script| CE
    CE -->|apenas saída final| M
  

Tool search com defer_loading (beta)

Com centenas de ferramentas, carregar todos os schemas no contexto é caro e degrada a seleção. O tool search (recurso beta) deixa o modelo descobrir ferramentas sob demanda: você declara as ferramentas com "defer_loading": true — elas ficam conhecidas pelo request, mas fora do contexto — e inclui a ferramenta de busca; o modelo pesquisa e apenas os schemas relevantes são carregados.

{
  "tools": [
    { "type": "tool_search_tool_20251119", "name": "tool_search_tool" },
    {
      "name": "get_weather",
      "description": "Clima atual por cidade.",
      "input_schema": { "type": "object", "properties": { "city": { "type": "string" } } },
      "defer_loading": true
    }
  ]
}

Os schemas descobertos são anexados ao request, não trocados — isso preserva o prefixo do prompt cache. Compare com editar o array tools diretamente, que invalida o cache inteiro. Tool search é para descoberta pelo modelo; quando é a sua aplicação que decide mudar o conjunto (mode switch, revogação), o recurso análogo é mid-conversation tool changes (também beta).

Exemplo Python: code execution com pause_turn

import anthropic

client = anthropic.Anthropic()

tools = [{"type": "code_execution_20260120", "name": "code_execution"}]
user_query = "Calcule media e desvio padrao de [3, 7, 8, 12, 14] e explique."
messages = [{"role": "user", "content": user_query}]

max_continuations = 5
continuations = 0

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=4096,
    thinking={"type": "adaptive"},
    tools=tools,
    messages=messages,
)

# O loop server-side pode pausar: reenvie para o servidor retomar
while response.stop_reason == "pause_turn" and continuations < max_continuations:
    continuations += 1
    messages = [
        {"role": "user", "content": user_query},
        {"role": "assistant", "content": response.content},
    ]
    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=4096,
        thinking={"type": "adaptive"},
        tools=tools,
        messages=messages,
    )

for block in response.content:
    if block.type == "text":
        print(block.text)
    elif block.type == "bash_code_execution_tool_result":
        print("stdout:", block.content.stdout)

Pegadinhas da prova

Resumo em 5 linhas

  1. Server-side (web_search, web_fetch, code_execution) executa na Anthropic — só declarar; client-side é executada pelo seu harness com tool_result de volta.
  2. stop_reason: "pause_turn" = loop server-side pausado; reenvie usuário + assistant e limite as continuações.
  3. PTC (beta): o modelo compõe chamadas num script no container; ferramentas expostas ao script via allowed_callers; só a saída final volta ao contexto.
  4. Tool search (beta): ferramentas com defer_loading: true são descobertas sob demanda; schemas são anexados, preservando o prompt cache.
  5. Use PTC para cadeias longas/intermediários grandes; tool search para bibliotecas grandes com poucas ferramentas relevantes por request.

Documentação oficial

Questões de fixação

1. Qual é a diferença fundamental entre web_search e uma ferramenta custom definida por você?

2. Uma resposta com code execution veio com stop_reason: "pause_turn". O que fazer?

3. Um agente precisa somar valores de 400 pedidos chamando get_order um a um; os resultados intermediários estouram o contexto e a latência. Qual recurso resolve isso na raiz?

4. Sua plataforma expõe 300 ferramentas internas, mas cada request usa 3–4. Qual abordagem mantém o contexto enxuto e preserva o prompt cache?