Skip to content

Tools基础 ​

早期大模型本身只能处理已有知识库的问题,无法处理一些实时性的问题,例如:

今天天气如何?
今天有什么爆炸性新闻?

OpenAI 提出了 Function Calling 的概念,让大模型能够指导 Agent 调用工具获取实时信息。

Function Calling 已经更名为 Tools.

Tools 的 工作流程

注意,不同的模型厂商,使用工具时略有差异。

以 OpenAI 为例进行演示

注册工具 ​

  1. 注册一个叫 getCurrentWeather 的函数,告诉模型它的作用和参数格式。

  2. 用户问:“北京的天气怎么样?”

  3. 模型就会自动决定:嗯,这需要调用那个工具。并返回函数名称和参数(location: "北京")给我们。

Step 1:定义工具函数和 tools 描述

Tools 各项描述含义:

  • type: "function" 目前只支持值为 function, 必须指定
  • function 是对具体函数的描述
  • name 是函数名, 需要跟函数的名称一致, 方便我们后续实现对函数名的调用
  • descirption 函数的描述, 你可以理解成对 LLM 决定什么是否调用该函数的唯一信息, 这部分清晰的表达函数的效果
  • parameters 函数的参数, OpenAI 使用的是通用的 JSON Schema 去描述函数的各个参数, 在我们这里使用了数组作为参数的输入, 其中有两个 key
    • location 一个 string 值表示位置
    • unit 表示请求的单位
  • required 通过这个 key 告知 LLM 该参数是必须的

使用工具 ​

调用模型,观察是否生成函数调用请求。

使用 openai 官方库来调用 OpenAI 的 gpt-3.5-turbo 模型。

询问模型一个问题,如下:

js
// index.js

// 前面代码略...

// 1. 模拟用户提问
const messages = [{ role: "user", content: "北京的天气怎么样?" }];

// 2. 模型判断是否调用函数
const result = await openai.chat.completions.create({
  model: "gpt-3.5-turbo-1106", // 指定模型
  messages, // 用户的问题
  tools, // 工具箱🧰 让大模型知道有哪些工具可以使用
});

console.log("模型返回内容:");
console.dir(result.choices[0], { depth: null });

模型输出内容:

js
{
  index: 0, // 本条消息在返回数组中的位置(第 0 条)
  message: {
    role: 'assistant',   // 角色:来自助手(模型)
    content: null,       // 没有自然语言内容,因为这一步是“发起工具调用”
    tool_calls: [        // 工具调用列表:本例中只有 1 个
      {
        id: 'call_WnSIQJJUjgifGqgAnzNkmgLR', // 此次工具调用的唯一 ID(后续对齐结果用)
        type: 'function',                    // 工具类型:函数调用
        function: {
          name: 'getCurrentWeather',         // 要调用的函数名(应与你声明的 tools 匹配)
          // 以“字符串化的 JSON”形式给出的参数(API 规范常见写法)
          // 使用时需要先 JSON.parse() 成对象再传给真实函数实现
          arguments: '{"location":"北京","unit":"celsius"}'
        }
      }
    ],
    refusal: null,   // 没有拒答(如果模型拒绝执行,会给出拒绝原因/说明)
    annotations: []  // 额外标注信息(如安全/敏感片段标注);此处为空
  },
  logprobs: null,        // 未返回 token 级别的对数概率(一般调试/研究才会用到)
  // 结束原因:'tool_calls' 表示该轮对话以“请求调用工具”作为结尾
  // 正确的下一步是:宿主/应用去执行这个工具,再把结果回传给模型
  finish_reason: 'tool_calls'
}

后续步骤 ​

目前已经完成了:

  • 用户提问
  • 模型决定要不要调用函数
  • 并返回 tool_calls,告诉我们该调用哪个函数、传什么参数

但这只是“调用的意图”,我们还需要完成“真正执行”与“继续对话”的闭环。

完整流程如下:

1. 用户提问 --> "北京天气如何?"
        ↓
2. 模型返回 tool_calls ➜ getCurrentWeather({ location: "北京" })
        ↓
3. JS 调用本地函数 --> 得到天气结果
        ↓
4. 把结果再发送给模型 --> 模型生成最终回答

课堂练习

完成后续代码。


-EOF-