AI项目实战|SpringBoot3+SpringAI+Uniapp
前言
AI不仅仅是风口,也是今后的时代潮流。本人花心血开发了一套AI实战项目,可商用。支持h5,小程序,app三端。可拿来二开,也可直接上架。不用担心版权问题,但是如果是倒卖源码,本人会追究其责任。
如果你是大学生,也可以抓住这个机会学习AI,源码并不难,都是java那一套。本人也会提供免费学习指导。
一. 详细功能
- 支持文本流失对话(流失)+ 图片生成。
- 支持用户创建自己的智能体。
- 支持动态添加应用,只需简单配置就能生成一个新的AI应用,无需任何代码编写。
- 动态调优应用的prompt提示词,历史对话轮数,System Role等大模型属性。
- 内置应用的提示词都是大厂优化的提示词,有相当高的参考价值。
- 支持用户自己切换大模型,可以任意切换成qwen,gpt4,coze等大模型厂商。
- 支持插件模式。动态对接新的大模型API(无需重启应用就可以新增一个大模型api的对接)
- 动态修改大模型属性:base-url和token
- 支持用户会员模式(包月)+ 非会员模式
- 实现了邮箱验证码登录
应用部分截图

视频演示功能
https://www.bilibili.com/video/BV1Hxvee2EUV/?vd_source=a91cfe3968c9698064bbfde47fb2a2cb
二. 技术架构
前台
- uniapp
- websocket
后台
- SpringBoot3.3.0
- 大模型底座: SpringAI + 通义千问 + Coze
- JDK17
- Sa Token
- Websocket
- MyBatisPlus+MySQL
三. 数据库表
四. 代码搭建步骤
用mysql新建一个数据库ai-waiter,然后执行语句:ai-waiter.sql。
修改application.yml配置
主要是修改邮箱服务器信息和数据库地址信息。
然后启动main函数:AiWaiterAppApplication
项目会监听两个协议,http协议+ws协议,端口都是 8999。
前端启动直接用Hbuilder导入项目,然后编译运行即可。
注意: 初始化的大模型只有3.5,需要增加4的token的可以联系小编。
五. 主要技术点讲解(开发人员)
插件开发
背景: 市面上有很多种大模型api。比如:openai,千问api,扣子api,讯飞星火等, 插件开发就是为了更好的分离对接代码,以及做到 不重启服务 就可以实现对接各大厂商api。
系统内置插件 OpenAIModelPlugin
系统源代码内置了一个SpringAI实现的插件: com. aiwaiter. openai. plugins. sys.OpenAIModelPlugin
public class OpenAIModelPlugin extends AbstractAIModelPlugin {
@Override
public void streamcall(Configure configure) {
System.out.println("请求 openai-AI>> " + configure);
OpenAiApi api = new OpenAiApi(configure.getBaseUrl(), configure.getToken());
OpenAiChatOptions options = OpenAiChatOptions.builder().withModel(configure.getModel()).withTemperature(0.7f) //温度系数
.build();
ChatModel myChatModel = new OpenAiChatModel(api, options);
ChatClient.Builder builder = ChatClient.builder(myChatModel);
builder.defaultSystem(configure.getRole());
ChatClient chatClient = builder.build();
// 构建用户消息
String curmsg = getUserText(configure);
List<Message> messages = new ArrayList<>();
if(!CollectionUtils.isEmpty(configure.getHistory())){
// 添加历史消息
for(DTO.History his : configure.getHistory()){
if(!StringUtils.isEmpty(his.getBotContent())){
messages.add(new AssistantMessage(his.getBotContent()));
continue;
}
messages.add(new UserMessage(his.getUserContent()));
}
}
messages.add(new UserMessage(curmsg)) ;
Flux<ChatResponse> stream = chatClient.prompt().messages(messages).stream().chatResponse();
stream.toStream().forEach(response -> {
response.getResults().forEach(item -> {
AssistantMessage output = item.getOutput();
boolean finish = false;
if (output.getMetadata().containsKey(