Spring AI + Ollama 实现 deepseek-r1 的API服务和调用

作者:蛮不讲李2025.11.06 14:09浏览量:1

简介:本文深入探讨如何利用Spring AI框架与Ollama工具链,构建并调用deepseek-r1大模型的API服务。通过详细的步骤解析与代码示例,帮助开发者快速实现模型部署与接口调用。

一、技术选型与架构设计

1.1 技术组件解析

Spring AI作为Spring生态中专注于AI开发的子项目,提供模型服务化、流式处理、多模型适配等核心能力。其与Spring Boot的深度整合,可快速构建RESTful API服务。Ollama则是开源的本地化模型运行框架,支持通过Docker容器部署LLM模型,提供高性能的推理服务。

1.2 架构设计思路

采用分层架构设计:

  • 表现层:Spring Boot Web构建REST API
  • 业务层:Spring AI处理模型交互逻辑
  • 数据层:Ollama容器运行deepseek-r1模型
  • 通信层:gRPC协议实现高效服务调用

这种设计兼顾开发效率与运行性能,特别适合需要本地化部署的私有化AI服务场景。

二、环境准备与模型部署

2.1 开发环境配置

需准备以下环境:

  • JDK 17+
  • Maven 3.8+
  • Docker 24.0+
  • Ollama最新版本

建议使用Linux服务器(Ubuntu 22.04+)以获得最佳性能,Windows/macOS需通过WSL2或Docker Desktop配置。

2.2 Ollama模型部署

  1. 安装Ollama:

    1. curl -fsSL https://ollama.com/install.sh | sh
  2. 下载deepseek-r1模型(以7B参数版为例):

    1. ollama pull deepseek-r1:7b
  3. 验证模型加载:

    1. ollama run deepseek-r1:7b "测试指令"

关键参数配置建议:

  • 显存需求:7B模型建议12GB+
  • 推理参数:--num-gpu 1 --temperature 0.7
  • 持久化存储:通过-v /path/to/models:/models挂载卷

三、Spring AI服务实现

3.1 项目初始化

使用Spring Initializr创建项目,添加以下依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.ai</groupId>
  4. <artifactId>spring-ai-ollama-starter</artifactId>
  5. <version>0.8.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-web</artifactId>
  10. </dependency>
  11. </dependencies>

3.2 核心配置

application.yml配置示例:

  1. spring:
  2. ai:
  3. ollama:
  4. base-url: http://localhost:11434
  5. model-id: deepseek-r1:7b
  6. chat:
  7. prompt-template: "用户:{{prompt}}\nAI:"

3.3 服务层实现

创建ChatService接口:

  1. public interface ChatService {
  2. String chat(String prompt);
  3. Stream<String> streamChat(String prompt);
  4. }

实现类使用Spring AI的OllamaClient:

  1. @Service
  2. public class OllamaChatService implements ChatService {
  3. private final OllamaChatClient chatClient;
  4. public OllamaChatService(OllamaChatClient chatClient) {
  5. this.chatClient = chatClient;
  6. }
  7. @Override
  8. public String chat(String prompt) {
  9. ChatRequest request = ChatRequest.builder()
  10. .messages(Collections.singletonList(
  11. AiMessage.builder().content(prompt).build()))
  12. .build();
  13. ChatResponse response = chatClient.call(request);
  14. return response.getGeneration().getContent();
  15. }
  16. @Override
  17. public Stream<String> streamChat(String prompt) {
  18. // 实现流式响应逻辑
  19. }
  20. }

3.4 控制器层实现

REST API端点示例:

  1. @RestController
  2. @RequestMapping("/api/chat")
  3. public class ChatController {
  4. @Autowired
  5. private ChatService chatService;
  6. @PostMapping
  7. public ResponseEntity<String> chat(
  8. @RequestBody ChatRequestDto request) {
  9. String response = chatService.chat(request.getPrompt());
  10. return ResponseEntity.ok(response);
  11. }
  12. @GetMapping("/stream")
  13. public ResponseEntity<StreamingResponseBody> streamChat(
  14. @RequestParam String prompt) {
  15. // 实现SSE流式响应
  16. }
  17. }

