# 引言
在构建智能代理时,我们需要为其提供一系列工具(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同时指定同步和异步实现。
总结和进一步学习资源
创建自定义工具可以极大地提升智能代理的功能。通过合理的工具名称、描述和参数验证,我们可以优化工具的使用体验。
进一步学习资源
参考资料
- LangChain 官方文档
- Pydantic 官方文档
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---