轻松创建自定义工具:LangChain函数和运行实例详解

151 阅读3分钟
# 引言

在构建智能代理时,我们需要为其提供一系列工具(Tools)以便于其执行特定任务。这篇文章将介绍如何通过LangChain创建自定义工具,包括使用函数创建工具和使用LangChain Runnables创建工具的方法。我们还将讨论潜在的挑战以及如何解决这些问题。

# 主要内容

## 什么是工具?

工具是可以被智能代理调用的功能模块,包括以下几个组成部分:

- **名称(name)**:工具的唯一标识符。
- **描述(description)**:工具的功能描述,帮助语言模型理解其用途。
- **参数模式(args_schema)**:使用Pydantic模型定义参数类型和验证方法。
- **直接返回(return_direct)**:是否在调用工具后立即返回结果。

## 创建工具的方法

LangChain支持三种创建工具的方法:通过函数、通过LangChain Runnables以及继承BaseTool类。

### 1. 使用函数创建工具

使用`@tool`装饰器是定义工具的最简单方法。装饰器会自动使用函数名称作为工具名称,并采用函数的文档字符串作为描述。

```python
from langchain_core.tools import tool

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

print(multiply.name)        # 输出工具名称
print(multiply.description) # 输出工具描述

2. 使用运行实例创建工具

LangChain Runnables可以通过as_tool方法转换为工具,允许指定名称、描述和参数schema。

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}.")]
)

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

as_tool = chain.as_tool(
    name="Style responder", description="Respond in the given style."
)

3. 继承BaseTool

通过继承BaseTool类可以创建具有更复杂逻辑的工具。此方法需要更多代码,但提供了最大的灵活性。

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

class CalculatorInput(BaseModel):
    a: int = Field(description="first number")
    b: int = Field(description="second number")

class CustomCalculatorTool(BaseTool):
    name = "Calculator"
    description = "useful for calculation tasks"
    args_schema: Type[BaseModel] = CalculatorInput
    return_direct: bool = True

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

代码示例

下面是一个使用@tool装饰器创建异步工具的完整示例:

from langchain_core.tools import tool

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

# 用于访问异步工具
print(await amultiply({"a": 2, "b": 5}))

常见问题和解决方案

1. 如何处理工具错误?

处理工具错误的一个简单策略是抛出ToolException并指定一个错误处理器。

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,
)

2. 如何创建异步工具?

异步工具可以通过实现_arun方法或使用StructuredTool.from_function同时指定同步和异步实现。

总结和进一步学习资源

创建自定义工具可以极大地提升智能代理的功能。通过合理的工具名称、描述和参数验证,我们可以优化工具的使用体验。

进一步学习资源

参考资料

  1. LangChain 官方文档
  2. Pydantic 官方文档

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---