3.5 实战:实现自定义 LangChain Tool
引言
小白理解 - 什么是 LangChain Tool?
Tool = AI 能调用的"技能"
类比:AI 就像一个实习生:
- 实习生很聪明,但不会所有事
- 你给他一个工具箱(Tools)
- 工具箱里有:搜索工具、计算器、天气查询...
- 实习生根据任务,选择合适的工具使用
用户:"北京今天天气怎么样?" AI 思考:"这需要查天气,我有 WeatherTool!" AI 调用:WeatherTool.run(location="北京") AI 回答:"北京今天晴天 25°C"
为什么要自定义 Tool?
LangChain 内置了一些 Tool,但你的业务可能需要:
- 查询公司内部数据库
- 调用自己的 API
- 执行特定计算
所以你需要学会自己写 Tool!
完整的 Tool 类实现
小白理解 - 代码结构
BaseTool(抽象基类) │ │ 定义"Tool必须有什么": │ - name:工具名字 │ - description:工具描述(告诉AI这工具干啥) │ - _run():实际执行的逻辑 │ - run():公开接口(自动计数等) │ └── WeatherTool(你的自定义工具) │ 实现: │ - name = "weather" │ - description = "获取城市天气" │ - _run() = 查天气的代码
python
from abc import ABC, abstractmethod
from typing import Optional
from pydantic import BaseModel, Field
class ToolInput(BaseModel):
"""Tool 输入基类"""
pass
class BaseTool(ABC):
"""Tool 抽象基类"""
def __init__(self):
self.call_count = 0
@property
@abstractmethod
def name(self) -> str:
pass
@property
@abstractmethod
def description(self) -> str:
pass
@abstractmethod
def _run(self, **kwargs) -> str:
pass
def run(self, **kwargs) -> str:
"""公共运行接口"""
self.call_count += 1
return self._run(**kwargs)
class WeatherInput(ToolInput):
location: str = Field(description="城市名称")
class WeatherTool(BaseTool):
"""天气查询工具"""
@property
def name(self) -> str:
return "weather"
@property
def description(self) -> str:
return "获取城市天气信息"
def _run(self, location: str) -> str:
return f"{location} 的天气:晴天 25°C"
# 使用
tool = WeatherTool()
print(tool.run(location="北京"))
print(f"调用次数: {tool.call_count}")关键代码解读:
代码 作用 为什么需要 @abstractmethod子类必须实现 确保每个 Tool 都有名字和描述 @property属性化访问 tool.name而不是tool.name()_run()实际逻辑 你只需要实现这个 run()公开接口 自动计数、日志、错误处理 BaseModelPydantic 验证 自动验证输入参数
更多 Tool 示例
计算器 Tool
python
class CalculatorTool(BaseTool):
"""计算器工具"""
@property
def name(self) -> str:
return "calculator"
@property
def description(self) -> str:
return "执行数学计算"
def _run(self, expression: str) -> str:
try:
result = eval(expression) # 注意:生产环境要安全处理
return str(result)
except Exception as e:
return f"计算错误: {e}"
# 使用
calc = CalculatorTool()
print(calc.run(expression="2 + 3 * 4")) # 14搜索 Tool
python
class SearchTool(BaseTool):
"""搜索工具"""
@property
def name(self) -> str:
return "search"
@property
def description(self) -> str:
return "搜索互联网获取信息"
def _run(self, query: str) -> str:
# 实际应用中这里会调用搜索 API
return f"搜索 '{query}' 的结果:..."
# 使用
search = SearchTool()
print(search.run(query="Python 教程"))本节小结
| 概念 | 一句话解释 |
|---|---|
| Tool | AI 能调用的技能 |
| BaseTool | 所有 Tool 的父类模板 |
| name | Tool 的名字(AI 用来识别) |
| description | Tool 的描述(AI 用来理解何时使用) |
| _run() | 你需要实现的核心逻辑 |
| run() | 公开接口,带自动计数 |
创建自己的 Tool 只需 4 步:
- 继承
BaseTool- 实现
name属性- 实现
description属性- 实现
_run()方法
下一节:3.6 小结和复习