CrewAI 进阶:自定义工具扩展 Agent 能力

学习路径: Day 3 | 难度: ⭐⭐ | 前置知识: 入门指南

🎯 为什么需要工具?

Agent 本身只有"思考"能力,但要完成实际任务,需要"动手"的工具。

就像人类:

  • 🧠 大脑 = Agent 的 LLM(思考、决策)
  • 🛠️ 工具 = 计算器、搜索引擎、API(执行具体操作)

📚 工具的两种创建方式

方式 1: 使用 @tool 装饰器(推荐)

最简单的方式,适合快速创建工具:

from crewai.tools import tool

@tool
def weather_tool(city: str) -> str:
    """查询城市天气信息"""
    weather_data = {
        "北京": "晴,15-25°C,微风",
        "上海": "多云,18-26°C",
    }
    return weather_data.get(city, "暂无数据")

方式 2: 继承 BaseTool(旧版)

from langchain_core.tools import BaseTool

class WeatherTool(BaseTool):
    name: str = "Weather Query Tool"
    description: str = "查询城市天气信息"
    
    def _run(self, city: str) -> str:
        return "天气数据..."

🛠️ 实战:骑行规划助手

让我们创建一个完整的骑行规划系统,包含 3 个工具。

工具 1: 天气查询

@tool
def weather_tool(city: str) -> str:
    """查询城市天气信息"""
    weather_data = {
        "北京": "晴,15-25°C,微风,适合出行",
        "上海": "多云,18-26°C,东南风 2 级",
        "广州": "小雨,22-28°C,湿度较大",
        "深圳": "晴,24-30°C,炎热",
    }
    return weather_data.get(city, f"{city}天气暂无数据")

工具 2: 路线规划

@tool
def route_tool(start: str, end: str) -> str:
    """查询两地之间的骑行路线"""
    routes = {
        ("北京", "上海"): "约 1200km,途经京沪高速,7-10 天",
        ("北京", "广州"): "约 1900km,途经京港澳高速,12-15 天",
        ("上海", "深圳"): "约 1400km,途经沈海高速,10-12 天",
    }
    key = (start, end)
    return routes.get(key, f"从{start}{end}的路线暂无数据")

工具 3: 装备推荐

@tool
def gear_tool(weather: str, distance: str) -> str:
    """根据天气和路线推荐骑行装备"""
    suggestions = []
    
    if "雨" in weather:
        suggestions.append("☔ 携带雨衣雨披")
        suggestions.append("💧 防水手机袋")
    
    if "炎热" in weather or "30" in weather:
        suggestions.append("🧴 防晒霜")
        suggestions.append("💧 携带 2L 以上饮用水")
    
    if "1000" in distance:
        suggestions.append("🔧 完整维修工具包")
    
    return "\n".join(suggestions) if suggestions else "✅ 标准骑行装备即可"

🔑 工具的两个关键参数

1. name(工具名称)

  • 作用: 唯一标识工具
  • 用途: 日志输出、调试追踪
  • 示例: "Weather Query Tool"

2. description(工具描述)⭐⭐⭐

  • 作用: 告诉 Agent 工具能做什么
  • 重要性: Agent 会根据描述决定是否使用这个工具
  • 技巧: 描述要清晰、具体
# ❌ 不好的描述
"""天气"""

# ✅ 好的描述
"""查询城市天气信息,包括温度、风力、天气状况"""

🎭 Agent 如何使用工具

步骤 1: 创建工具

@tool
def weather_tool(city: str) -> str:
    """查询城市天气信息"""
    return "天气数据..."

步骤 2: 分配给 Agent

planner = Agent(
    role='骑行路线规划师',
    goal='规划最佳骑行路线',
    tools=[weather_tool, route_tool],  # ← 这里!
    llm=llm,
)

步骤 3: Agent 自主决策

当 Agent 收到任务时,会:

  1. 理解任务: “规划从北京到上海的骑行路线”
  2. 查看工具:
    • weather_tool - “查询城市天气信息” ✅ 相关
    • route_tool - “查询两地之间的骑行路线” ✅ 相关
  3. 调用工具:
    weather_tool(city="北京")
    route_tool(start="北京", end="上海")
    
  4. 整合结果: 生成最终规划建议

📊 完整示例

from crewai import Agent, Task, Crew
from crewai.tools import tool

# 定义工具
@tool
def weather_tool(city: str) -> str:
    """查询城市天气信息"""
    return "晴,15-25°C"

@tool
def route_tool(start: str, end: str) -> str:
    """查询两地之间的骑行路线"""
    return "约 1200km,7-10 天"

# 创建 Agent(配备工具)
planner = Agent(
    role='骑行路线规划师',
    goal='规划最佳骑行路线',
    tools=[weather_tool, route_tool],
    llm="deepseek/deepseek-chat",
)

# 创建任务
task = Task(
    description="规划从北京到上海的骑行路线,查询天气和路线信息。",
    expected_output="详细的路线规划建议",
    agent=planner,
)

# 执行
crew = Crew(agents=[planner], tasks=[task])
result = crew.kickoff()
print(result)

💡 工具设计最佳实践

1. 单一职责原则

每个工具只做一件事:

# ✅ 好:职责单一
@tool
def weather_tool(city: str) -> str:
    """查询天气"""

@tool
def route_tool(start: str, end: str) -> str:
    """查询路线"""

# ❌ 不好:职责过多
@tool
def planning_tool(city: str, start: str, end: str) -> str:
    """同时查询天气、路线、推荐装备"""

2. 参数尽量简单

# ✅ 好:参数简单
@tool
def search_tool(query: str) -> str:
    """搜索信息"""

# ⚠️ 注意:参数过多
@tool
def complex_tool(a: str, b: str, c: str, d: str, e: str) -> str:
    """参数太多,Agent 可能不会用"""

3. 返回值明确

# ✅ 好:返回清晰的字符串
@tool
def weather_tool(city: str) -> str:
    return "晴,15-25°C,微风"

# ❌ 不好:返回复杂对象
@tool
def bad_tool(city: str) -> dict:
    return {"temp": 20, "wind": 3}  # Agent 可能无法正确解析

🔍 工具调试技巧

1. 开启 verbose

planner = Agent(
    role='规划师',
    verbose=True,  # ← 查看工具调用过程
    tools=[weather_tool],
)

2. 查看工具调用日志

你会看到:

🔧 Tool Execution Started
Tool: weather_tool
Args: {'city': '北京'}

✅ Tool Execution Completed
Output: 晴,15-25°C,微风

3. 测试工具函数

直接调用测试:

print(weather_tool("北京"))  # 确认返回值正确

🎓 内置工具推荐

crewai_tools 提供了很多开箱即用的工具:

from crewai_tools import (
    FileReadTool,        # 读取文件
    ScrapeWebsiteTool,   # 爬取网页
    SerperDevTool,       # Google 搜索
    PDFSearchTool,       # 搜索 PDF
    CSVSearchTool,       # 搜索 CSV
)

📝 总结

通过本文,你学会了:

  • ✅ 为什么要使用工具
  • ✅ 如何创建自定义工具(@tool 装饰器)
  • ✅ 工具的两个关键参数(name 和 description)
  • ✅ Agent 如何自主选择和调用工具
  • ✅ 工具设计的最佳实践
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