1. 项目概述:一个基于ChatGPT API的对话机器人

最近在GitHub上看到一个挺有意思的项目,叫 bradtraversy/chatgpt-chatbot 。这是一个由知名开发者Brad Traversy创建的,基于OpenAI的ChatGPT API构建的Web端对话机器人。说白了,它就是一个可以让你自己部署、自己定制的网页版聊天助手,界面简洁,功能直接,非常适合想快速体验或集成ChatGPT能力的开发者。

这个项目之所以吸引我,是因为它完美地解决了一个痛点:OpenAI官方的ChatGPT网页版虽然强大,但如果你想把它嵌入到自己的网站、应用里,或者想拥有一个界面更清爽、功能更聚焦的私人聊天工具,直接调用API并自己搭建前端界面就成了刚需。Brad的这个项目,就是一个绝佳的“脚手架”和“参考实现”。它用最主流的技术栈(Node.js后端、Express框架、前端HTML/CSS/JS),清晰地展示了如何从前端界面收集用户输入,到后端服务器安全地调用OpenAI API,再将AI的回复流式地推回前端展示的完整闭环。对于前端开发者、全栈新手,或者任何想理解现代AI应用前后端交互逻辑的人来说,这个项目都是一个极佳的学习范本和开发起点。

2. 核心架构与技术栈解析

2.1 前后端分离的经典模式

这个项目采用了经典的前后端分离架构。这种架构在现代Web开发中非常普遍,其核心思想是让前端(用户看到的界面和交互逻辑)和后端(处理业务逻辑、与数据库或第三方API通信)各司其职,通过定义好的接口(API)进行通信。

前端部分 非常简单直接,就是纯正的“三件套”:HTML、CSS和JavaScript。没有使用React、Vue这些重型框架,这使得代码极其易于理解和修改。HTML负责搭建聊天界面的骨架,比如消息气泡、输入框、发送按钮的布局;CSS则负责美化,让界面看起来现代、舒适;而JavaScript(Vanilla JS,即原生JS)则承担了所有动态交互:监听发送按钮的点击、将用户输入通过 fetch API发送到后端服务器、接收并处理服务器返回的AI回复(特别是流式数据),最后动态地将消息插入到聊天历史中。这种选择降低了学习门槛,任何有基础Web知识的开发者都能立刻上手。

后端部分 则基于Node.js和Express框架。Node.js使得我们可以用JavaScript来编写服务器端代码,这对于全栈JavaScript开发者来说非常友好。Express是一个极简的Web应用框架,它帮助我们快速搭建起一个HTTP服务器,并定义路由(比如 /api/chat 这个端点专门用来处理聊天请求)。后端的核心职责是作为一个“安全的中转站”和“逻辑处理器”。它接收前端发来的用户消息,然后代表前端去调用OpenAI的ChatGPT API。这里的关键在于, 你的OpenAI API密钥是存储在后端环境变量中的,永远不会暴露给前端浏览器 ,这是保障密钥安全、避免被恶意利用的生命线。后端在拿到AI的回复后,再将其封装成标准的HTTP响应,发回给前端。

2.2 关键技术点:流式响应(Streaming)

这个项目的一个亮点是实现了 流式响应(Streaming) 。如果你用过官方的ChatGPT,会发现它的回复是一个字一个字“打”出来的,而不是等AI全部生成完再一次性显示。这种体验更自然,减少了用户的等待焦虑。

bradtraversy/chatgpt-chatbot 中,这个功能是通过OpenAI API的 stream: true 参数以及服务器端事件(Server-Sent Events, SSE)或类似的流式传输技术实现的。具体流程是:

  1. 前端发起请求到后端的 /api/chat 端点,并携带用户消息。
  2. 后端收到请求后,使用 stream: true 参数调用OpenAI的Chat Completions API。
  3. OpenAI的服务器会开始以数据流的形式,分块(chunk)返回AI生成的文本。
  4. 后端服务器不是等所有数据块都收到后再一次性转发给前端,而是每收到一个数据块,就立即将其转发给前端。
  5. 前端通过监听 fetch 响应体的流( response.body ),实时地读取这些数据块,并逐个字符或单词地追加到聊天界面的消息气泡中。

这个过程对网络和代码实现有一定要求,但项目已经为我们搭建好了这个管道。理解这个机制,对于构建体验良好的AI应用至关重要。

