Skip to content

工具

工具 是一种将函数及其输入模式封装成可以传递给支持工具调用的聊天模型的方式。这使得模型可以请求使用特定输入执行此函数。

你可以定义自己的工具,或者使用 LangChain 提供的预构建集成

定义简单工具

你可以将一个普通的函数传递给 create_react_agent 用作工具:

API Reference: create_react_agent

from langgraph.prebuilt import create_react_agent

def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

create_react_agent(
    model="anthropic:claude-3-7-sonnet",
    tools=[multiply]
)

create_react_agent 会自动将普通函数转换为 LangChain 工具

自定义工具

为了更精确地控制工具的行为,请使用 @tool 装饰器:

API Reference: tool

from langchain_core.tools import tool

@tool("multiply_tool", parse_docstring=True)
def multiply(a: int, b: int) -> int:
    """Multiply two numbers.

    Args:
        a: First operand
        b: Second operand
    """
    return a * b

你也可以使用 Pydantic 定义自定义的输入模式:

from pydantic import BaseModel, Field

class MultiplyInputSchema(BaseModel):
    """Multiply two numbers"""
    a: int = Field(description="First operand")
    b: int = Field(description="Second operand")

@tool("multiply_tool", args_schema=MultiplyInputSchema)
def multiply(a: int, b: int) -> int:
    return a * b

如需进一步自定义,请参考 自定义工具指南

隐藏模型的参数

一些工具需要运行时专用的参数(例如用户 ID 或会话上下文),这些参数不应由模型控制。

您可以将这些参数放在代理的 stateconfig 中,并在工具内部访问这些信息:

API Reference: InjectedState | AgentState | RunnableConfig

from langgraph.prebuilt import InjectedState
from langgraph.prebuilt.chat_agent_executor import AgentState
from langchain_core.runnables import RunnableConfig

def my_tool(
    # 这将由 LLM 填充
    tool_arg: str,
    # 访问代理内部动态更新的信息
    state: Annotated[AgentState, InjectedState],
    # 访问在调用代理时传递的静态数据
    config: RunnableConfig,
) -> str:
    """My tool."""
    do_something_with_state(state["messages"])
    do_something_with_config(config)
    ...

禁用并行工具调用

一些模型提供商支持并行执行多个工具,但允许用户禁用此功能。

对于受支持的提供商,可以通过 model.bind_tools() 方法设置 parallel_tool_calls=False 来禁用并行工具调用:

API Reference: init_chat_model

from langchain.chat_models import init_chat_model

def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

model = init_chat_model("anthropic:claude-3-5-sonnet-latest", temperature=0)
tools = [add, multiply]
agent = create_react_agent(
    # 禁用并行工具调用
    model=model.bind_tools(tools, parallel_tool_calls=False),
    tools=tools
)

agent.invoke(
    {"messages": [{"role": "user", "content": "what's 3 + 5 and 4 * 7?"}]}
)

直接返回工具结果

使用 return_direct=True 可以立即返回工具结果并停止代理循环:

API Reference: tool

from langchain_core.tools import tool

@tool(return_direct=True)
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

agent = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=[add]
)

agent.invoke(
    {"messages": [{"role": "user", "content": "what's 3 + 5?"}]}
)

强制使用工具

要强制代理使用特定的工具,可以在 model.bind_tools() 中设置 tool_choice 选项:

API Reference: tool

from langchain_core.tools import tool

@tool(return_direct=True)
def greet(user_name: str) -> int:
    """问候用户。"""
    return f"Hello {user_name}!"

tools = [greet]

agent = create_react_agent(
    model=model.bind_tools(tools, tool_choice={"type": "tool", "name": "greet"}),
    tools=tools
)

agent.invoke(
    {"messages": [{"role": "user", "content": "Hi, I am Bob"}]}
)

避免无限循环

在没有停止条件的情况下强制使用工具可能会导致无限循环。请使用以下保护措施之一:

处理工具错误

默认情况下,代理会捕获在调用工具时引发的所有异常,并将这些异常作为工具消息传递给 LLM。要控制如何处理这些错误,可以使用预构建的 ToolNode —— 这是 create_react_agent 中执行工具的节点 —— 通过其 handle_tool_errors 参数:

from langgraph.prebuilt import create_react_agent

def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    if a == 42:
        raise ValueError("The ultimate error")
    return a * b

# Run with error handling (default)
agent = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=[multiply]
)
agent.invoke(
    {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
)
from langgraph.prebuilt import create_react_agent, ToolNode

def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    if a == 42:
        raise ValueError("The ultimate error")
    return a * b

tool_node = ToolNode(
    [multiply],
    handle_tool_errors=False  # (1)!
)
agent_no_error_handling = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=tool_node
)
agent_no_error_handling.invoke(
    {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
)
  1. 这会禁用错误处理(默认是启用的)。有关所有可用策略,请参见 API 参考
from langgraph.prebuilt import create_react_agent, ToolNode

def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    if a == 42:
        raise ValueError("The ultimate error")
    return a * b

tool_node = ToolNode(
    [multiply],
    handle_tool_errors=(
        "Can't use 42 as a first operand, you must switch operands!"  # (1)!
    )
)
agent_custom_error_handling = create_react_agent(
    model="anthropic:claude-3-7-sonnet-latest",
    tools=tool_node
)
agent_custom_error_handling.invoke(
    {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
)
  1. 这会在发生异常时向 LLM 发送自定义消息。有关所有可用策略,请参见 API 参考

有关不同工具错误处理选项的更多信息,请参阅 API 参考

与内存交互

LangGraph 允许从工具中访问短期和长期内存。有关更多信息,请参阅 Memory 指南:

预构建工具

你可以通过向 create_react_agenttools 参数传递一个包含工具规格的字典,使用模型提供商提供的预构建工具。例如,要使用来自 OpenAI 的 web_search_preview 工具:

API Reference: create_react_agent

from langgraph.prebuilt import create_react_agent

agent = create_react_agent(
    model="openai:gpt-4o-mini", 
    tools=[{"type": "web_search_preview"}]
)
response = agent.invoke(
    {"messages": ["What was a positive news story from today?"]}
)

此外,LangChain 支持与 API、数据库、文件系统、网络数据等交互的广泛预构建工具集成。这些工具扩展了代理的功能,并实现了快速开发。

你可以在 LangChain 集成目录 中浏览完整的可用集成列表。

一些常用的工具类别包括:

  • 搜索: Bing, SerpAPI, Tavily
  • 代码解释器: Python REPL, Node.js REPL
  • 数据库: SQL, MongoDB, Redis
  • 网络数据: 网页抓取和浏览
  • APIs: OpenWeatherMap, NewsAPI 等其他 API