本文正在参与「技能视角深入 ChatGPT」

摘要

本文首要解说在已有 openai 账户的状况下,大众号怎样运用 Node.JS 快速接入它们。

别的也附录了怎样快速运用本大众号体会 ChatGPT 与 DALL.E。

大众号快速接入教程

ChatGPT 接入大众号的条件是你首要得有一个大众号跟一个 openai 账户。创立 openai 账户最中心的便是要有一个能接纳短信的国外手机号,现在比较可行的网站应该是这个:sms-activate.org/cn 。其他注册流程我就不多赘述了,网上已经有许多教程。

其实大众号怎样接入,网上也有一些教程,可是或多或少都有些前置要求,比方,已经有了一台服务器做音讯处理;或许要调用做转发代理的;或许其实大众号接入教程,是群聊机器人的接入教程。

尽管我曾经开发过微信大众号,但最近6年都没碰过了,也没有自己的私人服务器。除了会 JavaScript,有一个 个人订阅号外,一无所有。所以后边首要介绍跟我这种相似状况下,怎样在半响以内,免费建立一个 ChatGPT 服务。

在正式教学之前,我先贴上已开源的代码:github.com/wuomzfx/wx-… 。由于后边的教程,其实首要仍是讲我源码完结的思路。假如你完全不关心进程的话,那也能够马上 clone 代码,看一眼 readme.md。在下面教程的第一步以后,你就能布置自己的大众号版 ChatGPT了。

假如你对源码完结好奇,那咱们来一同看看它是怎样完结并建立到大众号的:

先问一下 ChatGPT

公众号最低成本接入ChatGPT及如何优化体验?

仿制它答复的代码,新建一个 js 文件,装置一下相关依靠。并从 openai 账户页注册并仿制一个密钥,即可完结调用。信任基本前端入门的同学都能够顺利完结履行并初次测验。

账户密钥获取地址:platform.openai.com/account/api…

其实它这个答复已经有些落后了,由于这个模型是根据 2021年及曾经的数据训练的,答复难免会有些掉队。咱们其实能够直接看文档:sequelize.org/docs/v6/cor…

公众号最低成本接入ChatGPT及如何优化体验?

文档也已经十分清晰,而且调用十分简略。所以咱们理解,接入 ChatGPT 中心,其实十分简略。

第一步:布置微信云保管服务

既然 node 调用 GPT 如此简略,那咱们的首要工作其实便是搞一个音讯服务,能处理订阅号接受的音讯,并做调用与答复即可。

幸运的事,2023年了,微信大众号开发在这方面已经十分老练,在大众号后台「开发者东西」中,有一个「微信云保管」,它真如它自身所描绘,免服务器免运维,而且在一定运用量下仍是免费的。真的是,你只需写代码,push 代码,剩余它都能帮你搞定。

公众号最低成本接入ChatGPT及如何优化体验?

咱们的音讯服务十分简略,能够直接用 Koa 模板快速布置一个服务。

公众号最低成本接入ChatGPT及如何优化体验?

后续的进程十分简略、傻瓜,我就不逐个截图展示了,官方也有规范的教程文档:developers.weixin.qq.com/miniprogram…

然后很快你就能布置一个最简略的服务器,并通过它体系生成的域名,打开一个这样的网站。

公众号最低成本接入ChatGPT及如何优化体验?

修改代码也十分简略。在前一步流程中,你授权你的 github 后,它在你的 gihthub 会建一个库房(记住新建完以后,去把库房设置为私有),每逢你给这个库房 push master 代码时,它就会主动拉取最新代码从头布置。

到此为止,你就已经成功建立了一个服务器,还给你装备了数据库,你能够在上面开发任何你想要的功用。

但仍需求弥补一提的是,默认的云保管服务器,在你一段时间不调用它时,会主动封闭服务。有恳求来时才会重启服务,这会导致后续发音讯时,第一次发总是失利。所以,假如是作为音讯服务,主张调整相关装备:

在「服务列表-详细服务-服务设置」中,将实例副本数最小设置为1。不过这样也有个弊处,简单提早花完微信云保管的免费额度。

公众号最低成本接入ChatGPT及如何优化体验?

第二步:开发一个简略的音讯接口

