好厉害🙇‍♂️怎么现在ai一个字一个字蹦出来,好像人打字喔

开头

兄弟们,今天给大家整点干货!用 Node.js 调 ChatGPT API 搞个流式聊天效果,就跟官方那个一样一个字一个字往外蹦,贼拉简单!

这里用sse。(chatgpt设置stream为true即可。)

讲一下这里为啥用sse:

第1,简单 :只要http响应头 和 前端用EventSourceapi就可以。相对比websocket,还要心跳机制和一些连接管理那些。

第2,不要浪费:前端不需要频繁向后端发请求,sse单向的就够用了。

准备

安装 Node.js(版本16以上就行)

开个chatgpt号,开通api调用权限。

代码

  1. 前端代码(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>
  1. 后端代码(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。

相关推荐
一斤代码5 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子5 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年5 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说7 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409197 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding7 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
布兰妮甜7 小时前
Vue+ElementUI聊天室开发指南
前端·javascript·vue.js·elementui