以一个小demo了解AIGC全栈开发流程

引言

在这个充满创新和技术的时代,人工智能和大数据已经渗透到生活的方方面面。作为一名想要踏上AIGC全栈之路的小白,很多时候会感觉无从下手,不知道该如何开始。如果你也和我一样有这样的困惑,那么不妨来看看下面的小demo,也许能为你揭开AIGC全栈之路的神秘面纱。

项目介绍AI

今天我们通过一个小demo来聊聊如何通过openAI+JS+json-serve在传统前后端项目中搭载一个AI问答助理。 该项目涉及前端、后端和AI端的协作,主要介绍了三端的功能和合作流程。整体项目相对简单,具体包括:

  • 前端------负责页面展示和通过 Ajax 与后端和AI端进行交互。

  • 后端------使用 json-server 模拟数据库,提供接口给前端,处理数据存储与交互。

  • AI端------调用 OpenAI 接口,根据用户数据回答用户提出的问题,并将处理结果传递给前端展示给用户。

效果图:

准备工作

文件夹创建

创建一个新文件夹,并在这个文件夹下再创建3个子文件夹:ai_server(AI端)、backend(后端)、frontend(前端)。

初始化

分别进入ai_server(AI端)和 backend(后端)的终端 输入:

csharp 复制代码
npm init -y

将其初始化为后端项目。

成功后会出现package.json文件。

package.json项目配置文件,使用npm init -y 命令会自动在 Node.js 项目的根目录下创建一个新的package.json文件,并自动填充一些默认信息。这些默认信息包括项目的名称、版本、描述以及依赖项等。

前端

Bootstrap

Bootstrap 是一个流行的开源前端框架,用于开发响应式和移动设备优先的网站设计。它提供了一套用于快速开发界面的 CSS 和 JavaScript 组件,帮助开发者构建现代、响应式的网页设计。

使用 Bootstrap 非常简单,如果只需引入其 CSS 部分,只需要在 HTML 文件中添加以下代码:

html 复制代码
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

通过这一行代码,您就能够在项目中引入 Bootstrap 的 CSS 文件,从而利用其提供的样式和组件来快速构建出现代风格的界面。Bootstrap的使用使得页面设计和布局变得更加便捷和一致,有助于提升用户体验和整体视觉效果。

具体使用可以查看全局 CSS 样式 · Bootstrap v3 中文文档 | Bootstrap 中文网 (bootcss.com)

本项目也是采用bootstrap进行开发的。

HTML部分

从效果图可以看出,本项目的HTML结构非常简单,只由 标题+表格+表单组成。

html 复制代码
<div class="container">
    <div class="row col-md-6 col-md-offset-3">
        <!-- 标题 -->
        <h1>AI能力驱动的userData</h1>

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

        <!-- 表单 -->
        <div class="row">
            <form name="aiForm">
                <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>

        <!-- AI回答展示 -->
        <div class="row" id="message"></div>
    </div>
</div>

关键点:label(for) + input(id)

在前端开发中,label(for) + input(id)组合常用于创建表单标签与输入字段的关联,具有提高可访问性、用户体验和易用性的作用。这种做法使表单结构更清晰,允许灵活设计样式,同时符合HTML规范,有助于代码可维护性。通过在标签中设置for属性指向对应的input id (for与id一致) ,用户可以通过点击标签来聚焦对应的输入字段,从而改善用户体验和操作便捷性。

JS部分

这是前端最重要的部分,利用ajax与后端和AI端进行交互。

与后端联调------获取用户数据

这部分讲解与后端进行联调,并使用ajax与后端进行交互,获取用户数据,并将其渲染至页面中。

请求地址由后端提供,将在后端部分进行讲解。

js 复制代码
const oBody = document.querySelector("#user_table tbody");

let usersData = []; 

