🎯 课程主题
使用 @tool 装饰器定义工具,深入讲解 description 参数和 name_or_callable 参数的用法与优先级规则。
📝 核心知识点
1. @tool 装饰器基础
- 概念说明:
@tool装饰器可自动将普通 Python 函数转化为可被模型调用的工具,是官方推荐的声明方式。 - 关键细节:
- 代码量极少,相较裸函数方式更简洁。
- 必须提供描述:若不提供
description参数且函数没有docstring,运行时会报错。
from langchain_core.tools import tool
# 错误:没有 docstring 也没有 description → 报错
@tool
def get_weather(city: str) -> str:
return f"{city}天气晴朗"
# 正确:提供了 docstring
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气"""
return f"{city}天气晴朗"
2. description 参数与 docstring 的优先级
情况一:只有 docstring
description不传,工具描述取 docstring 内容。
@tool
def get_weather(city: str) -> str:
"""获取城市的天气"""
return f"{city}天气晴朗"
# description = "获取城市的天气"
情况二:只有 description 参数
- 工具描述取
description参数的值,可以没有 docstring。
@tool(description="获取具体城市的天气情况")
def get_weather(city: str) -> str:
return f"{city}天气晴朗"
# description = "获取具体城市的天气情况"
情况三:两者同时存在 → description 优先级更高
description参数会覆盖 docstring 作为工具描述。
@tool(description="获取具体城市的天气情况")
def get_weather(city: str) -> str:
"""获取天气信息"""
return f"{city}天气晴朗"
# description = "获取具体城市的天气情况"(优先)
3. parse_docstring 参数
- 概念说明:控制是否按 Google 风格解析 docstring 中的参数描述。
- 关键细节:
- 默认值为
False,此时 docstring 整体被视为工具描述,不会解析Args:等参数块。 - 设为
True后,会按 Google 风格解析 docstring,同时会启用格式校验(不合法则抛异常)。 - 即使启用了
parse_docstring=True,若有description参数,description仍优先作为工具描述,但参数描述(Args:)仍会生效。
- 默认值为
# 不加 parse_docstring → Args 不会解析为参数描述
@tool
def get_weather(city: str) -> str:
"""获取城市天气
Args:
city: 城市名称
"""
return f"{city}天气晴朗"
# city 没有参数描述,Args 被当作整体 description 的一部分
# 加 parse_docstring=True → Args 中的参数描述被正确解析
@tool(parse_docstring=True)
def get_weather(city: str) -> str:
"""获取城市天气
Args:
city: 城市名称
"""
return f"{city}天气晴朗"
# city 参数新增 description: "城市名称"
# parse_docstring=True + description → description 优先,参数描述仍生效
@tool(description="获取具体城市的天气", parse_docstring=True)
def get_weather(city: str) -> str:
"""获取某地天气
Args:
city: 城市名称
"""
return f"{city}天气晴朗"
# 工具描述: "获取具体城市的天气"(description 优先)
# city 参数描述: "城市名称"(parse_docstring 生效)
4. 工具命名:name_or_callable 参数
- 概念说明:通过
name_or_callable(或直接传字符串作为第一个位置参数)自定义工具名称。 - 关键细节:
- 默认工具名 = 函数名。可通过
name_or_callable覆盖。 - 日常开发中一般直接用函数名作为工具名,无需刻意修改。
- 避免使用
config、runtime等 LangChain 内部保留名称。
- 默认工具名 = 函数名。可通过
# 默认:工具名 = 函数名 "get_weather"
@tool
def get_weather(city: str) -> str:
"""获取城市天气"""
return f"{city}天气晴朗"
# 自定义工具名
@tool("GetWeather") # 或 @tool(name_or_callable="GetWeather")
def get_weather(city: str) -> str:
"""获取城市天气"""
return f"{city}天气晴朗"
# 工具名 = "GetWeather"(而非 "get_weather")
5. Docstring 格式校验(装-不装的区别)
| 场景 | 无 @tool | @tool(默认) | @tool(parse_docstring=True) |
|---|---|---|---|
| 无 docstring | 可运行 | 报错(要求提供 desc) | 报错(要求提供 desc) |
| docstring 格式不规范 | 当普通文本处理 | 当普通文本处理 | 报错(严格校验) |
| Args 参数描述 | 需手动加(有则解析) | 不解析(整体当 desc) | 解析并校验格式 |
🏗️ 架构与工作流
Python 函数
│
▼
@tool 装饰器 ─── description 参数(可选,优先级最高)
│ ─── parse_docstring 参数(可选,控制参数解析)
│ ─── name_or_callable 参数(可选,自定义工具名)
▼
Tool 对象 ──→ model.bind_tools() ──→ 模型可识别调用
💻 代码实战
见各知识点中的代码示例。
⚠️ 常见问题与避坑指南
- 必须提供描述:
@tool装饰的函数必须有 docstring 或description参数,否则运行时报错。 parse_docstring=True会启用严格校验:docstring 格式(换行、大写、冒号)不合法会直接抛异常;而不加该参数时只是不解析参数描述,不会报错。description优先级最高:无论是否启用parse_docstring,description参数始终覆盖 docstring 作为工具描述。- 不要使用保留名称:
config、runtime等是 LangChain 内部保留名,不能作为工具名。
💡 个人总结与延伸
@tool 装饰器是 LangChain 中最推荐的工具定义方式。实际开发建议:函数签名写好类型注解,docstring 写好功能描述,参数描述统一用 @tool(parse_docstring=True) + Google 风格 docstring 来管理,代码规范且可维护。description 参数一般可省略,直接用 docstring 描述即可。