2.3 环境变量与配置管理

任何涉及第三方API密钥的项目,安全都是第一位的。这个项目使用 .env 文件来管理环境变量。你会在项目根目录下找到一个 .env.example 文件,里面通常包含一个示例:

OPENAI_API_KEY=your_api_key_here
PORT=5000

你需要将其复制一份,重命名为 .env ,然后将 your_api_key_here 替换成你在OpenAI官网获取的真实API密钥。 PORT 则指定了后端服务器运行的端口(如5000)。

在代码中(通常是 server.js index.js ),通过 dotenv 这个npm包来加载 .env 文件中的变量:

require('dotenv').config();
const apiKey = process.env.OPENAI_API_KEY;

这样, apiKey 变量就安全地存储了你的密钥,并在调用OpenAI API时使用。 切记要将 .env 文件添加到你的 .gitignore 中,绝对不要将它提交到公开的Git仓库,否则你的密钥将暴露无遗,可能导致巨额账单。

3. 从零开始部署与运行指南

3.1 环境准备与项目获取

首先,确保你的电脑上已经安装了 Node.js (建议版本16或以上)和 npm (Node.js的包管理器,通常随Node.js一起安装)。你可以在终端输入 node -v npm -v 来检查是否安装成功。

接下来,获取项目代码。最直接的方式是从GitHub克隆:

git clone https://github.com/bradtraversy/chatgpt-chatbot.git
cd chatgpt-chatbot

如果你不常用Git,也可以直接在GitHub项目页面上点击“Code”按钮,然后选择“Download ZIP”,下载后解压到本地目录。

进入项目文件夹后,你会看到典型的项目结构:

chatgpt-chatbot/
├── index.html      # 前端主页面
├── style.css       # 前端样式文件
├── script.js       # 前端交互逻辑
├── server.js       # 后端服务器主文件
├── package.json    # 项目依赖和脚本定义
├── .env.example    # 环境变量示例文件
└── README.md       # 项目说明文档

3.2 依赖安装与配置

项目依赖的所有第三方包都定义在 package.json 文件的 dependencies 中。通常包括 express (Web框架)、 dotenv (环境变量加载)、 openai (OpenAI官方Node.js SDK)等。我们只需要一条命令就能安装所有依赖:

npm install

这条命令会读取 package.json ,自动下载并安装所有必需的包到本地的 node_modules 文件夹中。这个过程可能需要一点时间,取决于你的网络速度。

安装完成后,进行最关键的一步——配置API密钥。如前所述,复制 .env.example 文件为 .env

cp .env.example .env

(在Windows的CMD中,可以使用 copy .env.example .env )。

然后用文本编辑器(如VS Code、Notepad++)打开 .env 文件,将 OPENAI_API_KEY 的值替换为你自己的密钥。如何获取OpenAI API密钥?你需要注册OpenAI账号,并前往 OpenAI平台 的“API Keys”页面创建。注意,API调用是收费的,但新账号通常有少量免费额度供试用。

3.3 启动服务与测试

配置完成后,就可以启动应用了。查看 package.json scripts 部分,通常会定义启动命令。常见的是:

npm start

或者

node server.js

执行后,终端会显示服务器正在监听某个端口(如 Server running on port 5000 )。

此时,打开你的浏览器,访问 http://localhost:5000 (如果端口是5000)。你应该能看到一个简洁的聊天界面。在输入框里键入“Hello”或“介绍一下你自己”,然后点击发送。如果一切配置正确,你应该能看到AI的回复逐渐显示出来。

注意 :第一次运行时,如果遇到 Error: Cannot find module 'openai' 之类的错误,通常是因为依赖没有安装成功,请回到上一步重新执行 npm install 。如果前端无法连接到后端,检查终端里服务器是否成功启动,以及前端 script.js 中请求的URL(通常是 /api/chat )是否与后端 server.js 中定义的路由一致。

4. 核心代码深度剖析与定制

4.1 后端服务器(server.js)逻辑拆解

后端的核心文件通常是 server.js 。让我们逐块分析它的工作原理。

首先,它引入必要的模块并加载环境变量:

const express = require('express');
const OpenAI = require('openai');
require('dotenv').config();

这里, OpenAI 是官方提供的Node.js库,它封装了调用API的所有细节,比我们自己用 fetch axios 去构造HTTP请求要方便和安全得多。

