GPT 中的函数调用(function call)是什么?

在 OpenAI ChatGPT API 和 Google Gemini API 中我们可以看到函数调用的功能。这个功能是做什么用的?下面大概讲解。

Google Gemini API 函数调用 一节中的内容为例,该章节举了一个例子:

大语言模型(LLMs)往往无法进行准确的数学运算。比如说,给 Gemini 两个数 \(a\)\(b\),让它计算 \(a \times b\) 的值。Gemini 给出的值往往和实际计算值有所出入。

model = genai.GenerativeModel('gemini-pro')
chat = model.start_chat()

a = 2312371
b = 234234

response = chat.send_message(
    f"What's {a} X {b} ?"
)
print(response.text)

Gemini 给出的值是:

549899573314

\(a \times b\) 的实际值是 541635908814,Gemini 的计算并不正确。

我们会想:既然 Gemini 算不正确,但是这种小事我们用 Python 就能算正确了呀。能不能让 Gemini 像我们一样使用 Python 来进行计算呢?

答案是可以。

只要我们在本地定义好 Gemini 需要调用的函数,再向 Gemini 声明我们为它定义了哪些函数、函数的功能是什么,以及函数的参数有哪些,Gemini 就可以在它认为需要调用这些函数的时候,以对话的形式向我们请求调用这些函数。

比如说,我们希望 Gemini 的乘法运算能更准确一点,于是我们为它定义一个乘法函数:

def multiply(a, b):
    return a * b

我们还要告诉 Gemini 我们为它定义了 multiply 这个函数,用于计算两个数的乘积,并且它需要两个数字参数 ab

calculator = glm.Tool(
    function_declarations=[
      # 在这里进行函数声明
      glm.FunctionDeclaration(
        name='multiply',  # 函数名
        description="Returns the product of two numbers.",  # 功能描述
        # 在这里进行参数声明
        parameters=glm.Schema(
            type=glm.Type.OBJECT,
            properties={
                # 需要两个参数 a 和 b,类型为 NUMBER
                'a':glm.Schema(type=glm.Type.NUMBER),
                'b':glm.Schema(type=glm.Type.NUMBER)
            },
            required=['a','b']  # 声明必要参数,这里 a 和 b 都是必要的
        )
      )
    ])

这样,Gemini 就知道了我们为它准备了一个函数 multiply,用于乘法运算。

现在,我们再次询问 Gemini \(a \times b\) 的值:

model = genai.GenerativeModel('gemini-pro', tools=[calculator])
chat = model.start_chat()

a = 2312371
b = 234234

response = chat.send_message(
    f"What's {a} X {b} ?",
)

Gemini 在分析完我们的问题之后发现它要计算 \(a \times b\) 的值,并且还发现我们已经为它定义了一个函数 multiply 用于乘法运算。所以,它在生成回答之前,会先向我们请求调用 multiply 这个函数。我们在 response.candidates 这个属性中可以看到它请求调用的函数名:

response.candidates
[index: 0
content {
  parts {
    function_call {
      name: "multiply"
      args {
        fields {
          key: "b"
          value {
            number_value: 234234
          }
        }
        fields {
          key: "a"
          value {
            number_value: 2312371
          }
        }
      }
    }
  }
  role: "model"
}
finish_reason: STOP
]

可以看到,在 function_call 属性中,它请求了 multiply 这个函数,并且给出了函数的参数 ab

接下来,我们只需在本地为它执行 multiply 这个函数,并把函数的返回值传递给它即可:

fc = response.candidates[0].content.parts[0].function_call  # 获取 Gemini 请求的函数调用相关信息
if fc.name == 'multiply':  # 判断函数调用的名字是否为 multiply
    result = mutiply(fc.args['a'], fc.args['b'])  # 执行函数调用

# 最后,将函数调用的结果传递给 Gemini
response = chat.send_message(
    glm.Content(
    parts=[glm.Part(
        # 在这里传入函数调用的结果
        function_response = glm.FunctionResponse(
          name='multiply',
          response={'result': result}
        )
    )]
  )
)
posted @ 2024-02-05 21:45  Undefined443  阅读(210)  评论(0编辑  收藏  举报