开头
兄弟们,今天给大家整点干货!用 Node.js 调 ChatGPT API 搞个流式聊天效果,就跟官方那个一样一个字一个字往外蹦,贼拉简单!
这里用sse。(chatgpt设置stream为true即可。)
讲一下这里为啥用sse:
第1,简单 :只要http响应头 和 前端用EventSource
api就可以。相对比websocket,还要心跳机制和一些连接管理那些。
第2,不要浪费:前端不需要频繁向后端发请求,sse单向的就够用了。
准备
安装 Node.js(版本16以上就行)
开个chatgpt号,开通api调用权限。
代码
- 前端代码(index.html)
html
<html>
<body>
<!-- 聊天界面 -->
<div id="answer"></div>
<input id="input" placeholder="输入问题">
<button onclick="send()">发送</button>
<script>
const inputElem = document.getElementById('input');
const answerElem = document.getElementById('answer');
// 发送问题到后端
function send() {
const prompt = inputElem.value.trim();
if (!prompt) return;
answerElem.textContent = ''; // 清空回答区域
exec(prompt); // 执行请求
inputElem.value = ''; // 清空输入框
}
// 使用EventSource建立流式连接
function exec(prompt) {
const url = new URL('/chat', location.href);
url.searchParams.set('prompt', prompt); // 设置问题参数
const es = new EventSource(url); // 创建SSE连接
es.onmessage = (event) => {
const data = event.data;
if (data === '[DONE]') { // 流结束标记
es.close();
return;
}
const chunk = JSON.parse(data);
const content = chunk.choices[0].delta.content;
if (content) {
answerElem.textContent += content; // 追加内容到回答区域
}
};
}
</script>
</body>
</html>
- 后端代码(server.js)
js
import { createServer } from 'http'
import OpenAI from 'openai'
import { createReadStream } from 'fs'
// 初始化 OpenAI 客户端
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
const port = 3001
createServer(async (req, res) => {
const url = new URL(req.url!, 'file:///')
const query = Object.fromEntries(url.searchParams.entries())
// 根路径,返回 index.html
if (url.pathname === '/') {
createReadStream('./index.html').pipe(res)
return
}
// /chat 路径,处理聊天请求
if (url.pathname === '/chat') {
const prompt = query.prompt || ''
if (prompt.trim() === '') {
res.end('query prompt is required')
return
}
// 调用 OpenAI API 获取流式聊天数据
const gptStream = await openai.chat.completions.create({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: prompt }],
max_tokens: 100,
stream: true,
})
// 设置响应头为 SSE 格式
res.writeHead(200, { 'Content-Type': 'text/event-stream' })
for await (const chunk of gptStream) {
res.write(`data: ${JSON.stringify(chunk)}\n\n`) // 实时推送数据
}
req.on('close', () => {
console.log('req close...')
})
return
}
// 其他路径返回默认信息
res.end('other route')
}).listen(port)
console.log(`Server running at http://localhost:${port}/`)
跑起来
环境:
- Node.js
- npm 或 yarn
- OpenAI API 密钥
目录结构:
lua
/my-project
|-- server.js
|-- index.html
|-- .env
|-- node_modules/
|-- package.json
|-- package-lock.json
env文件:
后台给的,去复制写上去就好了。
js
OPENAI_API_KEY=你的OpenAI API
装依赖:
js
npm i openai
跑起来:
js
node server.js
服务器启动后,我们可以访问 http://localhost:3001/ 来查看聊天效果。在浏览器输入问题,点击发送,等待一会儿,你会看到实时返回的答案。答案会一块一块地显示出来,模拟了 ChatGPT 自己的流式效果。
放到服务器上:
买服务器,国内受限,买个外国的服务器,按量付费,自己玩玩,配置低也没关系。把代码部署上去,我一般是在服务器上装宝塔跑。
开端口:
最后主要要开通一下端口3001。
服务器安全组里一般就是,开放3001端口。
完结
sse是啥,sse是server-sent event
,叫它实时推送吧。openai的chatgpt本身就有这个一个个字蹦出来的效果,只要加个stream: true
这样子在它给出的api里面去配置一下就好了。
前端就用onmessage
去收,然后拼接。前后端打个配合。
就这么简单!1分钟就能搞个自己的AI聊天窗口,自己去做套壳ChatGPT。