<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zephery</title>
    <description>The latest articles on DEV Community by Zephery (@zephery).</description>
    <link>https://dev.to/zephery</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1031531%2Ffb2928cc-5466-40ea-a27c-6359bdb17cd6.png</url>
      <title>DEV Community: Zephery</title>
      <link>https://dev.to/zephery</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zephery"/>
    <language>en</language>
    <item>
      <title>微信公众号-chatgpt搭建</title>
      <dc:creator>Zephery</dc:creator>
      <pubDate>Wed, 22 Feb 2023 07:33:17 +0000</pubDate>
      <link>https://dev.to/zephery/wei-xin-gong-zhong-hao-chatgptda-jian-4k0a</link>
      <guid>https://dev.to/zephery/wei-xin-gong-zhong-hao-chatgptda-jian-4k0a</guid>
      <description>&lt;p&gt;想体验的可以去微信上搜索【旅行的树】公众号，也可以扫描当前二维码体验。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uSUDoCoC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/szfix6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uSUDoCoC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/szfix6.png" alt="image-20230221195341050" width="494" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  一、ChatGPT注册
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 短信手机号申请
&lt;/h3&gt;

&lt;p&gt;openai提供服务的区域，美国最好，这个解决办法是搞个翻墙，或者买一台美国的服务器更好。&lt;/p&gt;

&lt;p&gt;国外邮箱，hotmail或者google最好，qq邮箱可能会对这些平台进行邮件过滤。&lt;/p&gt;

&lt;p&gt;国外手机号，没有的话也可以去&lt;a href="https://sms-activate.org%EF%BC%8C%E8%B4%B9%E7%94%A8%E5%A4%A7%E6%A6%82%E9%9C%80%E8%A6%811%E7%BE%8E%E5%85%83%EF%BC%8C%E8%BF%99%E4%B8%AA%E7%BD%91%E7%AB%99%E8%AE%B0%E5%BE%97%E4%B9%9F%E7%94%A8%E5%9B%BD%E5%A4%96%E9%82%AE%E7%AE%B1%E6%B3%A8%E5%86%8C%EF%BC%8C%E9%9C%80%E8%A6%81%E5%85%88%E5%85%85%E5%80%BC%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98%E3%80%82"&gt;https://sms-activate.org，费用大概需要1美元，这个网站记得也用国外邮箱注册，需要先充值，使用支付宝支付。&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YNvWnetm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/vfh7kn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YNvWnetm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/vfh7kn.png" alt="image-20230220172107296" width="880" height="949"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;之后再搜索框填openai进行下单购买即可。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iTE6Spzc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ask.qcloudimg.com/http-save/6854995/ee59335a8cc5662585f2be689213a0d7.png%3FimageView2/2/w/1620" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iTE6Spzc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ask.qcloudimg.com/http-save/6854995/ee59335a8cc5662585f2be689213a0d7.png%3FimageView2/2/w/1620" alt="img" width="644" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 云服务器申请
&lt;/h3&gt;

&lt;p&gt;openai在国内不提供服务的，而且也通过ip识别是不是在国内，解决办法用vpn也行，或者，自己去买一台国外的服务器也行。我这里使用的是腾讯云轻量服务器，最低配置54元/月，选择windows的主要原因毕竟需要注册openai，需要看页面，同时也可以搭建nginx，当然，用ubuntu如果能自己搞界面也行。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2PxsTuHw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/4yrkq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2PxsTuHw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/4yrkq1.png" alt="image-20230221193455384" width="880" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 ChatGPT注册
&lt;/h3&gt;

