前言

今天我们来聊聊如何使用OpenAI和JavaScript的json-server技术来搭建一个独属于你的AI助理用来解决你提出各种请求,这项功能在传统的后端项目中是不可能实现的但是现在我们有了大模型这一利器我们可以使用大模型来快速的分析并处理我们给出的请求。

在AI时代我们可以使用JavaScript来快速构建一个独属于我们的AI助理,使用json-server技术将json文件快速变成后端数据,后端再调用OpenAI的接口来对你所发出的请求进行处理。话不多说,直接开干。

准备工作

第一次看本文章的朋友们,建议先仔细阅读前文:

使用OpenAI API进行情感分析的JavaScript实现

一文教你使用Node.js脚本调用OpenAi API接口实现对话功能

一: 创建项目文件

打开vscode,新建三个文件夹。这三个文件夹的作用分别是: Ai服务,后端目录,前端目录 ,文件夹结构如图所示:

lwpp3ig3.png

二:初始化工程

  1. 初始化后端项目工程 npm init -y
  2. 创建好了项目所需的文件夹后,右键进入backend文件夹的终端,进入到终端。

lwpp4luw.png

lwpp4utz.png

端输入指令 npm init -y 将项目初始为后端工程。初始化成功后会出现 packager.json 文件,如图所示:

lwpp5lm9.png

引入json-server

继续在当前终端中输入指令 npm i json-server 导入成功后,我们会在 package.json 文件夹中看到已经成功引入了 json-server 的依赖。如图所示:

lwpp6woj.png

导入后端数据

  1. 打开 package.json 文件,将 "scripts" 中的内容修改为: "dev": "json-server users.json"
  2. 新建一个名为 users.json 的文件,该文件中的内容则为本项目所需要用到的数据

最终结构如下图所示:

lwppa0ar.png

  1. 进入到 users.json 文件中输入需要用到的数据

这里给出本项目中用到的数据:

{
    "users": [
        {
            "id": 1,
            "name": "科比·布莱恩特",
            "hometown": "费城"
        },
        {
            "id": 2,
            "name": "坤坤",
            "hometown": "温州"
        },
        {
            "id": 3,
            "name": "阿伦·艾弗森",
            "hometown": "费城"
        },
        {
            "id": 4,
            "name": "丁真珍珠",
            "hometown": "理塘"
        }
    ]
}

到此,该项目的后端数据就构建好了。此时,继续在命令行输入指令 npm run dev ,将后端项目运行起来。此时可以在控制台看到后端地址。

lwppbbsw.png

打开浏览器,访问该地址可以看到 users.json 文件中的数据。

访问该地址的不同 id 时,可以看到该id对应的人物信息

lwppc3gk.png

OpenAI的接入

来到 ai_server 文件夹,右键进入到该文件的终端。

一. 初始化后端工程 npm init -y

该操作和上一步一致

二.导入项目所需要的库

  1. npm i openai

该指令用于在项目中安装 openai 这个包,有了这个包就可以使用OpenAI的API接口了。 执行这个命令会做以下几件事:

下载和安装包:从npm仓库下载 openai 包及其依赖到项目的 node_modules 目录。
更新 package.json:执行完这个命令会将 openai 添加到 dependencies 字段,记录为项目依赖。

如图所示:

lwppdjxx.png

  1. npm i dotenv

该指令用于安装 dotenv 这个包,有了这个包,可以使用 .env 配置文件,加载 .env 文件中的环境变量到 process.env 对象中。将项目的私密内容封装到 .env 文件中不向外处暴露,可以很大的提高项目的安全性能。 如下所示:

lwppf8bz.png

至此该项目所需的环境已经搭建完毕,下面我将为大家介绍如何编写代码实现。

代码编写

http服务的搭建(项目的核心部分)

来到 ai_server 文件夹,新建一个名为 main.jsjs 文件,输入以下js代码:

