Sang-DocAI / backend /agents /graph.py
SangDinhVan's picture
first commit
ae9742b
Raw
History Blame Contribute Delete
2.21 kB
"""
LangGraph orchestrator: wires all nodes with conditional edges.
Flow:
START
→ router_node
├─ CHAT → generator_node → END
└─ RAG → retriever_node → grader_node
├─ retry → retriever_node (max 2x)
└─ generate → generator_node → END
"""
from __future__ import annotations
from langgraph.graph import StateGraph, END
from backend.agents.state import GraphState
from backend.agents.nodes.router import router_node
from backend.agents.nodes.retriever import retriever_node
from backend.agents.nodes.grader import grader_node, should_retry
from backend.agents.nodes.generator import generator_node
def _route_after_router(state: GraphState) -> str:
return state.get("route", "RAG")
def _increment_retry(state: GraphState) -> dict:
"""Node nhỏ chỉ để tăng retry_count trước khi quay lại retriever."""
return {"retry_count": state.get("retry_count", 0) + 1}
def build_graph() -> StateGraph:
graph = StateGraph(GraphState)
# Thêm nodes
graph.add_node("router", router_node)
graph.add_node("retriever", retriever_node)
graph.add_node("grader", grader_node)
graph.add_node("generator", generator_node)
graph.add_node("increment_retry", _increment_retry)
# Entry point
graph.set_entry_point("router")
# Router → CHAT hoặc RAG
graph.add_conditional_edges(
"router",
_route_after_router,
{
"CHAT": "generator",
"RAG": "retriever",
},
)
# Retriever → Grader
graph.add_edge("retriever", "grader")
# Grader → Generate hoặc Retry
graph.add_conditional_edges(
"grader",
should_retry,
{
"retry": "increment_retry",
"generate": "generator",
},
)
# Retry → quay lại retriever
graph.add_edge("increment_retry", "retriever")
# Generator → END
graph.add_edge("generator", END)
return graph.compile()
# Singleton compiled graph
_compiled_graph = None
def get_graph():
global _compiled_graph
if _compiled_graph is None:
_compiled_graph = build_graph()
return _compiled_graph