&lt;p&gt;购买完之后，就可以直接打开openai的官网了，然后去&lt;a href="https://platform.openai.com/signup%E5%AE%98%E7%BD%91%E9%87%8C%E6%B3%A8%E5%86%8C%EF%BC%8C%E6%B3%A8%E5%86%8C%E8%BF%87%E7%A8%8B%E5%85%B7%E4%BD%93%E5%B0%B1%E4%B8%8D%E8%AE%B2%E4%BA%86%EF%BC%8C%E8%AE%B2%E4%B8%8B%E6%A0%B8%E5%BF%83%E9%97%AE%E9%A2%98%E2%80%94%E2%80%94%E7%9F%AD%E4%BF%A1%E9%AA%8C%E8%AF%81%E7%A0%81"&gt;https://platform.openai.com/signup官网里注册，注册过程具体就不讲了，讲下核心问题——短信验证码&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QJBgHh8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/oz1r8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QJBgHh8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/oz1r8x.png" alt="image-20230222104357230" width="570" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然后回sms查看验证码。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U16kgZm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/28gfhn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U16kgZm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/28gfhn.png" alt="image-20230222104225722" width="880" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;注册成功之后就可以在chatgpt里聊天啦，能够识别各种语言，发起多轮会话的时候，可能回出现访问超过限制什么的。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Bo7hIYU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/mrw3cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Bo7hIYU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/mrw3cz.png" alt="image-20230220173335691" width="880" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;通过chatgpt聊天不是我们最终想要的，我们需要的是在微信公众号也提供智能客服的聊天回复，所以我们需要在通过openai的api来进行调用。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IeIkzphl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/ykhrvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IeIkzphl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/ykhrvs.png" alt="image-20230222104316514" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  二、搭建nginx服务器
&lt;/h2&gt;

&lt;p&gt;跟页面一样，OpenAI的调用也是不能再国内访问的，这里，我们使用同一台服务器来搭建nginx，还是保留使用windows吧，主要还是得注意下面这段话，如果API key被泄露了，OpenAI可能会自动重新更新你的API key，这个规则似乎是API key如果被多个ip使用，就会触发这个规则，调试阶段还是尽量使用windows的服务器吧，万一被更新了，还能去页面上重新找到。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do not share your API key with others, or expose it in the browser or other client-side code. In order to protect the security of your account, OpenAI may also automatically rotate any API key that we've found has leaked publicly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;windows的安装过程参考网上的来，我们只需要添加下面这个配置即可，原理主要是将调用OpenAI的接口全部往官网转发。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;    &lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/v1/completions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;https://api.openai.com/v1/completions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;然后使用下面的方法进行调试即可：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST http://YOUR IP/v1/completions
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "model": "text-davinci-003",
  "prompt": "Say this is a test",
  "max_tokens": 7,
  "temperature": 0
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  三、公众号开发
&lt;/h2&gt;

&lt;p&gt;网上有很多关于微信通过chatgpt回复的文章，有些使用自己微信号直接做为载体，因为要扫码网页登陆，而且是网页端在国外，很容易被封；有些是使用公众号，相对来说，公众号被封也不至于导致个人微信号出问题。&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 微信云托管
&lt;/h3&gt;

&lt;p&gt;微信公众平台提供了微信云托管，无需鉴权，比其他方式都方便不少，可以免费试用3个月，继续薅羊毛，当然，如果自己开发能力足够，也可以自己从0开始开发。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OtOiWtpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/svjm7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OtOiWtpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/svjm7s.png" alt="image-20230220192603751" width="880" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;提供了各种语言的模版，方便快速开发，OpenAI官方提供的sdk是node和python，这里我们选择express（node）。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HFfcIWz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/kkjdna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HFfcIWz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/kkjdna.png" alt="image-20230220201004069" width="880" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 一个简单ChatGPT简单回复
&lt;/h3&gt;

&lt;p&gt;微信官方的源码在这，&lt;a href="https://github.com/WeixinCloud/wxcloudrun-express%EF%BC%8C%E6%88%91%E4%BB%AC%E7%9B%B4%E6%8E%A5fork%E4%B8%80%E4%BB%BD%E8%87%AA%E5%B7%B1%E6%9D%A5%E5%BC%80%E5%8F%91%E3%80%82"&gt;https://github.com/WeixinCloud/wxcloudrun-express，我们直接fork一份自己来开发。&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一个简单的消息回复功能（无db），直接在我们的index.js里添加如下代码。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://43.153.15.174/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;OpenAIApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;simpleResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCompletion&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-davinci-003&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI 挂了&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/message/simple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;消息推送&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 从 header 中取appid，如果 from-appid 不存在，则不是资源复用场景，可以直接传空字符串，使用环境所属账号发起云调用&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-wx-from-appid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ToUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MsgType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CreateTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;推送接收的账号&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ToUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;创建时间&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CreateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MsgType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;simpleResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;ToUserName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ToUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;CreateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;MsgType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;本地可以直接使用http请求测试，成功调用之后直接提交发布即可，在微信云托管上需要先授权代码库，即可使用云托管的流水线，一键发布。注意，api_base和api_key可以填写在服务设置-基础信息那里，一个是OPENAI_API_BASE，一个是OPENAI_API_KEY，服务会自动从环境变量里取。&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 服务部署
&lt;/h3&gt;

