OpenAI在6月13号降级了ChatGPT,推出了相似其网页版插件的性能——函数调用(Function calling),13号当天我在很多微信公众号就看到了这个音讯,甚至有人将函数调用称为杀手级个性,正好周末有空,就写个Demo试用下,验证下它是平平无奇还是真的能让人眼前一亮。

  官网给出的函数调用示例是接入查问天气的能力,我看到第一反馈 就这……。但当我写了一个简略抓取网页文本的函数,并将其接入到ChatGPT中后,我忽然意识到这的确是一个十分弱小的性能。之前的ChatGPT只能用文本交互,文本有个特点就是其规范性十分十分弱,同样的语义两个不同的人表述进去可能就是齐全不同的两句话,导致咱们很难用自然语言区管制一般的程序。而这次的函数调用能力,让其具备了输入强标准的内容,能够用来调起其余程序。这也意味着ChatGPT具备了和一般程序交互的能力,可设想的空间十分大。

  接下来我就用我实现的ChatGPT网页剖析能力作为示例,演示下如何让ChatGPT接入一般的python函数,最初我再总结下函数调用的能力和局限,顺便也畅想下函数调用到底还能够实现什么样的弱小性能。

Step1:实现一般函数

  首先就是要定义好一般的python函数,我这里写了一个简略的网页爬取的性能,给定url就能够抓取到网页下面的文本内容。这里只是一个简略实现,可能局部网页无奈失常抓取。

