from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command
# Estado compartilhado
class AgentState(TypedDict, total=False):
comentario_original: str
analise_do_agente: str
politicas_relevantes: str
status_da_moderacao: str
justificativa_final: str
aprovacao_humana: str
DIRETRIZES = {
"spam": "Proibido divulgar links, promoções enganosas e spam.",
"ofensivo": "Proibido insultar ou atacar outros usuários."
}
def agente_analisador(state: AgentState):
txt = state["comentario_original"].lower()
if any(x in txt for x in ["http", "grátis", "compre agora"]):
return {"analise_do_agente": "potencialmente problemático: spam"}
if any(x in txt for x in ["idiota", "burro", "lixo"]):
return {"analise_do_agente": "potencialmente problemático: ofensivo"}
return {"analise_do_agente": "positivo"}
def rota_analise(state: AgentState):
if "potencialmente problemático" in state["analise_do_agente"]:
return "pesquisador"
return "aprovar"
def agente_pesquisador(state: AgentState):
a = state["analise_do_agente"]
if "spam" in a:
return {"politicas_relevantes": DIRETRIZES["spam"]}
return {"politicas_relevantes": DIRETRIZES["ofensivo"]}
def agente_revisor(state: AgentState):
a = state["analise_do_agente"]
p = state.get("politicas_relevantes", "")
if "spam" in a:
s = "Remover por Spam"
elif "ofensivo" in a:
s = "Editar por linguagem inadequada"
else:
s = "Aprovado"
return {"status_da_moderacao": s, "justificativa_final": f"{a}. {p}"}
def aprovar_direto(state: AgentState):
return {
"status_da_moderacao": "Aprovado",
"justificativa_final": "Comentário sem violação."
}
def executar_acao_final(state: AgentState):
if state.get("aprovacao_humana") == "sim":
return {"status_da_moderacao": state["status_da_moderacao"]}
return {
"status_da_moderacao": "Cancelado pelo moderador",
"justificativa_final": "Ação crítica cancelada por intervenção humana."
}
# Grafo
builder = StateGraph(AgentState)
builder.add_node("analisador", agente_analisador)
builder.add_node("pesquisador", agente_pesquisador)
builder.add_node("revisor", agente_revisor)
builder.add_node("aprovar", aprovar_direto)
builder.add_node("executar_acao_final", executar_acao_final)
builder.add_edge(START, "analisador")
builder.add_conditional_edges("analisador", rota_analise, {
"pesquisador": "pesquisador",
"aprovar": "aprovar"
})
builder.add_edge("pesquisador", "revisor")
builder.add_edge("revisor", "executar_acao_final")
builder.add_edge("aprovar", END)
builder.add_edge("executar_acao_final", END)
memory = MemorySaver()
graph = builder.compile(
checkpointer=memory,
interrupt_before=["executar_acao_final"]
)
config = {"configurable": {"thread_id": "mod-1"}}
entrada = {"comentario_original": "Esse curso é lixo, compre agora grátis!"}
# Executa até pausar
for evento in graph.stream(entrada, config=config):
pass
estado = graph.get_state(config).values
print("\n=== PAUSADO PARA REVISÃO HUMANA ===")
print("Análise:", estado.get("analise_do_agente"))
print("Recomendação:", estado.get("status_da_moderacao"))
print("Justificativa:", estado.get("justificativa_final"))
resp = input("Confirmar ação? (sim/não): ").strip().lower()
# Retoma execução com decisão humana
for evento in graph.stream(Command(resume={"aprovacao_humana": resp}), config=config):
pass
resultado = graph.get_state(config).values
print("\n=== RESULTADO FINAL ===")
print("Status:", resultado.get("status_da_moderacao"))
print("Justificativa:", resultado.get("justificativa_final"))