最近,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请求之后,通过
axios的onDownloadProgress方法来接收后端发送的数据流,然后将其setData()到dom元素内。如果你想要实现上下文功能的话,可以记录上一次提问的信息,然后在发请求的时候将其拼接到这次提问信息的前面,这样就能实现上下文的功能了.
最后来看一下效果
总结
看过之后你是不是觉得十分的简单呢,快去为你自己网站添加一个GPT机器人吧...