使用 Node.js、Socket.IO 和 GPT-4 构建 AI 聊天机器人

2,721 阅读4分钟

由 GPT-4 等先进人工智能技术提供支持的聊天机器人可以显着提高用户参与度、提供即时帮助并提升整体用户体验。在本教程中,将构建一个利用 Node.jsSocket.IOGPT-4 API 强大功能的 AI 聊天机器人应用程序。通过分步指南,将了解如何创建无缝的实时聊天机器人体验,从而改变网站并给访问者留下深刻印象。

PIC.jpeg

要使用 GPT-4 创建一个提供聊天机器人功能的完整 Node.js Web 应用程序,需要一个 Express 服务器,使用 Socket.IO 进行实时通信,并使用 HTML 提供一个简单的前端, CSS 和 JavaScript 文件。

设置项目并安装依赖项

在深入研究聊天机器人的实施之前,需要先设置项目并安装必要的依赖项。在下面将引导完成创建项目结构、安装所需的 Node.js 包并确保顺利的开发体验。

第 1 步:为项目创建一个目录并进入到该目录

执行以下命令在第一步中创建一个新的项目目录:

mkdir ai-chatbot
cd ai-chatbot

第 2 步:初始化项目并安装所需的包

接下来,在项目文件夹中创建一个 package.json 文件,并确保安装了所有需要的依赖项:

npm init -y 
npm install express socket.io openai dotenv

第 3 步:创建一个 .env 文件来存储 OpenAI API 密钥:

OPENAI_API_THISKEY=your_openai_api_key

实现服务器逻辑

下面开始创建服务器端逻辑。

第 4 步:为服务器创建一个文件:service.js

require("dotenv").config();
const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const { Configuration, OpenAIApi } = require("openai");

const app = express();
const server = http.createServer(app);
const io = socketIO(server);
const port = process.env.PORT || 3001;

// OpenAI API 配置
const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_THISKEY,
});
const openai = new OpenAIApi(configuration);
// 静态文件目录
app.use(express.static("public"));

io.on("connection", (socket) => {
    console.log("New user connected");

    // Initialize the conversation history
    const conversationHistory = [];

    socket.on("sendMessage", async (message, callback) => {
        try {
            // Add the user message to the conversation history
            conversationHistory.push({ role: "user", content: message });

            const completion = await openai.createChatCompletion({
                model: "gpt-4",
                messages: conversationHistory,
            });

            const response = completion.data.choices[0].message.content;

            // Add the assistant's response to the conversation history
            conversationHistory.push({ role: "assistant", content: response });

            socket.emit("message", response);
            callback();
        } catch (error) {
            console.error(error);
            callback("Error: Unable to connect to the chatbot");
        }
    });

    socket.on("disconnect", () => {
        console.log("User disconnected");
    });
});

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

上述代码片段是使用 GPT-4 APIExpressSocket.IO 的 Node.js 聊天机器人 Web 应用程序的主要服务器端代码。

  1. dotenv 导入并配置为从 .env 文件加载环境变量。
  2. 导入必要的模块,例如expresshttpsocket.ioopenai
  3. 创建一个 Express 应用程序、一个 HTTP 服务器和一个 Socket.IO 服务器,服务器侦听指定端口(来自环境变量或默认为 3001)。
  4. OpenAI API 使用提供的 API 密钥进行配置。
  5. public 目录设置为 Express 应用程序的静态文件目录。
  6. 连接事件监听器被添加到 Socket.IO 服务器。当新用户连接时:
    • 记录用户的连接。
    • 一个名为 conversationHistory 的空数组被初始化以存储对话历史记录。
    • 事件监听器 sendMessage 被添加到连接的套接字。当用户发送消息时:用户的消息被添加到数组中 conversationHistoryGPT-4 API 请求以对话历史记录作为输入。聊天机器人的响应从 API 结果中提取并添加到数组中 conversationHistory 。最后,聊天机器人的响应通过事件发回给用户 message。如果出现错误,则会向用户发送错误消息。
  7. disconnect事件侦听器被添加到已连接的套接字中,以在用户断开连接时进行记录。
  8. 服务器启动,一条日志消息表明它正在指定端口上运行。

第 5 步:创建一个目录 public 并在其中创建 index.htmlstyles.cssscript.js 文件:

mkdir public
cd public
touch index.html styles.css script.js

前端部分

