前言
今天我们来聊聊如何使用OpenAI和JavaScript的json-server技术来搭建一个独属于你的AI助理用来解决你提出各种请求,这项功能在传统的后端项目中是不可能实现的但是现在我们有了大模型这一利器我们可以使用大模型来快速的分析并处理我们给出的请求。
在AI时代我们可以使用JavaScript来快速构建一个独属于我们的AI助理,使用json-server
技术将json文件快速变成后端数据,后端再调用OpenAI
的接口来对你所发出的请求进行处理。话不多说,直接开干。
准备工作
第一次看本文章的朋友们,建议先仔细阅读前文:
使用OpenAI API进行情感分析的JavaScript实现
一文教你使用Node.js脚本调用OpenAi API接口实现对话功能
一: 创建项目文件
打开vscode,新建三个文件夹。这三个文件夹的作用分别是:Ai服务,后端目录,前端目录
,文件夹结构如图所示:
二:初始化工程
初始化后端项目工程 npm init -y
创建好了项目所需的文件夹后,右键进入backend
文件夹的终端,进入到终端。
在终端输入指令npm init -y
将项目初始为后端工程。初始化成功后会出现packager.json
文件,如图所示:
引入json-server
继续在当前终端中输入指令npm i json-server
导入成功后,我们会在package.json
文件夹中看到已经成功引入了json-server
的依赖。如图所示:
导入后端数据
- 打开
package.json
文件,将"scripts"中的内容修改为:"dev": "json-server users.json"
- 新建一个名为
users.json
的文件,该文件中的内容则为本项目所需要用到的数据
最终结构如下图所示: 3.进入到users.json文件中输入需要用到的数据
这里给出本项目中用到的数据:
json
{
"users": [
{
"id": 1,
"name": "科比·布莱恩特",
"hometown": "费城"
},
{
"id": 2,
"name": "坤坤",
"hometown": "温州"
},
{
"id": 3,
"name": "阿伦·艾弗森",
"hometown": "费城"
},
{
"id": 4,
"name": "丁真珍珠",
"hometown": "理塘"
}
]
}
到此,该项目的后端数据就构建好了。此时,继续在命令行输入指令npm run dev
,将后端项目运行起来。此时可以在控制台看到后端地址。
打开浏览器,访问该地址可以看到users.json
文件中的数据。
访问该地址的不同id时,可以看到该id对应的人物信息
OpenAI的接入
来到ai_server文件夹,右键进入到该文件的终端。
一. 初始化后端工程npm init -y
该操作和上一步一致
二.导入项目所需要的库
1. npm i openai
该指令用于在项目中安装openai这个包,有了这个包就可以使用OpenAI的API接口了。 执行这个命令会做以下几件事:
- 下载和安装包:从npm仓库下载
openai
包及其依赖到项目的node_modules
目录。 - 更新
package.json
:执行完这个命令会将openai
添加到dependencies
字段,记录为项目依赖。
如图所示:
2. npm i dotenv
该指令用于安装dotenv这个包,有了这个包,可以使用.env
配置文件,加载.env
文件中的环境变量到process.env
对象中。将项目的私密内容封装到.env
文件中不向外处暴露,可以很大的提高项目的安全性能。 如下所示:
至此该项目所需的环境已经搭建完毕,下面我将为大家介绍如何编写代码实现。
代码编写
http服务的搭建(项目的核心部分)
来到ai_server
文件夹,新建一个名为main.js
的js文件,输入以下js代码:
javascript
// 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
来创建一个能够与OpenAI的GPT模型交互的服务,以处理特定的HTTP GET请求并返回AI生成的响应。下面是代码的详细解析:
导入模块和配置
- http: Node.js的内置模块,用于创建HTTP服务器。
- url: Node.js的内置模块,用于URL解析。
- OpenAI: 块用于与OpenAI API交互,主要是用来调用gpt-3.5-turbo模型。
- dotenv : 用于加载
.env
文件中的环境变量,用于读取封装的OpenAI的API密钥。
通过require
语句导入这些模块,并使用dotenv.config()
加载环境变量,然后实例化OpenAI
客户端,其中baseURL
指定了代理的API端点。
创建HTTP服务器
1.使用http.createServer()
方法创建一个HTTP服务器,传入一个异步函数作为回调处理请求和响应。 2.设置响应头允许跨域访问,允许任何源('*'
),允许GET、POST和OPTIONS请求方法,以及指定允许的请求头。
arduino
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有来源访问,也可以指定具体的域名
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 允许的请求方法
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
请求逻辑处理
- 判断请求URL是否包含
/users
路径,如果是,则继续处理。if (req.url.indexOf('/users') >= 0)
- 使用
url.parse()
解析请求URL的查询参数。const parsedUrl = url.parse(req.url, true);
- 解构出
question
和users
两个查询参数。const { question, users } = parsedUrl.query;
5. 构造一个prompt
,包含提供的JSON数据
和问题
,要求AI模型根据这些信息回答提出的问题。 6. 使用await client.chat.completions.create()
异步调用OpenAI API,传递模型类型(gpt-3.5-turbo
)、消息内容(包含构造的prompt)以及控制输出随机性的temperature
参数。 7. 从API响应中提取第一选择的回复内容。 8. 将回复内容封装成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
的文件,在该文件中输入以下代码:
xml
<!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)来实现一个用户信息展示和交互的示例。
获取用户数据
- 使用
fetch()
从http://localhost:3000/users
(该地址为后端项目封装数据的地址,查询方式见上文) 获取数据。 - 数据返回后,将其转换为JSON格式,并将结果赋值给
usersDate
。 - 遍历
usersDate
,动态创建表格行(<tr>
)并添加到oBody
中。
表单提交处理
- 给表单添加事件监听器到表单,当表单被提交时触发。
- 使用
event.preventDefault()
阻止表单的默认提交行为(防止页面跳转)。 - 获取用户在
questionInput
输入框中输入的问题。 - 使用
fetch()
向http://localhost:8888/users
发送问题
和用户数据
的GET请求。(注意:这里需要将用户数据信息转为json格式)
bash
fetch(`http://localhost:8888/users?question=${question}&users=${JSON.stringify(usersDate)}`)
- 服务器返回的数据转为JSON格式,并且从中获取
message
属性,最后将其内容显示在oMessage
元素内。
总结
前端的HTML页面与后端的Node.js服务器代码配合工作,用户可以在界面上查看用户数据,输入问题,然后获取AI的回复。
项目运行效果展示
来到ai_server
文件夹的终端,运行main.js
来启动后端服务器。
打开项目的前端页面,输入指令:请问有哪些同学是老乡
后端在接收到用户给出的请求时,调用OpenAi的接口立马给出了问题的答案。
本篇文章就到此为止啦,希望通过这篇文章能对你了解使用OpenAI API 搭建AI助理
有所帮助,本人水平有限难免会有纰漏,欢迎大家指正。如觉得这篇文章对你有帮助的话,欢迎点赞收藏加关注,感谢支持🌹🌹。