1. 项目概述与背景
作为一名长期深耕Java生态的技术开发者,我最近一直在探索如何将生成式AI能力无缝集成到企业级应用中。Spring AI框架的出现完美解决了这个问题,它让Java开发者能够以熟悉的Spring方式调用大语言模型。本文将分享我如何通过Spring AI 2.0整合DeepSeek模型搭建智能问答系统的完整过程。
这个项目的核心价值在于:
- 实现了大语言模型的本地化部署(基于Ollama)
- 通过Spring AI标准化接口调用模型
- 构建了同步和流式两种响应方式的问答服务
- 为后续扩展会话记忆等功能打下基础
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与模型部署
2.1 Ollama安装与配置
Ollama是我选择的模型运行环境,它让大语言模型的部署变得像安装普通软件一样简单。以下是详细的安装步骤:
2.1.1 Docker方式安装
推荐使用Docker安装,这是最便捷的方式:
bash复制docker pull ollama/ollama:0.5.10
docker run -d --name ollama -p 11434:11434 ollama/ollama:0.5.10
安装后验证运行状态:
bash复制docker ps | grep ollama
应该能看到容器正常运行并映射了11434端口。
注意:如果从默认仓库拉取镜像较慢,可以尝试国内镜像源如阿里云或华为云。例如:
bash复制docker pull registry.cn-hangzhou.aliyuncs.com/ollama/ollama:0.5.10
2.1.2 二进制方式安装(备选方案)
对于无法使用Docker的环境,可以直接下载二进制包:
- 访问Ollama官网下载对应系统的安装包
- 执行安装程序
- 运行
ollama serve启动服务
2.2 DeepSeek模型部署
2.2.1 模型选择策略
在Ollama支持的模型列表中,我选择了deepseek-r1:1.5b版本,主要考虑:
- 我的测试服务器配置有限(2核4G)
- 1.5B参数的模型在小型服务器上尚可运行
- 该版本对中文支持较好
如果硬件条件允许,建议选择更大的模型(如7B参数版本),响应质量和速度会显著提升。
2.2.2 模型安装步骤
- 进入Ollama容器:
bash复制docker exec -it ollama bash
- 拉取并运行模型:
bash复制ollama pull deepseek-r1:1.5b
ollama run deepseek-r1:1.5b
- 验证模型状态:
bash复制ollama ps
正常运行时应该能看到模型进程信息。
实测发现:在2C4G的服务器上,该模型响应时间约3-5秒/请求。如果遇到超时问题,可以尝试:
- 增加
--timeout参数- 减少并发请求数
- 升级服务器配置
3. Spring AI集成实现
3.1 项目基础配置
3.1.1 依赖管理
使用Spring Boot 4.0.2 + Spring AI 2.0.0-M2组合:
xml复制<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.2</version>
</parent>
<properties>
<java.version>17</java.version>
<spring-ai.version>2.0.0-M2</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
</dependencies>
重要提示:Spring AI 1.x和2.x的API差异较大,务必确认版本匹配。我在初期就因版本问题浪费了半天时间调试。
3.1.2 应用配置
application.properties关键配置:
properties复制spring.ai.ollama.base-url=http://127.0.0.1:11434
spring.ai.ollama.chat.model=deepseek-r1:1.5b
logging.level.org.springframework.ai.chat.client.advisor=debug
3.2 核心代码实现
3.2.1 ChatClient配置类
java复制@Configuration
public class OllamaConfig {
@Bean
public ChatClient chatClient(OllamaChatModel ollamaChatModel) {
return ChatClient.builder(ollamaChatModel)
.defaultSystem("你是一个热心、可爱的智能助手,你的名字叫小钢炮,请以小钢炮的身份和语气回答问题")
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
}
}
这里通过defaultSystem()方法设置了系统提示词(System Prompt),这相当于给AI模型一个初始角色设定。经过多次测试,合适的提示词能显著改善回答质量。
3.2.2 控制器实现
java复制@RestController
@RequestMapping("/ai/chat")
public class OllamaController {
@Resource
private ChatClient chatClient;
// 同步响应接口
@GetMapping
public String generate(@RequestParam String message) {
return chatClient.prompt(message).call().content();
}
// 流式响应接口
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStream(@RequestParam String prompt) {
return chatClient.prompt(prompt).stream().content();
}
}
关键设计点:
- 同步接口适合简单问答场景
- 流式接口(Server-Sent Events)能显著提升用户体验
- 响应内容类型设置为
text/event-stream以实现流式传输
3.3 效果测试与优化
3.3.1 同步接口测试
使用curl测试:
bash复制curl "http://localhost:8080/ai/chat?message=Java中的Stream有什么特点"
典型响应:
code复制小钢炮:Java中的Stream主要有以下特点:
1. 不是数据结构,不存储数据
2. 不会修改源数据
3. 延迟执行(终端操作触发)
4. 可并行处理...
3.3.2 流式接口测试
使用浏览器访问:
code复制http://localhost:8080/ai/chat/stream?prompt=解释下Spring的IoC原理
会看到文字逐步显示的效果,类似打字机输出。
性能优化发现:流式响应虽然用户体验好,但会延长总响应时间。建议:
- 前端实现打字机效果时添加最小延迟(如50ms/字)
- 对于复杂问题可以先返回"思考中..."提示
4. 常见问题与解决方案
4.1 模型部署问题
问题1:模型下载速度慢
- 解决方案:使用国内镜像源或预先下载模型文件
问题2:运行时报内存不足
- 解决方案:
bash复制
限制同时加载的模型数量docker run -d --name ollama -p 11434:11434 -e OLLAMA_MAX_LOADED_MODELS=1 ollama/ollama
4.2 Spring AI集成问题
问题1:调用超时
- 解决方案:
properties复制spring.ai.ollama.chat.options.timeout=60s
问题2:响应内容不完整
- 解决方案:调整maxTokens参数
java复制ChatClient.builder() .defaultOptions(ChatOptions.builder() .withMaxTokens(2000) .build())
4.3 性能优化建议
- 缓存机制:对常见问题答案进行缓存
- 请求合并:将多个短问题合并为一个请求
- 模型量化:使用4-bit量化版本减小内存占用
- 连接池:配置HTTP连接池复用连接
5. 扩展思路与改进方向
当前实现虽然可用,但还有很大改进空间:
-
会话记忆:通过ChatMemory接口实现多轮对话
java复制@Bean ChatMemory chatMemory() { return new InMemoryChatMemory(); } -
RAG增强:结合向量数据库实现知识增强
java复制@Bean VectorStore vectorStore() { return new SimpleVectorStore(); } -
微调模型:基于业务数据微调模型表现
-
前端优化:实现更友好的聊天界面
我在实际开发中发现,Spring AI的模块化设计让这些扩展变得非常容易。例如添加会话记忆只需引入相关依赖并配置ChatMemory bean即可。
这个项目最让我惊喜的是Spring AI的"约定优于配置"理念——大部分情况下只需定义好bean,框架就能自动处理复杂的模型交互细节。对于Java开发者来说,这比直接调用原生API要友好得多。
