Skip to content

工具开发

更新: 4/9/2026 字数: 0 字 时长: 0 分钟

本章详细介绍如何开发高质量的 Agent 工具,包括基础工具、高级工具、错误处理等。

工具基础

工具的本质

Tool Definition
────────────────────────────────────────────────────────

工具 = 函数 + 元数据 + 执行逻辑

┌─────────────────────────────────────────────────────────┐
│  Tool                                                    │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  函数签名 (Function Signature)                            │
│  def get_weather(city: str) -> str:                    │
│       │       │         │                               │
│       │       │         └── 返回类型                      │
│       │       └────────── 参数                           │
│       └──────────────── 函数名                           │
│                                                          │
│  文档字符串 (Docstring)                                  │
│  """获取城市天气                                         │
│                                                          │
│  Args:                                                   │
│      city: 城市名称                                      │
│                                                          │
│  Returns:                                                │
│      天气信息字符串                                       │
│  """                                                      │
│                                                          │
└─────────────────────────────────────────────────────────┘

为什么工具定义重要?

python
# LangChain 从 docstring 和签名自动提取信息
def get_weather(city: str) -> str:
    """
    获取城市天气

    参数:
        city: 城市名称,如 "北京"
    返回:
        天气信息
    """
    ...

# LangChain 自动生成 tool_schema

简单工具

基本函数工具

python
from langchain.agents import create_agent

# 最简单的工具:普通 Python 函数
def say_hello(name: str) -> str:
    """打招呼"""
    return f"你好,{name}!"

def get_current_time() -> str:
    """获取当前时间"""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def calculate(expression: str) -> str:
    """计算数学表达式"""
    try:
        result = eval(expression)
        return str(result)
    except:
        return "计算错误"

带参数模式的工具

ArgsSchema 定义

python
from langchain_core.tools import tool, StructuredTool
from pydantic import BaseModel, Field

# 方式一:使用 @tool 装饰器 + ArgsSchema
@tool(args_schema=WeatherInput)
def get_weather(city: str, country: str = "CN") -> str:
    """获取指定城市的天气预报"""
    return f"{city}今天晴朗,25°C"

# 定义输入模式
class WeatherInput(BaseModel):
    """天气查询参数"""
    city: str = Field(description="城市名称,如北京、上海")
    country: str = Field(
        default="CN",
        description="国家代码,CN=中国,US=美国"
    )

StructuredTool 方式

python
from langchain_core.tools import StructuredTool

def search_flights(
    departure: str,
    destination: str,
    date: str,
    passengers: int = 1
) -> str:
    """搜索航班"""
    return f"找到航班:{departure} -> {destination}"

# 使用 StructuredTool 显式定义
flight_tool = StructuredTool.from_function(
    func=search_flights,
    name="search_flights",
    description="""搜索航班信息

    适用场景:
    - 计划旅行
    - 出差安排
    - 探亲访友
    """,
    args_schema={...}
)

Pydantic 工具

完整 Pydantic 示例

python
from langchain_core.tools import tool
from pydantic import BaseModel, Field
from typing import Optional, Literal

class FlightSearchInput(BaseModel):
    """航班搜索输入参数"""
    
    departure: str = Field(
        description="出发城市/机场",
        examples=["北京", "PEK"]
    )
    
    destination: str = Field(
        description="目的城市/机场",
        examples=["上海", "SHA"]
    )
    
    date: str = Field(
        description="出发日期,格式 YYYY-MM-DD"
    )
    
    passengers: int = Field(
        default=1,
        ge=1,
        le=9,
        description="乘客数量(1-9人)"
    )

@tool(args_schema=FlightSearchInput)
def search_flights(
    departure: str,
    destination: str,
    date: str,
    passengers: int = 1
) -> str:
    """搜索航班"""
    flights = [
        {"no": "CA1234", "time": "08:00-10:30", "price": 800},
    ]
    result = f"从 {departure}{destination} 的航班:\n"
    for f in flights:
        result += f"• {f['no']} | {f['time']} | ¥{f['price'] * passengers}\n"
    return result

工具设计原则

设计检查清单

工具设计原则
═══════════════════════════════════════════════════════════════

✅ 名称清晰
   • 使用动词或动词短语:get, search, calculate, send
   • 名称唯一,不与其他工具混淆

✅ 描述准确
   • 说明工具用途
   • 列出适用场景
   • 明确输入输出格式

✅ 参数明确
   • 类型注解
   • 必选/可选区分
   • 默认值合理
   • 参数说明详细

✅ 错误处理
   • 参数验证
   • 异常捕获
   • 友好错误信息

✅ 返回友好
   • 结构化输出
   • 关键信息突出

错误处理

基础错误处理

python
@tool
def get_stock_price(symbol: str) -> str:
    """获取股票价格"""
    try:
        if not symbol.isalpha():
            raise ValueError("股票代码必须是字母")
        
        prices = {"AAPL": 175.50, "TSLA": 250.00}
        price = prices.get(symbol.upper())
        
        if price is None:
            return f"未找到股票 {symbol}"
        
        return f"{symbol} 当前价格: ${price}"
    
    except ValueError as e:
        return f"参数错误: {str(e)}"
    except Exception as e:
        return f"获取股票信息失败"

本章小结

工具开发要点
────────────────────────────────────────────────────────

✅ 普通函数 + docstring = 基础工具
✅ Pydantic BaseModel = 参数模式
✅ StructuredTool = 显式配置
✅ 错误处理 + 重试 = 可靠工具

最佳实践
────────────────────────────────────────────────────────
1. 工具名称:动词开头,如 get_, search_, calculate_
2. 参数说明:完整描述,示例值
3. 返回格式:结构化,友好可读
4. 错误处理:友好提示,不暴露内部细节

Released under the MIT License.