跳转到主要内容

工具

先决条件

概述

LangChain 中的 tool 抽象将 Python 函数 与定义函数 名称描述预期参数模式 相关联。

工具 可以传递给支持 工具调用聊天模型,允许模型请求使用特定输入执行特定函数。

关键概念

  • 工具是一种封装函数及其模式的方式,该模式可以传递给聊天模型。
  • 使用 @tool 装饰器创建工具,这简化了工具创建过程,并支持以下功能:
    • 自动推断工具的 名称描述预期参数,同时还支持自定义。
    • 定义返回 工件(例如图像、数据帧等)的工具
    • 使用 注入的工具参数 从模式中(因此从模型中)隐藏输入参数。

工具接口

工具接口在 BaseTool 类中定义,它是 Runnable 接口 的子类。

与工具模式相对应的关键属性

  • name:工具的名称。
  • description:工具的功能描述。
  • args:返回工具参数的 JSON 模式的属性。

执行与工具关联的函数的关键方法

  • invoke:使用给定的参数调用工具。
  • ainvoke:使用给定的参数异步调用工具。用于 Langchain 的异步编程

使用 @tool 装饰器创建工具

创建工具的推荐方法是使用 @tool 装饰器。此装饰器旨在简化工具创建过程,在大多数情况下应使用它。定义函数后,可以使用 @tool 对其进行装饰,以创建实现 工具接口 的工具。

from langchain_core.tools import tool

@tool
def multiply(a: int, b: int) -> int:
"""Multiply two numbers."""
return a * b
API 参考:tool

有关如何创建工具的更多详细信息,请参阅如何创建自定义工具指南。

注意

LangChain 还有其他几种创建工具的方法;例如,通过子类化 BaseTool 类或使用 StructuredTool。这些方法在如何创建自定义工具指南中展示,但我们通常建议在大多数情况下使用 @tool 装饰器。

直接使用工具

定义工具后,可以通过调用函数直接使用它。例如,要使用上面定义的 multiply 工具

multiply.invoke({"a": 2, "b": 3})

检查

您还可以检查工具的模式和其他属性

print(multiply.name) # multiply
print(multiply.description) # Multiply two numbers.
print(multiply.args)
# {
# 'type': 'object',
# 'properties': {'a': {'type': 'integer'}, 'b': {'type': 'integer'}},
# 'required': ['a', 'b']
# }
注意

如果您使用的是预构建的 LangChain 或 LangGraph 组件(如 create_react_agent),您可能不需要直接与工具交互。但是,了解如何使用它们对于调试和测试很有价值。此外,在构建自定义 LangGraph 工作流时,您可能会发现有必要直接使用工具。

配置模式

@tool 装饰器提供了其他选项来配置工具的模式(例如,修改名称、描述或解析函数的文档字符串以推断模式)。

有关更多详细信息,请参阅@tool 的 API 参考,并查看如何创建自定义工具指南中的示例。

工具工件

工具是模型可以调用的实用程序,其输出旨在反馈给模型。然而,有时,我们希望工具执行的工件可以被链或代理中的下游组件访问,但我们不想将其暴露给模型本身。例如,如果工具返回一个自定义对象、数据帧或图像,我们可能希望将有关此输出的一些元数据传递给模型,而无需将实际输出传递给模型。同时,我们可能希望能够在其他地方(例如在下游工具中)访问此完整输出。

@tool(response_format="content_and_artifact")
def some_tool(...) -> Tuple[str, Any]:
"""Tool that does something."""
...
return 'Message for chat model', some_artifact

有关更多详细信息,请参阅如何从工具返回工件

特殊类型注释

工具的函数签名中可以使用许多特殊类型注释来配置工具的运行时行为。

以下类型注释将最终从工具的模式中删除参数。这对于不应暴露给模型且模型不应能够控制的参数很有用。

  • InjectedToolArg:值应在运行时使用 .invoke.ainvoke 手动注入。
  • RunnableConfig:将 RunnableConfig 对象传递给工具。
  • InjectedState:将 LangGraph 图的整体状态传递给工具。
  • InjectedStore:将 LangGraph 存储对象传递给工具。

您还可以使用带有字符串文字的 Annotated 类型,为将在工具模式中公开的相应参数提供描述

  • Annotated[..., "字符串文字"] -- 为将在工具模式中公开的参数添加描述。

InjectedToolArg

在某些情况下,某些参数需要在运行时传递给工具,但不应由模型本身生成。为此,我们使用 InjectedToolArg 注释,它允许从工具的模式中隐藏某些参数。

例如,如果工具需要在运行时动态注入 user_id,则可以按以下方式构造

from langchain_core.tools import tool, InjectedToolArg

@tool
def user_specific_tool(input_data: str, user_id: InjectedToolArg) -> str:
"""Tool that processes input data."""
return f"User {user_id} processed {input_data}"
API 参考:tool | InjectedToolArg

使用 InjectedToolArg 注释 user_id 参数会告诉 LangChain 该参数不应作为工具模式的一部分公开。

有关如何使用 InjectedToolArg 的更多详细信息,请参阅如何将运行时值传递给工具

RunnableConfig

您可以使用 RunnableConfig 对象将自定义运行时值传递给工具。

如果您需要从工具中访问RunnableConfig对象。可以通过在工具的函数签名中使用 RunnableConfig 注释来实现。

from langchain_core.runnables import RunnableConfig

@tool
async def some_func(..., config: RunnableConfig) -> ...:
"""Tool that does something."""
# do something with config
...

await some_func.ainvoke(..., config={"configurable": {"value": "some_value"}})
API 参考:RunnableConfig

config 不会是工具模式的一部分,并且会在运行时注入适当的值。

注意

您可能需要访问 config 对象以将其手动传播到子类。如果您在异步环境中使用 python 3.9 / 3.10,并且需要手动将 config 对象传播到子调用,则会发生这种情况。

请阅读传播 RunnableConfig,以了解如何手动将 RunnableConfig 向下传播到调用链(或升级到 Python 3.11,其中不再存在此问题)。

InjectedState

有关更多详细信息,请参阅 InjectedState 文档。

InjectedStore

有关更多详细信息,请参阅 InjectedStore 文档。

最佳实践

在设计供模型使用的工具时,请记住以下几点

  • 命名良好、正确记录和正确类型提示的工具更易于模型使用。
  • 设计简单且范围狭窄的工具,因为它们更易于模型正确使用。
  • 使用支持 工具调用 API 的聊天模型来利用工具。

工具包

LangChain 有一个工具包的概念。这是一个非常薄的抽象,它将设计为一起用于特定任务的工具分组在一起。

接口

所有工具包都公开一个 get_tools 方法,该方法返回工具列表。因此您可以执行以下操作

# Initialize a toolkit
toolkit = ExampleTookit(...)

# Get list of tools
tools = toolkit.get_tools()

有关更多信息,请参阅以下资源


此页面是否对您有帮助?