接着,初始化Express应用和OpenAI客户端:

const app = express();
const port = process.env.PORT || 5000;

// 初始化OpenAI客户端,密钥从环境变量注入
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

注意, new OpenAI() 时直接传入了 apiKey 。确保你的 .env 文件已正确配置,否则这里会为 undefined ,导致后续调用失败。

然后,配置中间件。这两行至关重要:

app.use(express.json()); // 解析JSON格式的请求体
app.use(express.static('public')); // 将‘public’文件夹设置为静态资源目录

express.json() 中间件使得服务器能够理解前端发送过来的JSON数据(比如用户消息)。 express.static('public') 是服务于前端文件的关键。它告诉Express,所有对根路径(如 / , /style.css , /script.js )的请求,都去 public 目录下找对应的文件。在这个项目中,前端文件直接放在根目录,所以这里可能需要根据实际情况调整,比如改成 app.use(express.static(__dirname)) 来将整个项目根目录作为静态资源目录,或者将前端文件移入一个 public 文件夹。

接下来是核心的聊天API端点:

app.post('/api/chat', async (req, res) => {
  try {
    const userMessage = req.body.message; // 从请求体中获取用户消息

    // 调用OpenAI API,注意stream参数设置为true
    const stream = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo', // 指定使用的模型
      messages: [{ role: 'user', content: userMessage }], // 消息历史
      stream: true, // 启用流式输出
    });

    // 设置响应头,告诉前端这是一个流式响应
    res.setHeader('Content-Type', 'text/plain; charset=utf-8');
    res.setHeader('Transfer-Encoding', 'chunked');

    // 遍历数据流,将每个chunk发送给前端
    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content || '';
      res.write(content); // 将内容块写入响应流
    }
    res.end(); // 流结束,关闭响应

  } catch (error) {
    console.error('Error calling OpenAI API:', error);
    res.status(500).json({ error: 'Failed to get response from AI' });
  }
});

这段代码是项目的引擎:

  1. 接收请求 :通过 req.body.message 获取前端发送的用户消息。
  2. 调用API :使用 openai.chat.completions.create 方法,指定模型(如 gpt-3.5-turbo ,成本较低;也可换成 gpt-4 ,能力更强但更贵)、消息历史(这里只包含了当前用户消息,是一个简单的单轮对话。你可以修改 messages 数组来实现多轮对话历史),并关键地设置 stream: true
  3. 流式返回 :设置正确的响应头后,使用 for await...of 循环遍历API返回的流( stream )。每个 chunk 包含AI生成文本的一小部分( chunk.choices[0]?.delta?.content )。我们立即用 res.write(content) 将它发送给前端。
  4. 错误处理 :用 try...catch 包裹,如果API调用失败,返回500错误和友好提示。

最后,启动服务器:

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

4.2 前端交互(script.js)实现详解

前端逻辑集中在 script.js 中,它负责与用户交互,并与后端通信。

首先,它会获取DOM元素,例如消息容器、输入框和发送按钮:

const chatContainer = document.getElementById('chat-container');
const userInput = document.getElementById('user-input');
const sendButton = document.getElementById('send-button');

为发送按钮和输入框(回车键)绑定点击事件:

sendButton.addEventListener('click', sendMessage);
userInput.addEventListener('keypress', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) { // 支持Shift+Enter换行,Enter直接发送
    e.preventDefault();
    sendMessage();
  }
});

sendMessage 函数是前端的核心:

async function sendMessage() {
  const message = userInput.value.trim();
  if (!message) return;

  // 1. 将用户消息显示在界面上
  appendMessage('user', message);
  userInput.value = ''; // 清空输入框
  // 2. 显示一个“AI正在思考”的加载指示器
  const aiMessageElement = appendMessage('ai', '...'); // 先创建一个AI消息气泡

  try {
    // 3. 向后端发送POST请求
    const response = await fetch('/api/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: message }),
    });

    // 4. 处理流式响应
    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    aiMessageElement.textContent = ''; // 清占位符

    while (true) {
      const { done, value } = await reader.read();
      if (done) break; // 流读取完毕

      const chunk = decoder.decode(value); // 解码数据块
      aiMessageElement.textContent += chunk; // 逐块追加到AI消息气泡
      // 可选:自动滚动到最新消息
      chatContainer.scrollTop = chatContainer.scrollHeight;
    }
  } catch (error) {
    console.error('Error:', error);
    aiMessageElement.textContent = '抱歉,出错了。请稍后再试。';
  }
}

