LangChain 1.0 实战:用 @tool 装饰器5分钟搞定你的第一个AI工具函数
LangChain 1.0 极简实战:5分钟用@tool打造你的第一个AI工具函数
刚接触LangChain时,最让人头疼的往往不是概念理解,而是如何快速实现第一个能跑通的Demo。今天我们就用最直白的方式,从零开始创建一个天气查询工具函数,全程只需5分钟,不绕弯子,只讲实操。
1. 环境准备与基础工具创建
在开始之前,确保你的Python环境已经安装好LangChain核心包:
pip install langchain-core创建一个最简单的工具函数只需要三步:
- 导入
@tool装饰器 - 编写普通Python函数
- 添加清晰的docstring
来看这个查询城市温度的示例:
from langchain.tools import tool @tool def get_temperature(city: str) -> float: """获取指定城市的当前温度(摄氏度) Args: city: 需要查询的城市名称,如"北京" """ # 这里应该是调用天气API的代码 # 为演示返回模拟数据 return 22.5 if city == "北京" else 18.0关键点说明:
- 函数参数需要类型标注(如
str) - docstring中的参数说明会被LangChain自动解析
- 返回类型也要明确标注(如
float)
2. 工具属性自定义技巧
默认情况下,工具名称就是函数名,但我们可以通过装饰器参数自定义:
@tool("weather_checker", description="查询实时天气数据,包括温度、湿度和风速") def check_weather(location: str) -> dict: """实际实现中可以返回更丰富的天气数据""" return {"temp": 22, "humidity": 65, "wind": 10}属性自定义的三种方式:
| 自定义项 | 方法 | 示例 |
|---|---|---|
| 工具名称 | @tool("自定义名称") | @tool("天气查询") |
| 工具描述 | description=参数 | description="获取实时天气" |
| 参数说明 | docstring中的Args部分 | location: 城市名称或坐标 |
提示:description比docstring优先级更高,两者都存在时以description为准
3. 复杂参数处理方案
当需要处理复杂输入时,可以使用Pydantic模型定义参数结构:
from pydantic import BaseModel, Field from typing import Literal class WeatherQuery(BaseModel): location: str = Field(description="城市名称或经纬度坐标") unit: Literal["celsius", "fahrenheit"] = Field( default="celsius", description="温度单位,摄氏度或华氏度" ) include_forecast: bool = Field( default=False, description="是否包含三日预报" ) @tool(args_schema=WeatherQuery) def get_detailed_weather(query: WeatherQuery) -> str: """获取详细的天气信息""" base_info = f"{query.location}当前温度:22{query.unit[0]}" if query.include_forecast: base_info += "\n未来三日:晴转多云" return base_info这种方式的优势在于:
- 参数验证自动化
- 生成更准确的工具调用说明
- 支持复杂嵌套参数结构
4. 实战:集成到Agent测试
工具创建好后,最简单的测试方式是直接调用:
weather_tool = get_detailed_weather print(weather_tool.run({"location": "上海", "unit": "celsius"}))更真实的场景是集成到Agent中:
from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_openai import ChatOpenAI model = ChatOpenAI(model="gpt-3.5-turbo") tools = [get_detailed_weather] agent = create_tool_calling_agent(model, tools) agent_executor = AgentExecutor(agent=agent, tools=tools) response = agent_executor.invoke({ "input": "上海明天会下雨吗?用摄氏度显示温度" }) print(response["output"])常见问题排查:
- 工具未被识别 → 检查docstring格式是否正确
- 参数传递错误 → 确认参数类型标注是否准确
- 描述不清晰 → 优化description或docstring
5. 效率优化与小技巧
几个提升开发效率的实用技巧:
代码补全配置(VS Code示例):
{ "python.analysis.typeCheckingMode": "basic", "python.languageServer": "Pylance" }调试建议:
- 先用
tool.run()单独测试工具 - 打印工具的
args_schema查看参数结构 - 对复杂工具可以先写伪代码再实现
性能考量:
- 工具函数应当保持轻量
- 耗时操作考虑添加缓存
- I/O操作尽量使用异步
import asyncio from langchain.tools import tool @tool async def async_weather_check(city: str) -> str: """异步版本的天气查询""" await asyncio.sleep(0.1) # 模拟网络请求 return f"{city}天气晴"最后分享一个真实案例:曾遇到一个工具因为docstring中漏写了参数说明,导致Agent始终无法正确调用。后来发现LangChain对参数描述的完整性要求很高,每个参数都必须在Args部分明确说明用途。这个教训让我从此养成了写完整docstring的习惯。
