2、工具的定义方式1:不使用@tool

2.1 模型绑定工具并发送请求

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
# 从.env文件中加载环境变量
load_dotenv(override=True)
CLOSEAI_API_KEY = os.getenv("CLOSEAI_API_KEY")
CLOSEAI_BASE_URL = os.getenv("CLOSEAI_BASE_URL")
model = init_chat_model(
 model="gpt-5.4-mini",
 model_provider="openai",
 api_key=CLOSEAI_API_KEY,
 base_url=CLOSEAI_BASE_URL
)
from rich import print as rprint
# 定义工具
def get_weather(city: str):
return f"{city}天气晴朗"
# 将模型和工具绑定
model_with_tools = model.bind_tools([get_weather])
response = model_with_tools.invoke(
"今天北京天气如何"
)
rprint(response)
# print(response.tool_calls)

2.2 工具描述的各部分详解

2.2.1 了解:convert_to_openai_tool
执行model.bind_tools([get_weather]) ,底层最终会调用convert_to_openai_tool 生成工具描述。所
以我们可以直接调用后者查看解析后的工具描述。

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city: str):
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))

结果字段说明:
(1) type:定义当前数据节点必须是什么数据类型。常见类型有 string, number, integer, boolean,
object, array, null。object即是json对象。
(2) properties:用于定义JSON 对象(Object)中可以包含哪些属性(键),以及每个属性对应的
值类型和说明。
(3) required:当 type为 “object”时使用,是一个数组,列出了对象中必须存在的属性名。

问题:为什么不使用@tool装饰器修饰的函数,也可以理解为工具呢?
查看convert_to_openai_tool 底层源码:

elif isinstance(function, langchain_core.tools.base.BaseTool):
 oai_function = cast("dict", _format_tool_to_openai_function(function))
elif callable(function):
 oai_function = cast(
  "dict", _convert_python_function_to_openai_function(function)
)

相当于加了@tool修饰的函数走上面的分支,没有加@tool修饰的函数走下面的分支,后者会基于函数定
义和docstring生成pydantic模式的描述,然后转换为规范的tool_schema。
2.2.2 description说明
convert_to_openai_tool 会从docstring(文档字符串) 加载工具的描述信息,上面的案例中,
docstring 为空,所以抽取的description 为空。
docstring,文档字符串,使用三个双引号表示开始和结束。

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city: str):
"""
天气查询工具
"""
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))

2.2.3 参数说明
convert_to_openai_tool 会从docstring 加载参数说明,这里的docstring 必须遵循Google 风格。
Google 风格docstring 说明:https://google.github.io/styleguide/pyguide.html
Google 风格docstring 示例:https://www.sphinx-doc.org/en/master/usage/extensions/exa
mple_google.html
Python docstring 通用约定:https://peps.python.org/pep-0257/
基础用法不必完整阅读规范,只需要按照下面的示例仿写即可。

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city: str):
 """
 天气查询工具
 Args:
 city: 城市名称
 """
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))

使用 Args: 、Returns: 、Raises: 等关键字,这种方式可读性强。Agent通过工具的这些注释来理解
工具的用途和调用时机,因此清晰、准确的文档字符串是工具能被正确调用的前提。

AI 依赖 docstring 来理解工具。

# ❌ 不好:太模糊
@tool
def tool1(x: str) -> str:
 """做一些事情"""
 ...
# ✅ 好:清晰明确
@tool
def search_products(query: str) -> str:
 """
 在产品数据库中搜索产品
 Args:
 query: 搜索关键词,如"笔记本电脑"、"手机"
 Returns:
 产品列表的 JSON 字符串
 """
 ...

2.2.4 参数类型说明
参数类型来源于函数的类型注解。

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city):
 """
 天气查询工具
 """
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))

删除了参数类型注解,则工具描述中不包含参数类型说明
注意:如果docstring中包含参数说明,则对应的参数必须有类型注解,否则报错

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city):
 """
 天气查询工具
 Args:
 city: 城市名称
 """
 print("天气晴朗")
rprint(convert_to_openai_tool(get_weather))

报错如下:

Traceback…
ValueError: Arg city in docstring not found in function signature.

2.2.5 参数默认值说明
如果参数没有默认值,则会包含在required对应的列表中。
反之,则参数的描述信息会包含default 字段,并且不会出现在required列表中。

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(city: str="北京"):
 """
 天气查询工具
 Args:
 city: 城市名称
 """
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))

目前只有一个参数,并且有默认值,所以required字段被移除了。
举例2:

from langchain_core.utils.function_calling import convert_to_openai_tool
from rich import print as rprint
def get_weather(dt: str, city: str="北京"):
 """
 天气查询工具
 Args:
 dt: 日期
 city: 城市名称
 """
 return f"{city}天气晴朗"
rprint(convert_to_openai_tool(get_weather))
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像-大赛人网
欢迎您留下宝贵的见解!
提交
头像-大赛人网

昵称

取消
昵称

    请登录后查看评论内容