ChatGPT 浏览器插件实现思路解析

2022-12-10 16:44:44 浏览数 (3)

过去一周,ChatGPT 是机器学习领域最受关注的话题,随着它的热度不断上升,成功出圈引起了人们的广泛关注和讨论。在惊讶于它的性能和能力的同时,很多开发者也纷纷利用 ChatGPT 的技术,开发出各种有意思的应用。比如 《一大波 ChatGPT 开源项目,诞生了》。

ChatGPT 浏览器插件在这波开源项目里跑得最快,应用场景有挑事的意味:把 ChatGPT 放到搜索的场景下去和搜索引擎一较高下。

例如下面两款:

  • ChatGPT-Google by ZohaibAhmed
  • chat-gpt-google-extension by wong2

ChatGPT-Google 实现思路

项目地址:https://github.com/ZohaibAhmed/ChatGPT-Google

使用效果使用效果

整体构成

从插件的配置清单上可以看出,插件由两部分构成:

  1. 在页面上运行的 content scripts
  2. 在后台运行的 background script

后台运行的脚本入口文件为:src/bg/background.js

页面运行的脚本入口文件为:src/inject/inject.js,除了代码文件,还注入和 UI 相关的样式文件 src/inject/inject.css。因为功能限制在 google 搜索里生效,所以还限定了注入条件 https://www.google.com/*

插件构成插件构成

后台脚本

后台脚本相关代码后台脚本相关代码

从前面的分析可知,后台脚本相关代码在src/background 目录下,只有一个文件 background.js,内容非常简单。

background.jsbackground.js

一句话总结:收到页面发来的消息后,将页面上的插件按钮展示出来,给插件刷存在感,没了,可以直接忽略这部分。

页面交互

交互相关代码交互相关代码

界面相关的代码在 src/inject 目录下,内容很简单,一个样式文件和一个脚本文件,其中样式文件还是个空文件,直接忽略,主要看inject.js,核心代码是红框部分:

inject.jsinject.js

代码不多,概括一下执行流程:

  1. 打开 Google 网页时 inject.js 被注入,页面的代码开始执行
  2. 执行时向 background.js 发送一个消息,background.js 处理完消息后会执行回调
  3. 回调里会发起一个轮询任务:每隔 10ms 检查一下这个网页是否加载完毕
  4. 没加载完毕则继续轮询,加载完毕则取消轮询
  5. 加载完毕后,从页面上获取用户输入的搜索内容:document.getElementsByName("q")[0].value;
  6. 同时往页面上注入一个自定义的框,展示提示 "Generating ChatGPT Response" document.getElementById("appbar").insertAdjacentHTML('afterend', html);
  7. 接着就是发起网络请求,从本机的 localhost:5001/chat 端口获取 ChatGPT 生成的结果,将结果替换到页面上 id=GPTCHAT 的 HTML 元素里。

那么这个 localhost:5001/chat 是什么来头?这个就要看作者的另一个项目:chatgpt-api

后端代码

项目地址:https://github.com/ZohaibAhmed/chatgpt-api

这个项目的核心代码只有一个文件 server.py,按项目作者的话来说,就是提供了一个非官方的 ChatAPI。

Chat 接口Chat 接口

代码也很简短:

  1. 从请求中获取 q 字段的内容,也就是前面传输过来的搜索词
  2. 使用 send_message 把搜索词发送出去
  3. 通过 get_last_message 获取最后消息的返回结果
  4. 把结果作为 response 返回
send_message 和 get_last_messagesend_message 和 get_last_message

两个函数的实现如上,这里面的使用到的 boxPAGE 是什么?代码文件里找一找:

PAGEPAGE
程序启动操作程序启动操作

概括起来:使用 playwright 这个浏览器自动化测试框架启动了一个浏览器,而且设为有头模式,即把被控制的浏览器显示出来。

在 server.py 程序启动时 start_browser,打开 chatgpt 的网页,如果没有登录会提示登录,以登录的话,服务器就跑起来了。

可以看到这里设为非多线程,这是因为 chatgpt 网页限制一次只能进行一个会话,上一个问题没回答完,不能发起下一个问题。

回过头来看 CHAT 接口的代码,总结起来流程就是:

  1. 程序启动时,新建一个浏览器页面,跳转到 chatgpt 的网页
  2. 当接收到 chat 请求时,将请求的内容取出来,输入到 chatgpt 网页上的输入框,回车(send_message 函数)
  3. 查看 chatgpt 页面看页面是否还在加载 chatgpt 返回的结果,如果返回完了,将结果从网页上提取出来,返回
  4. 以上,就完成 Server 的功能

小结

这个项目本质上是一个披着浏览器插件外皮的 Web 自动化程序。

因为需要利用 playwright 操作目标界面,这部分功能浏览器插件做不了,因此用后端机器实现。

浏览器插件只是作为用户交互的入口代理,从界面上提取输入数据,从后端获取输入并展示出来。

受限于本身 ChatGPT 网页端的限制,只能配合本地搭建服务端使用,通用性不强。

同时由于利用的是 playwright 操作浏览器,性能开销和资源占用都挺大的。

总的来说,这个方案虽然粗暴,但在没有官方 API 的情况时却是蛮实用的,这个思路可以用在很多其他类似的场景上。

chat-gpt-google-extension 实现思路

项目地址:https://github.com/wong2/chat-gpt-google-extension

这个项目在前一个项目的基础上,做了进一步的优化,青出于蓝而胜于蓝:

  1. 跨平台支持:支持 Chrome、Firefox、Microsoft Edge,同时上架了官方商店
  2. 更方便易用:不再需要本地搭建服务端,利用浏览器插件本身提供的能力,模拟 chatgpt 网页去 openai 获取数据
  3. 交互更友好:信息展示在搜索结果列表的右侧,不影响浏览搜索结果,也便于查看 ChatGPT 的输出

TO BE CONTINUE

0 人点赞