这个函数清晰地展示了前端流式处理的步骤:显示用户消息 -> 创建AI消息占位 -> 发送请求 -> 读取响应流 -> 实时更新DOM。

appendMessage 函数负责创建和添加消息气泡到聊天容器,并应用不同的CSS类(如 user-message , ai-message )来区分用户和AI。

4.3 样式定制与界面美化

界面样式由 style.css 控制。Brad的原始设计通常简洁明了,但你可以完全根据自己的喜好进行定制。这是让你的聊天机器人拥有独特个性的好机会。

你可以修改的地方包括:

  • 颜色主题 :修改 :root 中的CSS变量或直接修改 background-color , color 属性来改变主色调、消息气泡颜色。
  • 布局与尺寸 :调整 #chat-container 的宽度、高度、边距、圆角等。
  • 字体 :通过 font-family 更换更美观的字体(如引入Google Fonts)。
  • 动画效果 :为消息的发送、接收添加淡入、滑动等CSS动画,提升交互体验。
  • 响应式设计 :添加媒体查询( @media ),让聊天界面在手机、平板等不同屏幕尺寸上都能良好显示。

例如,想让AI的消息气泡有不一样的风格:

.ai-message {
  background-color: #f0f7ff; /* 更柔和的蓝色背景 */
  border-left: 4px solid #4a9eff; /* 左侧蓝色装饰条 */
  margin-right: auto; /* 靠左对齐 */
}
.user-message {
  background-color: #e8f5e9; /* 绿色背景 */
  border-left: 4px solid #66bb6a;
  margin-left: auto; /* 靠右对齐 */
}

通过调整这些CSS,你可以轻松打造出从科技感到可爱风的各种界面。

5. 高级功能扩展与实战技巧

5.1 实现多轮对话上下文

原项目是一个简单的单轮对话,AI不记得之前的聊天内容。要实现真正的上下文对话,我们需要在后端维护一个“消息历史”数组,并在每次请求时将这个历史传递给OpenAI API。

在后端 server.js 中,我们可以引入一个简单的内存存储(对于演示或单用户场景):

// 在全局或某个作用域内定义一个消息历史数组
let conversationHistory = [
  { role: 'system', content: 'You are a helpful assistant.' } // 系统指令,设定AI角色
];

app.post('/api/chat', async (req, res) => {
  try {
    const userMessage = req.body.message;
    
    // 1. 将用户消息加入历史
    conversationHistory.push({ role: 'user', content: userMessage });

    const stream = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: conversationHistory, // 将整个历史传入,而非仅最新消息
      stream: true,
    });

    res.setHeader('Content-Type', 'text/plain; charset=utf-8');
    res.setHeader('Transfer-Encoding', 'chunked');

    let fullAiResponse = '';
    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content || '';
      res.write(content);
      fullAiResponse += content; // 同时累积完整的AI回复
    }
    res.end();

    // 2. 将AI的完整回复也加入历史
    conversationHistory.push({ role: 'assistant', content: fullAiResponse });

    // 3. (可选)限制历史长度,避免token超限或内存过大
    const MAX_HISTORY_LENGTH = 20; // 保留最近20轮对话
    if (conversationHistory.length > MAX_HISTORY_LENGTH * 2 + 1) { // *2 因为每轮有user和assistant两条,+1是system
      // 保留system消息和最近的N轮对话
      conversationHistory = [
        conversationHistory[0],
        ...conversationHistory.slice(-MAX_HISTORY_LENGTH * 2)
      ];
    }

  } catch (error) {
    console.error('Error:', error);
    res.status(500).json({ error: 'Failed to get response from AI' });
  }
});

这样,AI就能基于之前的对话进行回复了。注意,历史消息会消耗API调用的token,从而增加成本,所以需要合理限制历史长度。

5.2 集成其他模型与调整参数

OpenAI API提供了多种模型,你可以通过修改 model 参数轻松切换:

  • gpt-3.5-turbo :性价比高,响应快,适合大多数聊天场景。
  • gpt-4 / gpt-4-turbo :理解、推理和创意能力更强,但成本更高,速度可能稍慢。
  • gpt-4o :最新的多模态模型,在视觉、文本理解上更均衡。

