langchain_core.tools
模块详解
langchain_core.tools
是 LangChain 框架中用于定义和管理工具的核心模块,工具是代理(Agents)、链(Chains)或大语言模型(LLMs)与外部世界交互的接口。本文结合前文内容,详细介绍该模块的功能、主要组件、使用方法、实际应用及注意事项,确保内容条理清晰、易于理解。
1. 概述
1.1 什么是 langchain_core.tools
?
langchain_core.tools
模块提供了一套类和函数,用于创建、配置和管理工具。工具是封装特定功能的组件,例如数据检索、数学计算或 API 调用,允许语言模型通过调用工具与外部系统交互。该模块通过标准化的接口和灵活的配置选项,确保工具与 LangChain 的可运行对象(Runnable)生态系统无缝集成。
工具的核心作用是为模型提供结构化的调用接口,结合名称、描述和 JSON 模式,指导模型选择和使用工具。模块在 langchain-core
0.2.14 版本中引入,工件支持在 0.2.19 版本添加。
1.2 与其他组件的关系
- 与
BaseTool
:前文讨论的BaseTool
是模块中的核心抽象基类,所有工具都继承自它。 - 与
@tool
装饰器:tool
装饰器是模块的实用函数,简化工具创建,自动将函数转换为BaseTool
实例。 - 与
InjectedToolArg
:模块支持通过InjectedToolArg
标记运行时注入参数,增强安全性。 - 与
chain
装饰器:结合langchain_core.runnables.chain
,可在工具调用链中注入参数或处理工具输出。
1.3 核心功能
- 工具定义:提供基类(如
BaseTool
)和实现(如Tool
、StructuredTool
)以定义工具。 - 输入验证:通过 Pydantic 模型验证工具输入,确保类型安全。
- 运行时注入:支持通过
InjectedToolArg
注入敏感参数,防止模型生成。 - 工件支持:工具可返回内容和工件(如图片、数据框),工件用于下游处理。
- 灵活集成:工具与 LangChain Expression Language (LCEL) 兼容,可组成复杂链。
- 版本要求:需
langchain-core>=0.2.14
,工件支持需 >=0.2.19。
2. 模块结构与主要组件
以下是 langchain_core.tools
模块的主要组件,按类别组织:
2.1 基类和接口
组件 | 描述 |
---|---|
BaseTool | 抽象基类,所有工具的父类,继承自 RunnableSerializable 。定义工具接口,包括同步(_run )和异步(_arun )执行方法,支持 invoke 、batch 、stream 等操作。 |
BaseToolkit | 工具包基类,用于组织一组相关工具,便于功能分组和管理。 |
2.2 工具实现
组件 | 描述 |
---|---|
Tool | 简单工具类,继承自 BaseTool ,包装函数或协程,适合单一输入场景。 |
StructuredTool | 支持多参数输入的工具,使用 Pydantic 模式定义输入结构,适合复杂场景。 |
RetrieverInput | 输入模式(推测为 Pydantic 模型),用于定义检索器工具的输入结构。 |
2.3 注解和异常
组件 | 描述 |
---|---|
InjectedToolArg | 注解,标记不应由模型生成的参数,由运行时注入,增强安全性。 |
InjectedToolCallId | 注解(推测),用于注入工具调用 ID,可能用于跟踪或日志。 |
SchemaAnnotationError | 当 args_schema 缺失或类型注解错误时抛出的异常。 |
ToolException | 工具执行错误时抛出的可选异常,用于错误处理。 |
2.4 实用函数
函数 | 描述 |
---|---|
tool | 装饰器或函数,将 Python 函数转换为工具,自动推断名称、描述和参数。 |
create_schema_from_function | 从函数签名创建 Pydantic 模式,用于定义工具输入结构。 |
get_all_basemodel_annotations | 获取 Pydantic BaseModel 及其父类的所有注解。 |
convert_runnable_to_tool | 将任何 Runnable 对象转换为 BaseTool ,增强灵活性。 |
render_text_description | 生成工具名称和描述的文本,用于提示模型。 |
render_text_description_and_args | 生成工具名称、描述和参数的文本,用于提示模型。 |
create_retriever_tool | 创建文档检索工具,集成 LangChain 的检索器组件。 |
3. 使用方法
以下是 langchain_core.tools
模块的主要使用方式,结合前文内容展示具体示例:
3.1 继承 BaseTool
为复杂工具创建子类,定义 name
、description
、args_schema
并实现 _run
和 _arun
:
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Optional, Type
from langchain_core.callbacks import CallbackManagerForToolRun
class CalculatorInput(BaseModel):
a: int = Field(description="第一个数字")
b: int = Field(description="第二个数字")
class CustomCalculatorTool(BaseTool):
name = "Calculator"
description = "用于回答数学相关问题"
args_schema: Type[BaseModel] = CalculatorInput
return_direct: bool = True
def _run(
self,
a: int,
b: int,
run_manager: Optional[CallbackManagerForToolRun] = None
) -> int:
"""执行工具"""
return a * b
async def _arun(
self,
a: int,
b: int,
run_manager: Optional[AsyncCallbackManagerForToolRun] = None
) -> int:
"""异步执行工具"""
return self._run(a, b, run_manager=run_manager)
调用方式:
tool = CustomCalculatorTool()
result = tool.invoke({"a": 2, "b": 3}) # 输出 6
3.2 使用 @tool
装饰器
简化工具创建,自动推断模式:
from langchain_core.tools import tool
@tool
def add_numbers(a: int, b: int) -> int:
"""添加两个数字"""
return a + b
调用方式:
result = add_numbers.invoke({"a": 2, "b": 3}) # 输出 5
3.3 结合 InjectedToolArg
标记运行时注入参数,增强安全性:
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 # 假设的存储
注入参数(结合 chain
装饰器):
from langchain_core.runnables import chain
@chain
def inject_user_id(input):
"""注入用户 ID 到工具调用"""
tool_call = input["tool_call"]
user_id = input["user_id"]
tool_call_copy = tool_call.copy()
tool_call_copy["args"]["user_id"] = user_id
return {"tool_call": tool_call_copy}
chain = inject_user_id | update_favorite_pets
chain.invoke({"tool_call": {"name": "update_favorite_pets", "args": {"pets": ["dog"]}}, "user_id": "123"})
3.4 创建检索工具
使用 create_retriever_tool
创建文档检索工具:
from langchain_core.tools import create_retriever_tool
from langchain_core.vectorstores import VectorStoreRetriever
retriever = VectorStoreRetriever(...) # 假设的检索器
tool = create_retriever_tool(
retriever,
name="search_documents",
description="搜索相关文档"
)
4. 参数与配置
以下是模块中主要组件的关键参数:
4.1 BaseTool
初始化参数
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
args_schema | Type[BaseModel] | None | None | Pydantic 模型,定义输入参数结构和验证。 |
description | str | 无默认 | 工具描述,指导模型使用。 |
return_direct | bool | False | 若为 True ,输出直接返回,代理停止处理。 |
response_format | Literal['content', 'content_and_artifact'] | 'content' | 输出格式:仅内容或内容加工件。 |
handle_tool_error | bool | str | Callable | False | 处理 ToolException 的方式。 |
4.2 @tool
装饰器参数
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
name_or_callable | Optional[str | Callable] | None | 工具名称或可调用对象。 |
description | str | None | None | 工具描述,优先级高于文档字符串。 |
return_direct | bool | False | 若为 True ,输出直接返回。 |
args_schema | Type[BaseModel] | dict | None | None | 参数模式,定义输入结构。 |
response_format | Literal['content', 'content_and_artifact'] | 'content' | 输出格式。 |
parse_docstring | bool | False | 若为 True ,解析 Google 风格文档字符串。 |
error_on_invalid_docstring | bool | True | 若为 True ,无效文档字符串抛出错误。 |
5. 实际应用
langchain_core.tools
模块在以下场景中广泛使用:
- 代理系统:为代理提供工具列表,代理根据输入选择工具。例如,数学计算工具、搜索工具。
- 自定义工作流:在 LangGraph 或链中集成工具,实现模块化功能。例如,数据处理管道。
- 工件处理:工具返回内容和工件,工件用于下游处理,如生成图片或数据框。
- 运行时注入:结合
InjectedToolArg
,为工具注入敏感参数,如用户 ID。
示例:综合应用
创建一个工具链,结合 InjectedToolArg
和 chain
装饰器:
from langchain_core.tools import tool, InjectedToolArg
from langchain_core.runnables import chain
from typing import Annotated, List
@tool
def update_user_profile(name: str, user_id: Annotated[str, InjectedToolArg]) -> str:
"""更新用户配置文件"""
return f"Updated profile for user {user_id} with name {name}"
@chain
def inject_user_id(input):
"""注入用户 ID"""
return {**input, "user_id": "123"}
chain = inject_user_id | update_user_profile
result = chain.invoke({"name": "Alice"}) # 输出 "Updated profile for user 123 with name Alice"
6. 最佳实践
- 清晰描述:为工具提供详细的
description
,包含少样本示例,帮助模型选择。 - 输入验证:使用
args_schema
定义和验证输入,确保类型安全。 - 注入参数:结合
InjectedToolArg
保护敏感信息,防止模型生成。 - 文档字符串:使用 Google 风格文档字符串,确保
parse_docstring=True
时正确解析。 - 版本检查:确保安装
langchain-core>=0.2.14
,工件支持需 >=0.2.19,通过pip install -qU langchain
。
7. 注意事项与限制
- 抽象方法:继承
BaseTool
时必须实现_run
,否则抛出NotImplementedError
。 - 文档字符串格式:若使用
parse_docstring=True
,需正确格式化 Google 风格文档字符串,否则可能抛出SchemaAnnotationError
。 - 版本依赖:工件支持等功能需特定版本。
- 工件格式:工件需为可序列化对象(如字典、字节)。
- 类方法支持:在类方法上使用
@tool
可能需变通方法,建议使用StructuredTool.from_function
。
8. 结论
langchain_core.tools
模块为 LangChain 提供了定义和管理工具的强大功能,通过基类(如 BaseTool
)、工具实现(如 StructuredTool
)和实用函数(如 @tool
),支持开发者创建自定义工具并集成到复杂应用程序中。其支持输入验证、运行时注入和工件输出,确保工具的高效性和安全性。结合 InjectedToolArg
和 chain
装饰器,模块在代理系统和自定义工作流中表现尤为出色。