当前位置: 首页 > news >正文

Spring AI 的应用和开发

什么是Spring AI

官网Spring AI

        spring AI 是spring官方推出的集成框架,让spring Boot的开发者可以更好的调用大语言模型进行开发。常见的大模型(deepseek,chatGpt、Ollama、Azure OpenAI、阿里通义千问、百度文心一言 等)

什么是模型:在人工智能中,模型就是一个经过训练的数学函数,换句话说模型就是AI的大脑

什么是提示词:提示词是用户或者系统提供给大模型的指令或文本,用于引导模型进行特定的输出

Spring AI的应用与开发

环境的要求

JDK:最低要求是JDK17+

SpringBoot:最低要求是Spring Boot 3.2+

接入DeepSeek

我们需要在DeepSeek的官网上申请DeepSeek API Keys

DeepSeek API文档:

我们来使用一下

首先创建一个项目

通过<dependencyManagement>导入到BOM到项目中

<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M6</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

引入依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0-M6</version></dependency>

创建启动类

@SpringBootApplication
public class SpringAiApplication {public static void main(String[] args) {SpringApplication.run(SpringAiApplication.class,args);}
}

配置好application.yml中的API密钥

spring:application:name: spring-aiai:openai:
#      deepSeekapi-key: 写自己的api keybase-url: https://api.deepseek.comchat:options:model: deepseek-chattemperature: 0.7

Spring AI已经集成了OpenAI的API,因此我们不需要实现向OpenAI发送请求和接收响应的交互程序了, Spring AI已经实现了这⼀内容,我们只需要通过调⽤SpringAI为我们提供的接⼝即可

@RequestMapping("/ai")
@RestController
public class DeepSeekController {@Autowiredprivate OpenAiChatModel openAiChatModel;@RequestMapping("/chat")public String chat(String message){return openAiChatModel.call(message);}
}