你还可以调整其他参数来改变AI的行为:

const stream = await openai.chat.completions.create({
  model: 'gpt-4',
  messages: conversationHistory,
  stream: true,
  temperature: 0.7, // 创造性(0-2)。值越高,回答越随机、有创意;值越低,越确定、保守。
  max_tokens: 500, // 限制单次回复的最大长度(token数)。
  top_p: 1, // 核采样,与temperature二选一,控制词汇选择的随机性。
});

temperature 是一个非常重要的参数。如果你想要一个稳定、可靠的问答机器人,可以设为0.2-0.5;如果你想要一个更有趣、创意性的聊天伙伴,可以设为0.7-1.0。

5.3 部署到云端(以Vercel为例)

要让你的聊天机器人能被任何人访问,你需要将它部署到云服务器。这里以对Node.js项目非常友好的 Vercel 为例。

  1. 准备部署配置 :在项目根目录创建一个 vercel.json 文件(如果使用Vercel)。

    {
      "version": 2,
      "builds": [
        {
          "src": "server.js",
          "use": "@vercel/node"
        }
      ],
      "routes": [
        {
          "src": "/(.*)",
          "dest": "server.js"
        }
      ]
    }
    

    这个配置告诉Vercel,使用Node.js环境来构建和运行我们的 server.js 文件,并将所有请求都路由到它。

  2. 修改后端代码以适应服务器环境 :在 server.js 中,将静态文件服务修改为更通用的方式,并确保监听Vercel提供的端口。

    const path = require('path');
    // ... 其他引入 ...
    app.use(express.static(path.join(__dirname))); // 服务当前目录下的静态文件
    
    // 启动服务器,优先使用环境变量PORT(Vercel会提供)
    const port = process.env.PORT || 5000;
    app.listen(port, () => console.log(`Server running on port ${port}`));
    
  3. 在Vercel上配置环境变量

    • 将代码推送到GitHub仓库。
    • 登录Vercel,点击“New Project”,导入你的GitHub仓库。
    • 在项目设置的“Environment Variables”部分,添加 OPENAI_API_KEY ,值为你的密钥。
    • Vercel会自动检测 vercel.json 并部署。部署成功后,你会获得一个 https://your-project-name.vercel.app 的链接,任何人都可以访问你的聊天机器人了。

重要提示 :部署到公网后,务必考虑 速率限制 安全性 。原项目没有这些防护,恶意用户可能通过你的端点大量调用API,导致账单爆炸。简单的防护措施包括:在Vercel项目设置中配置函数执行超时时间和并发限制;或者在后端代码中添加简单的请求频率检查(例如使用 express-rate-limit 中间件)。

6. 常见问题排查与性能优化

6.1 部署与运行中的典型问题

在部署和运行过程中,你可能会遇到以下问题:

问题现象 可能原因 解决方案
运行 npm install 失败,报网络或权限错误 1. 网络连接问题(特别是某些包源)。
2. 本地Node.js/npm版本过旧。
3. 项目目录权限问题。
1. 检查网络,可尝试切换npm源: npm config set registry https://registry.npmmirror.com
2. 升级Node.js到LTS版本。
3. 确保对项目文件夹有读写权限。
服务器启动成功,但浏览器访问 localhost:5000 显示“Cannot GET /” 静态文件服务路径配置错误。 express.static 中间件没有正确指向前端文件所在目录。 检查 server.js app.use(express.static(...)) 的路径。如果前端文件在根目录,使用 app.use(express.static(__dirname)) app.use(express.static('.')) 。确保 index.html 在指定的目录下。
点击发送后,前端报错“Failed to fetch”或网络错误 1. 后端服务器未运行或端口不对。
2. 前端请求的URL( /api/chat )与后端定义的路由不匹配。
3. 跨域问题(如果前端和后端在不同端口或域名)。
1. 确认后端终端是否在运行且无报错。
2. 对比前端 fetch 的URL和后端 app.post 的路由是否完全一致。
3. 在后端添加CORS中间件: npm install cors ,然后在 server.js const cors = require('cors'); app.use(cors());
发送消息后,AI回复区域一直显示“...”或空白 1. OpenAI API密钥未正确设置或无效。
2. 账户余额不足或API调用额度用完。
3. 网络问题导致无法连接到OpenAI服务。
1. 检查 .env 文件中的 OPENAI_API_KEY ,确保没有多余空格,并在OpenAI平台验证密钥是否有效。
2. 登录OpenAI平台,检查Usage页面确认余额和用量。
3. 检查服务器终端是否有API调用错误日志。可能是网络超时,可尝试增加请求超时时间。
AI回复不完整或中途截断 1. 网络连接不稳定,流式传输中断。
2. 服务器或客户端设置了响应超时时间过短。
3. AI生成的回复达到了 max_tokens 限制。
1. 检查网络稳定性。
2. 在后端,确保响应流正确关闭( res.end() )。在前端,检查 fetch 请求和流读取逻辑是否完整。
3. 适当增加 max_tokens 参数值。
部署到Vercel后访问显示“Function Invocation Error” 1. vercel.json 配置错误。
2. 项目依赖未正确安装或打包。
3. 环境变量在Vercel上未设置或设置错误。
1. 检查 vercel.json 语法和配置是否正确指向入口文件。
2. 在Vercel的部署日志中查看构建错误信息。确保 package.json 中的依赖和脚本正确。
3. 在Vercel项目设置中,仔细核对 OPENAI_API_KEY 等环境变量的名称和值,确保与代码中 process.env.XXX 的变量名一致。