微信给的模板代码(github.com/WeixinCloud…)中的事例代码,是没有音讯相关的。所以咱们得自己先开发一个音讯接口,使得能接纳到 大众号的音讯并针对性做定制回复。

开发之前,对一些未开发过微信大众号的同学做点儿科普。订阅号的音讯推送分几种:

  1. 被迫音讯回复:指用户给大众号发一条音讯,体系接纳到后,能够回复一条音讯。
  2. 主动回复/客服音讯:能够脱离被迫音讯的5秒超时权限,在48小时内能够主动回复。但需求大众号完结微信认证。

相关文档地址:

  • 介绍文档:developers.weixin.qq.com/miniprogram…
  • 代码示例:developers.weixin.qq.com/miniprogram…

作为个人大众号,一般都无法完结企业认证,所以咱们没方法,只能运用被迫音讯回复。只用微信云保管完结被迫音讯回复十分简略。在上述的代码示例文档是以 Express 为示例的,但逻辑是一样的,我再列一个 koa 下的最小完结代码。

// 一个用户发什么音讯,就反弹什么音讯的音讯回复功用
router.post('/message/post', async ctx => {
  const { ToUserName, FromUserName, Content, CreateTime } = ctx.request.body;
  ctx.body = {
    ToUserName: FromUserName,
    FromUserName: ToUserName,
    CreateTime: +new Date(),
    MsgType: 'text',
    Content: `反弹你发的音讯:${Content}`,
  };
});

仿制这段代码,增加到你的 index.js文件中,commit & push master 后,微信云保管会主动布置。假如没有的话,能够手动点一下发布,走「履行流水线」发布。

公众号最低成本接入ChatGPT及如何优化体验?

布置以后,在云保管后台的「设置-大局设置」中,增加「音讯推送」。除了 「Path」要手动填写一下 刚刚代码的路由名「/message/post」外,其他都是能够下拉选择的。

公众号最低成本接入ChatGPT及如何优化体验?
点提交以后,它会查验一下 接口是否能调通,OK的话,你的音讯服务就布置成功了,能够通过微信大众号发个音讯测验一下看看。 假如这儿增加校验失利,或许的原因是这些,请自行排查:

  1. 并未成功布置云保管服务;
  2. 云保管服务并未有一个名为 /message/postPOST 接口;
  3. 该接口逻辑无法正常履行并回来;
  4. 服务设置中最小实例数为0,首次恳求时服务未发动。

都增加好后,能够在 「服务列表 – 服务器koa-xxx – 运行日志」里看详细日志状况,便利排查一些问题。

第三步:本地开发与调试

每次都 push 代码到线上测验,不免功率太低。咱们仍是要建立一个本地联调的环境。官方是引荐下载 Docker,装备 VsCode 插件去做联调。其实也没必要,咱们需求比较简略。只需本地有 MySql ,装置一个 PostMan,就足够做调试了。我自己测验布置 Docker,尽管也成功了,但进程难免仍是会有些奇奇怪怪的地方,没留意卡住了,怪挺费时的。所以仍是简略 npm install & npm start 吧。

至于 MySql 与 PostMan 怎样装置,这个就靠咱们自己百度或问 ChatGPT 了。

同样的,布置本地环境比较简略,我就不一步一步贴流程了,但会把一些或许要踩的坑,或许一些或许需求的文档,跟咱们讲一下

  1. 假如本地不是走docker,那么数据库并不会做初始化,所以需求自己 指令行 或许其他 GUI 东西来初始化一下库。在 container.config.js这个文件中,供给了初始化指令:CREATE DATABASE IF NOT EXISTS nodejs_demo; 模板代码里的数据库名为 nodejs_demo
  2. 假如本地不是走docker,数据库的账号密码需求自己环境变量设置一下,否则是无法连接数据库的。
  3. koa运用模板里用的 ORMsequelize,运用比较简略,也足够用,没用过能够看文档学一下,这是它的文档地址:sequelize.org/docs/v6/cor…
  4. 音讯接口的官网文档说不能超时5秒,但我测验真实呼应耗时最长大约3秒左右,而且文档里所说的重试好像也不会发生。假如你微信发音讯没呼应,能够看看是否是超时了。

