你好,今天聊一下 GPTs。
以下这篇文章首发于腾讯云开发者,是一篇应邀写的约稿,大概前后用了半个小时,仓促之下代码示例及行文措词都非常朴素。现实中真实的项目是绝不会如此简单的,但越简单的示例,越容易让读者抓住重点,这是我一直坚持的教程撰写风格。
我通过这个小示例想表达的是,通过 playwright + GPTs,我们可以做出许多有意思的应用,且成本低、安全、可塑性性强,就像打开了一道新世界的大门。在腾讯云开发者推送以后,我查看评论区,有一位读者说:
“我想开发一个依据需求(自然语言讲述)生成定制化GPT的GPT应用。”
看到这个评论,我就知道他已经打开属于他的新世界大门了。
通过以下示例,既可以调用 GPTs,也可以创建 GPTs,原理是一样的。甚至,如果有10个人要创建自己的GPTs,都没有必要购买10个 ChatGPT Plus 会员帐号,只需要一个帐号,就可以给10个人使用,且每个人的 GPTs 都是独立的、隔离的(因为GPTs是私有发布)。你明白了吗?
OpenAI 5 天令人目不暇接的宫斗大戏看起来好像落下了帷幕,背后的故事细节相信在未来的时间里会逐渐浮现清晰。本文旨在新闻如雪花般飞舞的这几天里,为你提供一些技术上的输入。知识的价值,历久弥新。
近期,OpenAI 举办了自己的第一次开发者春晚,并现场推出了新模型 GPT-4 Turbo,及 Plus 会员用户可以基于新模型进行功能自定义的 GPTs。
GPTs,其实就是一个允许用户不使用任何编程技术、不需要调用 ChatGPT API 即可完成训练的一个 AI。有人说,我不需要 GPTs,我用 LangChain+Agent+ChatGPT API 或其它大语言模型的 API,也能实现一个自定义的 GPT。
没错,这么理解是对的!但不是所有人都会编程,也不是所有人都知道 LangChain 如何调用以及 AI Agent 如何开发。ChatGPT 适时推出的 GPTs,它的目标用户群体其实是面向广大不会编程的用户。据 OpenAI 官方宣称,ChatGPT 周活已经达到了 1 亿,预测不久,几百万个甚至几千万个 GPTs 将出现在 GPT Store上。
我在这篇文章“不用编码,也不用会写严格的提示,创建自己的第一个GPT”中已经详细介绍过徒手创建 GPTs 的方法,整个过程很简单只需要七步,首先简单设置一下,再上传一些文件,即可大功告成。在发布的时候,我们还可以选择私有、分享可用及完全公开。
如下图所示,这是我创建的 GPTs —Story Weaver,它是一个私有的GPTs。
对于我们不想让别人看到的,只想让我们自己或团队成员使用的模型,我们则要发布为私有。对于私有的 GPTs,如果我们还想实现在本地自如地调用、并且程序自动化调用,我们应该怎么做呢?
有人可能会想:“我们可以使用 OpenAI 官方提供的 API。”但很遗憾的是,目前 OpenAI 还没有公布这样的接口;即使以后有,它极有可能也是需要付费的。我们在购买 Plus 会员基础上,调用自己创建的 GPTs 的时候,是否可以避免再次付费呢?
本篇我将用银河系最通俗易用的编程语言—— Python,用不到 50 行的总代码,带你打开新世界大门。不需要额外付费,也不需要调用任何 API,更不需要设置什么 API Token,就可以自动化调用我们自己创建的 GPTs。
在调用 GPTs 的时候,数据文件是我们提供的,消费代码也是在我们本地运行的,这就相当于我们在本地借用了 ChatGPT 强大的大语言模型能力,且成本低廉、方法又简单。
如果你想顺利运行稍后我所提供的 Python 示例,你需要准备以下这些条件:
稍后我们需要用到两个类库:pyperclip 与 playwright,我们需要在终端环境里依次安装它们:
注意:在安装完 playwright 以后,别忘记运行 playwright install,这一步是安装 playwright 运行时需要的浏览器组件。即使是我们本地已经安装了相关的浏览器,这一步也必不可少。
接下来再来简单介绍一下这两个类库。pyperclip 是处理剪切板数据的,允许我们访问本地剪切板并将数据导出,这个类库许多开发网页智能机器人的工程师们都使用过。
playwright 是大大鼎鼎的自动化测试框架,它由 Microsoft 开发,提供了一套简单而强大的 API,可以自动化运行基于 Chromium、Firefox 和 WebKit 浏览器的测试程序。与 playwright 齐名的另一个类似框架是 selenium,前者与后者相比,前者拥有更加现代化的 API、更快地响应速度和更强大的功能,所以我选择了前者。
一个自动化测试框架跟我们要做的有什么关系呢?我们为什么要安装它?
当然有关系!很多基于浏览器的自动化智能机器人,例如智能网页爬虫,都是 playwright 实现的。你明白了吗,playwright 不仅可以用于测试、代替测试工程师做一些重复性高的测试工作,还可以代替人做一些相对复杂的普通网页操作。
稍后我们在浏览器上打开自定义 GPTs 的网址、输入 Prompt、获取查询结果,这些操作都可以由 playwright 代替我们实现。本地程序的自动化是借由 playwright 实现的。
使用 playwright 开发智能网页机器人应用,有一个问题是无法避免的,这个问题就是用户验证。一般有以下两个解决思路:
1)第一个思路:自动监测网页状态并登录。
当未登录时,使用本地预先记录的账号跳转到登录页面实现自动登录,并在本地缓存登录后的 cookies。
本地写入 cookies 的代码:
cookies = context.cookies()
print(page.title())
f = open('cookies.json', 'w')
json.dump(cookies, f)
读取 cookies 以避免重复登录的代码是这样的:
def loadCookies(cookief):
cookiefile = open(cookief, 'r')
cookie_list = json.load(cookiefile) # json读取cookies
cookiefile.close()
return cookie_list
...
context = browser.new_context()
cookiefiles = ['cookies.json']
for cookiefile in cookiefiles:
context.add_cookies(loadCookies(cookiefile))
这两段代码今天我们并不打算使用,只需简单了解一下即可。这种方式还需要处理网页验证码,以及在 cookies 过期后还需要重新登录,比较复杂,除非迫不得已,我们不采用这种思路。
2)第二个思路:持久化登录。
所谓持久化登录,简而言之就是专门在硬盘上辟出一个空间给当前的网页机器人程序使用,运行期间产生的 cookies、图片等数据全部缓存在该目录下,由于 cookies 是缓存的,便不需要频繁登录,我们采用此方法。
首先创建一个项目目录,例如 browser_ai,在该目录下再创建一个 gpts_firefox_dir 目录,用作浏览器的持久化缓存目录。
现在祭出我们的第一部分 Python 代码,query_gpts.py 文件第一部分:
import time
import pyperclip
from playwright.sync_api import sync_playwright
def login():
with sync_playwright() as p:
context =p.firefox.launch_persistent_context(
'./gpts_firefox_dir',
headless=False,
slow_mo=500
)
page = context.pages[0]
page.goto('https://chat.openai.com/')
login()
简单解释一下这段 Python 代码:
其它代码无需过多注释,使用python query_gpts.py指令启动,在打开的浏览器中登录自己的 ChatGPT 会员账号,然后关闭程序。login 函数的使命就已经完成了。
下面真正的代码来了,query_gpts.py 文件第二部分:
...
def query():
with sync_playwright() as p:
browser =p.firefox.launch_persistent_context(
'./gpts_firefox_dir',
headless=False,
slow_mo=500
)
page = browser.pages[0]
# 这是私有的,要替换成你自己的GPTs URL
page.goto('https://chat.openai.com/g/g-OitD1zCwT-story-weaver')
time.sleep(2)
page.query_selector("#prompt-textarea").fill("告诉我,你的知识库截止日期是?")
page.wait_for_selector('button[data-testid="send-button"]').click()
time.sleep(10)
copy_button_selector = 'button.text-xs.dark\\:hover\\:text-gray-200'
copy_buttons = page.query_selector_all(copy_button_selector)
(copy_buttons[len(copy_buttons)-1]).click()
time.sleep(1)
clipboard_content = pyperclip.paste()
# 打印剪贴板内容
print(clipboard_content)
str = 'y'
while str == 'y':
str = input('等待中,是否继续等待?y/n。\n\n请输入:') # 控制休眠时间
page.close()
browser.close()
query()
这部分代码都干了啥?稍微解释一下吧:
程序完成后,使用 python query_gpts.py 指令运行,效果如下:
最后一步,程序中关于 y 的那部分 while 循环,是为了控制程序不退出。因为程序退出后,浏览器就关闭了,我们也没有办法进一步查看和操作界面了。
如果参数 headless 等于 Flase,能看到浏览器界面,运行效果是这样的:
GPT-4 Turbo发布后,很多通过第三方壳子应用使用 ChatGPT 服务的用户,怀疑自己用的是假 GPT-4,这时候可以使用上面这条提示问知识库截止日期,正确答案是 2023 年 4 月。
示例里面有一个地方的代码,在网页机器人开发中是公认的麻烦。例如,在 query 函数中,第 13 行、第 14 行、第 17 行,这三处的选择器代码并不容易写,尤其是最后一个。
page.query_selector("#prompt-textarea").fill("告诉我,你的知识库截止日期是?")
page.wait_for_selector('button[data-testid="send-button"]').click()
copy_button_selector = 'button.text-xs.dark\\:hover\\:text-gray-200'
为了解决这类问题,提高生产效率,playwright 提供了一个“由操作生成代码”的功能。以我们访问的 GPTs 网址为例,指令如下:
playwrightcodegen--browserfirefox https://chat.openai.com/g/g-OitD1zCwT-story-weaver
codegen 这个子程序可以帮助我们生成带有大量选择器的代码。参数 browser 是指定浏览器组件类型,这个参数其实无所谓,指不指定并不会影响目标页面上的元素。
codegen 指令会打开一个浏览器,我们在上面操作一番,在小窗口中便能看到生成的代码,如下图所示:
虽然此时生成的代码很粗犷,一般情况下并不能直接使用,但它可以帮助我们定位元素,以及获取元素的选择器写法。这是 codegen 指令存在的作用。
总而言之,这个示例很简单,没有输入,也没有输出——输出就是简单的打印,将 ChatGPT 返回的内容直接在终端中打印。对于登录,我们也采用了最简单的方法——手动登录。在实际项目中,这些问题都需要细化。
通过 playwright,我们实现了在本地调用远程私有 GPTs 的目的,数据是我们的,程序也是我们的,我们只是借用了 ChatGPT 的大语言模型能力。此外,我们也不需要额外花费 API 调用费用。
在此公众号后台回复「10008」,即可下载本文完整的示例代码。
作者推荐👇
戳此👈添加探长微信,与时间做朋友✈️
文章点赞有点少啊,支持探长请在下方点个赞👍
李艺,腾讯云 TVP,微信学堂专题讲师,极客时间视频专栏《微信小程序全栈开发实战》讲师,一汽大众等知名企业内训培训讲师。具有近 20 年互联网软件研发经验,参与研发的音视频直播产品曾在腾讯 QQ 上线,为数千万人使用。是国内早期闪客之一,曾自定义课件标准并完成全平台教育课件产品研发,官方评定为 Adobe 中国十五位社区管理员之一。同时,还是中国人工智能学会会员,在北京协同创新研究院负责过人工智能项目的研发。业余喜欢写作,在微信公众号/视频号“艺述论”分享技术经验,著有《微信小游戏开发》《小程序从0到1》等计算机图书。
-End-