fetch('http://localhost:3000/users')
    .then(data => data.json())
    .then(users => {
        usersData = users;
        oBody.innerHTML = users.map(user => `
            <tr>
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>${user.hometown}</td>
            </tr>
        `).join("");
    })
  • document.querySelector("#user_table tbody") 用于选择包含用户数据的表格的 tbody 元素。
  • usersData存储后端返回用户数据,便于之后传递给AI端。
  • 通过 Fetch API 发起 GET 请求获取 http://localhost:3000/users 的数据。
  • 第一个 .then() 将响应转换为 JSON 格式。
  • 第二个 .then() 接收 JSON 格式的用户数据,将数据赋值给 usersData 变量,并通过将数据映射到 HTML 表格行的方式将用户数据渲染到网页上。
  • join("")将数组转化为以空字符连接字符串,如果不加,数组会发生隐式转换从而变成以逗号连接的字符串,如果对类型转换不熟悉的,可以看看我之前的文章面试官:[] == ![],返回什么?为什么? - 掘金 (juejin.cn)

与AI端联调------获取AI回答

这部分讲解与AI端进行联调,并使用ajax与AI端进行交互,传递用户问题以及用户数据,并获取openAI回答展示到页面上。

js 复制代码
const oMessage = document.querySelector("#message");
const oForm = document.forms['aiForm'];

oForm.addEventListener('submit', function (event) {
    // 阻止表单默认提交行为
    event.preventDefault();

    // 获取用户输入
    const question = this["question"].value.trim();
    // console.log(question);
    if (question) {
        fetch(`http://localhost:8888/users?question=${question}&users=${JSON.stringify(usersData)}`)
            .then(data => data.json())
            .then(res => {
                // console.log(res);
                document.querySelector("#message").innerHTML = res.message;
            })
    }
})

代码与上一部分大差不差不做过多解释。

后端 ------ 提供用户数据

本项目只是一个小demo,因此我们将借助json-server来实现一个虚拟的后端服务器环境,在此之前,先简单介绍一下json-server数据模拟库。

json-server 数据模拟库

json-server 是一个用于快速搭建基于 JSON 文件的 RESTful API 的工具,可以帮助开发者快速搭建一个模拟的后端服务器,用于开发和测试前端应用程序。使用 json-server 可以避免复杂的后端开发,特别适合快速原型开发或前后端分离开发。

以下是一些关于 json-server 数据模拟库的特点和基本用法:

  1. 快速搭建:通过简单的命令行操作和配置文件,即可搭建一个虚拟的 RESTful API 服务器。
  2. 基于 JSON 数据:利用 JSON 文件来模拟数据,并通过 RESTful 接口进行访问和操作。
  3. 支持路由:可以自定义路由规则,定义不同的 URL 对应不同的数据。
  4. 支持过滤和查询:可以使用一些参数进行数据的过滤和查询,方便前端开发调试。
  5. 内置中间件:支持一些内置中间件,如身份验证、请求日志等,可以满足基本的开发需求。

本项目就是使用json-server来快速搭建一个模拟的后端服务器。

搭建流程

1. 通过npm安装 json-server

在backend的终端中输入:

css 复制代码
npm i json-server

成功后package.json文件中dependencies会自动添加json-server依赖:

2. 创建JSON对象

创建一个users.json文件,存储json数据。

在users.json文件中放入以下内容:

json 复制代码
{
    "users": [
        {
            "id": 1,
            "name": "小旺车",
            "hometown": "丰城"
        },
        {
            "id": 2,
            "name": "肖战",
            "hometown": "重庆"
        },
        {
            "id": 3,
            "name": "郭文韬",
            "hometown": "青海"
        },
        {
            "id": 4,
            "name": "椰汁",
            "hometown": "上饶"
        },
        {
            "id": 5,
            "name": "积米者",
            "hometown": "潮汕"
        }
    ]
}

这部分就是你要传递给前端的用户数据。

json对象:

是一种轻量级的数据交换格式,基于JS对象的语法,但独立于任何编程语言,通常用于在客户端和服务器之间传输数据。

语法:使用键值对的形式表示数据,使用大括号 {} 表示对象,使用方括号 [] 表示数组,每个键值对之间使用逗号 , 分隔。

数据类型:支持字符串、数字、布尔值、数组、对象、以及 null 值作为数据类型。