// ai openai, :8888/users?question=
// node 的内置模块 
// - 搭建http服务 
const http = require('http');
const url = require('url');
const OpenAI = require('openai');
require('dotenv').config();

const client = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
    // proxy 
    baseURL: 'https://api.chatanywhere.tech/v1'
})

const server = http.createServer(async function (req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有来源访问,也可以指定具体的域名,如'http://example.com'
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 允许的请求方法
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

    // http 基于请求响应的简单协议 req  请求   res 响应
    if (req.url.indexOf('/users') >= 0) {
        // users  ai 服务
        const parsedUrl = url.parse(req.url, true);
        // console.log(parsedUrl);

        const { question, users } = parsedUrl.query;
        console.log(question, users)
        const prompt = `
        ${users}
        请根据以上用户的json数据,回答${question}这个问题.
        如果回答不了,就返回不清楚,谢谢。
        `
        const response = await client.chat.completions.create({
            model: 'gpt-3.5-turbo',
            messages: [{ role: "user", content: prompt }],
            temperature: 0, // 控制输出的随机性,0表示更确定的输出
        });

        const result = response.choices[0].message.content || '';
        console.log(result);

        let info = {
            message: result
        }
        res.statusCode = 200;
        res.setHeader('Content-Type', 'text/json');
        res.end(JSON.stringify(info))

    }

})

server.listen(8888, function () {
    console.log('服务器启动了')
})

代码详解

以上代码主要作用是搭建一个基于 Node.js 的简单 HTTP 服务器,使用了 Node.js 的内置 http 模块和第三方模块 url、OpenAI 以及 dotenv 来创建一个能够与 OpenAIGPT 模型交互的服务,以处理特定的 HTTP GET 请求并返回 AI 生成的响应。下面是代码的详细解析:

导入模块和配置

  1. http: Node.js的内置模块,用于创建HTTP服务器。
  2. url: Node.js的内置模块,用于URL解析。
  3. OpenAI: 块用于与OpenAI API交互,主要是用来调用gpt-3.5-turbo模型。
  4. dotenv: 用于加载.env文件中的环境变量,用于读取封装的OpenAI的API密钥。

通过 require 语句导入这些模块,并使用 dotenv.config() 加载环境变量,然后实例化 OpenAI客户端,其中 baseURL 指定了代理的 API端点

创建HTTP服务器

  1. 使用 http.createServer() 方法创建一个 HTTP服务器,传入一个异步函数作为回调处理请求和响应。
  2. 设置响应头允许跨域访问,允许 任何源('*'),允许 GET、POSTOPTIONS 请求方法,以及指定允许的请求头。
 res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有来源访问,也可以指定具体的域名
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 允许的请求方法
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

请求逻辑处理

  1. 判断请求 URL 是否包含 /users 路径,如果是,则继续处理。if (req.url.indexOf('/users') >= 0)
  2. 使用 url.parse() 解析请求 URL 的查询参数。const parsedUrl = url.parse(req.url, true);
  3. 解构出 questionusers 两个查询参数。 const { question, users } = parsedUrl.query;
  4. 构造一个 prompt,包含提供的 JSON 数据和问题,要求 AI 模型根据这些信息回答提出的问题。
  5. 使用 await client.chat.completions.create() 异步调用 OpenAI API,传递模型类型(gpt-3.5-turbo)、消息内容(包含构造的prompt)以及控制输出随机性的temperature参数。
  6. 从API响应中提取第一选择的回复内容。
  7. 将回复内容封装成 JSON 对象 info,设置响应状态码为 200(成功),响应头为 Content-Type: text/json,最后使用 res.end() 发送JSON格式的响应给客户端。

启动服务器

调用 server.listen(8888) 使服务器在本地 8888 端口上监听 HTTP 请求。

总结

该服务器的核心功能是接收包含用户数据和问题的 HTTP GET 请求,利用 gpt-3.5-turbo 模型生成针对该问题的回答,然后将这个回答作为JSON响应返回给客户端。用于构建HTML页面中的AI助理功能,根据用户提供的一系列用户数据和问题,返回相应的解答。