&lt;p&gt;提交代码只github或者gitee都可以，值得注意的是，OpenAI判断key泄露的规则，不知道是不是判断调用的ip地址不一样，还是github的提交记录里含有这块，有点玄学，同样的key本地调用一次，然后在云托管也调用的话，OpenAI就很容易把key给重新更新。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P3H6I3pI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/wfekdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P3H6I3pI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/wfekdb.png" alt="image-20230220203313790" width="880" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;部署完之后，云托管也提供了云端调试功能，相当于在服务里发送了http请求。这一步很重要，如果没有调用成功，则无法进行云托管消息推送。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UMzNra8L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/129qih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UMzNra8L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/129qih.png" alt="image-20230220203711436" width="880" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这里填上你自己的url，我们这里配置的是/meesage/simple，如果没有成功，需要进行下面步骤进行排查：&lt;/p&gt;

&lt;p&gt;（1）服务有没有正常启动，看日志&lt;/p&gt;

&lt;p&gt;（2）端口有没有设置错误，这个很多次没有注意到&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s-YQSGgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/dn1f67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s-YQSGgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/dn1f67.png" alt="image-20230220203445297" width="880" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;保存成功之后，就可以在微信公众号里测试了。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T9VbyzJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/p82i06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T9VbyzJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/p82i06.png" alt="image-20230221134250689" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;体验还可以  &lt;/p&gt;

&lt;h2&gt;
  
  
  四、没有回复（超时回复问题）
&lt;/h2&gt;

&lt;p&gt;很多OpenAI的回答都要几十秒，有的甚至更久，比如对chatgpt问“写一篇1000字关于深圳的文章”，就需要几十秒，而微信的主动回复接口，是需要我们3s内返回给用户。&lt;/p&gt;

&lt;p&gt;订阅号的消息推送分几种：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;被动消息回复&lt;/strong&gt;：指用户给公众号发一条消息，系统接收到后，可以回复一条消息。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;主动回复/客服消息&lt;/strong&gt;：可以脱离被动消息的5秒超时权限，在48小时内可以主动回复。但需要公众号完成微信认证。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;根据微信官方文档，没有认证的公众号是没有调用主动回复接口权限的，&lt;a href="https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Explanation_of_interface_privileges.html"&gt;https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Explanation_of_interface_privileges.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pbkw0GgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/eeogjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pbkw0GgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/eeogjb.png" alt="image-20230221100251825" width="880" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;对于有微信认证的订阅号或者服务号，可以调用微信官方的/cgi-bin/message/custom/send接口来实现主动回复，但是对于个人的公众号，没有权限调用，只能尝试别的办法。想来想去，只能在3s内返回让用户重新复制发送的信息，同时后台里保存记录异步调用，用户重新发送的时候再从数据库里提取回复。&lt;/p&gt;

&lt;p&gt;1.先往数据库存一条 回复记录，把用户的提问存下来，以便后续查询。设置回复的内容为空，设置状态为 回复中（thinking）。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// 因为AI响应比较慢，容易超时，先插入一条记录，维持状态，待后续更新记录。&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;fromUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;aiType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AI_TYPE_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 为其他AI回复拓展，比如AI作画&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.抽象一个 chatGPT 请求方法 &lt;code&gt;getAIMessage&lt;/code&gt;，函数内部得到 GPT 响应后，会更新之前那条记录（通过用户id &amp;amp; 用户提问 查询），把状态更新为 已回答（answered），并把回复内容更新上。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="c1"&gt;// 成功后，更新记录&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MESSAGE_STATUS_ANSWERED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;fromUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.前置增加一些判断，当用户在请求时，如果 AI 还没完成响应，直接回复用户 AI 还在响应，让用户过一会儿再重试。如果 AI 此时已响应完成，则直接把 内容返回给用户。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// 找一下，是否已有记录&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;fromUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// 已回答，直接返回消息&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;MESSAGE_STATUS_ANSWERED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`[GPT]: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 在回答中&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;MESSAGE_STATUS_THINKING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;AI_THINKING_MESSAGE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.最后就是一个 &lt;code&gt;Promise.race&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="c1"&gt;// 3秒微信服务器就会超时，超过2.9秒要提示用户重试&lt;/span&gt;
    &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2900&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;AI_THINKING_MESSAGE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;getAIMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这样子大概就能实现超时之前返回了。  &lt;/p&gt;

