超简单! 三分钟为你的网站添加一个GPT聊天机器人

1,328 阅读3分钟

最近,chatGPT的热度已经降了下来,基本上人人都已经使用过了,前段时间我在使用一些免费的GPT问答网站时,发现访问特别容易崩溃(当然有VIP不过要付费),于是我就自己去开发了一个简单的GPT聊天系统,代码非常简单,今天空闲和大家分享一下...

使用框架/库

React、Express、chatgpt、axios

准备

OPENAI_API_KEY 这个API_KEY需要注册一个openAI的官网账号,不过国内IP好像被禁止注册了,可以到淘宝去买一个,登录的时候可能需要科学的方式才能登录成功

代码实现

在刚开始实现此功能的时候,我先是去官网找到了对应的API,然后直接调用,发现是不行的(可能是国内IP被禁用了),然后又去找了一些其他的API和二次封装的库,发现chatgpt是可以使用的,而且使用起来也是比较简单,附上链接,感兴趣的同学对照此文档去实现也是可以的

后端实现

在实现前,我们需要首先了解我们需要的一些配置项

  • model:必填项,指定要使用的ChatGPT模型名称。可以从OpenAI或Hugging Face等平台下载或训练自己的模型
  • apiKey:必填项,指定使用的API密钥,用于与ChatGPT API服务器进行通信
  • temperature:可选项,设置生成响应的温度值,范围为0到1,默认值为1。较高的温度会导致生成的响应更加随机和多样化(简单来说就是数值越大越智能)
  • maxTokens:可选项,设置生成响应的最大标记数,默认值为50。如果生成的响应超过了这个标记数,则会被截断

在后端处理方面,我们选择流式获取数据,这样前端可以通过后端发送的数据流实现连续生成文本的效果

/* POST ChatGPT. */
router.post('/', async function(req, res, next) {
  //Express默认使用commonJS导入,如果要使用es6导入需要以这种方式导入
  const { ChatGPTAPI } = await import('chatgpt')
  res.header('Content-type', 'application/octet-stream')

  try {
    const { message } = req.body
    let firstChunk = true
    const api = new ChatGPTAPI({  //生成chatGPT实例
      apiKey: process.env.OPENAI_API_KEY,
      completionParams: {
        model: 'gpt-3.5-turbo',
        temperature: 0.5,
      }
    })
    const response = await api.sendMessage(message, {
      onProgress: (chunkResponse) => {
        res.write(firstChunk ? JSON.stringify(chunkResponse) : `\n${JSON.stringify(chunkResponse)}`)
        firstChunk = false
        console.log(chunkResponse.text);  //这里获取的是实际返回的答案
      }
    })
    console.log('text', response.text);

    return { type: 'Success', data: response }
  } catch (error) {
    res.write(JSON.stringify(error))
  } finally {
    res.send()
  }
});

在这段代码中,我们首先生成一个ChatGPT的实例对象,然后为其添加基本的配置信息。chatgpt库提供了sendMessage函数,可以向ChatGPT模型发送消息,并返回模型生成的响应消息,第一个参数是接口携带的提问文本,第二个参数chatgpt为我们提供了一个onProgress函数供我们获取流式数据,然后通过res.write()方法不断向前端返回数据流就OK了,最后记得要send()一下

前端实现

前端实现的思路比较简单,就是获取后端返回最新的数据流,然后不断Set到DOM元素的Value中即可

import React, { useState } from 'react'
import axios from "axios";
import { Button, Input, Tag } from 'antd'

function App () {
  const [data, setData] = useState('')
  const [msg, setMsg] = useState('')

  const gptHandle = () => {
    axios.post(
      'http://localhost:3001',
      {
        message: msg
      },
      {
        // 服务端传入流式数据获取
        onDownloadProgress: ({ event }) => {
          const xhr = event.target
          const { responseText } = xhr
          // 不断获取最后一项数据
          const lastIndex = responseText.lastIndexOf('\n', responseText.length - 2)
          let chunk = responseText
          if (lastIndex !== -1)
            chunk = responseText.substring(lastIndex)
          try {
            const data = JSON.parse(chunk)
            setData(data.text)
          }
          catch (error) {
            console.log(error);
          }
        },
      }
    )
  }

  return (
    <>
      <Tag>
        {data || '快来向我提问吧~'}
      </Tag>
      <div>
        <Input placeholder='请输入你要搜索的内容' onChange={(e) => setMsg(e.target.value)} />
        <Button onClick={() => gptHandle()}>点击</Button>
      </div>
    </>
  );
}

这里我们在发起POST请求之后,通过axiosonDownloadProgress方法来接收后端发送的数据流,然后将其setData()到dom元素内。如果你想要实现上下文功能的话,可以记录上一次提问的信息,然后在发请求的时候将其拼接到这次提问信息的前面,这样就能实现上下文的功能了.

最后来看一下效果

20230512-101040.gif

总结

看过之后你是不是觉得十分的简单呢,快去为你自己网站添加一个GPT机器人吧...