OPENAI重磅更新:函数调用功能,足以改变开发流程的一次更

引言

今天OPENAI发布重磅更新,包括: 1.Chat Completions API 中的新函数调用功能 2.gpt-4和的更新和更易于操纵的版本gpt-3.5-turbo 3.新的 16k 上下文版本gpt-3.5-turbo(与标准 4k 版本相比) 4.我们最先进的嵌入模型的成本降低了 75% 5.输入令牌的成本降低,gpt-3.5-turbo模型降低了25% 6.gpt-3.5-turbo-0301和gpt-4-0314模型宣布弃用时间表

很多人觉得重磅在降低了成本,扩大了token数,但是这些都是在人们预料之中的,只有新的函数调用功能才是实至名归的“重磅”。

很多人不理解,什么是函数调用功能,这里举一个生动的例子: 从前我们要问gpt今天的天气,gpt会说不知道,因为需要你所处的地址,以及一个天气预报的网站的API。当我们可以使用函数调用功能,那么当gpt发现自己不知道地址和API的时候,就会在我们提供的函数库里面找,如果有相关的函数就会调用,从而实现功能。

如果有了解Langchain的朋友会发现,这不就是agent的功能吗?是的,OPENAI将这个功能“抄“到了自己的API接口服务中。让整个流程更加丝滑合理,符合逻辑。具体的差距后面会讲。下面我们先了解一下functions的参数。

functions具体参数介绍

functions 是 ChatCompletion API 中的可选参数,可用于提供函数规范。这样做的目的是使模型能够生成符合函数输入模式的输出。请注意,API 实际上不会执行任何函数调用。开发人员可以使用模型输出执行函数调用。

如果提供了函数参数,那么默认情况下,模型将决定何时适合使用其中一个函数。通过将 function_call 参数设置为 {"name": ""},也可以强制 API 使用特定函数。如果使用函数,输出将在响应中包含 "finish_reason": "function_call",以及具有函数名称和生成的函数参数的 function_call 对象。

函数由以下字段指定:

名称Name:函数的名称。

描述Description:函数作用的描述。该模型将使用它来决定何时调用该函数。

参数Parameters:参数对象包含函数需要的所有输入字段。这些输入可以是以下类型:String、Number、Boolean、Object、Null、AnyOf。有关详细信息,请参阅 API 参考文档。

必需Required:进行查询需要哪些参数。其余的将被视为可选的。

您可以通过执行函数并将函数执行的输出直接传回助手来链接函数调用。这可能会导致模型继续无限期地调用函数的无限循环行为,但是可以设置防护栏来防止这种情况发生。

具体例子

接下来用一个例子具体讲讲如何调用函数,注意,这里只介绍如何使用以及整个的逻辑,过多的代码细节不会讲解。(这里的代码是一个推友根据这个功能写的一个项目demo,地址是:github.com/hx23840/ope…

import requests
import openai
import json


def send_request(method, url, data=None, params=None):
    response = requests.request(method, url, json=data, params=params)
    response.raise_for_status()
    return response.json()


# Base URL
BASE_URL = "https://plugin.askyourpdf.com"  # 请将这个URL替换为实际的API URL


def download_pdf(url):
    path = "/api/download_pdf"
    full_url = BASE_URL + path
    params = {"url": url}
    response = send_request("POST", full_url, params=params)
    return response


def perform_query(doc_id, query):
    path = "/query"
    full_url = BASE_URL + path
    data = {"doc_id": doc_id, "query": query}
    response = send_request("POST", full_url, data=data)
    return response


openai.api_key = "YOUR_API_KEY"


# Step 1, send model the user query and what functions it has access to
def run_conversation():
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=[
            {"role": "user", "content": "I want to upload pdf use this url:https://arxiv.org/pdf/1706.03762.pdf"}],
        functions=[
            {
                "name": "download_pdf",
                "description": "upload a pdf",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "url": {"type": "string", "description": "The pdf url"},
                    },
                    "required": ["url"],
                },
            }
        ],
        function_call="auto",
    )

    message = response["choices"][0]["message"]

    # Step 2, check if the model wants to call a function
    if message.get("function_call"):
        # Step 3, call the function
        function_call = message.get('function_call')
        arguments = json.loads(function_call.get('arguments'))
        function_response = download_pdf(url=arguments.get("url"))

        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                {"role": "user", "content": "I want to search content with pdf, The query content is What is the "
                                            "Self-attention?,The doc id is " + function_response["docId"]}
            ],
            functions=[
                {
                    "name": "perform_query",
                    "description": "search content with a pdf",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "doc_id": {"type": "string", "description": "The doc id"},
                            "query": {"type": "string", "description": "The query content"},
                        },
                        "required": ["doc_id", "query"],
                    },
                }
            ],
            function_call="auto",
        )

        message = second_response["choices"][0]["message"]
        if message.get("function_call"):
            # Step 3, call the function
            function_call = message.get('function_call')
            arguments = json.loads(function_call.get('arguments'))
            function_response = perform_query(doc_id=arguments.get("doc_id"), query=arguments.get("query"))

            return function_response


print(run_conversation())

具体讲一下整个的调用逻辑: 我们先上传一个pdf文件,然后向gpt提问:我想要上传xxx文件,然后gpt发现自己需要一个上传pdf文件的函数,检查了你在functions里面写的description,然后找到了那个上传文件的函数,然后调用函数;接着我们向gpt提问:我想要查找xxx内容在xx文件中(这个文件就是我们上面上传的文件),然后gpt思考发现需要一个查询文件的函数,重复前面的操作,找到了我们给他的函数,再次工作。

整个过程你会发现非常的丝滑,过去我们是用langchain把过程写死,先调用xxx的api拿到xxx,再给gpt使用,也就是我们人为确定整个链路。但是这里我们是将gpt作为系统的大脑,需要什么功能,在functions里面找。

总结

我相信未来这个生态也是如此,gpt链接着几乎所有的API工具,在思考的过程中调用即可,不需要我们人为限制它思考的过程。

全部评论

相关推荐

投递美团等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务