Spaces:
Sleeping
Sleeping
| """ | |
| graph.py โ LangGraph ็ถๆๆบ็ป่ฃ | |
| ๅพ็ปๆ๏ผ | |
| [START] | |
| โ | |
| intent_router | |
| โ | |
| โโโโโโดโโโโโโโโโโโโโโโโโ | |
| โ mode==overview โ mode==followup/decompose | |
| โผ โผ | |
| tutor decomposer | |
| โ โ | |
| โ โโโโโโโโโโโโโดโโโโโโโโโโโโโ | |
| โ โ needs_decomposition? โ | |
| โ โโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| โ Yes โ No โ | |
| โ [END: ่ฟๅ tutor | |
| โ decompose โ | |
| โ plan็ปๅ็ซฏ] โ | |
| โ โ | |
| โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค | |
| โผ | |
| offtopic_eval | |
| โ | |
| [END] | |
| thread_id ่ฏดๆ๏ผ | |
| - ๅฝๅไฝไธบ config["configurable"]["thread_id"] ไผ ๅ ฅ graph.invoke() | |
| - ๅพไฝฟ็จ MemorySaver๏ผๅ ๅญ๏ผ่ฟ็จๅ session ็บงๅซ็ checkpointing๏ผ | |
| - ๆชๆฅๆฟๆขไธบ PostgresSaver / RedisSaver ๆถ๏ผๅช้ๆดๆน checkpointer๏ผๅ ถไฝไธๅ | |
| """ | |
| from __future__ import annotations | |
| from langgraph.checkpoint.memory import MemorySaver | |
| from langgraph.graph import END, START, StateGraph | |
| from agent.nodes.decomposer import decomposer_node | |
| from agent.nodes.offtopic_eval import offtopic_eval_node | |
| from agent.nodes.tutor import tutor_node | |
| from agent.nodes.tree_writer import tree_writer_node | |
| from agent.nodes.anchor_locator import anchor_locator_node | |
| from agent.state import AgentState | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # Router functions๏ผๆกไปถ่พน๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def route_after_intent(state: AgentState) -> str: | |
| """intent_router ๅ็่ทฏ็ฑ๏ผoverview ็ดๆฅๅฐ tutor๏ผๅ ถไฝๅ ็ป decomposer""" | |
| mode = state.get("mode", "followup") | |
| if mode == "tree_writer": | |
| return "tree_writer" | |
| if mode == "overview" or state.get("skip_decomposition", False): | |
| return "tutor" | |
| return "decomposer" | |
| def route_after_locator(state: AgentState) -> str: | |
| """anchor_locator ๅ็่ทฏ็ฑ๏ผๅคไบ็บฏๆ่งฃๆจกๅผ(decompose)ๆ้่ฆๆ่งฃ โ END๏ผๅฆๅ็ปง็ปญ tutor""" | |
| if state.get("mode") == "decompose" or state.get("needs_decomposition", False): | |
| return END | |
| return "tutor" | |
| def route_after_tutor(state: AgentState) -> str: | |
| """overview ไธ้่ฆ่ทๅๆฃๆต๏ผfollowup ๆ่งฃๆ [OFFTOPIC] ๆงๅถๆ ่ฎฐใ""" | |
| if state.get("mode") == "overview": | |
| return END | |
| return "offtopic_eval" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # Intent Router Node๏ผ่ฝป้๏ผไป ๅ mode ๆ ก้ช๏ผไธ่ฐ็จ LLM๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def intent_router_node(state: AgentState) -> dict: | |
| """ๆ ก้ชๅนถ่ง่ๅ mode ๅญๆฎต๏ผๆ ้ LLM ่ฐ็จ""" | |
| mode = state.get("mode", "followup") | |
| if mode not in ("overview", "followup", "decompose", "tree_writer"): | |
| mode = "followup" | |
| return {"mode": mode} | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๅพ็ๆๅปบไธ็ผ่ฏ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def build_graph(): | |
| """ๆๅปบๅนถ่ฟๅ็ผ่ฏๅฅฝ็ LangGraph ๅพ๏ผไฝฟ็จ MemorySaver ไฝไธบไธดๆถ Checkpointer๏ผ""" | |
| builder = StateGraph(AgentState) | |
| # ๆณจๅ Nodes | |
| builder.add_node("intent_router", intent_router_node) | |
| builder.add_node("decomposer", decomposer_node) | |
| builder.add_node("anchor_locator", anchor_locator_node) | |
| builder.add_node("tutor", tutor_node) | |
| builder.add_node("offtopic_eval", offtopic_eval_node) | |
| builder.add_node("tree_writer", tree_writer_node) | |
| # ๅ ฅๅฃ | |
| builder.add_edge(START, "intent_router") | |
| # intent_router โ tutor๏ผoverview๏ผๆ decomposer๏ผfollowup/decompose๏ผ | |
| builder.add_conditional_edges( | |
| "intent_router", | |
| route_after_intent, | |
| {"tutor": "tutor", "decomposer": "decomposer", "tree_writer": "tree_writer"}, | |
| ) | |
| # tree_writer โ END๏ผ็ปๆๅ mount plan๏ผ | |
| builder.add_edge("tree_writer", END) | |
| # decomposer โ anchor_locator (ๅฎไฝๅๆ็ๆฎต) | |
| builder.add_edge("decomposer", "anchor_locator") | |
| # anchor_locator โ END๏ผ้ๆ่งฃ๏ผ่ฟๅ plan๏ผๆ tutor๏ผๅไธ้ฎ้ข็ปง็ปญ๏ผ | |
| builder.add_conditional_edges( | |
| "anchor_locator", | |
| route_after_locator, | |
| {END: END, "tutor": "tutor"}, | |
| ) | |
| # tutor โ overview ็ดๆฅ็ปๆ๏ผfollowup ๅ่ฟๅ ฅ off-topic ๆงๅถๆ ่ฎฐ่งฃๆ | |
| builder.add_conditional_edges( | |
| "tutor", | |
| route_after_tutor, | |
| {END: END, "offtopic_eval": "offtopic_eval"}, | |
| ) | |
| # offtopic_eval โ END | |
| builder.add_edge("offtopic_eval", END) | |
| import os | |
| # ๅฆๆๆฃๆตๅฐๆฏๅจ LangGraph API / CLI / Studio ่ฟ่ก็ฏๅข๏ผๅไธไผ ้่ชๅฎไน checkpointer | |
| if any(k.startswith("LANGGRAPH_") for k in os.environ): | |
| return builder.compile() | |
| # MemorySaver๏ผ่ฟ็จๅ checkpointing๏ผ็จไบ thread_id ้็ฆปใ | |
| # ๆชๆฅๆขๆ PostgresSaver ๅช้ๆน่ฟไธ่ก๏ผ | |
| # from langgraph.checkpoint.postgres import PostgresSaver | |
| # checkpointer = PostgresSaver(conn_string=os.environ["DATABASE_URL"]) | |
| checkpointer = MemorySaver() | |
| return builder.compile(checkpointer=checkpointer) | |
| # ๆจกๅ็บงๅไพ๏ผ้ฟๅ ๆฏๆฌก่ฏทๆฑ้ๆฐ็ผ่ฏ | |
| graph = build_graph() | |