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…”