3. 定义dev脚本

这个脚本是启动模拟的后端服务器的入口,后期想要从后端获取数据,请先启动该脚本。

将package.json文件中的scripts修改为以下样式:

json 复制代码
"scripts": {
    "dev": "json-server users.json"
},
  • scripts:用于定义各种命令脚本。
  • "dev": "json-server users.json":这一行代码定义了一个名为 dev 的脚本命令,执行时会启动 json-server 服务器并使用 users.json 文件作为数据源。

4. 启动dev脚本

你可以选择在终端输入:

arduino 复制代码
npm run dev 

或者直接点击scripts上的调试进行运行

运行成功后,控制台返回如下:

箭头所指也就是前端的fetch请求地址。

后端完成效果图

后端启动后,前端就可以获取到用户数据并展现到界面中。

AI端 ------ 提供AI服务

在开始AI端代码编写之前,我们要先来了解一下之后要使用的http模块url模块 以及dotenv模块

模块介绍

http模块

http模块提供了创建HTTP服务器和客户端的功能。通过它可以轻松地构建和处理HTTP服务端和客户端的请求和响应。

http模块的一些常见功能和用法:

  1. 创建HTTP服务器
  • 使用http.createServer()方法可以创建一个HTTP服务器。你可以传入一个回调函数,该函数在每次接收到请求时被调用。

  • 通过在回调函数中操作requestresponse对象,可以处理客户端发来的请求并发送响应。

  • request对象 :request对象代表客户端的HTTP请求,其中包含了客户端发送的所有信息,如请求头、请求体、请求参数等。通过request对象,可以访问和处理客户端请求的各种属性和数据。

    request对象中常用的属性和方法:

    • request.url:获取请求的URL路径。
    • request.metho:获取请求的HTTP方法(GET、POST等)。
    • request.headers:获取请求头信息。
    • request.params:获取请求中的参数(对应路由参数或查询参数)。
    • request.body:获取请求体的内容(在POST请求中常用)。
  • response对象 :response对象代表服务器向客户端发送的HTTP响应,通过response对象,可以设置响应的状态码、响应头和响应体,并向客户端发送数据。

    response对象中常用的属性和方法:

    • response.statusCode:设置响应的状态码。
    • response.setHeader():设置响应头信息。
    • response.write():向响应体中写入数据。
    • response.end():结束响应过程并发送响应给客户端。
  1. 监听端口
  • 使用server.listen()方法可以让HTTP服务器监听指定的端口,以便接受客户端的请求。
  1. HTTP客户端
  • 除了创建服务器,http模块还可以作为HTTP客户端发送HTTP请求到其他服务器。
  • 通过http.request()方法可以向其他服务器发送GET或POST请求,并处理返回的响应数据。
  1. 处理请求事件
  • HTTP服务器提供了一系列事件,如request事件,当服务器接收到一个请求时就会触发该事件。
  • 还有connection事件、close事件等,可以让你在不同的情况下执行相应的逻辑。

通过使用http模块,可以方便地构建各种类型的HTTP服务器、客户端,并进行HTTP请求和响应的处理。

url模块

url模块用于处理URL字符串的解析、格式化以及操作。该模块提供了一系列方法,使开发者能够方便地处理URL相关的操作,如解析URL、构建URL、提取URL的各个部分等。

url模块常用方法和功能:

  1. 解析URL字符串
  • 使用url.parse()方法可以将URL字符串解析为一个URL对象,包含了URL的各个组成部分,如协议、主机、路径、查询参数等。
  1. 构建URL字符串
  • 使用url.format()方法可以根据传入的URL对象构建一个URL字符串。
  1. 处理相对路径
  • 使用url.resolve()方法可以用于解析相对路径,返回一个完整的URL字符串。
  1. URL对象操作
  • url模块还提供了其他方法,如url.resolveObject()用于解析URL对象,url.resolve()用于处理URL的路径解析。

