Skip to content

构建自定义工具

虽然 CrewAI 自带一套强大的工具集,但实际应用常常需要独有的集成——比如专有的内部 API、特定的数据库查询或复杂的数据转换。自定义工具(Custom Tools)正是在这些场景下大显身手。

CrewAI 提供了两种主要的自定义工具创建方法:

  • @tool 装饰器:快速、基于函数,适用于简单逻辑。
  • 继承 BaseTool 类:面向对象,支持复杂参数和验证,适用于生产环境。

对于简单的函数,你可以使用 Python 装饰器来修饰它。这里的 docstring(文档字符串)至关重要——它会成为 Agent(智能体)读取的描述,以理解 何时 使用该工具。

from crewai.tools import tool
@tool("Calculate Length")
def calculate_length(text: str) -> int:
"""Returns the length of the text provided."""
return len(text)
# Agent 中的用法
agent = Agent(..., tools=[calculate_length])

方法二:继承 BaseTool 类(推荐)

Section titled “方法二:继承 BaseTool 类(推荐)”

对于健壮的应用程序,我们推荐继承 BaseTool 类。这使我们能够使用 Pydantic 为输入定义严格的 schema(模式)。如果 LLM 尝试调用你的工具时缺少或使用了错误的数据类型,CrewAI 会捕获该错误并自动要求 LLM 进行自我纠正。

首先,我们使用 Pydantic 模型来定义工具期望的输入。

from pydantic import BaseModel, Field
class CustomAPIToolInput(BaseModel):
query: str = Field(..., description="The search query to send to the API")
limit: int = Field(5, description="Max number of results to return")

接下来,我们实现工具类,关联 schema 并定义 _run 方法。

from crewai.tools import BaseTool
from typing import Type
import requests
class CustomSearchTool(BaseTool):
name: str = "Internal Knowledge Search"
description: str = (
"Useful for searching the company's internal documentation. "
"Always use this before asking the user."
)
args_schema: Type[BaseModel] = CustomAPIToolInput
def _run(self, query: str, limit: int = 5) -> str:
# 在此处编写你的自定义逻辑
response = requests.get(
"https://api.internal.company/search",
params={"q": query, "limit": limit}
)
if response.status_code == 200:
return response.text
else:
return f"Error fetching data: {response.status_code}"
# 实例化并使用
custom_tool = CustomSearchTool()
  • 描述性名称:name 和 description 是提示词(prompt)的一部分。请务必具体。
  • 类型提示:始终为 _run 方法的参数添加类型提示。
  • 错误处理:如果你希望 Agent 能够重试或优雅地处理失败,请返回清晰的错误字符串,而不是直接抛出异常。