乐趣区

关于chatgpt:ChatGPT函数调用初体验让ChatGPT具备抓取网页文本的能力

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

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

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

Step1:实现一般函数

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

import requests
from bs4 import BeautifulSoup

def is_target_tag(tag):
    target_tags = ['p', 'code', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5']
    return tag.name in target_tags

def 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 os
import openai
import json
openai.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 和你的日历买通,那它是不是就能够帮你治理日程了;如果和你的笔记买通,那它是不是就能够帮你整顿笔记了;甚至是和你的股票账号买通,是不是就能够帮你炒股了;如果和脑机接口买通,那它是不是就能够管制……

退出移动版