通过使用url模块,可以轻松地解析、构建和操作URL,这在Web开发和服务器编程中非常有用。通过url模块,你能够处理URL的各个部分,从而更好地控制和管理URL相关的操作,使得处理URL变得更加便捷和高效。

dotenv模块

dotenv模块 用于加载环境变量和从.env文件中读取配置。在开发Node.js应用程序时,通常需要存储敏感信息或配置参数,如API密钥、数据库连接字符串等。

dotenv模块允许你从一个名为.env的文件中加载这些配置,使得管理环境变量和配置变得更加简单和安全。

AI端代码编写

代码流程

总体来说,AI端代码以以下流程进行:

  1. 创建HTTP服务器,并为CORS设置响应头,并且处理跨域问题。
  2. 处理特定路径的API请求,通过URL解析查询参数。
  3. 构建请求提示内容,并调用OpenAI的API生成回答。
  4. 将生成的回答作为JSON响应发送回客户端。
  5. 启动服务器,监听8888端口。

1. 安装openai和dotenv包

在ai_server的终端中输入:

npm i openai

npm i dotenv

2. 创建main.js文件(主文件)和.env(存放openai key)文件

.env文件 中存入openai Key,格式为:

OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxx

放入你自己的openai Key

可以通过chatanywhere/GPT_API_free: Free ChatGPT API Key,免费ChatGPT API,支持GPT4 API(免费),ChatGPT国内可用免费转发API,直连无需代理。可以搭配ChatBox等软件/插件使用,极大降低接口使用成本。国内即可无限制畅快聊天。 (github.com),点击箭头所指位置获取免费openai Key.

3. 引入相关包

在main.js中引入相关包

js 复制代码
const http = require('http');
const url = require('url');
const Openai = require('openai');
require('dotenv').config();
  1. http模块用于在 Node.js 中创建 HTTP 服务器。
  2. url模块用于 URL 的解析和格式化,获取前端传入的问题和用户数据。
  3. openai: openai库。
  4. require('dotenv').config(): dotenv 模块用于将环境变量从 .env 文件中openai Key加载到 process.env 中。

4. 构建HTTP服务器

使用http.createServer方法创建一个HTTP服务器:

js 复制代码
const server = http.createServer(async function (req, res) {
    ...
})

req -- request, HTTP请求对象

res -- response, HTTP响应对象

5. 设置CORS头

因为该项目前端(5500)、后端(3000)、AI端(8888)的端口号不同,所以我们需要设置必要的CORS(跨源资源共享)头,以便允许不同来源的请求:

js 复制代码
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); 
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  • res.setHeader('Access-Control-Allow-Origin', '*');:设置允许访问的来源,使用通配符 * 表示允许所有来源访问。
  • res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');:指定在请求中允许的方法, GET、POST 和 OPTIONS。
  • res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');:指定在请求中允许的头部信息, Content-Type 和 Authorization。

6. 处理请求并解析URL及其查询参数

js 复制代码
if (req.url.indexOf('/users') !== -1) {
    const parsedUrl = url.parse(req.url, true);
    const { question, users } = parsedUrl.query; 
}
  • if (req.url.indexOf('/users') !== -1) :检查请求的URL中是否包含'/users'。如果请求的URL中包含'/users',则条件成立,表示客户端正在请求与用户相关的信息。
  • const parsedUrl = url.parse(req.url, true); :使用url.parse()方法将请求的URL字符串解析为一个URL对象。这个方法可以将URL分解为各个部分,如协议、主机、路径、查询参数等。
  • const { question, users } = parsedUrl.query; :通过解构赋值 ,从parsedUrl.query对象中提取出questionusers属性的值。这些值是前端通过URL查询字符串传递到服务器端的数据,例如'/users?question=example&users=xxx'中的查询参数。

7. 实例化openai

实例化openai,同时,设置了一个包含 OpenAI API 密钥的授权标头以及proxy 代理

js 复制代码
const client = new Openai({
    // 使用权限
    apiKey: process.env.OPENAI_API_KEY,
    // proxy 代理
    baseURL: 'https://api.chatanywhere.tech/v1'
});

8. 构建prompt

根据用户数据和问题构建提示信息:

