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))
















请登录后查看评论内容