前端代码

来到 frontend 文件夹中,新建一个名为 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全栈</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container">
        <div class="row col-md-6 col-md-offset-3">
            <h1>AI全栈</h1>

            <table class="table table-striped" id="user_table">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>姓名</th>
                        <th>家乡</th>
                    </tr>
                </thead>
                <tbody>

                </tbody>
            </table>

            <form name="aiForm" method="get" action="http://www.baidu.com">
                <div class="form-group">
                    <label for="questionInput">向AI助理提问:</label>
                    <input type="text" name="question" class="form-control" id="questionInput"
                        placeholder="请输入您想问的users相关问题">
                </div>
                <button type="submit" class="btn btn-default">提交</button>
            </form>

            <div class="row" id="message"></div>

        </div>
    </div>

    <script>
        const oMessage = document.querySelector('#message');
        const oBody = document.querySelector('#user_table tbody');
        const oForm = document.forms['aiForm'];
        let usersDate = []


        fetch('http://localhost:3000/users')
            .then(data => data.json())
            .then(users => {
                usersDate = users;
                oBody.innerHTML = users.map(user => `
                    <tr>
                        <td>${user.id}</td>
                        <td>${user.name}</td>
                        <td>${user.hometown}</td>
                    </tr>
                `).join('')
            })

        oForm.addEventListener('submit', function (event) {
            // 阻止页面提交 阻止表单的默认行为
            event.preventDefault();
            // name 属性去找 性能更好
            const question = this["question"].value.trim();
            console.log(question);
            fetch(`http://localhost:8888/users?question=${question}&users=${JSON.stringify(usersDate)}`)
                .then(data => data.json())
                .then(res => {
                    // console.log(res);
                    document.querySelector('#message').innerHTML = res.message;
                })

        })
    </script>

</body>

</html>

代码详解

该项目的 HTML 页面结合了 Bootstrap 框架和 JavaScript(使用fetch API)来实现一个用户信息展示和交互的示例。

获取用户数据

  1. 使用 fetch()http://localhost:3000/users(该地址为后端项目封装数据的地址,查询方式见上文) 获取数据。
  2. 数据返回后,将其转换为JSON格式,并将结果赋值给 usersDate
  3. 遍历 usersDate,动态创建表格行()并添加到 oBody 中。

表单提交处理

  1. 给表单添加事件监听器到表单,当表单被提交时触发。
  2. 使用 event.preventDefault() 阻止表单的默认提交行为(防止页面跳转)。
  3. 获取用户在 questionInput 输入框中输入的问题。
  4. 使用 fetch()http://localhost:8888/users发送问题和用户数据的GET请求。(注意:这里需要将用户数据信息转为json格式)
fetch(`http://localhost:8888/users?question=${question}&users=${JSON.stringify(usersDate)}`)
  1. 服务器返回的数据转为 JSON格式,并且从中获取 message 属性,最后将其内容显示在 oMessage 元素内。

总结

前端的 HTML 页面与后端的 Node.js 服务器代码配合工作,用户可以在界面上查看用户数据,输入问题,然后获取 AI 的回复。

项目运行效果展示

来到 ai_server 文件夹的终端,运行 main.js 来启动后端服务器。

lwppsxe2.png

打开项目的前端页面,输入指令: 请问有哪些同学是老乡

后端在接收到用户给出的请求时,调用 OpenAi 的接口立马给出了问题的答案。

lwppuayw.png

lwppuqc1.png

本篇文章就到此为止啦,希望通过这篇文章能对你了解使用 OpenAI API 搭建 AI助理 有所帮助,本人水平有限难免会有纰漏,欢迎大家指正。如觉得这篇文章对你有帮助的话,欢迎点赞收藏加关注,感谢支持🌹🌹。

最后修改:2024 年 05 月 28 日
如果觉得我的文章对你有用,请随意赞赏o(* ̄▽ ̄*)ブ