langchain_core.tools.tool
装饰器详解
langchain_core.tools.tool
是 LangChain 框架中的核心组件,用于将 Python 函数转换为语言模型可调用的工具。本文详细介绍其功能、参数、使用方法、实际应用及注意事项,确保内容条理清晰、易于理解。
1. 概述
1.1 什么是 @tool
装饰器?
@tool
装饰器位于 langchain_core.tools.convert
模块,用于将 Python 函数或可运行对象转换为 BaseTool
对象,使其与 LangChain 的工具调用机制兼容。它通过分析函数签名和文档字符串,自动生成工具的名称、描述和参数模式,简化工具创建过程。该装饰器特别适合构建基于代理的系统、LangGraph 工作流或自定义链,允许模型调用外部功能并处理输出。
1.2 核心功能
- 自动模式推断:从函数的类型提示和文档字符串生成工具模式。
- 灵活配置:支持自定义工具名称、描述、参数模式和输出格式。
- 工件支持:可返回工件(如图片、数据框)供下游使用,不暴露给模型。
- 注入参数:结合
InjectedToolArg
,隐藏敏感参数(如用户 ID)。 - 版本要求:需
langchain-core>=0.2.14
,工件支持需 >=0.2.19。
2. 使用方法
2.1 基本用法
将 @tool
应用于函数,自动生成工具:
from langchain_core.tools import tool
@tool
def add_numbers(a: int, b: int) -> int:
"""添加两个数字。"""
return a + b
此代码创建一个名为“add_numbers”的工具,描述为“添加两个数字”,接受两个整数参数 a
和 b
,返回其和。
2.2 自定义用法
通过传递参数自定义工具属性:
@tool("custom_add", return_direct=True)
def add_numbers(a: int, b: int) -> int:
"""添加两个数字。"""
return a + b
工具命名为“custom_add”,return_direct=True
确保输出直接返回,绕过代理处理。
2.3 直接函数转换
使用 tool
函数直接转换:
def divide(a: float, b: float) -> float:
return a / b
divide_tool = tool(divide)
装饰器语法更简洁,适合大多数场景。
2.4 带工件的工具
支持返回工件,需设置 response_format="content_and_artifact"
:
@tool(response_format="content_and_artifact")
def generate_image(prompt: str) -> tuple[str, bytes]:
"""根据提示生成图片。"""
image_data = some_image_generation_function(prompt) # 假设的函数
return f"图片生成:{prompt}", image_data
返回模型使用的字符串和下游使用的图片工件。
3. 参数详解
以下是 @tool
装饰器的所有参数,包括类型、默认值、描述和示例:
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
name_or_callable | Optional[str | Callable] | None | 工具名称或可调用对象。字符串时覆盖默认名称;可调用对象时指定转换目标。 |
runnable | Optional[Runnable] | None | 可运行对象,用于直接转换,通常在装饰器中不使用。 |
description | str | None | None | 工具描述。优先级:参数 > 文档字符串 > 参数模式描述。 |
return_direct | bool | False | 若为 True,工具输出直接返回,代理停止处理。 |
args_schema | type[BaseModel] | dict[str, Any] | None | None | 参数模式,可为 Pydantic 模型或字典,提供验证或额外信息。 |
infer_schema | bool | True | 若为 True,从函数签名推断模式,支持 run 方法接受字典输入。 |
response_format | Literal[‘content’, ‘content_and_artifact’] | ‘content’ | 输出格式:‘content’ 仅返回内容;‘content_and_artifact’ 返回内容和工件元组。 |
parse_docstring | bool | False | 若为 True,解析 Google 风格文档字符串以提取参数描述。 |
error_on_invalid_docstring | bool | True | 若为 True 且 parse_docstring=True ,无效文档字符串抛出 ValueError。 |
3.1 参数示例
-
name_or_callable
@tool("custom_multiply") def multiply(a: int, b: int) -> int: """乘两个数字。""" return a * b
工具名称设置为“custom_multiply”。
-
runnable
from langchain_core.runnables import RunnableLambda def func(x: str) -> str: return x.upper() tool_instance = tool(runnable=RunnableLambda(func), name="uppercase")
-
description
@tool(description="计算两数之和") def add_numbers(a: int, b: int) -> int: """添加两个数字。""" return a + b
-
return_direct
@tool(return_direct=True) def calculator(expression: str) -> str: """计算数学表达式。""" return str(eval(expression)) # 仅示例,实际需安全处理
-
args_schema
from pydantic import BaseModel class AddSchema(BaseModel): a: int b: int @tool(args_schema=AddSchema) def add_numbers(a: int, b: int) -> int: """添加两个数字。""" return a + b
-
infer_schema
@tool(infer_schema=True) # 默认行为 def multiply(a: int, b: int) -> int: """乘两个数字。""" return a * b
-
response_format
@tool(response_format="content_and_artifact") def process_data(data: str) -> tuple[str, dict]: """处理输入数据并生成报告。""" report = {"summary": data} return f"数据处理完成:{data}", report
-
parse_docstring
@tool(parse_docstring=True) def multiply(a: int, b: int) -> int: """ 乘两个数字。 Args: a (int): 第一个数字。 b (int): 第二个数字。 Returns: int: a 和 b 的乘积。 """ return a * b
-
error_on_invalid_docstring
@tool(parse_docstring=True, error_on_invalid_docstring=False) def multiply(a: int, b: int) -> int: """乘两个数字。""" # 无效文档字符串,未定义参数 return a * b
4. 技术细节
- 实现:装饰器将函数转换为
BaseTool
对象,继承自Runnable
接口,支持 LangChain 的工具调用机制。 - 模式影响:
- 输入模式(
get_input_schema().schema()
):包含所有参数,包括注入参数。 - 工具调用模式(
tool_call_schema.schema()
):排除注入参数,模型仅生成非注入参数。
- 输入模式(
- 版本要求:引入于
langchain-core
0.2.14,工件支持需 >=0.2.19。 - 函数要求:支持多参数函数,推荐包含文档字符串和类型提示以提高模式准确性。
5. 实际应用
@tool
装饰器适用于以下场景:
- 代理系统:为代理提供工具执行任务,如计算、搜索或数据更新。
- 自定义工作流:在 LangGraph 或链中实现模块化功能,输出反馈给模型或下游组件。
- 工件处理:生成供下游使用的工件,如图片、数据框或报告。
示例:结合注入参数
from langchain_core.tools import tool, InjectedToolArg
from typing import Annotated, List
@tool
def update_favorite_pets(pets: List[str], user_id: Annotated[str, InjectedToolArg]) -> None:
"""更新用户的收藏宠物。"""
user_to_pets[user_id] = pets
user_id
由运行时注入,模型仅生成 pets
。
6. 最佳实践
- 命名与文档:使用描述性名称和详细 Google 风格文档字符串。
- 类型提示:包含类型注解以确保模式推断准确。
- 限定范围:为特定任务设计工具,增强清晰度和性能。
- 版本检查:确保安装
langchain-core>=0.2.14
,工件支持需 >=0.2.19,通过pip install -qU langchain
。 - 错误处理:设置
error_on_invalid_docstring=False
以避免无效文档字符串引发错误。
7. 注意事项与限制
- 类方法支持:在类方法上使用可能导致错误,建议在类外定义或使用
StructuredTool.from_function
。 - 文档字符串格式:若
parse_docstring=True
,需正确格式化 Google 风格文档字符串,否则可能抛出错误。 - 版本依赖:部分功能(如工件支持)需特定版本。
- 工件格式:工件需为可序列化对象(如字典、字节),以便下游处理。
8. 结论
langchain_core.tools.tool
装饰器是 LangChain 中创建自定义工具的强大工具。其自动模式推断、工件支持和灵活配置使其适合构建复杂代理系统和自定义工作流。开发者应遵循最佳实践,利用类型提示和最新版本以充分发挥其潜力。