Código Python sendo escrito para criar um agente de IA
llms-chatbots

Do Prompt ao Agente: Construa um Assistente de IA com Memória e Ferramentas em Python (2026)

NeuralPulse|27 de maio de 2026|12 min de leitura|Read in English
Preparando avatar...
🎬 NeuralPulse Shorts

Se você já chamou a API da OpenAI ou do Google para fazer um chatbot responder perguntas, sabe como é fácil chegar até ali. O problema vem depois: o chatbot não lembra da conversa anterior, não consegue pesquisar na web, não executa código, não faz nada além de texto.

Isso não é um agente. É uma demo.

Um agente de IA de verdade combina quatro componentes: um modelo de linguagem que raciocina, ferramentas que ele pode chamar, memória que persiste entre turnos, e um loop de orquestração que decide o próximo passo. Em 2026, frameworks como LangGraph (126 mil estrelas no GitHub), Vercel AI SDK e Claude Agent SDK tornaram isso acessível para qualquer desenvolvedor.

Neste tutorial, você vai construir um agente funcional em Python em duas abordagens: primeiro o loop ReAct puro para entender o mecanismo, depois com LangGraph para produção. No final, seu agente vai pesquisar na web, calcular expressões, lembrar de conversas anteriores e até persistir estado entre sessões.

O Que Separa um Chatbot de um Agente

Um chatbot recebe uma mensagem e devolve outra. Fim.

Um agente recebe um objetivo, planeja os passos, executa ferramentas, observa os resultados, e repete até concluir a tarefa. A diferença está no loop.

Seu ciclo básico — chamado ReAct (Reasoning + Acting) — funciona assim:

  1. O LLM recebe o histórico + a pergunta do usuário
  2. Ele decide: responder diretamente ou chamar uma ferramenta
  3. Se chamar ferramenta, executa e retorna o resultado para o LLM
  4. O LLM analisa o resultado e decide o próximo passo
  5. Repete até ter resposta final

É enganosamente simples. A maior parte dos erros em agentes de produção vem de implementações apressadas desse loop.

Pense em um cenário real: um assistente de suporte que precisa consultar a base de conhecimento, verificar o status do pedido no sistema e depois responder ao cliente. Sem o loop ReAct, você teria que hardcodar cada etapa. Com o loop, o LLM decide a sequência sozinho baseado nas ferramentas disponíveis.

O Detalhe que Faz Toda a Diferença: tool_choice

No código acima, usei tool_choice="auto". Isso permite que o LLM decida entre responder ou chamar ferramenta. Mas existem duas outras opções importantes:

  • tool_choice="none": força o LLM a responder sem ferramentas — útil quando você quer garantir uma resposta direta
  • tool_choice="required": força o LLM a chamar pelo menos uma ferramenta — bom para pipelines onde toda consulta precisa passar por validação primeiro

A escolha errada aqui é uma das fontes mais comuns de loops infinitos em agentes. Se o LLM fica chamando ferramentas sem nunca chegar a uma resposta final, você precisa de um limite de iterações (como o max_iteracoes=10 no exemplo acima) e um fallback bem definido.

Abordagem 1: Loop ReAct Puro (Sem Framework)

Antes de usar LangGraph, vale a pena escrever o loop manualmente. Você entende o que o framework faz por baixo dos panos.

import json
from openai import OpenAI

client = OpenAI()

TOOLS = [ { "type": "function", "function": { "name": "pesquisar_web", "description": "Pesquisa na web e retorna resumo dos resultados", "parameters": { "type": "object", "properties": { "query": {"type": "string"} }, "required": ["query"] } } }, { "type": "function", "function": { "name": "calcular", "description": "Executa expressão matemática", "parameters": { "type": "object", "properties": { "expressao": {"type": "string"} }, "required": ["expressao"] } } } ]

def executar_ferramenta(nome, args): if nome == "calcular": return str(eval(args["expressao"])) if nome == "pesquisar_web": return f"Resultados simulados para: {args['query']}" return "Ferramenta não encontrada"

def agente_react(mensagem_usuario, max_iteracoes=10): mensagens = [{"role": "user", "content": mensagem_usuario}]

for _ in range(max_iteracoes):
    resposta = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=mensagens,
        tools=TOOLS,
        tool_choice="auto"
    )
    msg = resposta.choices[0].message
    mensagens.append(msg)
    
    if not msg.tool_calls:
        return msg.content
    
    for chamada in msg.tool_calls:
        resultado = executar_ferramenta(
            chamada.function.name,
            json.loads(chamada.function.arguments)
        )
        mensagens.append({
            "role": "tool",
            "tool_call_id": chamada.id,
            "content": resultado
        })

return "Número máximo de iterações atingido"

Esse código funciona. Mas tem problemas: não persiste estado entre sessões, não tem checkpoint para retomar após falha, e o loop linear fica frágil em tarefas com múltiplas ramificações. É aqui que o LangGraph entra.

Abordagem 2: Agente com LangGraph

LangGraph substitui o loop linear por um grafo direcionado com estados tipados, checkpoint nativo e suporte a condicionais. Cada nó do grafo é uma etapa do processamento; cada aresta define como a execução flui.

from langgraph.graph import StateGraph, END
from typing import TypedDict, List
import json

class EstadoAgente(TypedDict): mensagens: List[dict] proximo_passo: str

def node_llm(estado: EstadoAgente): resposta = client.chat.completions.create( model="gpt-4o-mini", messages=estado["mensagens"], tools=TOOLS ) msg = resposta.choices[0].message estado["mensagens"].append(msg) if msg.tool_calls: estado["proximo_passo"] = "ferramentas" else: estado["proximo_passo"] = "fim" return estado

