员外注释:Wolfram的ChatGPT插件貌似是目前最好的几个ChatGPT Plugin之一,这篇文章从动手实现,到我意想不到的反向操作电脑(这还可以延伸到各类硬件),最后说原理,对于开发Plugin的开发者应该有一些帮助。
中文译文:ChatGPT的即时插件:介绍Wolfram ChatGPT插件套件
英文原文:Instant Plugins for ChatGPT: Introducing the Wolfram ChatGPT Plugin Kit
在一分钟内构建一个新插件…
几周前,我们与OpenAI合作发布了Wolfram插件,使ChatGPT可以使用Wolfram语言和Wolfram|Alpha作为工具,在ChatGPT内部自动调用。可以将其视为向ChatGPT添加广泛的“计算超能力”,从而让它获得 Wolfram语言和Wolfram|Alpha中所有通用的计算功能和计算知识。
但是如果您想制作自己的特殊插件,进行特定的计算或者访问仅在您自己的电脑或电脑系统上可用的数据或服务怎么办呢?今天,我们发布了第一个版本的开发套件来实现这一点。借助整个Wolfram Language技术栈构建,并且我们已经成功地使整个过程变得非常简单——至少基本定制 ChatGPT 插件现在只需要不到一分钟就可以轻松部署。
需要进行一次(非常简单)设置-验证OpenAI身份并安装Plugin Kit。然后你就可以开始创建你的第一个插件。
要运行这里的示例,您需要:
开发者可以访问ChatGPT的OpenAI插件系统
可以访问Wolfram语言系统(包括免费的Wolfram Engine for Developers、Wolfram Cloud Basic等)
您现在还需要使用PacletInstall[“Wolfram/ChatGPTPluginKit”]安装ChatGPT Plugin Kit(插件套件)。
这是一个非常简单的例子。假设你为一个单词创造了一个“强度”的概念,将其定义为“字母数字”的总和(“a”为1,“b”为2等)。在 Wolfram 语言中,您可以计算如下:
而且作为十多年来的标准,您可以立即将这样的计算部署为 Wolfram Cloud 中的 Web API——可通过 Web 浏览器、外部程序等立即访问:
但是现在有一种新的部署形式:作为ChatGPT的插件。首先,您需要获取插件工具包:
然后您就可以立即部署您的插件了。只需要:
最后一步是您需要告诉ChatGPT有关您的插件。在Web界面中(按照当前配置),选择“Plugins > Plugin store > Develop your own plugin”(“插件”>“插件商店”>“开发自己的插件”),并将来自ChatGPTPluginDeployment的URL插入到你的对话框中 (通过点击复制按钮获取 ) :
现在一切准备就绪。您可以开始与ChatGPT谈论“单词强度”,它将调用您的插件(默认情况下称为“WolframCustom”)来计算它们:
展开这个对话气泡,可以了解ChatGPT与插件之间的通信:
没有插件,它就不知道“字母强度”是什么。但有了插件,它就能够做出各种(相当惊人的)事情——比如这样:
关于角马属性的修饰很迷人,但如果打开聊天气泡,就可以看到它是如何得出答案的——它只是开始尝试不同的动物(“狮子”,“斑马”,“角马”):
软件工程师会立即注意到,我们设置的插件正在本地主机上运行,也就是在您自己的计算机上执行。正如我们将要讨论的那样,这通常是一件非常有用的事情。但是您也可以使用Plugin Kit创建纯粹在Wolfram Cloud(或者阿里云/腾讯云/华为云…)中执行的插件(例如,您不必在计算机上安装Wolfram Engine)。
你所要做的就是使用ChatGPTPluginCloudDeploy
——然后你会得到一个Wolfram Cloud中的URL,你可以告诉ChatGPT这个插件的位置:
实际上,您可以直接在网络浏览器中完成整个设置过程,无需进行任何本地 Wolfram 安装。只需在 Wolfram Cloud 中打开一个笔记本,并从那里部署您的插件即可:
让我们来做一些其他的例子。接下来,让我们发明一个“地理影响圆盘(geo influence disks)”的概念,然后部署一个插件来呈现这样的东西(稍后我们将谈论一些正在进行的细节):
现在我们可以安装这个新插件,然后开始向ChatGPT询问“地理影响圆盘(geo influence disks)”:
ChatGPT 成功调用了插件,并返回了一张图片。有趣的是,它猜测(事实上是正确的)“地理影响圆盘”应该是什么意思。请记住,它无法看到图片或读取代码,因此它的猜测只能基于 API 函数名称和提出的问题。当然,在调用 API 函数时,它必须有效地理解至少一点内容——x
应该表示位置,而 radius
则表示距离。
再举个例子,我们来制作一个插件,可以向用户(即部署插件的人)发送短信:
现在只需要说“发送一条信息…”(“send me a message…”)
一条短信将会到达——在这种情况下,它还带有ChatGPT的小装饰:
这是一个插件,它还会发送提到的动物的“警报图片”:
是的,需要许多技术才能实现这一点:
作为另一个例子,让我们创建一个插件来检索我的个人数据——这里是我在 Wolfram databin数据中积累了数年的心率数据:
现在我们就可以使用ChatGPT来对这些数据提出自己的问题了:
而且,如果安装了主要的Wolfram插件,我们可以通过ChatGPT的“语言用户界面”立即对这些数据进行实际计算:
这个例子使用了 Wolfram Data Drop 系统。但是,我们也可以用类似 SQL 数据库(关系型数据库)的东西来做同样类型的事情。如果你已经设置好插件以访问私有数据库,那么通过 ChatGPT 和 Wolfram 插件真正令人惊叹的事情就能够实现。
通过Plugins(插件)操控你的电脑
当您通过ChatGPT的标准Web界面使用它时,ChatGPT是在OpenAI的服务器上运行。但是,通过插件,您可以“回溯”——通过您的Web浏览器——以使事情发生在自己的本地计算机上。我们稍后将讨论这个“引擎盖下”的工作原理,但现在可以说一下:当您使用ChatGPTPluginDeploy
(而不是ChatGPTPluginCloudDeploy
)部署插件时,在插件中实际运行的Wolfram语言代码将在本地计算机上运行。因此,这意味着它可以访问计算机上的本地资源,如摄像头、扬声器、文件等。
例如,这里我正在设置一个插件来使用我的计算机摄像头拍照(使用 Wolfram 语言的 CurrentImage[ ]
函数)—然后将图片与我指定的任何颜色混合(我们稍后会讨论 CloudExport
的用法):
安装插件后,我对ChatGPT说:“想象一下我穿着绿色的衣服!”然后,ChatGPT会立即调用插件,让我的电脑拍摄我的照片,并将其与绿色混合(包括我的“我不知道这是否有效”的表情):
译者:这真的好吗???
好的,让我们尝试一个稍微复杂一些的例子。在这里,我们将创建一个插件来让ChatGPT在我的电脑上打开笔记本,并开始写入内容。为了实现这一点,我们将定义几个API端点(并将整个插件命名为“NotebookOperations”):
首先,让我们告诉ChatGPT创建一个新笔记本
然后在我的屏幕上弹出了一个新的笔记本:
如果我们查看从中部署插件的 Wolfram 语言会话中的符号 nb,我们将发现它是由 API 设置的:
现在让我们使用其他的API端点向笔记本添加内容:
这就是我们可以获得的结果:
这段文字是由ChatGPT编写的;图片则来自于网络图像搜索。 (我们也可以使用Wolfram语言中的新ImageSynthesize[]
函数制作全新的猫咪图片。)
最后,让我们请ChatGPT展示一张用CurrentNotebookImage
从电脑屏幕上捕捉到的笔记本截图:
我们还可以添加另一个端点,使用CloudPublish
将笔记本发布到云中,并可能通过电子邮件发送URL。
我们可以将前面的示例视为在笔记本中累积结果。但是我们也可以只在Wolfram语言符号的值中累积结果。这里,我们将符号“result”初始化为空列表。然后,我们定义了一个API来附加到此列表,但是给出了提示,仅当有单词结果时才执行此附加操作:
让我们为ChatGPT设置一个“练习”:
此时,result
仍为空:
现在让我们来问第一个问题:
ChatGPT并不会直接显示答案。但它会调用我们的API并将其附加到result
中:
让我们来问问另一个问题:
现在 result
中包含了两个答案:
如果我们在笔记本中放置Dynamic[result]
,每当ChatGPT调用API时,我们会看到它动态地改变。
在最后一个例子中,我们从ChatGPT内部修改了符号的值。如果我们感觉勇敢,可以让ChatGPT评估计算机上的任意代码,例如使用调用ToExpression
的API。但是,是的,赋予ChatGPT执行自己制作的任意代码的能力似乎会使我们面临某种“天网风险”(并使我们更加想知道“AI宪法
”之类的事情)。
但比执行任意代码更安全的做法是让ChatGPT有效地“四处查找”我们的文件系统。让我们设置以下插件:
首先,我们设置一个要操作的目录:
现在让我们问ChatGPT关于那些文件:
使用 Wolfram 插件,我们可以让它制作这些文件类型的饼图:
现在我们要求它做一些非常“LLM-ey”的事情,并总结每个文件的内容(在API中,我们使用Import导入文件的纯文本版本):
还有很多事情可以做。这里有一个插件,可以计算从您的电脑到服务器的ping时间:
或者,作为另一个例子,您可以设置一个插件来创建定时任务,在指定的时间提供电子邮件(或短信等)提醒:
ChatGPT 负责认真排队任务:
然后,每隔大约10秒钟,我的邮箱里就会弹出一个(也许有些可疑的)动物笑话:
最后一个例子,让我们考虑一下在我的电脑上播放曲调的本地任务。首先,我们需要一个能够解码音符并播放它们的插件(”ChatGPTPluginDeploy”用于告诉ChatGPT插件已经完成了工作——因为ChatGPT本身无法知道这一点):
在这里,我们给ChatGPT想要的音符——是的,这立即在我的电脑上演奏出来:
现在,作为对一位著名虚构人工智能的致敬,让我们尝试演奏另一首曲子:
是的,ChatGPT整理了一些笔记,并将它们打包到插件中;然后插件播放了它们:
依然可以运行:
但是…等一下!那是什么曲调?ChatGPT似乎还不能像HAL那样(可疑地)宣称:
“没有[HAL] 9000电脑曾经犯过错误或扭曲信息。按任何实际定义的词语,我们都是防错和无误的。“
说说工作原理【敲黑板】
我们现在已经看到了许多使用ChatGPT插件工具包的示例。但是它们是如何工作的?底层是什么?当您运行ChatGPTPluginDeploy时,实际上正在设置一个Wolfram语言函数,可以从ChatGPT内部调用该函数,以便在需要时使用。为了使这个过程顺利进行,需要使用Wolfram语言独特能力的广泛谱系,并与ChatGPT中某些“聪明”的功能相结合。
从软件工程角度来看,ChatGPT插件基本上就是一个或多个Web API(连同告诉ChatGPT如何调用这些API的“清单”)。那么如何在Wolfram语言中设置Web API呢?十年前我们发明了一种极其简单易行的方法。
像Wolfram语言中的所有内容一样,Web API也由符号表达式表示,在这种情况下形式为APIFunction[…]. 那么APIFunction里面有什么呢?其中有两个部分:一段实现所需功能的Wolfram Language代码和规范说明,在将字符串传递给APIFunction之前应该如何解释这些字符串(例如来自Web API)。
以下是一小段 Wolfram Language 代码, 在此案例中用于否定颜色并使其变浅: =>
如果我们愿意,我们可以将其重构为一个应用于两个参数的“纯函数”:
纯函数本身只是一个符号表达式,它会被计算为其自身:
如果需要的话,我们可以给纯函数的参数命名,并将它们与其名称作为键一起提供到一个关联 () :
但是假设我们想要从 Web API 调用我们的函数。Web API 中的参数始终为字符串。那么,如何将字符串(例如“lime green”)转换为 Wolfram 语言可以理解的符号表达式呢?好吧,我们必须使用 Wolfram 语言的自然语言理解能力。
以下是一个示例,其中我们正在说希望将字符串解释为颜色:
那个颜色样本到底是什么?就像 Wolfram 语言中的其他所有内容一样,它只是一个符号表达式:
好的,现在我们准备将所有内容打包成APIFunction
。第一个参数表示我们要表示的API有两个参数,并描述了我们希望如何解释这些参数。第二个参数给出了实际的Wolfram语言函数,该API计算它们。单独使用,APIFunction
只是一个符号表达式,其本身就可以评估:
但如果我们为参数提供值(这里使用关联),它将被计算:
目前,所有这些都只是在我们的 Wolfram 语言会话中发生。但要获得实际的 Web API,我们只需“云部署”APIFunction
:
现在我们可以从Web浏览器中调用此Web API:
是的,那就是符号表达式的结果。如果我们想要一些可视化的东西,我们可以告诉APIFunction将其结果作为PNG输出:
现在它将显示为网络浏览器中的图像:
(请注意,CloudDeploy 部署的 Web API 默认情况下权限设置为只有我可以运行。如果使用 CloudPublish,则任何人都可以运行它。)
好的,那么我们如何设置我们的 Web API 以便作为 ChatGPT 插件调用呢?一个直接的问题是,在最简单的级别上,ChatGPT 只处理文本,因此我们必须将结果转换为文本。所以让我们进行一些 Wolfram 语言编程来实现这个目标。以下是 Wolfram 知识库中常见颜色值和名称列表:
当然,我们也知道许多其他命名颜色的集合,但在这里不必担心它们:
现在我们可以使用Nearest函数来找到最接近我们所得颜色的常见颜色:
现在让我们将其放入APIFunction中(这里我们已经“图标化”了颜色列表;我们也可以定义一个单独的函数来查找最近的颜色,它会自动随CloudDeploy一起带来):
现在我们已经准备好使用ChatGPTPluginDeploy了。 ChatGPT插件的工作方式是,我们必须为与我们的API对应的“端点”命名。 这个名称以及我们在API中用于参数的名称将被ChatGPT用来确定何时以及如何调用我们的插件。 但在这个例子中,我们只想为端点使用某种唯一名称,这样我们就可以在聊天中引用它而不会让ChatGPT将其与其他内容混淆。 所以让我们称之为ColorMangle。 现在让我们进行部署:
到目前为止,我们关于APIFunction及其调用的所有内容在ChatGPTPluginDeploy和ChatGPTPluginCloudDeploy中都是相同的。但接下来要说的就不同了。因为ChatGPTPluginDeploy设置API函数在本地计算机上执行,而ChatGPTPluginCloudDeploy则将其设置为在Wolfram Cloud(或Wolfram Enterprise Private Cloud等)上运行。
本地部署和云端部署都有优缺点。在本地运行可以让您获得计算机的本地功能,如相机、文件系统等。在云端运行则允许其他人也能运行您的插件(但目前除非您将插件注册到OpenAI,否则一次只有有限数量的人能安装您的插件)。
好吧,让我们来谈谈本地插件部署。ChatGPTPluginDeploy 在您的计算机上有效地设置了一个最小化 Web 服务器(使用10行 Wolfram 语言代码实现),在 ChatGPTPluginDeploy 选择的端口上运行,并且每当它收到对 API URL 的请求时调用 Wolfram 引擎与您的 API 函数进行交互。
这是 ChatGPTPluginDeploy 正在使用的操作系统套接字(是的,Wolfram 语言将套接字——像其他所有东西一样——表示为符号表达式):
好的,但是ChatGPT怎么知道你的API呢?首先,您需要通过ChatGPT UI的 Plugins > Plugin store > Develop your own plugin(插件>插件商店>开发自己的插件)告诉它您正在使用的端口。您可以通过单击ChatGPTPluginDeployment对象中的 图标或以编程方式找到端口:
您输入此URL,然后告诉ChatGPT“查找清单文件”:
让我们看一下它找到了什么:
这是一个“清单”,它告诉插件安装程序的相关信息。我们没有指定太多内容,所以大部分都是默认值。但清单中重要的一部分是提供API规范URL的部分:http://localhost:59353/.well-known/openapi.json
访问该URL后,我们可以找到这个“OpenAPI规范”:
最后,点击Install localhost plugin
,该插件将出现在您的ChatGPT会话中已安装插件列表中
当ChatGPT启动时安装了插件,它的“系统提示”中会包含一个额外的部分,让它可以“学习”如何调用该插件:
现在我们可以开始使用这个插件了:
是的,它有效。但这里有一些魔法。ChatGPT不得不“拆开”我们所要求的内容,意识到API端点称为ColorMangle
是相关的,然后确定其颜色参数应该是“青柠绿”,级别应该是“0.5”。打开盒子,我们可以看到它所做的:
现在我们可以开始在其他地方使用“颜色混合”——尽管ChatGPT急于告诉我们,“颜色混合”是一种“虚构的操作”,可能是为了避免被指责不尊重某个国家的旗帜颜色:
在我们处理的这个案例中,ChatGPT成功地将文本片段正确“连接”到API中的适当参数。而且它是从我们为参数使用的名称(以及我们给出的端点名称)所获得的信息碎片中实现了这一点(相当惊人)。
但有时候我们需要告诉它更多信息,我们可以通过在ChatGPTPluginDeploy
内指定插件提示来实现:
现在我们不仅需要谈论颜色:
起初,它没有成功地“解开”“冰岛的颜色”,但后来它纠正了自己,并得到了答案。(是的,如果我们写一个更好的提示,也许我们本可以避免这种情况。)
实际上,您可以提供多个级别的提示。您可以为整个插件包括一个相当长的提示。然后,您可以为每个单独的API端点提供较短的提示。最后,您可以通过将“color”→ “Color”替换为类似于以下内容来帮助ChatGPT解释API中单个参数:
当您设置插件时,它可以包含许多端点,执行不同的操作。此外,在共享提示之外,这特别方便的原因之一是(出于安全原因),任何给定子域只能有一个关联的插件。因此,如果想要具有各种功能,则必须通过使用不同的端点来实现。
对于ChatGPTPluginCloudDeploy
,每个子域仅限一个插件意味着任何给定用户一次只能部署一个云插件。但对于本地插件规则略有不同,并且ChatGPTPluginDeploy
可以通过在不同端口上运行它们来部署多个插件-事实上,默认情况下ChatGPTPluginDeploy
每次调用时都会选择随机未使用的端口。
但是本地插件如何工作?它如何“回到”您的计算机?魔法基本上发生在ChatGPT Web
前端中。所有插件工作方式都是当将要调用该插件时,LLM逐标记生成过程停止,并且“外循环”的下一个动作是调用该插件-然后将其提供给LMM在下一步中将添加到字符串中。好吧,在本地插件的情况下,“外循环”使用聊天窗口前端中JavaScript向指定了localhost 端口 的计算机发送请求。(顺便说一下,一旦ChatGPTPluginDeploy
打开端口,它将保持打开状态,直到您在其套接字对象上明确调用Close。)
当使用本地插件时,它们在部署插件的Wolfram语言会话中运行其Wolfram语言代码。这意味着例如(如我们在某些情况下看到的那样),设置的值在进行另一个调用时仍然存在。
在云中,它不会立即以这种方式工作,因为每个API调用实际上是独立的。但是可以轻松地将状态保存在云对象中(例如使用CloudPut
或CloudExpression
等)以便可以跨多个API调用具有“持久性内存”。
ChatGPT内部的LLM(目前)仅设置为处理文本。那么图像怎么办?好吧,插件可以将它们放入Wolfram Cloud中,并将其URL传递给ChatGPT。 ChatGPT已经设置能够直接呈现特定类型的东西-如图像。
因此-正如我们上面所看到的-要从插件“输出”图像(或几个图像),我们可以使用CloudExport将每个图像放入云对象中,在PNG格式中进行操作。然后ChatGPT可能需要一些提示来显示嵌入式输出中的图片。
部署Wolfram Language
插件于ChatGPT中存在一些稍微棘手的“管道”,其中大部分在ChatGPTPluginDeploy
和ChatGPTPluginCloudDeploy
中自动处理。但是通过基于Wolfram语言的基本符号结构(及其集成部署功能)来构建,可以非常简单地为ChatGPT创建复杂的自定义Wolfram语言插件,并为LLM和Wolfram语言周围不断发展的生态系统做出贡献。