跳至正文

记网站从 GPT-3 升级至 GPT-3.5-Turbo 的过程

  •  

OpenAI 公司于去年年底推出的 ChatGPT 人工智能语言模型备受关注,相信朋友们在很多地方都见到了它的身影。作为小站的站长,我也是第一时间了解并注册了账号,经过一段时间的体验,我感觉 ChatGPT 在许多地方都能发挥不小的作用,在语言大模型领域可以算是一项较大的突破。面对这么强大的聊天功能,再加上官方限制注册。我自然也打起了小算盘,我在 OpenAI 网站上找到了可以免费使用的 API,利用 Github 上的开源 Html 框架,将 ChatGPT 搬到了自己的服务器上。

网站上线后,反响很不错。但我也发现了一个问题,就是 OpenAI 提供给第三方个人免费使用的API貌似不是最新的GPT-3.5 模型,我猜测其为较旧的GPT-3模型,这个版本的模型还不能像 ChatGPT 一样能给出特别拟人化的回应。经过一番查证,果然如此,OpenAI 并未放出 GPT-3.5 模型的 API,第三方开发者只能使用 GPT-3.

近期,OpenAI 宣布正式开放其 GPT-3.5 系列模型的 API 给第三方开发者使用。因为是刚更新,所以我所使用的网页框架并未更新支持 GPT-3.5。作者不更新那我就自己更新!抱着试一试的想法,我对照着 OpenAI 的开发文档将配置中的 “model” 类型改为了 “GPT-3.5-Turbo”,结果肯定是失败的。于是我从浏览器的报错入手。

随便输入一个问题,发现浏览器对 API 的 POST 请求抛出了 404,这意味着 OpenAI 的 API URL 可能发生了变化。查阅开发文档得知,OpenAI 的 API 请求目录发生了变化,故根据开发文档修改了请求目录。

404

修改请求 URL 后再次尝试请求,出现 “TypeError: Cannot read properties of undefined” 错误,其含义为“无法读取未定义的属性”。判断为 API 改动导致 OpenAI 侧无法读取我的请求,于是再次查阅开发文档,与网站的前端请求函数对比发现内容请求语句不正确,GPT-3.5 的正确请求应该为:

{
  "model": "gpt-3.5-turbo",
  "messages": [{"role": "user", "content": "Hello!"}] // content 为发送的内容
}

而我第一次修改后的请求语句为:

// 已经过节选,以匹配官方示例,提升可读性
{
 "model": "gpt-3.5-turbo"
 "prompt": document.getElementById("chat-gpt-input").value, // 获取文本框中的内容发送至 GPT
}

可以看到,由于模型的更换,请求中的 “messages” 替换了之前的 “prompt”,且 “messages” 中的内容变成了一组 Json 嵌套信息,所以内容请求需要做出调整。

得知这个问题后,开始进一步修改请求内容。在这里我犯了个初学者常常犯的错误:在函数中,双引号””内直接写了变量获取语句,没有进行转义处理,这样的结果就是写在双引号””的获取语句被当作字符串进行了处理。

下面是我第二次修改的请求语句:

var data = JSON.stringify({
 "messages":[{"role": "user", "content": "document.getElementById("chat-gpt-input").value"}], // 语句未转义,被当成字符串处理
 "temperature": 0.5,
 "top_p": 1,
 "frequency_penalty": 0,
 "presence_penalty": 0,
 "model": "gpt-3.5-turbo"
});

发现问题后,我使用 Javascript 的连接语法对变量进行处理,这样就可以直接将数据插入请求的双引号””中,避免转义语句带来的麻烦。

下面是我第三次修改的请求语句:

var data = JSON.stringify({
 "messages":[{"role": "user", "content": ""+document.getElementById("chat-gpt-input").value}], // 插入获取到的变量数据
 "temperature": 0.5,
 "top_p": 1,
 "frequency_penalty": 0,
 "presence_penalty": 0,
 "model": "gpt-3.5-turbo"
});

修改完成后,测试网站是否正常运行,随便输入一个问题描述,发现请求顺利发送至 API,但 API 返回的回复并未按照预期打印在网站文本框中。于是我从网站的 Response 函数开始排查,发现函数中的 “responseText” 对象无法读取,导致定时器失效,无法打印出返回的答案。

如下是原先的 “responseText” 对象的读取过程:

// 已经过节选,以提升可读性
xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            var json = JSON.parse(xhr.responseText);
            var response = json.choices[0].text; // 获取返回的内容

            // 将CHATGPT的返回内容输出到文本框
            var responseText = document.getElementById("chatgpt-response");
            var index = 0;

查阅开发文档,发现 API 返回的内容出现了变化,以下是官方给出的 Response 示例:

{
 'id': 'chatcmpl-6p9XYPYSTTRi0xEviKjjilqrWU2Ve',
 'object': 'chat.completion',
 'created': 1677649420,
 'model': 'gpt-3.5-turbo',
 'usage': {'prompt_tokens': 56, 'completion_tokens': 31, 'total_tokens': 87},
 'choices': [
   {
    'message': {
      'role': 'assistant',
      'content': 'The 2020 World Series was played in Arlington, Texas at the Globe Life Field, which was the new home stadium for the Texas Rangers.'},
    'finish_reason': 'stop',
    'index': 0
   }
  ]
}

从官方的示例中可以看出,更新后的 API 返回的 Json 信息多出了一层嵌套,下面是更新后的嵌套关系:

'choices' --> 'message' --> 'content'

所以要想正确获取到返回的信息,必须对函数中 “responseText“ 对象的获取路径进行修改。

下面是我修改后的路径:

// 已经过节选,以提升可读性
xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            var json = JSON.parse(xhr.responseText);
            var response = json.choices[0].message.content; // 更新后的嵌套关系

            // 将GPT的返回值输出到文本框
            var responseText = document.getElementById("chatgpt-response");
            var index = 0;

修改后再次测试,发现正确返回了答案并成功打印在了文本框中。

按照预期运行

更新过程结束。

升级后的 GPT-3.5 更加智能了,不会像之前一样给出一个莫名其妙的答案,欢迎大家体验!

网址:ChatGPT – wljay Network Service

完全免费,国内正常使用。

Github链接:MOLAaaaaaaa/chatgpt-html-Chatgpt3.5-support: chatgpt html online (github.com)

修改后的框架已经合并至主线,鸣谢 @sbaliyun

该文章共有 1 条评论

在此发布你的想法