根据以上的信息,我再贴一个最小的能完结 CharGPT 调用的代码,便利本地调试。请记住,由于超时的问题,它很难在微信大众号里得到呼应。你能够本地调试并取得成果。

const configuration = new Configuration({
  apiKey: 你的apiKey,
});
const openai = new OpenAIApi(configuration);
async function getAIResponse(prompt) {
  const completion = await openai.createCompletion({
    model: 'text-davinci-003',
    prompt,
    max_tokens: 1024,
    temperature: 0.1,
  });
  return (completion?.data?.choices?.[0].text || 'AI 挂了').trim();
}
router.post('/message/post', async ctx => {
  const { ToUserName, FromUserName, Content, CreateTime } = ctx.request.body;
  const response = await getAIResponse(Content);
  ctx.body = {
    ToUserName: FromUserName,
    FromUserName: ToUserName,
    CreateTime: +new Date(),
    MsgType: 'text',
    Content: response,
  };
});

通过 postman测验,你能够取得如下成果(当然,你的问题跟答案都或许会不一样)。

公众号最低成本接入ChatGPT及如何优化体验?

(这道题它出的不免有点儿蠢….)

第四步:处理超时与多轮对话的问题

网上大部分许多教程,并没有告诉咱们怎样去处理超时与多轮对话的问题。

处理这俩个问题,都必须依靠数据库。因而sequelize的文档仍是主张咱们看一下,后者换成你了解的 ORM。

超时问题

这个其实也好解,Promise.race即可。大致思路是:

  1. 先往数据库存一条 回复记载,把用户的发问存下来,以便后续查询。设置回复的内容为空,设置状况为 回复中(thinking)。
  // 由于AI呼应比较慢,简单超时,先插入一条记载,保持状况,待后续更新记载。
  await Message.create({
    fromUser: FromUserName,
    response: '',
    request: Content,
    aiType: AI_TYPE_TEXT, // 为其他AI回复拓展,比方AI作画
  });
  1. 笼统一个 chatGPT 恳求方法 getAIMessage,函数内部得到 GPT 呼应后,会更新之前那条记载(通过用户id & 用户发问 查询),把状况更新为 已答复(answered),并把回复内容更新上。
  // 成功后,更新记载
  await Message.update(
    {
      response: response,
      status: MESSAGE_STATUS_ANSWERED,
    },
    {
      where: {
        fromUser: FromUserName,
        request: Content,
      },
    },
  );
  1. 前置增加一些判断,当用户在恳求时,假如 AI 还没完结呼应,直接回复用户 AI 还在呼应,让用户过一瞬间再重试。假如 AI 此时已呼应完结,则直接把 内容回来给用户。
  // 找一下,是否已有记载
  const message = await Message.findOne({
    where: {
      fromUser: FromUserName,
      request: Content,
    },
  });
  // 已答复,直接回来音讯
  if (message?.status === MESSAGE_STATUS_ANSWERED) {
    return `[GPT]: ${message?.response}`;
  }
  // 在答复中
  if (message?.status === MESSAGE_STATUS_THINKING) {
    return AI_THINKING_MESSAGE;
  }
  1. 终究便是一个 Promise.race
  const message = await Promise.race([
    // 3秒微信服务器就会超时,超越2.9秒要提示用户重试
    sleep(2900).then(() => AI_THINKING_MESSAGE),
    getAIMessage({ Content, FromUserName }),
  ]);

这样就处理了超时问题,便是假如呼应比较慢的话,用户会一向重试发音讯…有点儿蠢。没方法,谁叫咱们没有客服音讯的接口权限呢。

多轮对话

曾经我认为,ChatGPT 完结多轮对话,或许是保持了一个 sessionId,只需带上这个 sessionId,就能完结多轮对话。后来我在 openai 文档里看了半响,也没看到相似功用的参数。你问 chatGPT,它也会跟你瞎扯淡,给你一个过错方向。

公众号最低成本接入ChatGPT及如何优化体验?

无奈去 google,才在 stackoverflow 找到了答案:stackoverflow.com/questions/7…

原来 ChatGPT 完结多轮对话方法很简略粗暴,便是把之前的对话存起来,从头拼接起来 + 这次的问题,一同作为 prompt再传给它就好了…

不过通过我实测,直接拼接好像效果不太好,我测验了一些拼接计划,现在这个计划效果还算比较满意:

async function buildCtxPrompt({ FromUserName }) {
  // 获取最近10条对话
  const messages = await Message.findAll({
    where: {
      fromUser: FromUserName,
      aiType: AI_TYPE_TEXT,
    },
    limit: 10,
    order: [['updatedAt', 'ASC']],
  });
  // 只要一条的时候,就不必封装上下文了
  return messages.length === 1
    ? messages[0].request
    : messages
        .map(({ response, request }) => `Q: ${request}\n A: ${response}`)
        .join('\n');
}

需求留意的是,查询时,时间的排序不要错了,不然很简单 驴唇不对马嘴。

这样,咱们就完结了一个能多轮对话的 微信 ChatGPT 了。至于 AI 作画怎样完结,这个就比较简略了。我的源码也已经集成了它的完结,有兴趣同学能够看看。

到此为止,咱们就基本完结了微信版 ChatGPT 的中心完结。假如你恰好有个大众号,并想接入,那能够下载源码,参考教程完结布置接入。 github.com/wuomzfx/wx-…

为什么答复的效果不如 ChatGPT 官网

假如你在各大大众号或一些群里体会过别人建立的 ChatGPT 。你会发现,大部分体会都是不如官网的答复体会的。在咱们这次完结中,即使咱们完结了多轮对话的才能,它也是体会不如官方的。

我不是指 UI 交互上官网供给的更友爱,而是 UI 对话上,官网的对话才能好像会更强一些。比方 同样是问,「怎样运用 Node.JS 调用你」,咱们自己建立的服务的答复是这样的:

公众号最低成本接入ChatGPT及如何优化体验?

比较官网的答复,明显它没理解,「你」指的是 ChatGPT。那为什么咱们自己建立的 AI 帮手才能不如官网供给的服务呢?官网并不开源,我无法从代码层面去感知,我只能根据官网文档的一些信息,做一些个人猜想。不过我对 AI 常识的了解十分少,假如有不对的,欢迎大佬们帮助指正。

从官方文档来看,官方服务版的 ChatGPT 的模型并非根底版的text-davinci-003,而是通过了「微调:fine-tunes」。文档地址在这:platform.openai.com/docs/guides…

大致意思便是,能够通过 API 上传训练数据,根据现有模型,从头微调出一个「自定义的模型」。早在 21 年官网就有篇博文,介绍了通过这种方法,能够极大的提高某些范畴的问答精确率。而且举了好几个公司的例子,在运用 微调版的自定义模型后,帮助它们的运用取得了十分高精确率的 AI 反应。详细的内容能够看这篇博文:openai.com/blog/custom…

现在每天成百上千万人拜访官服版的 ChatGPT,根据用户的问答反应,又能生成海量的新的微调数据,这些数据又能从头去微调官服版的 ChatGPT 模型。于是官服版天然会比咱们调用根底的text-davinci-003显得更精确与好用。

除了微调之外,还有一种我理解是 「常识库」的方法来提高某些详细范畴的问答精确率。在某些特殊的范畴,ChatGPT 或许没有一些齐备的常识来答复你。这时,你能够把现有的「常识」作为上下文,拼接上当时的问题,合成一个 prompt 传递给 GPT,GPT会根据上下文总结出你问题的答案并回复给你。

但有一个问题便是,「常识库」往往数据十分巨大,实践调用 API 时,咱们会发现 兼并上下文后的 prompt ,已远远超出了 API 的约束。因而,openai 供给了一种两段式的方法:

  1. 先将巨量的常识库拆块,并运用 openai 供给的Embeddings才能(AI 小白的理解是把许多文本向量化,完结更好的相似性匹配)将常识内容向量化。关于它的文档在这:platform.openai.com/docs/guides…
  2. 当用户发问时,能够通过「发问文本」,匹配到详细是常识库中的某一小节内容,把这小节常识提取出来。只把这一小节常识作为上下文,拼接到 prompt 传递给 GPT。

官网文档以及 openai 的gihub 供给了几个事例,咱们有兴趣能够读一下,加深一下了解:

  1. How to build an AI that can answer questions about your website:platform.openai.com/docs/tutori…
  2. Question Answering using Embeddings:github.com/openai/open…

