From a3e2a5aea406b1b2378b35fef2a9378a9cb987b7 Mon Sep 17 00:00:00 2001 From: root <953994191@qq.com> Date: Sat, 2 May 2026 00:44:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8A=B6=E6=80=81=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=E9=97=AE=E9=A2=98:=20=E7=A7=BB=E9=99=A4=20di?= =?UTF-8?q?ct=20=E8=A7=A3=E5=8C=85=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/main_graph/nodes/llm_call.py | 2 +- backend/app/main_graph/nodes/tool_call.py | 43 +++++++++++------------ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/backend/app/main_graph/nodes/llm_call.py b/backend/app/main_graph/nodes/llm_call.py index 5de699e..f84aa95 100644 --- a/backend/app/main_graph/nodes/llm_call.py +++ b/backend/app/main_graph/nodes/llm_call.py @@ -141,7 +141,7 @@ def create_llm_call_node(llm, tools: list): "has_tool_calls": has_tool_calls } - log_state_change("llm_call", {**state, **result}, "离开") + log_state_change("llm_call", state, "离开") return result except Exception as e: diff --git a/backend/app/main_graph/nodes/tool_call.py b/backend/app/main_graph/nodes/tool_call.py index 0f9a9c3..b871865 100644 --- a/backend/app/main_graph/nodes/tool_call.py +++ b/backend/app/main_graph/nodes/tool_call.py @@ -9,46 +9,46 @@ from langchain_core.messages import AIMessage, ToolMessage from app.main_graph.config import get_stream_writer # 本地模块 -from app.main_graph.state import MessagesState +from app.main_graph.state import MainGraphState from app.utils.logging import log_state_change from app.logger import debug, info def create_tool_call_node(tools_by_name: Dict[str, Any]): """ 工厂函数:创建工具执行节点 - + Args: tools_by_name: 名称到工具函数的映射字典 - + Returns: 异步节点函数 """ - + from langchain_core.runnables.config import RunnableConfig - - async def call_tools(state: MessagesState, config: RunnableConfig) -> Dict[str, Any]: + + async def call_tools(state: MainGraphState, config: RunnableConfig) -> Dict[str, Any]: """ 工具执行节点(异步方法) - + Args: state: 当前对话状态 config: 运行时配置 - + Returns: 包含 ToolMessage 的状态更新 """ log_state_change("tool_node", state, "进入") - - last_message = state['messages'][-1] + + last_message = state.messages[-1] if not isinstance(last_message, AIMessage) or not last_message.tool_calls: log_state_change("tool_node", state, "离开(无工具调用)") return {"messages": []} results = [] loop = asyncio.get_event_loop() - + info(f"🛠️ [工具调用] 准备执行 {len(last_message.tool_calls)} 个工具") - + for tool_call in last_message.tool_calls: tool_name = tool_call["name"] tool_args = tool_call["args"] @@ -66,7 +66,7 @@ def create_tool_call_node(tools_by_name: Dict[str, Any]): # 获取流式写入器并发送工具调用开始事件 writer = get_stream_writer() writer({"type": "custom", "data": {"type": "tool_start", "tool": tool_name}}) - + try: # 修复闭包问题:将变量作为默认参数传入 lambda # 如果工具支持异步 (ainvoke),优先使用异步调用 @@ -75,27 +75,26 @@ def create_tool_call_node(tools_by_name: Dict[str, Any]): else: observation = await loop.run_in_executor( None, - lambda args=tool_args: tool_func.invoke(args) # 默认参数捕获当前值 + lambda args=tool_args: tool_func.invoke(args) ) - - # 字符打印 + result_preview = str(observation).replace("\n", " ") debug(f" └─ ✅ 结果: {result_preview}") results.append(ToolMessage(content=str(observation), tool_call_id=tool_id)) - + # 发送工具调用完成事件 writer({"type": "custom", "data": {"type": "tool_end", "tool": tool_name, "success": True}}) except Exception as e: debug(f" └─ ❌ 异常: {e}") results.append(ToolMessage(content=f"Error: {e}", tool_call_id=tool_id)) - + # 发送工具调用失败事件 writer({"type": "custom", "data": {"type": "tool_end", "tool": tool_name, "success": False, "error": str(e)}}) info(f"🛠️ [工具调用] 执行完成,返回 {len(results)} 条 ToolMessage") - + result = {"messages": results} - log_state_change("tool_node", {**state, **result}, "离开") + log_state_change("tool_node", state, "离开") return result - - return call_tools \ No newline at end of file + + return call_tools