js 复制代码
const prompt = ` 
    ${users} 
    请根据以上用户的json数据,回答${question}这个问题。
    如果回答不了,就返回不清楚,不要凭空捏造。
`

构建prompt的过程就是设计一段文本,其中包含了问题、说明、情境或要求等信息,以引导模型生成期望的文本回复。通过精心构建prompt,可以控制模型输出的内容,使其更贴近需求。

9. 调用OpenAI API

使用OpenAI的API调用gpt-3.5-turbo模型生成回答:

js 复制代码
const response = await client.chat.completions.create({
    // model 模型 gpt-3.5-turbo
    model: 'gpt-3.5-turbo',
    
    messages: [{ role: "user", content: prompt }],
    temperature: 0, // 控制输出的随机性,0表示更确定的输出
});
// 提取响应结果
const result = response.choices[0].message.content || '';
  • const response = await client.chat.completions.create({...}) :这行代码使用OpenAI API的create方法异步生成回复。client.chat.completions是创建对话完成请求的接口。

  • 模型选择和设置:指定使用的模型为gpt-3.5-turbo

  • messages: [{ role: "user", content: prompt }],使用角色 user 用户向openai提问,content 为上面构建的prompt,包括提问和用户数据。

  • temperature: 0,temperature参数控制生成的随机性。值越低(接近0),输出越确定和一致;值越高(接近1),输出越随机。

  • const result = response.choices[0].message.content || ''从响应对象中提取生成的文本内容。response.choices[0]openai会返回多个回答,选择第一个。response.choices[0].message.content。使用|| ''来防止content为null或undefined的情况。

10. 发送响应

创建包含结果的JSON对象并发送给前端:

js 复制代码
let info = { 
message: result 
} ;
// 设置HTTP响应的状态码为200,表示成功。
res.statusCode = 200; 

// 设置响应头部的Content-Type为text/json,表明响应内容是JSON格式的数据。
res.setHeader('Content-Type', 'text/json'); 

// `info`对象转换为JSON字符串,并通过res.end返回
res.end(JSON.stringify(info));

11. 启动服务器

服务器开始监听8888端口(可以自定义端口号),前端请求时也使用该端口号进行访问.

js 复制代码
server.listen(8888, () => { console.log('server is running'); });

项目运行

  1. 运行后端

在backend终端输入 npm run dev运行

  1. 运行AI端

在backend终端输入 node node .\main.js运行

  1. 运行前端

输入问题点击提交就会显示openai的回答。

总结

虽然这只是个小demo,希望这个小demo能为你开启AIGC全栈之路带来一丝启发和帮助,让我们一起在这个充满技术魅力的领域里探索未知!如果你觉得这篇文章有帮助或有所启发,别忘了给我一个鼓励的

源码仓库地址: fullstack/ai_user · WYX0831/WYX_fullstack_ai - 码云 - 开源中国 (gitee.com)

相关推荐
liruiqiang0511 分钟前
机器学习 - 衡量模型的特性
人工智能·机器学习
m0_7482486516 分钟前
SpringBoot整合easy-es
spring boot·后端·elasticsearch
thinkMoreAndDoMore21 分钟前
深度学习(3)-TensorFlow入门(梯度带)
人工智能·深度学习·tensorflow
Dream251227 分钟前
【Transformer架构】
人工智能·深度学习·transformer
我命由我1234528 分钟前
微信小程序 - 自定义实现分页功能
前端·微信小程序·小程序·前端框架·html·html5·js
黎智程28 分钟前
AI助力小微企业技术开发规范化管理 | 杂谈
人工智能
一个热爱生活的普通人35 分钟前
golang的切片(Slice)底层实现解析
后端·go
红目香薰44 分钟前
Trae——慧码速造——完整项目开发体验
后端
web150854159351 小时前
超级详细Spring AI运用Ollama大模型
人工智能·windows·spring
啊哈哈哈哈哈啊哈哈1 小时前
J4打卡—— ResNet 和 DenseNet结合实现鸟类分类
人工智能·pytorch·分类