import requestsfrom bs4 import BeautifulSoupdef is_target_tag(tag):    target_tags = ['p', 'code', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5']    return tag.name in target_tagsdef get_text_from_url(url):    response = requests.get(url, headers=headers)    html = response.text    soup = BeautifulSoup(html, 'html.parser')    extracted_tags = soup.find_all(is_target_tag)    res_text = ''     for tag in extracted_tags:        res_text = res_text + tag.get_text(strip=True) + '\n'    return res_text

  这里应用的是request包发动申请,应用bs4的BeautifulSoup来解析html标签,代码将html中所有的段落、代码、题目内容都抓取进去。

Step2: 用json-schema格局将函数形容进去

  这一步的作用就是把能够调用的一般函数信息用ChatGPT能够辨认的格局形容进去,这里OpenAI间接采纳了JSON-Schema。也比较简单,就是形容进去有哪些函数能够用、函数别离实现了什么样的性能、每个函数有哪些参数、哪些是必填参数、哪些是选填参数…… 这里我用来抓取url对应文本的函数形容如下:

functions = [    {        "name": "getText",        "description": "抓取url对应的网页里的文本内容",        "parameters": {            "type": "object",            "properties": {                "url": {                    "type": "string",                    "description": "网址url",                }            },            "required": ["url"],        },    }]

  留神,这里functions能够有不止一个,只有你能精确将函数性能及入参格局用json-schema形容进去,ChatGPT就能给你调起。 另外这里为了不便调起,咱们还须要保留一个办法名到理论办法的映射关系,具体如下:

available_functions = {    "get_text_from_url": get_text_from_url,} 

Step3: 调用ChatGPT的时候带上函数信息

  接下来咱们只须要在原有Api的参数中减少functions,让ChatGPT通晓有哪些函数能够调用,而后让他决定要不要调。残缺的代码及正文如下:

import osimport openaiimport jsonopenai.api_key = os.getenv("OPENAI_API_KEY")def chat(content):    messages = [        {"role": "user", "content": content}    ]    response1 = openai.ChatCompletion.create(        model="gpt-3.5-turbo-0613",        messages=messages,        functions=functions,        function_call="auto"    )    response_message = response1["choices"][0]["message"]    rtn_message = response1["choices"][0]["message"]    # 如果ChatGPT返回后果会通知你,是否须要调用函数,咱们只须要依据它返回的函数名、参数调起对应的函数    # 而后将函数的返回后果再给到ChatGPT,让他进行下一步的操作      if response_message.get("function_call"):        # 找到须要调用的函数,并将ChatGPT给的参数传进去         function_name = response_message["function_call"]["name"]        fuction_to_call = available_functions[function_name]        function_args = json.loads(response_message["function_call"]["arguments"])        # 用这种形式能够调起任意python函数,不必像官网那样还要指定参数名          function_response = fuction_to_call(**function_args)        # 获取到函数调用后果后,须要将后果拼接到对话记录里,并再次调用ChatGPT        messages.append(response_message)         messages.append(            {                "role": "function",                "name": function_name,                "content": function_response,            }        )         # 二次调用的返回后果里就是咱们预期的后果了         response2 = openai.ChatCompletion.create(            model="gpt-3.5-turbo-0613",            messages=messages,        )        rtn_message = response2["choices"][0]["message"]    return rtn_message['content']

咱们简略验证下成果:

chat('总结下这篇文章,将其中的要点提炼进去 https://zxs.io/article/1924')

返回后果如下:

这篇文章总结了应用ChatGPT晋升程序员编程能力的办法和场景。作者通过两个月的应用发现,尽管ChatGPT目前还无奈齐全代替程序员在一些强上下文的编程场景下的能力,但在一些通用化的编程场景下,它的体现依然可行。作者提炼出以下利用ChatGPT的场景:1. 代码评审:ChatGPT能够检测代码的语法错误、代码格调问题、潜在的bug和性能问题,但须要留神辅助工具的局限性,倡议与其余代码审查工具和人工审查相结合应用。  2. 代码优化:除了代码评审,ChatGPT还能够帮忙优化并重写代码,但同样须要联合其余专业人士的倡议进行综合优化。  3. 代码释义:应用ChatGPT生成代码释义,以加重保护老代码的累赘。  4. 提供解决方案:形容遇到的问题,让ChatGPT给出倡议和解决方案。  5. 代码生成:ChatGPT能够间接生成相干代码,如分布式锁注解的代码,在理论应用中须要自行甄别和辨认生成的代码。  6. 设计模式和架构倡议:ChatGPT能够提供在代码设计和架构设计上的倡议。  7. 学习新常识:在不相熟的畛域应用ChatGPT帮忙学习。  文章提到了一些应用ChatGPT的实例,并强调了在应用过程中须要留神甄别数据的时效性和准确性。最初,作者认为尽管ChatGPT无奈代替程序员的大部分技能,但能够作为一个工具来晋升工作效率。

  能够看到对于我博客的网址还是十分好用的,我也测试了CSDN、掘金等技术网站,也能够失常应用。但有些网站拿不到后果,不是ChatGPT不行,而是我get_text_from_url办法写的太low了,有些状况下的确没法抓取到内容。

备注:应用函数调用时须要降级最新的openai包,另外目前也只有gpt-3.5-turbo-0613和gpt-4-0613两个模型才反对函数调用,其余模型还不反对。

总结

   不论是从官网查问天气的示例,还是从我这个抓取网页的示例来看,接入函数调用的能力并不简单。另外须要留神到的一点,尽管这个性能叫函数调用,但ChatGPT并不会帮你去调这些函数,而是帮你判断何时去调用这些函数,给你调用函数所须要的参数,最终必定得是由你本人去调用函数的。从它的返回数据格式能够看出,以后版本的函数调用还有个局限点,就是以后版本只能在一次对话中调起一个函数,如果遇到那种须要屡次调用的操作,就只能通过多轮对话的形式实现了。

   尽管函数调用这个性能看似简略,但我感觉这个性能让ChatGPT领有了和现有程序买通的能力,以前它只能帮你做决策、给倡议,但当初它还能够去帮你执行。举个很理论的例子,当初ChatGPT用的最多的中央就是客服之类的问答场景,当初的零碎只能做一些信息替换,比方商品征询、退换货信息征询……,但如果接入函数调用性能,用户就能够间接在对话的过程中实现整个流程,这当初是齐全能够做到的,不过这个货色刚进去,其决策的可靠性还须要验证,连OpenAI在官网上都提醒:

We strongly recommend building in user confirmation flows before taking actions that impact the world on behalf of users (sending an email, posting something online, making a purchase, etc).
咱们强烈建议在代表用户采取影响世界的动作(发送电子邮件、在线公布内容、进行购买等)之前,先由用户确认。

  如果你还意识不到函数调用的弱小能力,我再举一些简略的例子:如果ChatGPT和你的日历买通,那它是不是就能够帮你治理日程了; 如果和你的笔记买通,那它是不是就能够帮你整顿笔记了;甚至是和你的股票账号买通,是不是就能够帮你炒股了;如果和脑机接口买通,那它是不是就能够管制……