跳到主要内容Spring AI 实战入门:从环境搭建到 RAG 应用 | 极客日志JavaAIjava算法
Spring AI 实战入门:从环境搭建到 RAG 应用
本文详细介绍了 Spring AI 框架的实战应用,涵盖从基础环境搭建到高级功能的全流程。内容包括集成 DeepSeek 和阿里云 DashScope 等大模型,掌握 ChatClient 与 ChatModel 接口的区别,实现角色预设与流式响应。此外,还深入讲解了函数调用机制、本地 Ollama 部署、图像与语音模型处理,以及基于向量数据库的 RAG 检索增强生成技术。通过综合案例演示了如何构建智能简历筛选助手,展示了 Spring AI 在 Java 企业级应用中的灵活性与扩展性。
Spring AI 实战入门
在当今技术快速迭代的背景下,人工智能已成为行业标配。作为主流的 Java 开发框架,Spring 社区紧跟潮流推出了 Spring AI 框架,旨在将 Spring 的设计原则应用于 AI 领域。
1. Spring AI 简介
1.1 什么是 Spring AI
Spring AI 是一个面向 AI 工程的应用程序框架。它的核心目标是将 Spring 生态系统的可移植性和模块化设计原则引入 AI 领域,促进使用 POJO 作为构建块。简单来说,它提供了开发 AI 大模型应用所需的基本抽象模型,拥有多种实现方式,让开发者能用很少的代码改动实现组件的轻松替换。
官网地址:https://spring.io/projects/spring-ai