自己整了一个前端的AI框框,可以更好的观察和调试,需要的可以借用

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>AI Chat Demo</title><script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white shadow-xl rounded-2xl w-full max-w-2xl p-6"><h1 class="text-2xl font-bold text-center text-blue-600 mb-4">AI Chat 聊天界面</h1><!-- 输入框 --><div class="flex gap-2 mb-4"><input id="userInput"type="text"placeholder="请输入你的问题..."class="flex-grow border rounded-xl p-2 focus:outline-none focus:ring-2 focus:ring-blue-400"><button onclick="sendMessage()"class="bg-blue-500 text-white px-4 py-2 rounded-xl hover:bg-blue-600 transition">发送</button></div><!-- 聊天显示区域 --><div id="chatBox" class="h-96 overflow-y-auto border rounded-xl p-3 bg-gray-50 space-y-3"><!-- 聊天内容会追加到这里 --></div>
</div><script>async function sendMessage() {const input = document.getElementById("userInput");const chatBox = document.getElementById("chatBox");const message = input.value.trim();if (!message) return;// 显示用户消息const userMsg = document.createElement("div");userMsg.className = "text-right";userMsg.innerHTML = `<span class="inline-block bg-blue-500 text-white px-3 py-2 rounded-xl">${message}</span>`;chatBox.appendChild(userMsg);chatBox.scrollTop = chatBox.scrollHeight;input.value = "";try {// 调用后端接口const response = await fetch(`/ai/chat?message=${encodeURIComponent(message)}`);const text = await response.text();// 显示 AI 回复const aiMsg = document.createElement("div");aiMsg.className = "text-left";aiMsg.innerHTML = `<span class="inline-block bg-gray-200 px-3 py-2 rounded-xl">${text}</span>`;chatBox.appendChild(aiMsg);chatBox.scrollTop = chatBox.scrollHeight;} catch (err) {alert("请求出错: " + err);}}// 回车键发送消息document.getElementById("userInput").addEventListener("keydown", e => {if (e.key === "Enter") sendMessage();});</script>
</body>
</html>

我们来访问,调用成功了

接入ChatGpt

ChatGPT是OpenAI开发并发布的核⼼产品之⼀,如果要使用ChatGpt,我们需要《科学上网》,创建好ChatGPT的账号后,创建API Keys

添加其依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency>

配置API密钥

spring:ai:openai:api-key: your-api-keys

调用接口

@RequestMapping("/ai")
@RestController
public class ChatGptController {@Autowiredprivate OpenAiChatModel openAiChatModel;@RequestMapping("/chat2")public String chat2(String message){return openAiChatModel.call(message);}
}

Spring AI-聊天模型

在Spring AI框架中,ChatModel和ChatClient构建对话式AI的两大核心接口

ChatClient

ChatClient是对ChatModel封装后更高级的API接口

ChatClient的使用

创建ChatClient然后注入使用

@RequestMapping("/chat")
@RestController
public class ChatClientController {@Autowiredprivate ChatClient chatClient;@GetMapping("/call")public String generation(String userInput) {return this.chatClient.prompt().user(userInput)//请求⼤模型.advisors(new SimpleLoggerAdvisor())//设置单个对话的advisor.call()//返回⽂本.content();}
}

我们也可以为AI设定角色预设

通过defaultSystem来配置系统角色

@Configuration
public class ChatClientConfiguration {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder) {return chatClientBuilder.defaultSystem("你的名字叫小瑞,你是一个全能助手").defaultAdvisors(new SimpleLoggerAdvisor())//设置全局的advisor.build();}
}

结构化输出

如果你想从AI大模型接收结构化输出,Spring AI支持将ChatModel/ChatClient方法的返回类型从String更改成其他的类型

生成一份菜单

record Recipe(String dishName, List<String> ingredients){}@GetMapping("/entity")public String entity(String userPut){Recipe recipe=this.chatClient.prompt().user(String.format("请帮我生成%s的食谱",userPut)).call().entity(Recipe.class);return recipe.toString();}

实现流式输出

使⽤ ChatClient 的 stream() ⽅法⽣成实现 Flux<String> 流

就是一点一点输出,不是等待加载完后整体输出

@GetMapping(value = "/stream", produces = "text/html;charset=utf-8")public Flux<String> stream(String userPut){return this.chatClient.prompt().user(userPut).stream().content();}

打印日志

Spring AI借用Advisors来实现日志的打印功能的

Spring AI 内置了⼀些Advisor, SimpleLoggerAdvisor 就在其中, 主要功能是记录⽇志

设置日志的级别

logging:level:root: info                          # 全局默认日志级别org.springframework.ai.chat.client.advisor: debug  # 只针对 Spring AI 的 advisor

流式编程

SSE协议

Http协议本身设计为无状态的请求-响应模式,是无法做到服务器主动发送消息给客户端,但是通过SSE技术可以实现流式编程,允许服务器向浏览器推送数据流,也就是说,服务器向客⼾端声明,接下来要发送的是流消息(streaming),这时客⼾端不会关闭连接,会⼀ 直等待服务器发送过来新的数据流。

数据格式

数据格式是 纯文本格式

SSE 数据是 一行一行的文本,以 \n(换行符) 分隔,每条事件之间用 空行 分隔。

@RestController
@RequestMapping("/sse")
public class SseController {@RequestMapping("/data")public void data(HttpServletResponse response) throws IOException, InterruptedException {response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 20; i++) {String s="data:" + new Date() +"\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}}
}

浏览器端 JS可以这样接收

 // 创建 EventSource 对象,指向你的 SSE 接口const evtSource = new EventSource("/sse/data");// 当接收到消息时触发evtSource.onmessage = function(e) {console.log("收到消息:", e.data);

注:SSE必须是单向,消息必须以 \n\n 结尾,浏览器会自动在连接断开时尝试重连

使用Flux更优雅的实现SSE协议

public class FluxTest {public static void main(String[] args) throws InterruptedException {Flux<String> flux=Flux.just("apple","banana","pear").delayElements(Duration.ofSeconds(1));flux.map(String::toUpperCase).subscribe(System.out::println);Thread.sleep(5000);}
}

ChatModel

是Sping AI中的核心接口

简单对话的实现

@RequestMapping("/ai")
@RestController
public class DeepSeekController {@Autowiredprivate OpenAiChatModel openAiChatModel;@RequestMapping("/chat")public String chat(String message){return openAiChatModel.call(message);}
}

chatModel中的Prompt,通常指的是输入给模型的提示词/上下文信息

 @RequestMapping("/chatByPrompt")public String chatByPrompt(String message){Prompt prompt=new Prompt(message);ChatResponse call = openAiChatModel.call(prompt);return call.getResult().getOutput().getText();}

角色预设

@RequestMapping("/roleChat")public String roleChat(String message){SystemMessage systemMessage=new SystemMessage("你的名字叫小瑞,你是一个智能的电脑管家助手");UserMessage userMessage=new UserMessage(message);Prompt prompt=new Prompt(systemMessage,userMessage);ChatResponse call = openAiChatModel.call(prompt);return call.getResult().getOutput().getText();}

流式输出

 @RequestMapping(value = "/streamChat",produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamChat(String message){Prompt prompt=new Prompt(message);return openAiChatModel.stream(prompt).map(x->x.getResults().get(0).getOutput().getText());}

ChatClient 和ChatModel的区别

ChatModel是SpringAI框架中的底层接⼝,直接与具体的⼤语⾔模型交互,提供了简单的call和stream方法,开发者需要手动处理提示词组装其中的细节,使用上灵活,ChatClient对ChatModel进⾏了封装,不需要开发者手动处理其中的细节,提高了开发的效率。

本地部署大模型

我们使用ollama进行本地的部署

我们需要在ollama的官网上 Ollama 下载ollama,安装后,ollama会默认启动

拉取模型deepseek-r1

ollama的使用

引入ollama 的依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId></dependency>

配置application.yml

server:port: 8081
spring:application:name: spring-ollama-demoai:ollama:base-url: http://127.0.0.1:11434chat:model: deepseek-r1:1.5b

简单的对话

@RequestMapping("/ollama")
@RestController
public class OllamaController {@Autowiredprivate OllamaChatModel ollamaChatModel;@RequestMapping("/Call")public String Call(String message){return ollamaChatModel.call(message);}@RequestMapping("/stream")public String stream(String message){return ollamaChatModel.stream(new Prompt(message)).toString();}
}

将其封装成ChatClient

@Configuration
public class ChatClientConfiguration {@Beanpublic ChatClient chatClient(OllamaChatModel chatModel){return ChatClient.builder(chatModel).defaultAdvisors(new SimpleLoggerAdvisor()).defaultSystem("你的名字是小瑞").build();}
}

Spring AI Alibaba

Spring AI Alibaba 开源项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。

申请阿⾥云百炼平台API-KEY大模型服务平台百炼控制台

获得API-KEY

在项目中引入依赖

<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency>

配置.yml

server:port: 8082
spring:application:name: spring-alibaba-demoai:dashscope:api-key: 你的API-KEYchat:options:model: qwen-vl-max-latest #模型名称multi-model: true #是否启⽤多模型

实现简单的对话

@RestController
@RequestMapping("/alibaba")
public class AlibabaController {private final ChatClient chatClient;public AlibabaController(ChatClient chatClient) {this.chatClient = chatClient;}@RequestMapping("/call")public String call(String message){return chatClient.prompt(message).call().content();}@RequestMapping("/stream")public Flux<String> stream(String message){return chatClient.prompt(message).stream().content();}
}

设置默认的系统信息

@BeanChatClient chatClient1(ChatClient.Builder builder){return builder.defaultSystem("你是名字是小瑞").build();}

也可以在创建ChatClient的时候,在调用前修改请求的参数

@BeanChatClient chatClient(ChatClient.Builder builder) {return builder.defaultSystem(" 请你给我回答问题时, 前⾯带⼀个 {word}").build();}
@GetMapping("/chat")public String chat(String message, String words) {return chatClient.prompt(message).system(sp->sp.param("word", words)).call().content();}

多模态

多模态性指模型同时理解和处理⽂本、图像、⾳频及其他数据格式等多源信息的能⼒

我们借助Spring AI Alibaba来实现多模态

<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.0.0.2</version>
</dependency>

记得在.yml文件中添加,开启多模态

    chat:options:model: qwen-vl-max-latest #模型名称multi-model: true #是否启⽤多模型

通过上传图片,让AI进行分析

@RestController
@RequestMapping("/multi")
public class ImageController {private final ChatClient chatClient;public ImageController(ChatClient chatClient) {this.chatClient = chatClient;}@GetMapping("/image")public String image(String message) throws Exception {String url = "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg";List<Media> mediaList = List.of(new Media(MimeTypeUtils.IMAGE_JPEG, new URI(url)));UserMessage userMessage = UserMessage.builder().text("请分析这张图片并描述内容: "+message).media(mediaList).build();ChatResponse chatResponse = chatClient.prompt(new Prompt(userMessage)).call().chatResponse();return chatResponse.getResult().getOutput().getText();}
}

希望能对大家有所帮助!!!!

http://www.dtcms.com/a/358790.html

相关文章:

  • 突发,支付宝发布公告
  • GitHub 热榜项目 - 日榜(2025-08-30)
  • Unity笔记(八)——资源动态加载、场景异步加载
  • DbVisualizer:一款功能强大的通用数据库管理开发工具
  • 自动修改psd_生成套图 自动合并图片 自动生成psd文字层
  • Go 语言面试指南:常见问题及答案解析
  • 【具身智能】【机器人动力学】台大林佩群笔记-待持续更新
  • 索引结构与散列技术:高效数据检索的核心方法
  • HTS-AT模型代码分析
  • Shell脚本编程入门:从基础语法到流程控制
  • 本地运行 Ollama 与 DeepSeek R1 1.5B,并结合 Open WebUI 测试
  • 告别图片处理焦虑:用imgix实现智能、实时且高效的视觉媒体交付(含案例、截图)
  • Linux shell命令扩涨
  • HarmonyOS Router 基本使用详解:从代码示例到实战要点
  • 免费开源的 Gemini 2.5 Flash 图片生成器
  • Robolectric如何启动一个Activity
  • Coze源码分析-API授权-删除令牌-后端源码
  • SQL注入6----(其他注入手法)
  • 普蓝自研AutoTrack-4X导航套件平台适配高校机器人实操应用
  • 《Java反射与动态代理:从原理到实践》
  • 以声为剑,绘山河热血——刘洋洋《不惧》8月30日全网上线
  • 【深入解析——AQS源码】
  • OpenCV安装及其开发环境配置(Windows系统Visual Studio 2022)
  • 【物联网】MQTT / Broker / Topic 是什么?
  • 【分享】如何显示Chatgpt聊天的时间
  • 【Android】JSONObject和Gson的使用
  • 数据结构青铜到王者第十三话---优先级队列(堆)(2)
  • 中级函数三
  • 如何使用 DeepSeek 帮助自己的工作?—— 从效率工具到能力延伸的实战指南
  • BGP路由协议(四):工作原理