Construir um agente de IA é relativamente fácil.
Construir um que use ferramentas (tools), exponha uma API e transmita para o cliente o que está acontecendo exige mais algumas peças.
Neste tutorial, vamos construir um exemplo pequeno, mas completo, usando LangGraph, FastAPI e Server-Sent Events (SSE).
O agente vai receber um pedido do usuário, decidir se precisa de uma tool, chamar uma API de clima de verdade quando necessário e devolver o resultado por um endpoint HTTP em streaming.
A arquitetura vai ficar assim:
O objetivo não é construir uma plataforma de produção.
Em vez disso, vamos focar na menor arquitetura que mostra como esses componentes se encaixam numa aplicação real e executável.
No final, você terá uma base funcionando, que pode rodar localmente e estender com suas próprias tools, estado, persistência, autenticação ou frontend.
O código-fonte completo está no repositório que acompanha o artigo:
salada-dados/langgraph-fastapi-example
O que vamos construir
Nossa aplicação tem três responsabilidades principais.
Primeiro, o LangGraph orquestra o agente.
Ele recebe o estado da conversa, chama o modelo de linguagem, decide se uma tool precisa ser executada, executa a tool quando necessário e depois devolve o controle ao modelo.
Segundo, o FastAPI expõe o agente via HTTP.
Em vez de chamar o grafo diretamente de um script Python, os clientes podem interagir com ele por um endpoint de API.
Terceiro, os Server-Sent Events permitem que o servidor envie vários eventos na mesma resposta HTTP.
Isso nos dá uma interface de streaming simples entre o backend e qualquer cliente que consuma o agente.
Conceitualmente, um pedido segue este caminho:
Este é um exemplo propositalmente pequeno, mas a mesma separação de responsabilidades se torna útil em sistemas de agentes maiores.
O grafo cuida da orquestração.
As tools cuidam das interações com capacidades externas.
O FastAPI cuida da interface HTTP.
E o SSE fornece o transporte para enviar as atualizações de volta ao cliente.
Manter essas responsabilidades separadas também vai facilitar estender o exemplo depois.
Estrutura do projeto
A aplicação mantém separadas as responsabilidades da API, do agente e das tools.
Uma visão simplificada do projeto:
app/
├── agents/
│ ├── graph.py
| ├── state.py
│ └── tools.py
│
├── api/
│ └── ...
│
└── main.py
Os arquivos do repositório trazem a implementação completa, mas a distinção de arquitetura que importa é entre o grafo do agente e as tools disponíveis para esse grafo.
graph.py é responsável por montar o agente LangGraph.
tools.py contém as capacidades externas que o modelo pode acionar.
Essa separação importa mais do que parece à primeira vista.
À medida que um agente cresce, o grafo deve descrever como a execução flui, enquanto cada tool deve descrever quais ações externas estão disponíveis.
Uma API de clima, uma consulta ao banco, uma busca em documentos ou uma integração com um serviço de terceiros não deveriam precisar saber como o grafo é orquestrado.
Isso nos dá uma direção de dependência mais ou menos assim:
Neste tutorial, nosso serviço externo é o Open-Meteo.
Criando uma tool de verdade com o Open-Meteo
Uma tool fica interessante quando conecta o modelo a informações que ele ainda não tem.
O clima é um bom exemplo.
Um modelo de linguagem consegue entender uma pergunta como:
Como está o tempo em São Paulo?
Mas ele não tem como saber, de forma confiável, o clima atual a partir dos pesos do modelo.
Essa informação precisa vir de uma fonte externa.
Por isso, nosso agente expõe uma tool de clima que usa o Open-Meteo.
A ideia importante não é o clima em si. É a fronteira que estamos criando:
O modelo não faz requisições HTTP arbitrárias.
Em vez disso, damos a ele uma capacidade controlada, com uma interface definida.
No projeto, a implementação do clima fica em:
app/agents/tools.py
O módulo também expõe a coleção de tools disponíveis para o agente.
Conceitualmente:
TOOLS = [
get_weather,
]
Mais adiante, quando criarmos o modelo, essa coleção de tools será vinculada a ele.
Essa é a ponte entre o raciocínio em linguagem natural e o código executável.
O modelo pode decidir:
Preciso de informações do clima para responder a esta pergunta.
Mas continua sendo responsabilidade da aplicação definir quais capacidades existem de fato e qual código tem permissão para executar.
Essa distinção fica cada vez mais importante quando as tools fazem mais do que buscar informações públicas.
Um agente de produção pode acabar tendo tools capazes de:
search_documents
query_database
create_ticket
send_email
update_customer
schedule_job
Nesse ponto, o design das tools passa a fazer parte da segurança e da arquitetura de domínio da aplicação, e não apenas de um recurso do LLM.
No nosso exemplo, porém, mantemos a tool simples de propósito.
Ela nos dá uma chamada externa real sem tirar o foco do fluxo de execução do LangGraph.
Construindo o agente LangGraph
Agora podemos conectar o modelo de linguagem e as nossas tools.
O LangGraph modela um agente como um grafo de execução.
Em vez de pensar só em termos de:
podemos representar um fluxo em que a execução passa por nós diferentes.
Nosso exemplo precisa de duas capacidades importantes:
O primeiro nó aciona o modelo de linguagem.
O segundo executa as tools solicitadas.
Depois que uma tool roda, o controle volta ao modelo, para que ele interprete o resultado e produza a resposta final.
Isso cria o loop básico do agente:
O LangGraph nos dá uma forma explícita de representar esse loop, em vez de escondê-lo dentro de uma única chamada opaca ao agente.
Esse modelo de execução explícito se torna especialmente útil à medida que os fluxos crescem.
Por exemplo, um grafo maior poderia acabar assim:
Não precisamos dessa complexidade aqui.
O importante é entender a base primeiro:
o estado passa pelos nós, os nós fazem o trabalho e as arestas decidem para onde a execução vai em seguida.
Com o grafo funcionando, o próximo desafio é torná-lo disponível fora do Python.
É aí que o FastAPI entra na arquitetura.
Por que colocar o FastAPI na frente do LangGraph?
Uma aplicação LangGraph roda perfeitamente dentro de um processo Python.
Mas a maioria dos agentes úteis acaba precisando se comunicar com outra coisa:
- uma aplicação web;
- um app mobile;
- outro serviço de backend;
- uma automação;
- ou outro agente.
Isso significa que precisamos de uma fronteira para a aplicação.
O FastAPI nos dá essa fronteira.
Em vez de acoplar um cliente diretamente ao LangGraph, expomos um contrato HTTP:
Essa separação tem uma consequência importante.
O cliente não precisa saber que o LangGraph existe.
Ele só precisa entender a API.
Isso nos deixa livres para mudar o grafo interno sem necessariamente mudar cada consumidor da aplicação.
Mas ainda há um problema.
A execução de um agente nem sempre é instantânea.
Um pedido pode envolver:
Se tratarmos isso como uma requisição HTTP convencional, o cliente pode simplesmente ficar esperando até tudo terminar.
Para uma demo pequena, isso pode ser aceitável.
Para uma aplicação de IA interativa, geralmente não é uma boa experiência.
Queremos que o servidor consiga enviar informações enquanto o pedido ainda está em execução.
Isso nos leva à integração central deste tutorial:
FastAPI + Server-Sent Events + LangGraph.