LangChain 工具概念指南

文章目录
概述
工具是可以被模型调用的实用程序,其输出设计为反馈给模型。工具是代理的核心组成部分,它们使模型能够与外部世界进行交互。
关键概念
工具接口
LangChain中的所有工具都实现了Tool接口。该接口定义了工具的基本属性和方法:
关键属性:
- name: 工具的名称
- description: 工具功能的描述
- args: 返回工具参数的JSON模式的属性
执行工具相关功能的关键方法:
- invoke: 使用给定参数调用工具
- ainvoke: 异步调用工具,用于LangChain的异步编程
使用 @tool 装饰器创建工具
创建工具的推荐方式是使用@tool装饰器。这个装饰器旨在简化工具创建过程,应该在大多数情况下使用。定义函数后,您可以用@tool装饰它来创建实现工具接口的工具。
from langchain_core.tools import tool
@tool
def multiply(a: int, b: int) -> int:
"""将两个数字相乘。"""
return a * b
注意: LangChain还有其他几种创建工具的方法,例如通过继承
BaseTool类或使用StructuredTool。这些方法在自定义工具创建指南中有所展示,但我们通常建议在大多数情况下使用@tool装饰器。
直接使用工具
定义工具后,您可以通过调用函数直接使用它。例如,使用上面定义的multiply工具:
multiply.invoke({"a": 2, "b": 3})
检查工具
您还可以检查工具的模式和其他属性:
print(multiply.name) # multiply
print(multiply.description) # 将两个数字相乘。
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]:
"""执行某些操作的工具。"""
...
return '给聊天模型的消息', 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:
"""处理输入数据的工具。"""
return f"用户 {user_id} 处理了 {input_data}"
用InjectedToolArg注解user_id参数告诉LangChain这个参数不应作为工具模式的一部分暴露。
有关如何使用InjectedToolArg的更多详细信息,请参阅如何将运行时值传递给工具。
RunnableConfig
您可以使用RunnableConfig对象将自定义运行时值传递给工具。
如果您需要从工具内部访问RunnableConfig对象,可以通过在工具的函数签名中使用RunnableConfig注解来实现。
from langchain_core.runnables import RunnableConfig
@tool
async def some_func(..., config: RunnableConfig) -> ...:
"""执行某些操作的工具。"""
# 对config做一些操作
...
await some_func.ainvoke(..., config={"configurable": {"value": "some_value"}})
config不会成为工具模式的一部分,将在运行时注入适当的值。
注意: 如果您在异步环境中使用Python 3.9/3.10并需要手动将
config对象传播到子调用,您可能需要访问config对象。请阅读传播RunnableConfig以了解如何手动将RunnableConfig传播到调用链中的更多详细信息(或升级到Python 3.11,这不再是问题)。
InjectedState
有关更多详细信息,请参阅InjectedState文档。
InjectedStore
有关更多详细信息,请参阅InjectedStore文档。
最佳实践
在设计供模型使用的工具时,请记住以下几点:
- 命名良好、文档正确且类型提示恰当的工具更容易被模型使用
- 设计简单且范围狭窄的工具,因为它们更容易被模型正确使用
- 使用支持工具调用API的聊天模型来利用工具
工具包
LangChain有一个工具包的概念。这是一个非常薄的抽象层,将设计为特定任务一起使用的工具组合在一起。
接口
所有工具包都暴露一个get_tools方法,该方法返回工具列表。因此您可以这样做:
# 初始化工具包
toolkit = ExampleToolkit(...)
# 获取工具列表
tools = toolkit.get_tools()
相关资源
有关更多信息,请参阅以下资源:
- @tool的API参考
- 如何创建自定义工具
- 如何将运行时值传递给工具
- 所有LangChain工具操作指南
- 显示与LangGraph一起使用的其他操作指南
- 工具集成,请参阅工具集成文档
总结
这个文档详细介绍了LangChain中工具的核心概念:
- 工具定义: 工具是可以被模型调用的实用程序,用于与外部世界交互
- 创建方式: 推荐使用
@tool装饰器创建工具 - 接口规范: 所有工具都实现统一的Tool接口
- 特殊功能: 支持工具工件、特殊类型注解等高级功能
- 最佳实践: 强调工具的命名、文档和设计原则
- 工具包概念: 将相关工具组织在一起的抽象层
这些概念为构建强大的AI代理系统提供了基础框架。
82

被折叠的 条评论
为什么被折叠?