所以官服版,或许也保持了一个自己的常识库,在咱们发问时,能够根据这个常识库,帮咱们做更精确的答复。

怎样体会?

看了这么多,假如你想切切实实体会一下 ChatGPT,但由于一些环境约束的确没法体会,那能够重视我的大众号把玩一下。

微信查找「相学长」大众号并重视,你与大众号发送的任何音讯,都会主动转发到 ChatGPT,取得与它的对话体会。而且能够进行多轮对话,它会感知之前的对话内容,并与你作答。比方这样:

公众号最低成本接入ChatGPT及如何优化体验?

一起你留意到了一个细节:它经常会答复「我已经在编了,请稍等几秒后仿制原文再说一遍」。原因是 ChatGPT 尽管很强,但不能很快答复。而订阅号要求体系必须要在5秒(实践测验3秒)内作答。所以假如呼应超越3秒,我会先让体系答复这段话。稍等一瞬间后你再仿制之前的话术 发到大众号,体系将会把 到时 GPT 已做好的答复快速发回给你。

除了体会文本对话,我也加了 图片生成的功用(DALL.E)。现在网上咱们都在评论 ChatGPT ,但在这之前,AI 作画也火过一阵。DALL.E 是 openai 公司推出的一个 AI 作画的服务。它的体系接入,比较接入 ChatGPT ,本钱更低,由于不需求做多轮对话缓存。

而且对我来说,反而 AI 作画比文本对话更有用。由于说话我还算行,但画画我是真的不行了。有的时候,写一篇文章,想找一张封面图,是真的找不到。网上有些图片或许还有侵权问题。DALL.E 帮我处理了这样的问题。

假如想体会 AI 作画,很简略。跟大众号发以「作画」最初的音讯,后边跟上对这幅画的描绘关键词,稍等一下后,体系将会回你这张图片的 URL 地址。由于 url 地址是国外的,所以你的拜访或许会比较慢,也需求你略微等一下。

公众号最低成本接入ChatGPT及如何优化体验?

其实我这个大众号的头像 便是通过 DALL.E 生成的,现在我感觉从头生成的这只 橘猫好像更可爱,咱们说我要不要换这个橘猫的新头像呢

假如你觉得你的图片尽管不错,但能够再优化一下。其实 DALL.E 也支持 AI 修图,比方把我头像这只胖猫变成了一只瘦猫。

公众号最低成本接入ChatGPT及如何优化体验?

不过 P 图这个功用,我并没有集成到大众号,未来假如有精力,能够再搞一搞。

终究多说几句

一方面是关于 微信大众号 本身的感触。对,在咱们在畅想 AI 时,我其实先想的是微信大众号。这或许是由于我十分早的接触到了 微信大众号开发。早在 2013/2014 年的时候,微信大众号刚起步,当时乃至还没有 订阅号/服务号 之分。

当年我大三,总是自称为互联网弄潮儿,的确也感觉到了这种第三方敞开渠道好像在未来能扮演十分重要的效果。于是,我的第二专业毕业论文(工商管理二专),写的便是互联网敞开渠道相关的内容。

这在我大四找实习的时候,又遇到了巧事。过去与未来,产生了一种神奇的干涉,让我坍缩在微信大众号上。我通过曲曲折折,终究实习的一家创业公司,恰好也是做微信大众号开发的。以致于后来我的毕业设计,也是自己想的 -「根据微信敞开渠道完结一个借贷体系」。2015 年的毕设,我用了 Angular + Ionic + 微信敞开渠道,现在想想,仍是比较「互联网弄潮儿」的。

后来我在那家公司干到 2017 年头才走,差不多是做了 2 年左右的微信大众号体系开发。在那之后,就简直再也没碰过了。直到这个月,我重启了我大学时就建的个人大众号。

就好像一个良久没看到的小孩子,你会觉得它突然长高了许多一样。再次接触微信大众号开发,我也感觉它好像「老练」了,「强大」了许多。曾经个人开发微信大众号的本钱特别高,整服务器、数据库、域名注册、域名备案,仍是需求费许多精力的,尽管当年也爱学习爱折腾不怕累。但现在这个微信云保管的确整的好,一条龙服务。

