LangChain Agent的return_direct参数失效问题及解决方案咨询
问题描述
我编写了一段可复现代码搭建回答简单问题的Agent,用来验证return_direct参数的问题:不管把这个参数设为True还是False,工具的输出都会被传递给LLM。相关代码如下:
# Import necessary packages import pandas as pd import sys import os from dotenv import load_dotenv from langchain_community.tools import StructuredTool from typing import Literal from langchain_core.tools import tool from langgraph.prebuilt import create_react_agent from langchain_openai import ChatOpenAI sys.path.append("..") from config import this_dir load_dotenv(os.path.join(this_dir,".env")) # Define function to print final output of Agent def print_stream(stream): for s in stream: message = s["messages"][-1] if isinstance(message, tuple): print(message) else: message.pretty_print() # Define function that will go into the tool def get_weather(city: Literal["nyc", "sf"]): """Use this to get weather information.""" if city == "nyc": return "It might be cloudy in nyc" elif city == "sf": return "It's always sunny in sf" else: raise AssertionError("Unknown city") # Define the tool weather_tool = StructuredTool.from_function( name = "get_weather_information", description="get weather information", func=get_weather, return_direct=True) # Initialize the LLM model. model = ChatOpenAI(model="gpt-4o", temperature=0) # Define toolkit (only 1 tool in this case) tools = [weather_tool] # Define simple system prompt prompt = "Respond in Italian" # Define the graph graph = create_react_agent(model, tools=tools, state_modifier=prompt) # Define user_question inputs = {"messages": [("user", "What's the weather in NYC?")]} # Print messages print_stream(graph.stream(inputs, stream_mode="values"))
请问如何强制Agent直接返回工具的原始输出(即不将输出传递给LLM)?
解决方案
LangGraph的create_react_agent是预构建的React流程,默认逻辑是工具调用后会把结果送回LLM进行最终总结,工具的return_direct参数在这里不起作用——这个参数主要针对LangChain老版本的AgentExecutor,而非LangGraph的流程。
要实现直接返回工具原始输出,需要自定义Agent的流程逻辑,跳过工具调用后的LLM总结步骤。以下是具体实现:
import pandas as pd import sys import os from dotenv import load_dotenv from langchain_community.tools import StructuredTool from typing import Literal from langchain_core.messages import HumanMessage, ToolMessage from langgraph.graph import StateGraph, END from langchain_openai import ChatOpenAI from langgraph.prebuilt import ToolExecutor, ToolInvocation from langchain_core.runnables import RunnableConfig from typing import TypedDict, List sys.path.append("..") from config import this_dir load_dotenv(os.path.join(this_dir,".env")) # 定义Agent的状态结构 class AgentState(TypedDict): messages: List[object] # 定义工具执行器 def get_weather(city: Literal["nyc", "sf"]): """Use this to get weather information.""" if city == "nyc": return "It might be cloudy in nyc" elif city == "sf": return "It's always sunny in sf" else: raise AssertionError("Unknown city") weather_tool = StructuredTool.from_function( name = "get_weather_information", description="get weather information", func=get_weather) tools = [weather_tool] tool_executor = ToolExecutor(tools) # 初始化LLM model = ChatOpenAI(model="gpt-4o", temperature=0).bind_tools(tools) # 定义LLM节点:生成工具调用或直接回答 def call_model(state: AgentState, config: RunnableConfig): messages = state["messages"] response = model.invoke(messages, config) return {"messages": [response]} # 定义工具调用节点 def call_tool(state: AgentState, config: RunnableConfig): messages = state["messages"] # 获取最后一条消息中的工具调用指令 tool_call = messages[-1].tool_calls[0] # 构造工具调用请求 action = ToolInvocation( tool=tool_call["name"], tool_input=tool_call["args"], ) # 执行工具并获取结果 response = tool_executor.invoke(action, config) # 将工具结果转为ToolMessage格式 tool_message = ToolMessage( content=response, tool_call_id=tool_call["id"], ) return {"messages": [tool_message]} # 定义条件判断:是否需要调用工具 def should_continue(state: AgentState): messages = state["messages"] last_message = messages[-1] # 如果存在工具调用指令,进入工具调用节点;否则直接结束流程 if hasattr(last_message, "tool_calls") and last_message.tool_calls: return "call_tool" return END # 构建状态图 graph_builder = StateGraph(AgentState) graph_builder.add_node("call_model", call_model) graph_builder.add_node("call_tool", call_tool) graph_builder.set_entry_point("call_model") # 添加条件边:从LLM节点判断是否需要调用工具 graph_builder.add_conditional_edges( "call_model", should_continue, {"call_tool": "call_tool", END: END}, ) # 工具调用完成后直接终止流程,跳过LLM总结步骤 graph_builder.add_edge("call_tool", END) # 编译状态图 graph = graph_builder.compile() # 打印输出的函数 def print_stream(stream): for s in stream: message = s["messages"][-1] if isinstance(message, ToolMessage): print("工具原始输出:", message.content) else: if isinstance(message, tuple): print(message) else: message.pretty_print() # 测试输入 inputs = {"messages": [HumanMessage(content="What's the weather in NYC?")]} # 运行并打印结果 print_stream(graph.stream(inputs, stream_mode="values"))
关键修改说明
- 手动构建LangGraph状态图,替代预构建的
create_react_agent - 工具调用节点执行完成后直接连接到
END终止流程,跳过将结果送回LLM的步骤 - 自定义状态结构和节点逻辑,确保工具输出直接作为最终结果返回
内容的提问来源于stack exchange,提问作者Andrea Neri
相关产品推荐
相关产品推荐

