Spring Ai 从Demo到搭建套壳项目(一)初识与实现与deepseek对话模式
前言
为什么说Java长青,主要是因为其生态圈完善,Spring又做了一款脚手架,把对接各个LLM厂商的sdk做了一遍,形成一系列的spring-ai-starter-** 的依赖。 目前为止版本去到1.0.0.M6,golang跟不上了吧, Make Java Greate Again!!
我打算这个系列介绍这个spring-ai-starter和各个LLM的关系,介绍实际操作,演示一下官网的一些关键点和没讲到的细节,还有后续会讲如何使用spring-ai搭建一个套壳项目(啥是套壳项目下一章会讲),从后端,到spring-ai对接,到前端的制作。比较希望大家已经对LLM有些基础的理解。
一、技术框架
如果没有框架,你需要做什么?
- 你要自己写http调用代码,来分别对各个LLM模型接口(或者SDK,例如https://api-docs.deepseek.com/zh-cn/api/create-chat-completion/) 的请求,等待他结果的返回,解析响应。spring-ai就同一个了接口。
- 还有支持Advisor,就像面向切面那样,发送请求前,检查文本有没有命中禁用词,就例如企业不允许把代码透露出去,也不允许使用某些黑词,就可以这里检查。
- 还有支持MCP调用能力,如果不对接spring-ai,你就要自己实现MCP协议的调用代码,来达到调用别的服务。例如:后续会实现的使用高德地图mcp,得到高德查看坐标工具,交通工具,路线规划工具,天气工具。
- 支持会话跟踪,如果你不接spring-ai,你还需要自己记录会话到表,或者让前端把说过的话,一次过传给后端,后端再告诉ai来做context上下文跟踪。
- RAG检索增强,可以通过他告诉ai又额外的一套文本,让某个LLM分析这个文本,得到你想要的答案。我觉得这个点可以用于客服话术,先拟定好话术,通过RAG解析话术的文本,当用户跟ai对话的时候,附带这个解析后的spring-ai的Document类对象,得到话术的结果。例如:设定话术用户发送一串数字,就回复“这个订单有什么问题?”
那目前市面上有什么框架呢?
- 目前看到的java相关的有org.springframework.ai这个group下的
spring-ai-starter-**
这个前缀的依赖。其后缀包括open-ai, aliyun , deepseek, anthropic等,他就是整合了对多个LLM厂商的接口,统一封装,底层还是调用各个LLM厂商的SDK。
那为什么spring要封装呢?其实你看名字叫starter就知道了,一般叫starter的都是脚手架,就如springcloud,springboot那样,通过yml或者properties的配置,来实现自动装配,生成一个springbean,
方便你去调用。
spring:
ai:
openai:
api-key: ${你的key}
base-url: ${请求openai的地址}
deepseek:
api-key: ${你的key}
base-url: "https://api.deepseek.com"
chat:
options:
model: deepseek-chat
如这里就固定了层级格式,让你填写地址和key就可以了。
- 还有alibaba提供的框架,他基于上面这个依赖做的封装,这种就是套壳。
大家有没有发现上面代码需要对每个大预言模型都生成分别的api-key,所以就有人就想自己做一个统一的使用各个LLM地方,就如Cursor、Pandora,你看这些软件上,可以访问各个LLM的模型而不用对各个模型分别付费,这种统一地方的软件就是给钱包月或者按次数买1个apikey,就可以用各个LLM模型了
所以spring-ai-alibaba-stater-**系列,也是要去阿里百炼(旧名灵积)上生成一个key,就可以去使用不同的模型的一款套壳框架(https://bailian.console.aliyun.com/), 现在也是免费的,但他可以给你免费使用这么多个LLM也是有成本的,以后还是得收费。
二、现在就演示一下,如何对接spring-ai,并使用deepseek模型进行对话
当前先了解spring-ai这个基础框架,第三章再来演示如何对接spring-ai-alibaba版的。因为spring-ai-alibaba现在免费,你当前可以基于这个套壳框架,再套壳后,给商用起来,但是当alibaba开始收费,你又要对接各个厂商了,而且某些公司还不能用alibaba的api-key,所以spring-ai这个基础框架还是要了解的。
建立maven 工程
引入依赖,一定要使用jdk 17 ,因为springboot已经3了
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>3.3.4</version>
</dependency>
</dependencies>
spring-boot-starter-webflux这个东西就是响应式接口的关键,没有他,就没有持续输出文字的效果 spring-ai-starter-model-deepseek 这个就是spring对deepseek的封装。
配置application.xml
server:
port: 8081
spring:
application:
name: spring-ai-deepseek-chat-model-example
ai:
deepseek: ## 这一行是你选择的LLM模型,如果是openai,这里就填openai, base-url就是填对应厂商的地址
api-key: ${你申请的apikey}
base-url: "https://api.deepseek.com"
chat:
options:
model: deepseek-chat
embedding:
enabled: false
创建主类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
创建Controller
@RequestMapping("/openai")
@ResponseBody
@Controller
public class DeepSeekChatModelController {
private final ChatModel deepSeekChatModel;
// 主要就是这个地方,springboot已经把yml里的配置,生成好一个叫ChatModel的bean,注入进来controller里就可以直接使用了
public DeepSeekChatModelController(ChatModel chatModel) {
this.deepSeekChatModel = chatModel;
}
// 这个是同步等待LLM的结果,再回复给前端。
@GetMapping("/simple/chat/{prompt}")
public String simpleChat (@PathVariable(value = "prompt") String prompt) {
return deepSeekChatModel.call(new Prompt(prompt)).getResult().getOutput().getText();
}
/**
* Stream 流式调用。可以使大模型的输出信息实现打字机效果。
* 这个就是sse方式回复内容给前端,就不用等所有的内容都收到才给前端
* @return Flux<String> types.
*/
@GetMapping("/stream/chat/{prompt}")
public Flux<String> streamChat (@PathVariable(value = "prompt") String prompt,HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
Flux<ChatResponse> stream = deepSeekChatModel.stream(new Prompt(prompt));
return stream.map(resp -> resp.getResult().getOutput().getText());
}
}
实验结果
通过请求与deepseek对话,用localhost:8081/openai/simple/chat/或者localhost:8081/openai/stream/chat/ 两个接口都是可以的。
三、 但是大家有没有发现,拿不到实时数据,而是只教你怎么去拿实时数据
因为deepseek只是一个文本类搜索和推荐的工具,他的数据是一年以前的搜索库里的数据,不是最新的。
那么要如何获取最新的数据呢?请看下一章。
公————地藏思维
Spring Ai 从Demo到搭建套壳项目(一)初识与实现与deepseek对话模式的更多相关文章
- Spring+SpringMvc+Mybatis框架集成搭建教程一(项目创建)
一.框架搭建环境 Spring 4.2.6.RELEASE SpringMvc 4.2.6.RELEASE Mybatis 3.2.8 Maven 3.3.9 Jdk 1.7 Idea 15.04 二 ...
- Spring+SpringMvc+Mybatis框架集成搭建教程四(项目部署及测试)
在IDEA中将项目部署到本地Tomcat下进行运行并验证整合结果 (1).点击如下图所示的下拉按钮,弹出Edit Configurations...后点击该项. (2).跳出如下界面后,点击红框内的& ...
- Spring Boot(一):环境搭建,建立简单项目
一.基本环境搭建 1.下载IntelliJ IDEA :http://www.jetbrains.com/idea/ 2.拖到页面最下面下载旗舰版 3.新建项目 4.设置本地Maven 5.删除多于文 ...
- Spring+SpringMvc+Mybatis框架集成搭建教程五(项目源码发布到GitHub)
一.背景 我们做完了上面的四步操作以后,来把我们写好的项目提交到自己的GitHub仓库进行版本管理,具体步骤如下. 二.提交步骤 1.首先你要保证你已经有GitHub的账号和密码(没有可以去githu ...
- Spring+SpringMvc+Mybatis框架集成搭建教程
一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以在自己搭建SSM框架集成的时候,出现了这样或者那样的问题,很是苦恼 ...
- mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(附demo和搭建过程遇到的问题解决方法)
文章介绍结构一览 一.使用maven创建web项目 1.新建maven项目 2.修改jre版本 3.修改Project Facts,生成WebContent文件夾 4.将WebContent下的两个文 ...
- SSM(Spring+SpringMVC+Mybatis)框架搭建详细教程【附源代码Demo】
[前言] 应某网络友人邀约,需要一个SSM框架的Demo作为基础学习资料,于是乎,就有了本文.一个从零开始的SSM框架Demo对一个新手来说,是非常重要的,可大大减少在学习过程中遇到的各种各样的坑,说 ...
- Spring Cloud Eureka Server集群Demo级搭建
将上篇随笔Spring Cloud Eureka服务Demo级搭建进行改造,改造成一个在本机的伪集群 1.修改hosts文件(windows10 hosts文件位置:C:\Windows\System ...
- Spring Security OAuth2 Demo
Spring Security OAuth2 Demo 项目使用的是MySql存储, 需要先创建以下表结构: CREATE SCHEMA IF NOT EXISTS `alan-oauth` DEFA ...
- Intellij IDEA采用Maven+Spring MVC+Hibernate的架构搭建一个java web项目
原文:Java web 项目搭建 Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring ...
随机推荐
- 在 Hugging Face 上部署语音转语音模型
介绍 S2S (语音到语音) 是 Hugging Face 社区内存在的一个令人兴奋的新项目,它结合了多种先进的模型,创造出几乎天衣无缝的体验: 你输入语音,系统会用合成的声音进行回复. 该项目利用 ...
- GitFlow ⼯作流
前言 Git 是一个开源分布式版本控制系统,它可以很方便的帮我们记录文件的改动,就像下面一样: 我们可以很快的跳到文件改动的某一个版本(就像时空穿梭一样). Git 在程序开发中,作为一个源码管理系统 ...
- phpstorm、goland常用快捷键
1) 文件操作相关的快捷键 快捷键 作用 Ctrl + E 打开最近浏览过的文件 Ctrl + N 快速打开某个 struct 结构体所在的文件 Ctrl + Shift + N 快速打开文件 Shi ...
- NumPy学习10
今天学习了3节: 18, NumPy副本和视图 19, NumPy字节交换 20, NumPy Matrix矩阵库 numpy_test10.py : import numpy as np ''' 1 ...
- Netty源码—7.ByteBuf原理二
大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.Byte ...
- 开发app步骤总结
以下是用IDEA后端Java开发(如Spring Boot)与Android Studio前端开发app的逻辑实现步骤详解: 一.技术选择 通信协议:推荐使用RESTful API(HTTP/HTTP ...
- C# 调用 Win10/11 文件关联对话框
方法一:调用未公开接口 IOpenWithLauncher Adobe Acrobat 应该是调用的未公开接口方法 [ComImport] [InterfaceType(ComInterfaceTyp ...
- AI工具推荐:使用AnythingLLM帮助你学习
AnythingLLM介绍 AnythingLLM 是一个最容易使用的全能 AI 应用,可以进行 RAG.AI 代理等多种功能,无需编写代码或担心基础设施问题. GitHub地址:https://gi ...
- zk源码—4.会话的实现原理
大纲 1.创建会话 (1)客户端的会话状态 (2)服务端的会话创建 (3)会话ID的初始化实现 (4)设置的会话超时时间没生效的原因 2.分桶策略和会话管理 (1)分桶策略和过期队列 (2)会话激活 ...
- Mono与IL2CPP
Mono: Mono是.NET Framework 的一种开源实现. Mono项目将使开发者用各种语言(C#,VB.NET等)开发的.NET应用程序,能在任何Mono支持的平台上运行, 包括Linux ...