def node_ferramentas(estado: EstadoAgente): ultima_msg = estado["mensagens"][-1] for chamada in ultima_msg.tool_calls: resultado = executar_ferramenta( chamada.function.name, json.loads(chamada.function.arguments) ) estado["mensagens"].append({ "role": "tool", "tool_call_id": chamada.id, "content": resultado }) estado["proximo_passo"] = "llm" return estado

def router(estado: EstadoAgente): if estado["proximo_passo"] == "ferramentas": return "ferramentas" elif estado["proximo_passo"] == "fim": return END return "llm"

grafo = StateGraph(EstadoAgente) grafo.add_node("llm", node_llm) grafo.add_node("ferramentas", node_ferramentas) grafo.set_entry_point("llm") grafo.add_conditional_edges("llm", router) grafo.add_edge("ferramentas", "llm") app = grafo.compile()

A diferença fundamental: com LangGraph, o ciclo llm → ferramentas → llm é explícito no grafo, e cada execução passa por checkpoint automaticamente. Se o processo cair no meio de uma chamada de ferramenta, ele retoma de onde parou.

Por que Grafos São Melhores que Loops Lineares?

O loop ReAct puro é sequencial: uma chamada de ferramenta por vez, sempre na mesma ordem. Um grafo permite:

  • Ramificações condicionais: dependendo da saída do LLM, o fluxo vai para nós diferentes
  • Nós paralelos: múltiplas ferramentas executando ao mesmo tempo
  • Human-in-the-loop: um nó de aprovação que pausa a execução até um humano autorizar
  • Subgrafos: agentes especializados dentro do agente principal, cada um com seu próprio grafo

Em produção, essa flexibilidade não é luxo — é necessidade. Um agente de suporte, por exemplo, pode precisar consultar o banco de clientes e o estoque ao mesmo tempo (paralelo), e só prosseguir se o gerente aprovar um desconto (human-in-the-loop).

Memória Persistente com Checkpoint

O checkpoint nativo do LangGraph é um dos seus diferenciais. Com uma linha, você conecta um banco SQLite e seu agente passa a lembrar de tudo entre sessões:

from langgraph.checkpoint.sqlite import SqliteSaver

with SqliteSaver.from_conn_string("memoria.db") as saver: app = grafo.compile(checkpointer=saver) config = {"configurable": {"thread_id": "usuario-123"}}

resultado = app.invoke(
    {"mensagens": [{"role": "user", "content": "Qual era aquele artigo que discutimos ontem?"}]},
    config
)

Cada thread_id representa uma sessão independente. O agente recupera automaticamente o histórico completo daquele usuário. Isso resolve o problema mais comum de chatbots em produção: a amnésia entre conversas.

Ferramentas Reais: Conectando o Agente ao Mundo

Um agente sem ferramentas é um chatbot fancy. Com ferramentas, ele se torna útil. Veja como adicionar uma busca real na web usando a API de busca do DuckDuckGo:

from duckduckgo_search import DDGS

def pesquisar_web(query: str) -> str: with DDGS() as ddgs: resultados = list(ddgs.text(query, max_results=3)) return "\n".join( f"{r['title']}: {r['body'][:200]}" for r in resultados )

Basta registrar a ferramenta no array TOOLS com a descrição correta. O LLM decide quando usá-la com base na descrição — por isso docstrings claras são essenciais.

Próximos Passos

Seu agente já funciona com ferramentas e memória persistente. A partir daqui, você pode:

  • Adicionar mais ferramentas: calculadora, acesso a banco de dados, envio de e-mail, consulta a APIs externas
  • Multi-agentes: use o padrão supervisor + sub-agentes do LangGraph para delegar tarefas complexas
  • Human-in-the-loop: adicione nós de aprovação antes de ações críticas (enviar e-mail, executar código)
  • Streaming: implemente astream_events do LangGraph para mostrar o raciocínio do agente em tempo real
  • Observabilidade: conecte LangSmith para rastrear cada chamada de ferramenta e custo de tokens

Colocando o Agente no Ar

Com o checkpoint do LangGraph, seu agente já persiste estado. Falta expor ele como uma API. O jeito mais simples é com FastAPI:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Pergunta(BaseModel): mensagem: str sessao: str

@app.post("/chat") async def chat(req: Pergunta): config = {"configurable": {"thread_id": req.sessao}} resultado = app.invoke( {"mensagens": [{"role": "user", "content": req.mensagem}]}, config ) return {"resposta": resultado["mensagens"][-1]["content"]}

Com isso, qualquer frontend — React, Streamlit, até um bot do Telegram — pode conversar com seu agente. Cada sessao vira uma conversa independente com seu próprio histórico.

Resumo: O Mapa para Construir Agentes em 2026

AbordagemComplexidadeProduçãoIdeal para
Loop ReAct puroBaixaNãoAprender o mecanismo
LangGraph básicoMédiaSimAgentes com ferramentas
LangGraph + checkpointMédiaSimAgentes com memória persistente
LangGraph + subgrafosAltaSimSistemas multi-agentes

Comece pelo loop puro, entenda cada peça, e só então migre para o framework. Em 2026, construir agentes não é mais magia. É engenharia de software com um novo tipo de API. Seu eu do futuro — quando o agente quebrar às 3 da manhã — vai agradecer por ter começado com a abordagem certa.

Compartilhar:
NeuralPulse

NeuralPulse

Blog profissional sobre Inteligencia Artificial. Exploramos tendencias, ferramentas, tutoriais e analises profundas sobre como a IA esta transformando negocios, tecnologia e o dia a dia.

Receba as novidades sobre IA

Junte-se a milhares de leitores que acompanham as ultimas tendencias em inteligencia artificial.

Comentarios

Powered by Disqus

Para ativar os comentarios, configure seu shortname do Disqus no componente.

<div id="disqus_thread"></div>