function-calling:将LLM与业务系统集成

了解LLM的函数调用功能,该功能允许聊天机器人与任何事物进行交互,为AI驱动的应用程序开辟了新的可能性。

defagi avatar
  • defagi
  • 3 min read

想象一下,如果让你开发一款AI助手,对它说这样的话:“帮我查询下物流订单XXXX”.在LLM没有Function calling之前是很难做到的.随着语言模型不断突破界限并不断发展。ChatGPT 背后的公司 OpenAI 最近在其 GPT 模型中引入了一项名为函数调用(Function calling)的强大新功能。函数调用简化了与外部工具和 API 通信的聊天机器人的创建,为 AI 驱动的应用程序开辟了新的可能性领域。

newsgpt

什么是函数调用?

函数调用是 OpenAI 的GPT-4-0613和GPT-3.5 Turbo-0613模型中的一项新功能。这些 AI 模型经过训练,可以根据用户的提示检测函数调用的需求,并以结构化的调用请求(而不是常规文本)进行响应。

函数调用允许聊天机器人与其他系统交互,从而使 GPT 模型能够回答它们原本无法回答的问题,例如需要实时信息或训练集中未包含的数据的问题。换句话说,函数调用提供了另一种方法来教 AI 模型如何与外部世界交互。

函数调用的目的是什么?

在函数调用之前,只有两种方法可以增强 GPT 语言模型的功能:

  • 微调:通过提供示例响应进一步训练语言模型。微调是一种强大的技术,但需要大量工作(和成本)来准备训练数据。此外,在 OpenAI 在 GPT-3.5 和 GPT-4 模型中启用此功能之前,只有少数较旧的模型可以进行微调。
  • 嵌入:使用上下文数据丰富提示可以扩展机器人的知识并创建更准确的响应。缺点是这种上下文会占用大量标记,从而增加成本,并留下更少的标记用于构建复杂的响应。

函数调用增加了第三种扩展 GPT 功能的方法,即允许它要求我们代表它运行函数。然后,该模型可以获取函数的结果并构建一个可读的响应,无缝融入当前对话。

如何使用函数调用

函数调用的引入改变了我们与 GPT API 交互的方式。在这些函数出现之前,交互很简单:

  1. 向 API 发送提示
  2. 收到回复
  3. 重复

展示函数调用之前与 GPT API 的基本交互的图表

通过函数调用,序列变得更加复杂:

  1. 向用户发送提示以及可调用函数的列表。
  2. GPT 模型以常规文本响应或函数调用请求进行响应。
  3. 如果模型请求函数调用,您的聊天机器人的工作就是执行它并将结果返回给 API。
  4. 然后,模型会使用提供的数据形成连贯的文本响应。但是,在某些情况下,API 可能会请求新的函数调用。

展示了使用函数调用与 GPT API 进行更复杂的交互

使用聊天完成 API 进行函数调用

为了允许模型调用函数,我们必须使用Chat Completions API。该 API 接受带有 JSON 负载的 POST 请求,其中包含要处理的消息列表。发送给 API 的典型提示如下所示:

{
  "model": "gpt-3.5-turbo",
  "messages": [
    {
      "role": "user",
      "content": "How many planets does the solar system have?"
    }
  ]
}

通知role: userAPI 是content用户生成的。GPT API 可能会回复以下内容:

{
  "id": "chatcmpl-7WVo3fYwerpAptzeqU46JamOvgBzh",
  "object": "chat.completion",
  "created": 1687983115,
  "model": "gpt-3.5-turbo-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "There are eight planets in the solar system. They are:\n\n1. Mercury\n2. Venus\n3. Earth\n4. Mars\n5. Jupiter\n6. Saturn\n7. Uranus\n8. Neptune"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 44,
    "total_tokens": 59
  }
}

对应role: assistant于 GPT 模型生成的消息。为了保持对话流畅,我们必须在每次请求时将整个消息历史记录返回给 API。例如,如果我们想深入研究上一个问题,相应的 JSON 负载将是:

{
  "model": "gpt-3.5-turbo",
  "messages": [
    {
      "role": "user",
      "content": "How many planets does the solar system have?"
    },
    {
      "role": "assistant",
      "content": "There are eight planets in the solar system. They are:\n\n1. Mercury\n2. Venus\n3. Earth\n4. Mars\n5. Jupiter\n6. Saturn\n7. Uranus\n8. Neptune"
    },
    {
      "role": "user",
      "content": "Tell me more about the second planet."
    }
  ]
}

为了让语言模型知道它可以调用函数,我们需要将它们的列表添加到有效负载中。例如:

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {
      "role": "user",
      "content": "How is the weather in NYC?"
    }
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": [
              "celsius",
              "fahrenheit"
            ]
          }
        },
        "required": [
          "location"
        ]
      }
    }
  ]
}

你可能已经注意到,我们将模型切换为“gpt-3.5-turbo-0613”,因为它支持函数调用。如果模型决定调用该函数,我们将收到一个类型的响应,role: assistant其function_call属性定义如下:

{
  "id": "chatcmpl-7WWG94C1DCFlAk5xmUwrZ9OOhFnOq",
  "object": "chat.completion",
  "created": 1687984857,
  "model": "gpt-3.5-turbo-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "function_call": {
          "name": "get_current_weather",
          "arguments": "{\n  \"location\": \"New York, NY\"\n}"
        }
      },
      "finish_reason": "function_call"
    }
  ],
  "usage": {
    "prompt_tokens": 81,
    "completion_tokens": 19,
    "total_tokens": 100
  }
}

get_current_weather我们的任务是使用提供的参数执行。OpenAI不会执行该函数。相反,我们的聊天机器人会运行它并解析返回的数据。

一旦我们检索到天气数据,我们就会使用一种名为 的新角色类型将其发送回模型function。例如:

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {
      "role": "user",
      "content": "How is the weather in NYC?"
    },
    {
      "role": "assistant",
      "content": null,
      "function_call": {
        "name": "get_current_weather",
        "arguments": "{\n  \"location\": \"New York, NY\"\n}"
      }
    },
    {
      "role": "function",
      "name": "get_current_weather",
      "content": "Temperature: 57F, Condition: Raining"
    }
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": [
              "celsius",
              "fahrenheit"
            ]
          }
        },
        "required": [
          "location"
        ]
      }
    }
  ]
}

请注意,我们将整个消息历史记录传递给了 API,包括我们的原始提示、来自模型的函数调用以及在我们的代码中执行天气函数的结果。这使语言模型能够理解调用该函数的上下文。

最后,模型可能会以正确格式的答案回答我们最初的问题

{
  "id": "chatcmpl-7WWQUccvLUfjhbIcuvFrj2MDJVEiN",
  "object": "chat.completion",
  "created": 1687985498,
  "model": "gpt-3.5-turbo-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The weather in New York City is currently raining with a temperature of 57 degrees Fahrenheit."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 119,
    "completion_tokens": 19,
    "total_tokens": 138
  }
}

推荐