LangGraph: Criando Agentes de IA com Python | python.dev.br
Aprenda a usar LangGraph para criar agentes de IA com grafos, memória e controle humano em Python. Tutorial prático com exemplos reais.
Se você acompanha o ecossistema Python em 2026, já deve ter notado que agentes de IA deixaram de ser curiosidade de laboratório e viraram ferramenta de produção. Frameworks como CrewAI e OpenAI Agents SDK trouxeram o conceito para mais perto dos desenvolvedores, mas quando o assunto é controle fino, durabilidade e fluxos complexos, o LangGraph se destaca como a principal escolha.
Neste artigo, vamos entender o que é o LangGraph, por que ele se diferencia de outras abordagens, e construir um agente funcional passo a passo em Python. Se você já trabalha com LLMs e APIs de IA ou conhece o OpenAI Agents SDK, vai perceber como o LangGraph complementa esse ecossistema.
O que é o LangGraph?
O LangGraph é um framework open-source (licença MIT) criado pela equipe do LangChain para orquestrar agentes de IA como grafos dirigidos. Em vez de encadear chamadas de LLM de forma linear, você define nós (funções de processamento) e arestas (transições entre nós), criando fluxos que podem ter ciclos, ramificações condicionais e estado persistente.
A versão 1.1.6, lançada em abril de 2026, consolidou o LangGraph como padrão para aplicações que precisam de:
- Execução durável — o agente persiste através de falhas e retoma de onde parou
- Human-in-the-loop — pontos de aprovação humana antes de ações críticas
- Memória — estado de curto e longo prazo entre interações
- Streaming — respostas parciais em tempo real para o usuário
Por que grafos em vez de chains?
Se você já usou LangChain, sabe que uma chain é uma sequência linear: prompt → LLM → parser → saída. Isso funciona para tarefas simples, mas agentes reais precisam de decisões dinâmicas.
Imagine um assistente que:
- Recebe uma pergunta do usuário
- Decide se precisa buscar dados na web ou no banco
- Executa a busca escolhida
- Analisa o resultado e decide se precisa de mais informação
- Gera a resposta final
Esse fluxo tem ramificações (passo 2) e ciclos (passo 4 pode voltar ao passo 2). Um grafo modela isso naturalmente. Uma chain linear, não.
Instalação e setup inicial
Primeiro, instale o LangGraph e as dependências. Se você usa o uv como gerenciador de pacotes, o processo é direto:
# Com uv (recomendado)
# uv add langgraph langchain-openai
# Com pip tradicional
# pip install langgraph langchain-openai
Você também precisa de uma chave de API de um provedor de LLM. Neste tutorial, usaremos a OpenAI, mas o LangGraph funciona com qualquer provedor compatível com LangChain.
import os
os.environ["OPENAI_API_KEY"] = "sua-chave-aqui"
Conceitos fundamentais
Antes de construir o agente, vamos entender os três pilares do LangGraph:
1. State (Estado)
O estado é um dataclass ou TypedDict que carrega todas as informações do agente entre os nós:
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
class EstadoAgente(TypedDict):
mensagens: Annotated[list, add_messages]
tentativas: int
resultado_final: str
O add_messages é um reducer — em vez de substituir a lista de mensagens, ele acumula novas mensagens ao estado existente.
2. Nodes (Nós)
Cada nó é uma função Python que recebe o estado atual e retorna as atualizações:
from langchain_openai import ChatOpenAI
modelo = ChatOpenAI(model="gpt-4o-mini", temperature=0)
def chatbot(estado: EstadoAgente) -> dict:
resposta = modelo.invoke(estado["mensagens"])
return {"mensagens": [resposta]}
3. Edges (Arestas)
As arestas definem o fluxo entre nós. Podem ser fixas ou condicionais:
def decidir_proximo(estado: EstadoAgente) -> str:
ultima = estado["mensagens"][-1]
if ultima.tool_calls:
return "ferramentas"
return "fim"
Construindo um agente completo
Vamos criar um agente que pesquisa informações e responde perguntas usando ferramentas. Este exemplo mostra o padrão ReAct (Reasoning + Acting) implementado como grafo:
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode
from langchain_core.tools import tool
# Definindo uma ferramenta simples
@tool
def buscar_clima(cidade: str) -> str:
"""Busca a previsão do tempo para uma cidade."""
# Em produção, aqui teria uma chamada real a uma API
climas = {
"São Paulo": "Parcialmente nublado, 22°C",
"Rio de Janeiro": "Ensolarado, 31°C",
"Curitiba": "Chuva leve, 16°C",
}
return climas.get(cidade, f"Dados não disponíveis para {cidade}")
@tool
def buscar_populacao(cidade: str) -> str:
"""Busca a população estimada de uma cidade brasileira."""
populacoes = {
"São Paulo": "12,4 milhões",
"Rio de Janeiro": "6,8 milhões",
"Curitiba": "1,9 milhão",
}
return populacoes.get(cidade, f"Dados não disponíveis para {cidade}")
# Configurando o modelo com as ferramentas
ferramentas = [buscar_clima, buscar_populacao]
modelo_com_tools = modelo.bind_tools(ferramentas)
# Nó do chatbot
def chatbot(estado: EstadoAgente) -> dict:
resposta = modelo_com_tools.invoke(estado["mensagens"])
return {"mensagens": [resposta]}
# Função de roteamento condicional
def roteador(estado: EstadoAgente) -> str:
ultima_mensagem = estado["mensagens"][-1]
if hasattr(ultima_mensagem, "tool_calls") and ultima_mensagem.tool_calls:
return "ferramentas"
return END
# Montando o grafo
grafo = StateGraph(EstadoAgente)
grafo.add_node("chatbot", chatbot)
grafo.add_node("ferramentas", ToolNode(ferramentas))
grafo.add_edge(START, "chatbot")
grafo.add_conditional_edges("chatbot", roteador)
grafo.add_edge("ferramentas", "chatbot")
agente = grafo.compile()
Para executar o agente:
from langchain_core.messages import HumanMessage
resultado = agente.invoke({
"mensagens": [HumanMessage(content="Qual o clima em São Paulo e a população de Curitiba?")],
"tentativas": 0,
"resultado_final": "",
})
for msg in resultado["mensagens"]:
print(f"{msg.type}: {msg.content}")
O agente automaticamente decide que precisa chamar duas ferramentas, executa ambas, e depois gera uma resposta consolidada. Esse ciclo de raciocínio → ação → observação é o coração do padrão ReAct.
Adicionando memória persistente
Uma das maiores vantagens do LangGraph é a memória entre conversas. Com um checkpointer, o estado do agente sobrevive entre sessões:
from langgraph.checkpoint.memory import MemorySaver
memoria = MemorySaver()
agente_com_memoria = grafo.compile(checkpointer=memoria)
# Primeira interação
config = {"configurable": {"thread_id": "conversa-1"}}
resultado1 = agente_com_memoria.invoke(
{"mensagens": [HumanMessage(content="Meu nome é Diego")], "tentativas": 0, "resultado_final": ""},
config=config,
)
# Segunda interação — o agente lembra do nome
resultado2 = agente_com_memoria.invoke(
{"mensagens": [HumanMessage(content="Qual é meu nome?")], "tentativas": 0, "resultado_final": ""},
config=config,
)
# O agente responde: "Seu nome é Diego"
Para produção, o LangGraph oferece checkpointers para PostgreSQL e SQLite, garantindo durabilidade real dos dados.
Human-in-the-loop: aprovação humana
Em cenários críticos, você quer que um humano aprove antes do agente executar uma ação. O LangGraph suporta isso nativamente com interrupt:
from langgraph.types import interrupt
@tool
def executar_pagamento(valor: float, destino: str) -> str:
"""Executa um pagamento financeiro."""
aprovacao = interrupt({
"acao": "pagamento",
"valor": valor,
"destino": destino,
"pergunta": f"Aprovar pagamento de R${valor:.2f} para {destino}?"
})
if aprovacao == "sim":
return f"Pagamento de R${valor:.2f} para {destino} realizado."
return "Pagamento cancelado pelo usuário."
Quando o agente chega nesse ponto, a execução pausa e espera a aprovação humana. Isso é essencial para aplicações financeiras e outras situações críticas.
Streaming de respostas
Para interfaces de chat, você quer mostrar a resposta conforme ela é gerada:
async for evento in agente_com_memoria.astream_events(
{"mensagens": [HumanMessage(content="Explique Python em 3 parágrafos")], "tentativas": 0, "resultado_final": ""},
config=config,
version="v2",
):
if evento["event"] == "on_chat_model_stream":
token = evento["data"]["chunk"].content
if token:
print(token, end="", flush=True)
Quando usar LangGraph vs alternativas
| Cenário | LangGraph | OpenAI Agents SDK | CrewAI |
|---|---|---|---|
| Fluxos complexos com ciclos | Excelente | Limitado | Bom |
| Human-in-the-loop | Nativo | Manual | Básico |
| Memória persistente | Nativo | Manual | Básico |
| Facilidade de começar | Moderada | Alta | Alta |
| Controle de estado | Total | Parcial | Parcial |
| Vendor lock-in | Nenhum (MIT) | OpenAI | Nenhum |
Se você precisa de controle total sobre o fluxo de execução e durabilidade em produção, o LangGraph é a escolha certa. Para protótipos rápidos ou agentes simples, o OpenAI Agents SDK pode ser mais direto.
Boas práticas para produção
- Defina estados tipados — use type hints para evitar erros em tempo de execução
- Limite ciclos — configure
recursion_limitpara evitar loops infinitos - Use checkpointers — nunca rode agentes em produção sem persistência de estado
- Monitore com tracing — o LangSmith integra nativamente para observabilidade
- Teste cada nó isoladamente — como são funções puras, cada nó pode ser testado com pytest
Conclusão
O LangGraph amadureceu em 2026 como o framework padrão para agentes de IA em Python que precisam ir além de chamadas lineares a LLMs. A abstração de grafos oferece flexibilidade para modelar qualquer fluxo, enquanto recursos como memória, streaming e human-in-the-loop resolvem problemas reais de produção.
Se você está começando com Python e IA, vale começar pelo nosso guia de Python e LLMs antes de mergulhar no LangGraph. Já para quem quer explorar performance e tipagem, confira como o ty type checker pode ajudar em projetos grandes.
Para quem também trabalha com outras linguagens, vale conferir como Go lida com concorrência em golang.com.br — a comparação entre agentes Python e goroutines Go é fascinante. Quem usa Rust para performance pode explorar rustlang.com.br e entender como o Rust complementa pipelines de IA.
Equipe python.dev.br
Contribuidor do Python Brasil — Aprenda Python em Português