如何创建自定义工具

在构建智能代理时,需要为其提供可使用的工具列表。工具不仅仅是某个函数的调用,它包含多个组件:

  • name: 工具的唯一名称。
  • description: 描述工具的功能。这些信息会被用于语言模型或代理的上下文。
  • args_schema: 可选但推荐,用于提供更多的信息或验证预期的参数。
  • return_direct: 仅对代理相关。如果为True,调用工具后代理会直接返回结果给用户。

LangChain支持从以下几种方式创建工具:

  • 函数
  • LangChain Runnables
  • 通过继承BaseTool类 —— 这种方法提供了最高的灵活性,但要求更多的代码和努力。

本文将详细介绍这些方法。

使用函数创建工具

使用@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)  # 输出参数描述

异步实现

可以创建异步实现的工具,如下:

from langchain_core.tools import tool

@tool
async def amultiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

高级用法

可以解析注解、嵌套模式和其他特性:

from typing import Annotated, List
from langchain_core.tools import tool

@tool
def multiply_by_max(
    a: Annotated[str, "scale factor"],
    b: Annotated[List[int], "list of ints over which to take maximum"],
) -> int:
    """Multiply a by the maximum of b."""
    return a * max(b)

multiply_by_max.args_schema.schema()

从LangChain Runnables创建工具

可以将LangChain Runnables转换为工具,示例如下:

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

prompt = ChatPromptTemplate.from_messages(
    [("human", "Hello. Please respond in the style of {answer_style}.")]
)

# Placeholder LLM
llm = GenericFakeChatModel(messages=iter(["hello matey"]))
chain = prompt | llm | StrOutputParser()

as_tool = chain.as_tool(
    name="Style responder", description="Description of when to use tool."
)
print(as_tool.args)

通过继承BaseTool创建工具

通过继承BaseTool类,可以定义自定义工具,示例如下:

from typing import Optional, Type
from langchain.pydantic_v1 import BaseModel
from langchain_core.callbacks import (
    AsyncCallbackManagerForToolRun,
    CallbackManagerForToolRun,
)
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 = "Calculator"
    description = "useful for when you need to answer questions about math"
    args_schema: Type[BaseModel] = CalculatorInput
    return_direct: bool = True

    def _run(
        self, a: int, b: int, run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool."""
        return a * b

    async def _arun(
        self,
        a: int,
        b: int,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        return self._run(a, b, run_manager=run_manager.get_sync())

multiply = CustomCalculatorTool()
print(multiply.name)
print(multiply.description)
print(multiply.args)
print(multiply.return_direct)
print(multiply.invoke({"a": 2, "b": 3}))

错误处理

在使用工具与代理时,可能需要处理错误。最简单的策略是在工具内部抛出ToolException并指定错误处理程序handle_tool_error

示例代码如下:

from langchain_core.tools import ToolException

def get_weather(city: str) -> int:
    """Get weather for the given city."""
    raise ToolException(f"Error: There is no city by the name of {city}.")

get_weather_tool = StructuredTool.from_function(
    func=get_weather,
    handle_tool_error=True,
)
print(get_weather_tool.invoke({"city": "foobar"}))

通过以上方法,您可以创建多种类型的自定义工具并集成到智能代理中,大大增强了智能系统的功能。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值