1
resposta

04 Etapa #2

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"))
1 resposta

Olá, Moacir! Como vai?

Parabéns pela resolução da atividade!

Observei que você explorou o uso do TypedDict para estruturar estados de forma clara com Python, utilizou muito bem o StateGraph para definir rotas condicionais de execução e ainda compreendeu a importância da revisão humana para garantir decisões mais seguras em processos críticos de moderação.

Continue postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Sugestão de conteúdo para você mergulhar ainda mais no tema:

Alguns materiais estão em inglês, mas é possível compreendê-los usando o recurso de tradução de páginas do próprio navegador.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

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