You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 03:42:27