以下 HTML 代码表示聊天机器人 Web 应用程序的主页。它提供基本结构,包括聊天机器人前端所需的 CSS 和 JavaScript 文件,需要插入到 index.html 中:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>AI Chatbot</title>
        <meta
            name="keywords"
            content="GPT、AI、ChatGPT、Docker、Vue、angular、ember、ChatGPT、Html、WEB Point"
        />
        <meta
            name="description"
            content="An AI chatbot full stack project driven by GPT-4,used node.js、express、socke.io"
        />
        <meta http-equiv="content-language" content="en" />
        <meta name="author" content="https://github.com/QuintionTang" />
        <link rel="stylesheet" href="styles.css" />
    </head>
    <body>
        <div id="chat-container">
            <div id="messages"></div>
            <form id="message-form">
                <input
                    type="text"
                    id="message-input"
                    placeholder="Type your message"
                    autocomplete="off"
                />
                <button type="submit">Send</button>
            </form>
        </div>
        <script src="/socket.io/socket.io.js"></script>
        <script src="script.js"></script>
    </body>
</html>

第 7 步:将以下 CSS 代码添加到 styles.css 文件中

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #262e35;
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
*,
:after,
:before {
    box-sizing: border-box;
}
#chat-container {
    border-radius: 5px;
    display: flex;
    line-height: 1.5;
    width: 100%;
    height: 100vh;
    flex-direction: column;
}

#messages {
    overflow-y: auto;
    padding: 1.5rem !important;
    height: calc(100vh - 91px);
}

#message-form {
    display: flex;
    padding: 1.5rem !important;
    border-top: 1px solid #36404a;
}

#message-input {
    flex-grow: 1;
    border: 1px solid #36404a;
    border-radius: 5px;
    border-radius: 0.4rem;
    font-size: 0.875rem;
    min-height: calc(1.5em + 1rem + 6px);
    background-color: rgb(54, 64, 74);
    padding: 0.5rem 1rem;
    color: #fff;
}

button {
    background-color: #007bff;
    border-radius: 0.4rem;
    color: white;
    border: none;
    border-radius: 5px;
    padding: 0.5rem 1rem;
    padding: 6px 12px;
    margin-left: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #0056b3;
}

.ctext-wrap {
    display: flex;
    margin-bottom: 10px;
    background-color: #7269ef;
    border-radius: 8px 8px 8px 8px;
    color: #fff;
    padding: 12px 20px;
    position: relative;
}

第 8 步:将以下 JavaScript 代码添加到 script.js 文件中

const socket = io();

const messageForm = document.getElementById("message-form");
const messageInput = document.getElementById("message-input");
const messages = document.getElementById("messages");

function displayMessage(role, message) {
    const div = document.createElement("div");
    div.innerHTML = `<p><b>${
        role === "user" ? "You" : "Assistant"
    }:</b> ${message}</p>`;
    messages.appendChild(div);
    messages.scrollTop = messages.scrollHeight;
}

messageForm.addEventListener("submit", (e) => {
    e.preventDefault();

    const message = messageInput.value;
    displayMessage("user", message); //

    socket.emit("sendMessage", message, (error) => {
        if (error) {
            return alert(error);
        }

        messageInput.value = "";
        messageInput.focus();
    });
});

socket.on("message", (message) => {
    displayMessage("assistant", message);
});
  1. Socket.IO 客户端实例是使用该变量创建io()并分配给该socket变量的。
  2. DOM 元素,例如消息表单、消息输入字段和消息容器,使用getElementById
  3. displayMessage函数定义为在消息容器中创建和显示聊天消息。它以消息发送者的角色(用户助理)和消息内容作为参数,使用格式化消息创建一个新元素,将div其附加到消息容器,并将容器滚动到底部。
  4. 事件侦听器添加到消息表单以处理表单提交:默认的表单提交行为被阻止使用e.preventDefault()。从输入字段中检索用户的消息并使用该displayMessage函数显示。该sendMessage事件通过带有用户消息的 Socket.IO 客户端发出,并提供错误回调函数。如果有错误,它会显示为警报。否则,输入字段被清除,焦点返回到输入字段。
  5. 事件侦听器添加到 Socket.IO 客户端以处理 message 事件:当从服务器接收到一条消息(聊天机器人的响应)时,displayMessage 将使用角色 助手 调用该函数,并将接收到的消息显示在聊天中。

测试应用程序

测试是为了验证逻辑,下面来测试一下。

第 9 步:通过运行启动服务器

node service.js

现在,可以在浏览器中访问 http://localhost:3000 并与 GPT-4 聊天机器人进行交互。聊天机器人将回复消息,可以与其进行对话。

如上所见:聊天机器人知道对话的上下文并提供考虑了对话历史的答案。

结论

到此使用 Node.js、Socket.IO 和 GPT-4 API 成功构建了 AI 支持的聊天机器人 Web 应用程序。凭借其上下文感知功能和实时交互,聊天机器人可以满足当今用户不断变化的期望。

随着继续开发和完善聊天机器人,可能性是无限的。可以进一步自定义聊天机器人的功能、外观以及与其他服务的集成以满足特定需求。