函数调用(工具调用)101
作者:董兆涵
日期:2025 年 1 月 17 日
您可能熟悉 Grok API 的基本操作,例如构建聊天机器人,或者让 LLM 根据您的对话输入解决问题。
通过函数调用(也称为工具调用),您可以扩展 Grok 的功能,使其能够与您的本地系统交互,从而让 Grok 请求您的本地系统执行任务,例如更新数据库、调用另一个 API 分配资源,或者在网站上查找信息等。
目标
通过本教程,您应该能够设置一个基本的函数调用以检索数据并将其与 Grok 结合使用。
示例场景
想象一下,现在是冬天,您舒适地坐在家里。您正计划在 3 天内与家人和朋友一起进行一次滑雪旅行。您不确定天气会怎样以及如何最好地准备。
当然,您可以谷歌天气,但您也希望 Grok 给出一些个性化的建议。您着手构建一个具有函数调用的聊天机器人,该机器人可以检索实时天气预报。
函数调用(工具调用)概述
建议阅读:xAI API 文档中的函数调用
让 Grok 使用函数调用包括
- 定义一个函数以在您的系统上执行所需的操作。
- 在您的 API 请求中将函数参数签名提供给 Grok,以便 Grok 知道这些函数可在您的本地系统上使用。
- 当 Grok 确定您的请求需要通过这些函数提供的额外信息/操作时,它将在 API 响应消息中发送一个
tool_call
对象。 - 您的系统处理 Grok 请求的
tool_call
,并将结果返回给 Grok。(您还可以为 Grok 添加可选请求) - Grok 使用这些结果生成响应,并可能根据具体情况请求更多
tool_calls
。
简而言之——Grok 在 xAI API 响应中调用我们的本地函数,我们的本地函数通过 xAI API 请求将结果返回给 Grok。
构建模块
现在有了函数调用的基本概念,让我们开始构建以下内容
- Grok 可以使用的函数
- 函数调用处理程序,用于处理 Grok 在响应中请求函数调用时的情况
- 设置 xAI API 聊天请求和响应管道
首先让我们安装一些依赖项
1. 在本地创建 Grok 可以使用的函数
为了获取天气预报,我们将使用NOAA API Web 服务。
我们可以通过从https:///api.weather.gov/gridpoints/{wfo}/{x},{y}/forecast
检索数据,获取 2.5 公里网格区域的 7 天天气预报,格式如下。wfo
和{x},{y}
可以从https://api.weather.gov/points/{latitude in signed decimal degrees},{longitude in signed decimal degrees}
获得。例如,以下是马萨诸塞州波士顿的天气预报,从端点https://api.weather.gov/gridpoints/BOX/72,90/forecast
检索。
对于我们的用例,我们将预测区域限制在几个受欢迎的滑雪区,并将 NOAA API 响应中的properties.periods
返回给 Grok。
在这里,我们将使用 Pydantic 定义函数输入和输出。
您可以预览当 Grok 请求科罗拉多州阿斯彭的天气预报时,我们发送给 Grok 的数据。
要调用的函数已定义!太好了!现在我们需要发送函数名称和参数签名,以便 Grok 知道如何调用该函数。
2. 函数处理程序,用于调用我们定义的函数并将结果添加到对话历史记录中
通过我们之前定义的函数,我们可以向 Grok 发送请求。
让我们看看 Grok 将如何回应
您可以在响应ChatCompletionMessage
中看到,Grok 包含了以下内容:tool_calls=[ChatCompletionMessageToolCall(id='call_67298806', function=Function(arguments='{"location":"vali"}', name='get_weather_forecast'), type='function')
。
我们需要设计一个处理程序来处理tool_calls
,通过
- 将 Grok 的响应添加到聊天历史记录中,以防我们想继续对话。
- 决定 Grok 的响应是否包含
tool_call
。如果没有- 向终端用户打印 Grok 的响应消息。
- 跳过以下步骤。
- 调用名为
get_weather_forecast
的函数。 - 将函数结果添加到聊天历史记录中,如下所示
现在我们对 Grok 之前的消息调用处理程序,看看我们的chat_history
发生了什么
现在我们终于可以将其发回给 Grok,以获得推荐!
3. 设置整个管道以生成推荐
回顾一下
- 我们定义了本地函数
get_weather_forecast()
,用于检索 NOAA 天气预报供 Grok 运行。 - 我们定义了一个
function_calls_handler()
,用于将 Grok 的响应添加到聊天历史记录中,并在 Grok 请求时运行该函数。- 作为此功能的一部分,我们还定义了一个
tools_map
来映射 Grok 给出的函数名 -> 可调用函数对象。
- 作为此功能的一部分,我们还定义了一个
我们将运行我们的聊天请求/响应到这一点
您可以将用户输入、对 Grok 的调用和 function_call_handler 封装在一个循环中。这样,Grok 将持续回答您的问题!