&lt;h2&gt;
  
  
  五、会话保存
&lt;/h2&gt;

&lt;p&gt;掉接口是一次性的，一次接口调用完之后怎么做到下一次通话的时候，还能继续保持会话，是不是应该类似客户端与服务端那种有个session这种，但是实际上在openai里是没有session这种东西的，令人震惊的是，chatgpt里是通过前几次会话拼接起来一起发送给chatgpt里的，需要通过回车符来拼接。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;buildCtxPrompt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 获取最近10条对话&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;fromUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromUserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;aiType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AI_TYPE_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updatedAt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// 只有一条的时候，就不用封装上下文了&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Q: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n A: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;之后就可以实现会话之间的保存通信了。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sYPNZNn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/52pp5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sYPNZNn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/52pp5f.png" alt="image-20230218203309437" width="854" height="1674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  六、其他问题
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 限频
&lt;/h3&gt;

&lt;p&gt;chatgpt毕竟也是新上线的，火热是肯定的，聊天窗口只能开几个，api调用的话，也是有限频的，但是规则具体没有找到，只是在调用次数过多的时候会报429的错误，出现之后就需要等待一个小时左右。&lt;/p&gt;

&lt;p&gt;对于这个的解决办法只能是多开几个账号，一旦429就只能换个账号重试了。&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 秘钥key被更新
&lt;/h3&gt;

&lt;p&gt;没有找到详细的规则，凭个人经验的话，可能github提交的代码会被扫描，可能ip调用的来源不一样，最好还是开发一个秘钥，生产一个秘钥吧。&lt;/p&gt;

&lt;h3&gt;
  
  
  6.3 为啥和官网的回复不一样
&lt;/h3&gt;

&lt;p&gt;我们这里用的模型算法是text-davinci-003，具体可以参考：&lt;a href="https://platform.openai.com/docs/models/overview%EF%BC%8C%E4%B9%9F%E7%AE%97%E6%98%AF%E4%B8%80%E4%B8%AA%E6%AF%94%E8%BE%83%E8%80%81%E7%9A%84%E6%A0%B7%E6%9C%AC%E4%BA%86%E5%90%A7"&gt;https://platform.openai.com/docs/models/overview，也算是一个比较老的样本了吧&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YES786Yq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/qh4efq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YES786Yq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/qh4efq.png" alt="image-20230221192417900" width="880" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;从官方文档来看，官方服务版的 ChatGPT 的模型并非基础版的&lt;code&gt;text-davinci-003&lt;/code&gt;，而是经过了「微调：fine-tunes」。文档地址在这：&lt;a href="https://link.juejin.cn/?target=https%3A%2F%2Fplatform.openai.com%2Fdocs%2Fguides%2Ffine-tuning"&gt;platform.openai.com/docs/guides…&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6.4 玄学挂掉
&lt;/h3&gt;

&lt;p&gt;有时候消息没有回复，真的不是我们的问题，chatgpt毕竟太火了，官网的这个能力都经常挂掉，也可以订阅官网修复的通知，一旦修复则会发邮件告知你。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XAdamq4K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/4hod0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XAdamq4K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/4hod0s.png" alt="image-20230221175150025" width="880" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;参考：&lt;a href="https://juejin.cn/post/7200769439335546935"&gt;https://juejin.cn/post/7200769439335546935&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  最后
&lt;/h2&gt;

&lt;p&gt;代码地址：&lt;a href="https://github.com/Zephery/wechat-gpt"&gt;https://github.com/Zephery/wechat-gpt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;左边公众号，右边捐赠付款码（创作不易，感恩）&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BShZI6YM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/e6tcpq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BShZI6YM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p.ipic.vip/e6tcpq.png" alt="image-20230221203304340" width="880" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