四、高级功能实现

4.1 流式响应实现

使用Spring的StreamingResponseBody:

  1. public ResponseEntity<StreamingResponseBody> streamChat(
  2. @RequestParam String prompt) {
  3. StreamingResponseBody stream = outputStream -> {
  4. // 通过Ollama的SSE接口获取流式数据
  5. // 逐块写入outputStream
  6. };
  7. return ResponseEntity.ok()
  8. .header(HttpHeaders.CONTENT_TYPE, "text/event-stream")
  9. .body(stream);
  10. }

4.2 上下文管理

实现多轮对话的上下文保持:

  1. public class ConversationManager {
  2. private Map<String, List<Message>> conversations = new ConcurrentHashMap<>();
  3. public List<Message> getConversation(String sessionId) {
  4. return conversations.computeIfAbsent(sessionId, k -> new ArrayList<>());
  5. }
  6. public void addMessage(String sessionId, Message message) {
  7. getConversation(sessionId).add(message);
  8. }
  9. }

4.3 性能优化

关键优化点:

  1. 连接池配置:

    1. spring:
    2. ai:
    3. ollama:
    4. connection-pool:
    5. max-size: 10
    6. idle-timeout: 30000
  2. 批处理优化:

    1. @Bean
    2. public OllamaChatClient ollamaChatClient(OllamaProperties properties) {
    3. return new OllamaChatClientBuilder(properties)
    4. .batchSize(512) // 最大token批处理
    5. .build();
    6. }

五、部署与运维

5.1 Docker化部署

Dockerfile示例:

  1. FROM eclipse-temurin:17-jdk-jammy
  2. WORKDIR /app
  3. COPY target/*.jar app.jar
  4. EXPOSE 8080
  5. ENTRYPOINT ["java","-jar","app.jar"]

docker-compose.yml配置:

  1. version: '3.8'
  2. services:
  3. ollama:
  4. image: ollama/ollama
  5. volumes:
  6. - ./models:/models
  7. ports:
  8. - "11434:11434"
  9. api:
  10. build: .
  11. ports:
  12. - "8080:8080"
  13. depends_on:
  14. - ollama

5.2 监控方案

推荐监控指标:

  • 请求延迟(P99 < 500ms)
  • 错误率(< 0.1%)
  • 模型加载时间
  • 显存使用率

Prometheus配置示例:

  1. scrape_configs:
  2. - job_name: 'spring-ai'
  3. metrics_path: '/actuator/prometheus'
  4. static_configs:
  5. - targets: ['api:8080']

六、实践建议

  1. 模型选择策略:

    • 7B模型适合边缘设备
    • 33B模型需要专业GPU
    • 考虑量化版本降低显存需求
  2. 安全实践:

    • 实现API密钥认证
    • 输入内容过滤
    • 输出内容审计
  3. 扩展方案:

    • 多模型路由(根据请求复杂度选择模型)
    • 缓存层设计(Redis缓存常见问答)
    • 异步处理队列(RabbitMQ/Kafka)

七、常见问题解决

  1. 连接超时

    • 检查Ollama服务是否运行
    • 验证网络防火墙设置
    • 增加连接超时时间配置
  2. 显存不足

    • 降低batch_size
    • 使用更小参数量的模型
    • 启用交换空间(Swap)
  3. 流式响应卡顿

    • 检查网络带宽
    • 优化SSE分块大小(建议512-1024字节)
    • 增加服务器资源

通过以上技术方案,开发者可以快速构建基于Spring AI和Ollama的deepseek-r1模型服务,实现从本地部署到API服务化的完整链路。该方案特别适合需要数据主权控制的金融、医疗等行业应用场景。