共计 4414 个字符,预计需要花费 12 分钟才能阅读完成。
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 和你的日历买通,那它是不是就能够帮你治理日程了;如果和你的笔记买通,那它是不是就能够帮你整顿笔记了;甚至是和你的股票账号买通,是不是就能够帮你炒股了;如果和脑机接口买通,那它是不是就能够管制……