1
resposta

[Projeto] Faça como eu fiz: criar agente de e-mails

Eu implementei:

  1. Perfil do usuário
  2. Regras de triagem
  3. Evento de e-mail simulado
  4. Modelo Pydantic para saída estruturada
  5. Prompt de sistema com placeholders
  6. Ferramentas agênticas com @tool
  7. Agente ReAct com create_react_agent
  8. Grafo de triagem com LangGraph
  9. Router condicional
  10. Fluxos de responder, notificar e ignorar
  11. Simulação de escrita de e-mail
  12. Simulação de agenda
  13. Simulação de consulta de calendário

e economizei os recursos da seguinte forma:

  1. A triagem usa uma única chamada estruturada ao Gemini.
  2. O agente ReAct só roda se a classificação for "responder".
  3. E-mails ignorados não chamam ferramentas.
  4. E-mails apenas notificados não chamam o agente ReAct.
  5. As ferramentas são simuladas, então não há custo externo.

Para trazer mais detalhes do que eu implementei nesta atividade, descrevo da seguinte maneira: criei um agente de e-mails utilizando LangGraph, Pydantic e ferramentas agênticas. O objetivo foi simular um fluxo de triagem automática, no qual um e-mail recebido funciona como evento gatilho para o grafo.

Inicialmente, defini um perfil de usuário e um conjunto de regras de triagem para orientar a classificação dos e-mails. Em seguida, implementei um modelo Pydantic com campos de raciocínio, classificação, prioridade e motivo, garantindo que a resposta do modelo fosse estruturada e mais fácil de utilizar no fluxo.

Também criei ferramentas agênticas com decoradores, como WriteMail, ScheduleMeeting e CheckCalendar, simulando ações que um assistente de e-mails poderia realizar em um ambiente real. Essas ferramentas foram integradas a um agente ReAct criado com create_react_agent, permitindo que o modelo decidisse quando criar rascunhos, consultar disponibilidade ou simular uma reunião.

Por fim, construí um grafo com um nó de triagem e uma função triagem_router, responsável por direcionar o fluxo para responder, notificar ou ignorar o e-mail. Dessa forma, foi possível validar uma arquitetura simples, mas próxima de um cenário real, onde agentes de IA podem auxiliar na organização de mensagens, priorização de demandas e automação controlada de respostas.

link do código: https://github.com/Moquiuti/LangGraph_Orquestrando_agentes_e_multiagentes/blob/main/Criar_agente_de_e_mails.ipynb

1 resposta

Olá, Leandro. Como vai?

Parabéns pela excelente implementação do projeto. O seu fluxo demonstra um entendimento sólido de como arquitetar sistemas multiagentes eficientes usando LangGraph. O grande destaque do seu trabalho foi a preocupação com a otimização de recursos e custos, algo fundamental em cenários de produção.

Ao isolar a lógica de triagem em uma única chamada estruturada e condicionar a execução do agente ReAct apenas quando a ação é responder, você evita o desperdício de tokens com e-mails irrelevantes. Essa estratégia de filtragem prévia é uma das melhores práticas no desenvolvimento de aplicações com LLMs.

Como você compartilhou o seu repositório e o fluxo já está redondo, uma excelente forma de complementar e aprofundar ainda mais o seu projeto seria preparar o grafo para lidar com a persistência de dados. No LangGraph, podemos fazer isso utilizando o conceito de Memory (através de um MemorySaver), o que permite que o agente se lembre do contexto de interações passadas ou mantenha o histórico de e-mails do mesmo remetente.

Veja um exemplo conceitual de como aplicar um checkpoint de memória na hora de compilar o seu grafo:

from langgraph.checkpoint.memory import MemorySaver

# Inicializa a memória em formato de checkpoint
memory = MemorySaver()

# Ao compilar o grafo, você injeta o checkpointer
app = workflow.compile(checkpointer=memory)

# Para rodar mantendo o histórico de uma conversa ou sessão específica:
config = {"configurable": {"thread_id": "usuario_leandro_123"}}
app.invoke({"messages": [evento_email]}, config)

O uso do thread_id garante que, se o mesmo usuário enviar um novo e-mail de acompanhamento (follow-up), o nó de triagem ou o próprio agente ReAct consigam consultar o histórico daquela "thread" específica para tomar decisões ainda mais precisas.

Outro ponto super positivo foi o uso do Pydantic para a saída estruturada. Garantir que o modelo responda estritamente com campos como prioridade e motivo elimina falhas de tipagem na função triagem_router e torna as transições de estado do LangGraph totalmente confiáveis.

Seu projeto ficou com uma estrutura muito próxima do mercado real. Continue explorando essas conexões e testando novas condições no grafo!

Espero que possa ter lhe ajudado!