From d16ad6185e20214fcf6300b481ece078bf378650 Mon Sep 17 00:00:00 2001 From: root <953994191@qq.com> Date: Fri, 8 May 2026 01:59:19 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=9B=BE?= =?UTF-8?q?=E4=B8=BA=E6=A0=87=E5=87=86=20agent/tools=20=E5=88=86=E7=A6=BB?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/main_graph/main_graph_builder.py | 99 +++++++++++++------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/backend/app/main_graph/main_graph_builder.py b/backend/app/main_graph/main_graph_builder.py index f99445f..09a8ba4 100644 --- a/backend/app/main_graph/main_graph_builder.py +++ b/backend/app/main_graph/main_graph_builder.py @@ -1,12 +1,15 @@ """ -极简 Agent 主图 - 简化版本! -因为完整的 ReAct 循环已经在 agent.py 里了! +Agent 主图 - 标准 LangGraph 结构 +将 ReAct 循环分离为独立的 agent/tools 节点 """ +from typing import Literal from langgraph.graph import StateGraph, START, END from backend.app.main_graph.state import AgentState from backend.app.main_graph.nodes.memory_trigger import memory_trigger_node, set_mem0_client from backend.app.main_graph.nodes.agent import create_agent_node +from backend.app.main_graph.nodes.tools import tools_node +from backend.app.main_graph.nodes.finalize import finalize_node from backend.app.logger import info @@ -16,7 +19,20 @@ def build_agent_graph( max_steps: int = 10 ): """ - 构建简化的 Agent 图(ReAct 循环在 agent 节点内) + 构建标准 Agent 图 + + 节点: + - init_state: 初始化状态 + - memory_trigger: 记忆触发 + - agent: 单步推理 + - tools: 工具执行 + - finalize: 后处理 + + 边: + - START -> init_state -> memory_trigger -> agent + - agent -> (条件边) -> tools 或 finalize + - tools -> agent (循环) + - finalize -> END Args: chat_services: 模型服务字典 @@ -26,57 +42,70 @@ def build_agent_graph( Returns: 构建好的 StateGraph(未编译) """ - # ========== 设置全局客户端 ========== + # 设置全局客户端 if mem0_client: set_mem0_client(mem0_client) - # ========== 1. 初始化节点:重置步数 ========== + # ========== 1. init_state 节点 ========== async def init_state_node(state: AgentState): - info("[Init State] 初始化状态,重置步数") + info("[Init State] 初始化状态") return { "current_step": 0, - "max_steps": max_steps + "max_steps": max_steps, + "tool_call_history": [], + "tool_result_history": [], + "tools_used": [], + "stop": False, + "stop_reason": "", } - # ========== 2. 记忆节点(可选) ========== - retrieve_memory_node = None - if mem0_client: - try: - from ..nodes.retrieve_memory import create_retrieve_memory_node - retrieve_memory_node = create_retrieve_memory_node(mem0_client) - except Exception as e: - info(f"[Graph Builder] 记忆节点初始化失败: {e}") - - # ========== 3. Agent 节点(包含完整 ReAct 循环,支持动态模型切换) ========== + # ========== 2. Agent 节点 ========== agent_node_fn = create_agent_node(chat_services) - # ========== 4. 完成节点 ========== - async def finalize_node_simple(state: AgentState): - info("[Finalize] 进入完成节点") - return {} + # ========== 3. 条件边函数 ========== + def should_continue(state: AgentState) -> Literal["tools", "finalize"]: + """根据 agent 节点输出决定下一步""" + # 手动停止标志 + if getattr(state, "stop", False): + return "finalize" - # ========== 5. 构建图 ========== + # 检查是否有工具调用 + last_msg = state.messages[-1] + if hasattr(last_msg, 'tool_calls') and last_msg.tool_calls: + return "tools" + + return "finalize" + + # ========== 4. 构建图 ========== graph = StateGraph(AgentState) + # 添加节点 graph.add_node("init_state", init_state_node) - if retrieve_memory_node: - graph.add_node("retrieve_memory", retrieve_memory_node) graph.add_node("memory_trigger", memory_trigger_node) graph.add_node("agent", agent_node_fn) - graph.add_node("finalize", finalize_node_simple) + graph.add_node("tools", tools_node) + graph.add_node("finalize", finalize_node) - # ========== 6. 边的连接 ========== + # 边的连接 graph.add_edge(START, "init_state") - - if retrieve_memory_node: - graph.add_edge("init_state", "retrieve_memory") - graph.add_edge("retrieve_memory", "memory_trigger") - else: - graph.add_edge("init_state", "memory_trigger") - + graph.add_edge("init_state", "memory_trigger") graph.add_edge("memory_trigger", "agent") - graph.add_edge("agent", "finalize") + + # 条件边: agent -> tools 或 finalize + graph.add_conditional_edges( + "agent", + should_continue, + { + "tools": "tools", + "finalize": "finalize" + } + ) + + # 循环回边: tools -> agent + graph.add_edge("tools", "agent") + + # 结束 graph.add_edge("finalize", END) - info("✅ [Graph Builder] 简化 Agent 图构建完成(ReAct 在节点内)") + info("✅ [Graph Builder] 标准 Agent 图构建完成") return graph