Você já leu umas doze postagens de "agentes de IA chegaram!" só neste mês. A Anthropic lançou o Managed Agents em 8 de abril. O Google lançou o ADK. A OpenAI empurrou o Agents SDK deles. Toda apresentação fala "agentes autônomos" como se fosse um feitiço mágico. Mas você nunca construiu o loop real que alimenta todos eles — as 50 linhas de Python onde um modelo chama uma função, lê o resultado e decide o que fazer em seguida. Sem isso, toda demo de fornecedor parece igualmente impressionante, e você não consegue distinguir uma feature real de uma embalagem de presente cara.
Por que "Só Usar uma Plataforma" Não Funciona
A jogada óbvia: escolher uma plataforma gerenciada e deixar ela cuidar de tudo. Mas o problema é que você está terceirizando o entendimento. O Managed Agents da Anthropic cobra $0,08 por hora de sessão. O Agents SDK da OpenAI tem suas próprias abstrações. O Google ADK usa workflows baseados em grafos. Cada plataforma encapsula o mesmo padrão central em opiniões diferentes sobre memória, permissões e cobrança — mas se você não conhece o padrão em si, não consegue avaliar quais opiniões importam para o SEU caso de uso. Uma análise de 2024 da MIT Sloan Management Review sobre projetos de IA empresarial coloca a taxa de sucesso de piloto-para-produção em IA agêntica em cerca de 5%. O modo de falha não é o framework. São equipes que não entendem o que está por baixo.
Então vamos construir a coisa.
A Receita: 50 Linhas para Visão de Raio-X
Passo 0: Instalar o SDK
Em 27 de abril de 2026, o SDK Python mais recente da Anthropic — um kit de ferramentas que permite ao seu código Python conversar com o cérebro do Claude — é o v0.97.0. Um comando:
pip install anthropic
Configure sua API key — uma senha secreta que identifica sua conta nos servidores da Anthropic:
export ANTHROPIC_API_KEY="sk-ant-..."
Passo 1: Definir Suas Tools
Tools são funções que o Claude pode pedir para você executar. Você as descreve usando JSON Schema — um formato padronizado para dizer "essa função recebe esses inputs nessas formas." O Claude lê essas descrições como um cardápio e escolhe o que pedir.
Insight crítico: descrições importam mais que nomes. O Claude decide quando chamar uma tool com base no que a descrição diz. Descrição vaga = comportamento imprevisível.
/faion é a skill guarda-chuva do faion-network — ela puxa metodologia relevante de 12 domínios especializados (dev, produto, marketing, ops, ...) para a conversa, baseada na sua sessão atual.
/faion
Qual a forma correta de projetar schemas de parâmetros para uma tool MCP que
um LLM vai chamar autonomamente? Foco em qualidade de descrição, campos
required e restrições de enum.
Aqui está uma definição real de tool — uma consulta de clima e um criador de eventos no calendário:
tools = [
{
"name": "get_weather",
"description": "Get current weather for a city. Use when the user asks about weather, temperature, or outdoor conditions.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name, e.g. 'New York'"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
},
{
"name": "create_event",
"description": "Create a calendar event. Use when the user wants to schedule, book, or plan something.",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"start": {"type": "string", "format": "date-time"},
"end": {"type": "string", "format": "date-time"}
},
"required": ["title", "start", "end"]
}
}
]
Observe: required controla o comportamento. Pule um campo required e assista o Claude alucinar valores. Exija campos demais e chamadas válidas serão bloqueadas.
Passo 2: Construir a Camada de Execução
É aqui que o SEU código roda. O Claude nunca executa nada por conta própria — ele manda um pedido educado tipo "por favor rode get_weather com {city: 'Chicago'}", e seu código faz o trabalho de verdade:
def run_tool(name, input_data):
if name == "get_weather":
# Em produção, você chamaria uma API de clima aqui
return {"temp": 72, "condition": "sunny", "city": input_data["city"]}
if name == "create_event":
return {"event_id": "evt_456", "status": "created", "title": input_data["title"]}
return {"error": f"Unknown tool: {name}"}
Passo 3: O Loop — Onde a Agência Acontece
Essa é a parte que toda plataforma envolve em milhares de linhas de abstração. O loop agêntico — o ciclo onde o Claude chama tools, lê resultados e decide o próximo passo — tem mais ou menos 20 linhas:
import json
import anthropic
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What's the weather in Chicago? If it's nice, schedule a picnic tomorrow at noon."}]
response = client.messages.create(
model="claude-sonnet-4-20250514", max_tokens=1024,
tools=tools, messages=messages
)
while response.stop_reason == "tool_use":
# Claude pode solicitar MÚLTIPLAS tools de uma vez — processe TODAS
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = run_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
response = client.messages.create(
model="claude-sonnet-4-20250514", max_tokens=1024,
tools=tools, messages=messages
)
print(response.content[0].text)
Esse prompt dispara DUAS chamadas de tool autônomas: primeiro get_weather (para checar Chicago), depois create_event (para agendar o piquenique) — e o Claude encadeia sem você mandar. Esse é o momento "ahá": o modelo lê o resultado do clima, decide que o tempo está bom e chama a próxima tool por conta própria.
Toda plataforma de agentes é esse loop mais opiniões sobre memória, permissões, cobrança e deploy empilhadas por cima.
Passo 4: Tratamento de Erros — Não Quebre, Ensine
Quando uma tool falha, não quebre seu loop. Envie o erro de volta com is_error: True para que o Claude possa se adaptar — tentar de novo com input diferente, explicar o problema ou tentar uma abordagem diferente:
/faion
Quais padrões de tratamento de erros funcionam melhor em loops agênticos
com tool-use — especificamente para erros recuperáveis vs fatais? Quando
o agente deve tentar de novo vs desistir?
def run_tool_safe(name, input_data):
try:
return run_tool(name, input_data), False
except Exception as e:
return {"error": str(e)}, True
# Dentro do loop, substitua a construção de tool_results:
result, is_err = run_tool_safe(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
"is_error": is_err
})
O Claude lê o erro e responde de forma inteligente: "Tentei agendar o piquenique mas o calendário só permite eventos em horário comercial. Quer que eu tente sábado de manhã?"
Passo 5: Adicionar um Fusível de Segurança
Um loop descontrolado queima tokens — pequenos pedaços de palavras que o Claude processa, aproximadamente ¾ de uma palavra em inglês cada — até você matar o processo. Adicione um contador:
MAX_ITERATIONS = 10
iteration = 0
while response.stop_reason == "tool_use" and iteration < MAX_ITERATIONS:
iteration += 1
# ... mesmo corpo do loop ...
if iteration >= MAX_ITERATIONS:
print("Loop atingiu o limite de segurança. Algo provavelmente está errado.")
Nenhuma plataforma gerenciada vai te dizer que isso é a primeira coisa a adicionar. Eles lidam com isso silenciosamente — e cobram pelo privilégio.
Armadilhas que Mordem em Produção
1. O bug "só a primeira tool". O Claude pode retornar múltiplos blocos tool_use em uma resposta — checando o clima em três cidades simultaneamente, por exemplo. Se você só processa o primeiro bloco (comum em tutoriais), o modelo fica confuso com resultados faltando. Sintoma: o Claude fica repetindo o mesmo pedido. Correção: itere TODOS os blocos, retorne TODOS os resultados em uma mensagem. O tutorial oficial chama isso de progressão Ring 2 → Ring 3.
2. Inchaço da janela de contexto. A janela de contexto — quanta informação o Claude consegue "ver" de uma vez, como memória de trabalho — enche rápido. Cada chamada de tool e resultado se acumulam. Uma saída verbosa de comando pode consumir milhares de tokens em um turno. O Agent SDK cuida da compactação automaticamente; o SDK bruto não. Correção: resuma saídas grandes antes de alimentá-las de volta, ou trunque para as partes relevantes.
3. Sem sandboxing. Sua função run_tool roda com SUAS permissões. Se o Claude pedir para deletar um arquivo e sua tool obedecer, o arquivo já era. De acordo com a análise da Momentic, o time deles aprendeu isso da pior maneira ao longo de 3 meses de execuções autônomas de agentes: "sandboxing não é opcional... as coisas saem do controle mais rápido do que você imagina."
4. Campos required faltando. Se seu schema diz required: ["city"] mas o usuário diz "como tá o tempo?", o Claude vai alucinar uma cidade em vez de perguntar. Correção: torne a descrição explícita — "Se o usuário não especificar uma cidade, pergunte em vez de adivinhar."
O Que Você Pode Fazer Agora
Você tem um loop agêntico funcional. Todo anúncio de fornecedor a partir de agora mapeia diretamente para ele. Managed Agents? É o seu loop mais checkpointing, monitoramento e recuperação de falhas — por $0,08/hora de sessão. Agents SDK da OpenAI vs Google ADK? Mesmo loop, opiniões diferentes sobre handoff e workflows baseados em grafos.
O próximo pitch de plataforma chega na sua mesa. Em vez de confiar na demo, você pergunta: qual camada do MEU loop isso substitui — e essa camada é realmente meu gargalo?





