**如何构建自定义工具:LangChain 工具的全面指南**

在开发智能代理时,为了增强其功能,我们通常需要提供一组工具(Tools)供其调用。LangChain 提供了多种便捷的方法来定义和配置这些工具,包括从函数构建工具、使用结构化工具StructuredTool以及通过继承BaseTool类构建自定义工具。本指南将重点介绍如何通过实际代码示例,逐步掌握工具的创建和使用。


技术背景介绍

工具是智能代理与外界交互的桥梁。通过工具,代理能够执行诸如数据处理、API调用、计算等具体任务。一个工具通常包含以下几个关键组件:

  • name: 工具的唯一标识。
  • description: 工具的功能描述,用于帮助模型理解工具的用途。
  • args_schema: 参数模式,基于Pydantic模型,用于描述输入的结构与约束条件。
  • return_direct: 是否直接返回结果,而不继续调用模型。

LangChain 提供了四种常见的方式来构建工具:

  1. 使用装饰器 @tool
  2. 使用结构化工具 StructuredTool.from_function
  3. 从 LangChain Runnables 转换工具
  4. 通过继承 BaseTool 类自定义工具

核心原理解析

无论采用哪种方式构建工具,核心的设计理念是让工具具备:

  1. 明确的输入输出:通过 args_schema 定义输入验证规则。
  2. 良好的描述性:通过 name 和 description 告知模型工具的功能。
  3. 同步&异步支持:工具需要支持异步调用以适应现代代码需求。

以下各部分将结合代码详细讲解这些方式。


代码实现演示

1. 使用 @tool 装饰器快速创建工具

@tool 是最简单的方式,通过装饰现有函数即可将其转化成一个工具。

from langchain_core.tools import tool

# 定义一个基础工具,用于计算两个数的乘积
@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

# 打印工具的相关属性
print(multiply.name)          # 输出: multiply
print(multiply.description)   # 输出: Multiply two numbers.
print(multiply.args)          # 输出: {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
  • 异步支持
@tool
async def amultiply(a: int, b: int) -> int:
    """Multiply two numbers asynchronously."""
    return a * b

注意: 使用@tool时,函数的注释(docstring)会自动作为工具的描述,因此必须提供函数注释。


2. 使用 StructuredTool.from_function 定义结构化工具

相比 @toolStructuredTool.from_function 提供了更多的配置选项,比如工具名称、自定义参数模式以及异步协程支持。

from langchain.pydantic_v1 import BaseModel, Field
from langchain_core.tools import StructuredTool

class CalculatorInput(BaseModel):
    a: int = Field(description="First number")
    b: int = Field(description="Second number")

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

calculator = StructuredTool.from_function(
    func=multiply,
    name="Calculator",
    description="A tool for multiplying two numbers",
    args_schema=CalculatorInput,
    return_direct=True,
)

# 调用工具
print(calculator.invoke({"a": 3, "b": 4}))   # 输出: 12
  • 覆盖异步实现
async def amultiply(a: int, b: int) -> int:
    return a * b

calculator = StructuredTool.from_function(func=multiply, coroutine=amultiply)

3. 从 LangChain Runnables 转换为工具

LangChain Runnables 可以通过 .as_tool 方法快速转换为工具。

from langchain_core.language_models import GenericFakeChatModel
from langchain_core.prompts import ChatPromptTemplate

# 定义一个Prompt和Placeholder模型
prompt = ChatPromptTemplate.from_messages([("human", "Hello, please respond in the style of {answer_style}.")])
llm = GenericFakeChatModel(messages=iter(["hello matey"]))
chain = prompt | llm

# 转换为工具
as_tool = chain.as_tool(
    name="StyleResponder",
    description="Respond in a specific style."
)

# 查看工具参数
print(as_tool.args)  # {'answer_style': {'title': 'Answer Style', 'type': 'string'}}

4. 继承 BaseTool 类创建自定义工具

如果您需要完全控制工具的行为,可通过继承 BaseTool 来构建自己的工具。

from langchain.pydantic_v1 import BaseModel, Field
from langchain_core.tools import BaseTool

class CalculatorInput(BaseModel):
    a: int = Field(description="First number")
    b: int = Field(description="Second number")

class CustomCalculatorTool(BaseTool):
    name = "CustomCalculator"
    description = "Perform multiplication of two numbers."
    args_schema = CalculatorInput
    return_direct = True

    def _run(self, a: int, b: int) -> int:
        return a * b

    async def _arun(self, a: int, b: int) -> int:
        return self._run(a, b)

# 使用工具
custom_tool = CustomCalculatorTool()
print(custom_tool.invoke({"a": 2, "b": 5}))  # 输出: 10

应用场景分析

  1. 数据预处理:构建清洗、格式化或转换数据的工具供智能代理调用。
  2. API集成:定义工具以封装对外部API的访问,例如天气查询、库存获取等。
  3. 复杂任务管理:通过 BaseTool 定义复杂逻辑(如数据库操作、多步流程处理)。
  4. 异步环境支持:在协程代码中通过支持异步功能减少阻塞操作。

实践建议

  1. 明确工具的输入输出:为工具定义清晰的参数和返回值,避免不必要的模型推理消耗。
  2. 优化工具描述:将 description 写得尽量简洁而明确,以提高模型调用工具的效率。
  3. 优先支持异步实现:在需要高并发的场景中,设计异步工具以提高性能。
  4. 错误处理策略:通过 handle_tool_error 提供健壮的错误恢复机制。

如果遇到问题欢迎在评论区交流。

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值