1
resposta

criar agente de e-mails

1️ Arquitetura do Sistema

Fluxo do grafo:

Email recebido

Classificador (LLM + Pydantic)

Router de Triagem

Responder Agendar Ignorar

O agente:

Classifica o e-mail

Decide a ação

Executa ferramenta apropriada

Pode notificar o usuário

2️ Configuração Inicial
Estrutura
email_agent
main.py
.env
requirements.txt
.env
GOOGLE_API_KEY=your_key_here
Instalação
pip install langgraph langchain langchain-google-genai pydantic python-dotenv
3️ Importações e Setup
import os
from dotenv import load_dotenv
from typing import Literal
from pydantic import BaseModel, Field
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.agents import tool
from langgraph.graph import StateGraph, END
from langchain.agents import create_react_agent
from langchain_core.messages import HumanMessage
load_dotenv()

llm = ChatGoogleGenerativeAI(
model="gemini-1.5-flash",
temperature=0
)
4️ Perfil do Usuário e Regras
user_profile = {
"name": "Moacir",
"role": "Advogado",
"priorities": ["processos judiciais", "clientes", "audiências"]
}

triage_rules = """
Regras de Triagem:
1 Se for cliente → Responder
2 Se mencionar reunião → Agendar
3 Se for spam/publicidade → Ignorar
4 Se for urgente → Notificar imediatamente
"""
5️ Simulação de E-mail (Evento Gatilho)
incoming_email = """
Assunto: Reunião urgente sobre audiência

Prezado Dr. Moacir,
Precisamos agendar reunião para tratar da audiência de amanhã.
Att,
Cliente João
"""
6️ Modelo Pydantic para Classificação
class EmailClassification(BaseModel):
reasoning: str = Field(description="Raciocínio para classificar o e-mail")
classification: Literal[
"responder",
"agendar",
"ignorar",
"notificar"
]
7️ Prompt do Sistema
system_prompt = f"""
Você é um assistente que classifica e executa ações sobre e-mails.

Perfil do usuário:
Nome: {user_profile['name']}
Profissão: {user_profile['role']}
Prioridades: {user_profile['priorities']}

{triage_rules}

Analise o e-mail e retorne:

  • reasoning
  • classification
    """
    8️ Ferramentas Agênticas
    WriteMail
    @tool
    def WriteMail(content: str):
    """Envia resposta ao e-mail."""
    return f"E-mail enviado com conteúdo:\n{content}"
    ScheduleMeeting
    @tool
    def ScheduleMeeting(details: str):
    """Agenda reunião no calendário."""
    return f"Reunião agendada: {details}"
    CheckCalendar
    @tool
    def CheckCalendar(date: str):
    """Consulta disponibilidade no calendário."""
    return f"Horários disponíveis na data {date}: 14h e 16h"
    9️ Criando o Agente ReAct
    tools = [WriteMail, ScheduleMeeting, CheckCalendar]

agent = create_react_agent(
llm=llm,
tools=tools,
system_prompt=system_prompt
)
10 Função Classificadora
def classify_email(state):
prompt = system_prompt + f"\nE-mail:\n{state['email']}"
response = llm.invoke(prompt)

# Simulação estruturada (ideal usar with_structured_output)
classification = "agendar"

return {
    "classification": classification,
    "reasoning": response.content
}

1️1️ Router de Triagem
def triage_router(state):
if state["classification"] == "responder":
return "responder_node"
elif state["classification"] == "agendar":
return "agendar_node"
elif state["classification"] == "notificar":
return "notificar_node"
else:
return END
1️2️ Construção do Grafo
builder = StateGraph(dict)

builder.add_node("classify", classify_email)

builder.add_node("responder_node", lambda s: {
"result": WriteMail.invoke("Resposta automática enviada.")
})

builder.add_node("agendar_node", lambda s: {
"result": ScheduleMeeting.invoke("Reunião confirmada.")
})

builder.add_node("notificar_node", lambda s: {
"result": "Usuário notificado via push."
})

builder.set_entry_point("classify")

builder.add_conditional_edges(
"classify",
triage_router,
{
"responder_node": "responder_node",
"agendar_node": "agendar_node",
"notificar_node": "notificar_node",
END: END
}
)

builder.add_edge("responder_node", END)
builder.add_edge("agendar_node", END)
builder.add_edge("notificar_node", END)

graph = builder.compile()
1️3️ Executando o Fluxo
initial_state = {
"email": incoming_email
}

result = graph.invoke(initial_state)

print(result)
Resultado Esperado

Para o e-mail de exemplo:

Classificação → agendar

Ferramenta executada → ScheduleMeeting

Saída → “Reunião agendada…”

1 resposta

Oi, Moacir! Como vai?
Agradeço por compartilhar seu código com a comunidade Alura.

Gostei de como você estruturou a arquitetura do agente, separando bem a etapa de classificação e o roteamento das ações. O uso do StateGraph deixou o fluxo organizado e fácil de entender, principalmente na divisão entre responder, agendar e notificar. Isso facilita muito a manutenção e futuras melhorias no agente.

Uma dica interessante para o futuro é usar o método strip() para remover espaços extras do e-mail antes de enviar para classificação. Isso ajuda a evitar pequenas inconsistências no processamento do texto. Veja este exemplo:


def classify_email(state):
    email = state["email"].strip()
    prompt = system_prompt + "\nEmail:\n" + email
    response = llm.invoke(prompt)
    return {"classification": "agendar", "reasoning": response.content}

Esse código remove espaços no início e no final do texto antes de enviar para o modelo, deixando a entrada mais limpa.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!