目前 Spring AI 发布了预览版 (PRE)、快照版 (SNAPSHOT) 以及正式版 (GA)。推荐使用 GA 版本以保证稳定性,SNAPSHOT 版本则持续更新。
1.2 主要功能
- 多模型支持:涵盖 OpenAI、DeepSeek、Microsoft、Ollama、Amazon、Google HuggingFace 等主流供应商。
- 多模态能力:支持聊天、文本转图像、文本转声音等。
- 向量数据库集成:支持 Azure Vector Search、Chroma、Milvus、Neo4j、Redis、PineCone、PostgreSQL/PGVector 等。
- 函数调用:支持 Function Calling 功能,允许模型触发外部函数。
- 自动配置:支持 Spring Boot 自动配置和快速启动。
2. 快速入门:集成 DeepSeek
2.1 准备工作
DeepSeek 是一款由深度求索开发的 AI 大模型,基于 Transformer 架构,在成本与性能上具有显著优势。对于 Java 应用,我们可以通过 Spring AI 轻松集成。
获取 API Key
- 访问 DeepSeek 开放平台并注册登录。
- 创建 API Key。
- 根据需求充值(需完成实名认证)。
接口文档:https://api-docs.deepseek.com/zh-cn/
2.2 创建 SpringBoot 工程
建议使用 JDK 17 及以上版本,Spring Boot 3.x。
引入依赖
在父模块 pom.xml 中添加公共依赖:
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17
1.0.0-M5
org.springframework.boot
spring-boot-starter-web
org.springframework.ai
spring-ai-openai-spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.18.30
org.springframework.ai
spring-ai-bom
${spring-ai.version}
pom
import
</maven.compiler.target>
<spring-ai.version>
</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
</dependency>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
</dependency>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
<scope>
</scope>
</dependency>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
<version>
</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
<version>
</version>
<type>
</type>
<scope>
</scope>
</dependency>
</dependencies>
</dependencyManagement>
配置文件
在子模块 application.properties 中配置:
server.port=8899
spring.application.name=spring-ai-deepseek-demo
# DeepSeek 的 Api key
spring.ai.openai.api-key=sk-****************
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.options.model=deepseek-chat
spring.ai.openai.chat.options.temperature=0.7
注意:temperature 参数控制生成文本的多样性。值越高越随机,值越低越确定。
启动类与 Controller
@SpringBootApplication
public class SpringAiHelloApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiHelloApplication.class, args);
}
}
package com.atguigu.ai.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatDeepSeekController {
@Resource
private OpenAiChatModel chatModel;
@GetMapping("/ai/generate")
public String generate(@RequestParam(value = "message", defaultValue = "hello") String message) {
String response = this.chatModel.call(message);
System.out.println("response: " + response);
return response;
}
}
测试接口 localhost:8899/ai/generate?message=你好,即可看到响应结果。
3. 聊天模型详解
3.1 概述
Spring AI 的聊天模型 API 为开发者提供了便捷通道,能够无缝集成 AI 驱动的聊天功能。借助预训练语言模型,它能依据用户输入生成自然流畅的回复。
3.2 ChatClient 接口
ChatClient 是定义与聊天服务交互客户端的核心接口,主要用于创建客户端对象、设置请求规范及发起请求。
简单对话
通过构造器注入 ChatClient.Builder 来定制客户端行为。
package com.atguigu.ai.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/chat")
public String chat(@RequestParam(value = "message", defaultValue = "你是谁") String message) {
return this.chatClient.prompt()
.user(message)
.call()
.content();
}
}
角色预设
可以通过配置类设置默认的系统角色(System Prompt),避免每次请求都重复指定。
package com.atguigu.ai.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AIConfig {
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("你是一名资深 Java 开发专家,精通 Spring 框架。").build();
}
}
流式响应
非流式输出 (call) 需要等待模型生成完所有内容;流式输出 (stream) 则逐个字符输出,能显著提升用户体验,特别是在推理效率不高时。
@GetMapping(value = "/chat/stream", produces = "text/html;charset=UTF-8")
public Flux<String> chatStream(@RequestParam(value = "message") String message) {
return chatClient.prompt().user(message).stream().content();
}
3.3 ChatModel 接口
ChatModel 定义了与 AI 模型交互的基本方法,继承自 Model<Prompt, ChatResponse>。虽然 ChatClient 底层使用 ChatModel,但在某些需要精细控制 Prompt 或 ChatResponse 的场景下,直接使用 ChatModel 更为合适。
@GetMapping("/chatModel02")
public String chatModel02(@RequestParam("message") String message) {
ChatResponse call = chatModel.call(new Prompt(
message,
OpenAiChatOptions.builder()
.model("deepseek-chat")
.temperature(0.8)
.build()));
return call.getResult().getOutput().getContent();
}
4. 函数调用 (Function Calling)
函数调用允许大语言模型在生成回答时触发预定义的外部函数,从而实现动态数据获取或业务逻辑操作。
4.1 核心流程
- 定义函数:声明可供模型调用的函数(名称、描述、参数结构)。
- 模型交互:将函数信息与用户输入一起发送给模型。
- 执行函数:解析模型的调用请求,执行业务逻辑。
- 返回结果:将执行结果返回给模型,生成最终回答。
4.2 实现示例
package com.atguigu.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import java.util.function.Function;
@Slf4j
@Configuration
public class CalculatorService {
public record AddOperation(int a, int b) {}
public record MulOperation(int m, int n) {}
@Bean
@Description("加法运算")
public Function<AddOperation, Integer> addOperation() {
return request -> {
log.info("执行加法运算:{} + {} = {}", request.a, request.b, request.a + request.b);
return request.a + request.b;
};
}
@Bean
@Description("乘法运算")
public Function<MulOperation, Integer> mulOperation() {
return request -> {
log.info("执行乘法运算:{} * {} = {}", request.m, request.n, request.m * request.n);
return request.m * request.n;
};
}
}
@GetMapping(value = "/function", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public String ragJsonText(@RequestParam(value = "message") String message) {
return ChatClient.builder(chatModel).build()
.prompt()
.system("""
您是算术计算器的代理。您能够支持加法运算、乘法运算等操作。
当用户询问数学计算时,您必须调用相应的函数来处理。
支持的函数:
- addOperation: 加法运算,需要两个数字参数
- mulOperation: 乘法运算,需要两个数字参数
请用中文回复,并在适当的时候调用函数。
""")
.user(message)
.functions("addOperation", "mulOperation")
.call()
.content();
}
5. 本地部署 Ollama
Ollama 是一个用于本地化部署和管理大型语言模型的工具,支持多种开源模型。
5.1 安装与配置
- 下载并安装 Ollama:https://ollama.com
- 设置环境变量
OLLAMA_MODELS 指定模型存储路径。
- 拉取模型,例如:
ollama pull deepseek-r1:1.5b
- 启动服务:
ollama run deepseek-r1:1.5b
5.2 代码集成
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
配置 application.properties:
server.port=8892
spring.application.name=spring-ai-ollama-demo
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=deepseek-r1:1.5b
spring.ai.ollama.chat.options.temperature=0.7
6. Spring AI Alibaba
Spring AI Alibaba 是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供了完整的开源配套。
6.1 快速入门
spring.autoconfigure.exclude=org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration
6.2 代码示例
@RestController
public class SpringAiAlibabaController {
private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!";
private ChatClient dashScopeChatClient;
public SpringAiAlibabaController(ChatClient.Builder chatClientBuilder) {
this.dashScopeChatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
.defaultAdvisors(new SimpleLoggerAdvisor())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())
.build();
}
@GetMapping("/simple/chat")
public String simpleChat(@RequestParam("query") String query) {
return dashScopeChatClient.prompt(query).call().content();
}
}
7. 其他模型能力
7.1 图像模型
Spring AI 的 Image Model API 抽象了'文生图'的交互过程。以 DashScope 为例:
@GetMapping("/generate-image")
public void getImage(@RequestParam(value = "msg", defaultValue = "生成一只小猫") String msg, HttpServletResponse res) {
ImageResponse response = imageModel.call(new ImagePrompt(
msg,
DashScopeImageOptions.builder()
.withModel(DashScopeImageApi.DEFAULT_IMAGE_MODEL)
.withN(1)
.withHeight(1024)
.withWidth(1024)
.build()));
String imageUrl = response.getResult().getOutput().getUrl();
try {
URL url = URI.create(imageUrl).toURL();
InputStream in = url.openStream();
res.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
res.getOutputStream().write(in.readAllBytes());
res.getOutputStream().flush();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
7.2 语音模型
Text-to-Speech API 支持将文字内容转化为语音,可配置语速、音调、音量等参数。
8. RAG (检索增强生成)
RAG (Retrieval-Augmented Generation) 结合了检索系统和生成模型,利用外部知识库帮助大模型生成更准确、有依据的回答,有效解决知识局限性和幻觉问题。
8.1 工作流程
- 用户输入问题。
- 问题向量化:调用 Embedding 模型将问题转换为高维向量。
- 向量数据库检索:检索知识库中相似的文档片段。
- 构建上下文:结合系统提示词和检索到的内容构造 Prompt。
- 调用 LLM:生成最终回答。
8.2 实现步骤
配置向量存储
@Bean
VectorStore vectorStore(@Qualifier("dashscopeEmbeddingModel") EmbeddingModel embeddingModel) {
SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build();
List<Document> documents = List.of(new Document(
"产品说明:名称:Java 开发语言\n" +
"产品描述:Java 是一种面向对象开发语言。\n" +
"特性:\n" +
"1. 封装\n" +
"2. 继承\n" +
"3. 多态\n"));
simpleVectorStore.add(documents);
return simpleVectorStore;
}
编写 Controller
@GetMapping(value = "/chat", produces = "text/plain; charset=UTF-8")
public String generation(@RequestParam("userInput") String userInput) {
return dashScopeChatClient.prompt()
.user(userInput)
.advisors(new QuestionAnswerAdvisor(vectorStore))
.call()
.content();
}
9. 综合案例:智能简历筛选
本案例结合 RAG 知识库与函数调用,实现一个招聘助手。
9.1 环境搭建
9.2 构建知识库
将候选人简历(txt 文件)放入 resource 目录,通过 TextReader 读取并切分后存入向量库。
@Bean
VectorStore vectorStore(@Qualifier("dashscopeEmbeddingModel") EmbeddingModel embeddingModel) {
SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build();
String filePath = "张三简历.txt";
TextReader textReader = new TextReader(filePath);
List<Document> documents = textReader.get();
TokenTextSplitter splitter = new TokenTextSplitter(1200, 350, 5, 100, true);
splitter.apply(documents);
simpleVectorStore.add(documents);
return simpleVectorStore;
}
9.3 工具与 Agent
定义查询岗位的函数,并在 Controller 中串联人设、知识库和工具。
@GetMapping("/ai/agent")
public String agent(@RequestParam("query") String query) {
List<Document> documents = vectorStore.similaritySearch(query);
String info = documents.size() > 0 ? documents.get(0).getContent() : "";
String systemPrompt = "角色与目标:你是一个招聘助手...";
String userPrompt = "给你提供一些数据参考:{info},请回答我的问题:{query}。";
SystemMessage systemMessage = new SystemMessage(systemPrompt);
PromptTemplate promptTemplate = new PromptTemplate(userPrompt);
Message userMessage = promptTemplate.createMessage(Map.of("info", info, "query", query));
Prompt prompt = new Prompt(List.of(userMessage, systemMessage),
DashScopeChatOptions.builder().withFunctions(Set.of("recruitServiceFunction")).build());
List<Generation> results = chatModel.call(prompt).getResults();
return results.stream().map(x -> x.getOutput().getContent()).collect(Collectors.joining());
}
测试接口 localhost:8896/ai/agent?query=java 语言有哪些特性,观察 AI 如何结合简历信息和工具返回结果进行回答。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online