假如这套设施从头回到2015年,那个时候我也会 ORM,也会 Node.js,也会看文档,跟这篇文章的技能要求没有任何差异,乃至英文阅览水平比现在还好一些。信任我一定会由于半响就能布置一个自定义音讯服务,一个自定义网站而振作不已。一起,我的毕设或许也能够完结的更快更好。(我一向耿耿于怀,我的毕设只拿了良好,而不是优异。而那些用着老套课题,各种网络 copy 的不少毕设却是优异)

然后才是关于 AI 的感触。我第一次接触 AI,同样是大学,应该是大三的选修课程吧,课程名便是 「人工智能」。不瞒咱们,我一个字的常识都没有记住。由于这堂课不必考试,终究查核便是自己写 2 页关于「人工智能」的某部分常识总结就行,而且仍是 Word 打印就行。教师还特意着重,咱们不必写(打印)太多,自己要多总结,2页就好了。

终究到期末的时候,咱们就在各种网上找「人工智能」相关的文章或论文,然后裁剪裁剪,交给教师。我已经忘掉我找的是什么内容了,大约便是七八页的内容,我裁剪到了 3 页,实在裁不下去了。毕竟比较人工智能,我的语文水平更高,我只是在裁剪与总结文字,并非是总结常识。

而我的一个室友,他比较懒,差不多也是七八页的内容,原模原样提交上去了。而终究,他取得了一个 优异,而我又是一个 良好,人工智能就成为他这四年唯逐个门分数超越我的学科。于是,第一次接触 AI ,就给我造成了并不是很好的影响。

进到社会以后,我应该至少超越 3 次有想学习 AI 的主意。由于这几年简直每过一段时间,就会有一些相应的 爆炸性 新闻出来,比方 阿尔法狗大战柯洁。这让人觉得,程序员不学 AI,真的就要被筛选了。一起,这也增加了我买显卡时,更想买旗舰显卡的理由。(我买它不只仅是为了玩游戏,也是为了研究机器学习)

然后开端了 「查找相关材料并增加保藏 – 打开材料学习 – 看不懂 – 算了不学了」的多轮循环。我现在的 Chrome 标签里还躺着 Google 的机器学习教程。我也不知道是几几年加的,总归很久了。

公众号最低成本接入ChatGPT及如何优化体验?

到如今,我这次把玩 ChatGPT 与 DALL.E,能够说是作为程序员,真实在编程运用上离 AI 最近的一次,而且还玩的不亦乐乎。曾经都是纯理论学习,编码上好像有测验,但都并未成功,包括 TensorFlow.js 之类。由于它们真的比较枯燥,遇到一些小问题,我就没动力继续了。

这就让我又会想到了大学,我因玩 chrome 插件,玩微信大众号而接触了前端,并为之深深招引。终究在前端这个范畴,走了快 10 年,在职业发展上,也取得了一些建树。但在人工智能方面,却仿佛一个 嘤嘤学语 的婴儿。直到今天,好像才取得了一些 编程上的乐趣。而乐趣来源于:根底设施的充分完善,让大部分人能更低本钱的接触、体会 AI。一起也让 AI 以更丰富的、风趣的、也更有商业或许的形态表现出来。

跟曾经学习 AI 时,各种枯燥把我劝退不同。在把玩 ChatGPT、调用 openai 的 api 时,反而会想着 那几个 model有啥差异;我有没有方法,练一个特殊的 model,真的成为我自己的个人 AI 助理。尽管我还没真的进行什么学习。或许往下走,我又要步入从入门到跑路的循环。但至少,我对它学习的动力,不只仅只来自于触不行及的一些新闻带来的焦虑感;还能来自于,学到好像能真的马上对自己有用。能够快速的获取到正反应。

这次 ChatGPT 的火爆,信任会有更多程序员又预备开端学习 AI 了。我的主意是,假如真的想学,能够先从 运用层面入手,先把它当东西,找到运用场景。对运用场景的不断深化要求,天然会让咱们对其底层原理与常识需求有更多的了解,就更有动力去学习。

说了这么多,我的感触其实便是一句话:感谢各种根底设施的老练,感谢他们背后的建设者,让我这种自驱力差的人,能继续成为互联网弄潮儿

终究的终究,微信查找并重视「相学长」大众号,免费体会 ChatGPT & DALL.E。