6.2 成本控制与监控策略

使用OpenAI API会产生费用,尤其是流量较大时。必须建立成本意识:

  1. 理解计费方式 :OpenAI API按token用量计费。Token可以粗略理解为单词或字词的一部分。不同模型单价不同(如gpt-3.5-turbo比gpt-4便宜很多)。你可以在OpenAI官网的 定价页面 查看最新价格。

  2. 设置使用限额 :这是最重要的防护措施。在OpenAI平台的“Usage limits”页面,你可以为API密钥设置 硬性月度消费限额 。强烈建议在项目初期就设置一个你能承受的额度(例如5美元或10美元),这样即使发生意外,损失也可控。

  3. 监控用量 :定期查看OpenAI平台“Usage”页面,了解每天的token消耗和费用情况。对于关键项目,可以考虑编写简单的脚本,定期调用OpenAI的用量API,并将数据发送到你的监控面板或通过邮件/短信提醒。

  4. 优化请求

    • 精简上下文 :如前所述,维护过长的对话历史会消耗大量token。合理限制历史消息轮数。
    • 调整参数 :在不影响体验的情况下,适当降低 max_tokens ,限制单次回复长度。
    • 选择合适的模型 :对于简单的聊天任务, gpt-3.5-turbo 通常是性价比最高的选择。

6.3 安全性增强建议

将你的API密钥视为密码,并采取以下措施保护你的应用:

  1. 永远不要将密钥暴露给前端 :这是铁律。所有涉及API密钥的调用必须通过你自己的后端服务器进行。本项目已经做到了这一点。

  2. 使用环境变量 :正如本项目所做,将密钥存储在 .env 文件中,并通过 process.env 读取。确保 .env .gitignore 中。

  3. 部署时的环境变量 :在Vercel、Railway等部署平台,通过其提供的环境变量配置界面来设置密钥,而不是写在代码里。

  4. 实施API速率限制 :使用如 express-rate-limit 这样的中间件,限制单个IP地址在特定时间窗口内可以发起的请求数量,防止恶意刷接口。

    npm install express-rate-limit
    
    const rateLimit = require('express-rate-limit');
    const limiter = rateLimit({
      windowMs: 15 * 60 * 1000, // 15分钟
      max: 100, // 每个IP在15分钟内最多100次请求
      message: '请求过于频繁,请稍后再试。'
    });
    app.use('/api/', limiter); // 将限流器应用到所有/api/开头的路由
    
  5. 输入验证与清理 :对前端发送来的用户消息进行基本的验证和清理,防止注入攻击(虽然对于纯文本聊天风险较低,但仍是好习惯)。例如,检查消息长度,过滤或转义一些特殊字符。

通过以上步骤,你不仅能成功运行 bradtraversy/chatgpt-chatbot 这个项目,更能深入理解其运作机制,并具备对其进行定制、扩展和加固的能力。这个项目就像一把钥匙,为你打开了构建基于大语言模型的个性化应用的大门。

更多推荐