Spring AI快速入门以及项目的创建
1. Spring AI概述
1.1 Spring AI是什么?
这是Spring官方推出的首个稳定版人工智能(AI)集成框架。旨在帮助Java/Spring开发者更便捷地在企业级应用中集成AI能力(如大语言模型、机器学习、向量数据库、图像生成等)。它的发布标志着Spring生态正式进入AI时代,为Java开发者提供了标准化的AI开发工具链,AI技术正式进入Spring生态的核心工具链。
2. 术语介绍
2.1 模型
模型旨在处理和生成信息的算法,通常模仿人类的认知功能。通过从大数据集中学习模式和洞察,这些模型可以进行预测、生成文本、图像或其他输出,从而增强各行各业的各种应用。比如ChatGPT等等。每种模型的能力不同,适合的任务也不同。
可以简单理解为模型是⼀个"超级加工厂",这个工厂是经过特殊训练的,训练师给它看了海量的例子(数 据),并告诉它该怎么做。通过看这些例子,它自己摸索出了⼀套规则,学会了完成某个"特定任务"。模型就是⼀套学到的"规则"或者"模式",它能根据你给的东西,产生你想要的东西。
我们给的东西就称之为:输入
模型产出的结果,就称之为输出
Spring AI的作用就是让我们在Java/Spring应用中,能非常方便地:
选择不同的模型
构造和发送输入(Prompt)
接受并处理输出(AI响应)
2.2 LLM
LLM(Large Language Model),大语言模型,也称大型语言模型,是人工智能模型中专门处理文本的⼀种类型,属于语言模型的范畴。LLM的特点是规模庞大,包含数⼗亿的参数,在大量的文本数据上进行训练,学习语言数据中的复杂模式,旨在理解和生成⼈类语言。可以执行广泛的任务,包括文本总结、翻译、情感分析等。
2.3 提示词
提示词是用户或系统提供给大语言模型(LLM)的指令或文本,用于引导模型生成特定输出。可以理解为模型的输入,无论是一个单词、一个问题、一段描述,还是结构化指令,都可视为提示词。
类型 | 定义 | 核心功能 | 示例 |
---|---|---|---|
用户提示词 | 由终端用户直接输入,触发单次任务 | 传达及时需求(如提问、创作指令) | 用户输⼊:"总结这篇论文的核心观点" |
系统提示词 | 有开发者预设,嵌入系统后端 | 定义模型角色、行为规范、知识边界 | 预设:"你是⼀名严谨的学术助手, 回答需引用权威文献" |
系统提示词如同"操作系统",持续影响所有交互(如角色设定、安全过滤),用户提示词如同"操作指令",驱动单次任务执行(如生成报告、翻译文本)。
2.4 词元(Tokens)
词元是大语言模型(LLM)处理文本时地最小语义单位。用于将文本拆解为模型可理解的离散单元。
词元通过分词器将文本拆分而来,不同模型的分词规则不同,同⼀个词在不同模型中可能被拆分成不同词元。
模型的上下文窗口(如128K)实际是词元数量限制,API收费通常按词元数计费(词元=金钱),词元数越多,计算耗时和内存占用越高。所以在使用时,应尽量避免冗余词(如请,谢谢)。
3. Spring AI快速入门
3.1 环境要求
JDK
最低要求:JDK 17+(Spring Boot 3.x强制要求)
推荐版本:JDK21、JDK17
Spring Boot
最低要求:Spring Boot 3.2+(Spring AI 1.0.0起强制依赖)
推荐版本:Spring Boot 3.4.x、Spring Boot 3.3.x
3.2 准备工作
3.2.1 DeepSeek介绍
DeepSeek 以开源和高效推理为核心竞争力,主要模型包括:
DeepSeek-R 系列(如 R1):专注复杂推理的模型,数学、代码能力突出,支持深度思考模式(高智能推理状态)。
DeepSeek-V 系列(如V2,V3):通用语言模型,支持文本生成、多轮对话等任务,性能对标 GPT-4 Turbo4。
DeepSeek-Coder:专注于代码生成与补全,支持多语言编程(Python,Java等),强化学习优化训 练成本仅为同类模型的1/30。
3.2.2 申请DeepSeek API Keys
1.点击[API开放平台],进入API开放平台,注册用户。
2.注册之后,自行充值
充之前需要先实名认证
3. 创建API Keys
3.3 项目初始化
1.创建一个空地Maven项目,删除所有代码,只保留pom.xml
目录结构:
2. 完善pom文件
添加依赖,声明父工程地打包方式为pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-api-project</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.3</version><relativePath/> <!-- lookup parent from repository --></parent></project>
3.3.1 创建子项目
声明依赖和插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring-api-project</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-ai-demo</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><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><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
3.3.2 完善代码
启动类
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringAiApplication {public static void main(String[] args) {SpringApplication.run(SpringApplication.class, args);}
}
创建配置文件
spring:application:name: spring-ai-demo
3.4 接入DeepSeek
Spring AI生态专门为OpenAI及兼容API服务设计了Starter spring-ai-openaispring-boot-starter,用于快速集成大模型语言能力到Spring Boot应用中。
核心价值包括:
简化配置:自动封装了OpenAI API的请求/响应等逻辑
统一接口:提供ChatClient等标准化接口,支持无缝切换不同模型提供商
Spring生态集成:与Spring Boot的自动配置、依赖注入等特性深度整合。
3.4.1 添加依赖
上面给出的pom文件是完整的,这个可以不用再加入到pom文件中。
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
3.4.2 配置API密钥
spring:application:name: spring-ai-demoai:openai:#OpenAI# api-key: sk-proj-XXXXX#DeepSeekapi-key: sk-yuor-keybase-url: https://api.deepseek.comchat:options:model: deepseek-chattemperature: 0.7
3.4.3 接口编写
Spring AI已经集成了OpenAI的API,因此我们不需要向OpenAI发送请求和接收响应的交互程序了,我们只需要调用Spring AI为我们提供的接口即可。
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ds")
public class DeepSeekChatController {@Autowiredprivate OpenAiChatModel chatModel;@GetMapping("/chat")public String generate(String message){return chatModel.call( message);}
}
3.4.4 测试
访问接口:127.0.0.1:8080/ds/chat?message=你是谁
4. Spring AI-聊天模型
Spring AI的聊天模型,通过标准化的接口设计,使开发人员可以将AI模型的聊天功能集成到应用程序中。它利用预先训练的语言模型,例如GPT(Generative Pre-trained Transformer),以自然语言生成类似人类的响应。
API的工作原理通常是向AI模型发送提示或部分对话,然后AI模型根据其训练数据和对自然语言模式的理解生成响应。然后,把响应将返回给应用程序,应用程序可以将其呈现给用户或将其用于进一步处理。
在Spring AI框架中,ChatModel和ChatClient是构建对话式AI应用的两大核心接口。上面我们使用了ChatModel完成了与AI模型的交互,接下来我们对这两个接口分别进行介绍。
4.1 ChatClient
ChatClient是Spring AI 框架中封装复杂交互流程的高阶API接口,旨在简化开发者与大语言模型(如 GPT、通义千问等)的集成过程。ChatClient 提供了与AI模型通信的Fluent API,它支持同步和反应式(Reactive)编程模型,将与LLM及其他组件交互的复杂性进行封装,给用户提供开箱即用的服务。
4.4.1 实现简单对话
根据用户输入的消息,进行响应。并进行角色的设置。
1.创建ChatClient,注入并使用。
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfiguration {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder) {return chatClientBuilder.defaultSystem("你是一名Java程序员,参与过许多项目").build();}
}
@RequestMapping("/chat")
@RestController
public class ChatClientController {@Autowiredprivate ChatClient chatClient;@GetMapping("/call")public String generation(String userInput){//创建一个提示词promptreturn this.chatClient .prompt()//用户输入.user(userInput)//调用ai.call()//返回响应.content();}
}
2. 测试
访问接口:127.0.0.1:8080/chat/call?userInput=你是谁
4.1.2 结构化输出
如果您想从LLM接收结构化输出,Spring AI支持将ChatModel/ChatClient方法的返回类型从String更改为其他类型。
通过 entity() 方法将模型输出转为自定义实体,需确保输出格式符合JSON规范。
1. 编写代码
//格式化输出record Recipe(String dish, List<String> ingredients){}@GetMapping("/entity")public String entity(String userInput){Recipe recipe=this.chatClient.prompt().user(String.format("请帮我生成%s的食谱",userInput)).call().entity(Recipe.class);return recipe.toString();}
2. 测试
访问接口:127.0.0.1:8080/chat/entity?userInput=西红柿炒鸡蛋
4.1.3 实现流式输出
用和大模型进行交互时,由于大模型⼀次输出内容较多,等待全部内容生成完毕会导致用户等待时间过长,这对用户的体验非常不友好。可以采用流式输出的方式(例如ChatGPT和DeepSeek逐字显示回答)。
1. 流式输出的介绍
大模型流式输出(Streaming Output)是通过逐步生成内容而非一次性返回完整结果的技术。Spring AI使用ChatClient 的stream() 方法生成Flux 流,适用于需要更轻量级客户端控制 的场景.。
适合场景:实时对话,代码补全,长文本生成。
2. 代码实现
//流式输出@GetMapping(value = "/stream",produces = "text/html;charset=utf-8")public Flux<String> stream(String userInput){return this.chatClient.prompt()//用户输入.user(userInput)//调用AI 流式输出.stream()//返回响应.content();}
3. 测试
访问:127.0.0.1:8080/chat/stream?userInput=你是谁
4.2 ChatModel
4.2.1 概述
ChatModel是Spring AI构建对话应用的核心接口,它抽象了应用与模型交互的过程,包括使用Prompt作为输入,使用ChatResponse 作为输出等。ChatModel的工作原理是接收Prompt或部分对话作为输入,将输入发送给后端大模型,模型根据其训练数据和对自然语言的理解生成对话响应,应用程序可以将响应呈现给用户或用于进⼀步处理。
String call(String message) 方法就是对message进行了封装,简化了ChatModel的初始化使用,避免了更复杂的Prompt输入和ChatResponse输出,本质上调用的依然是ChatResponse call(Prompt prompt)。
default String call(String message) {Prompt prompt = new Prompt(new UserMessage(message));Generation generation = call(prompt).getResult();return (generation != null) ? generation.getOutput().getText() : "";}
ChatClient本质上也是基于ChatModel进行的封装和增强。
public interface ChatClient {static ChatClient create(ChatModel chatModel) {return create(chatModel, ObservationRegistry.NOOP);}static ChatClient create(ChatModel chatModel, ObservationRegistryobservationRegistry) {return create(chatModel, observationRegistry, null);}static Builder builder(ChatModel chatModel) {return builder(chatModel, ObservationRegistry.NOOP, null);}}
4.2.2 实现简单对话
编写代码
@GetMapping("/chatByPrompt")public String chatByPrompt(String message){Prompt prompt=new Prompt(message);ChatResponse response=chatModel.call(prompt);return response.getResult().getOutput().getText();}
测试
接口:127.0.0.1:8080/ds/chatByPrompt?message=你是谁
4.2.3 角色预设
1. 编写代码
在Prompt中通过System Message 明确与预定角色身份
@GetMapping("/role")public String role(String message){SystemMessage systemMessage=new SystemMessage("你是一个英国人,只会讲英语");UserMessage userMessage=new UserMessage(message);Prompt prompt=new Prompt(List.of(systemMessage,userMessage));ChatResponse chatResponse=chatModel.call(prompt);return chatResponse.getResult().getOutput().getText();}
2. 测试
127.0.0.1:8080/ds/role?message=你是谁
4.2.4 实现流式输出
ChatModel 也提供了stream方法来实现流式输出
@RequestMapping(value = "/stream", produces = "text/html;charset=utf-8")public Flux<String> stream(String message){Prompt prompt=new Prompt(message);Flux<ChatResponse> response=chatModel.stream(prompt);return response.map(x->x.getResult().getOutput().getText());}
接口测试:127.0.0.1:8080/ds/stream?message=你是谁
4.2.5 ChatClient 和 ChatModel区别
ChatClient 和ChatModel 是Spring AI 框架提供的与大语言模型(LLM)交互的两大核心接口。但二者设计理念和适用场景不太一样。
ChatModel 是Spring AI 框架中的底层接口,直接与具体的大语言模型(如通义千问、OpenAI)交互,提供基础的 call 和 stream 方法,开发者需手动处理提示词组装、参数配置和响应解析等细节,在使用上相对更加灵活。
ChatResponse response = openAiChatModel.call(new Prompt(message));
return response.getResult().getOutput().getText();
ChatClient 对ChatModel进行了封装,相比如ChatModel 原⼦类API,ChatClient屏蔽了与AI大模型 的交互的复杂性,它自动集成提示词管理、响应格式化、结构化输出映射等能力,提高了开发效率。
Recipe recipe = this.chatClient.prompt()//⽤⼾输⼊的信息 .user(String.format("请帮我⽣成%s的⻝谱", userInput))//请求⼤模型 .call()//返回⽂本 .entity(Recipe.class);
能力对比
维度 | ChatModel | ChatClient |
---|---|---|
交互方式 | 手动构建Prompt,解析响应 | 链式API,自动封装请求与响应 |
结构化输出 | 手动解析文本 | 支持.entity(Class)自动映射POJO |
扩展能力 | 依赖外部组件 | 内置Advisor机制,提供更高级的功能,如提供上下文记忆,RAG等功能 |
适合场景 | 适合需要精细控制模型参数的场景,比如模型试验,参数调优等定制需求 | 适合快速构建AI服务,如带记忆的客服系统 |