伊蕾娜的编程之旅

  1. 首页
  2. SpringAI的学习之旅
  3. 正文

SpringAI整合DeepSeek

2026年3月17日 0人点赞

现如今,AI正发展的如火如荼。许多厂商都推出了自己的AI应用。那么Java程序员如何在自己的项目中使用AI呢?答案是Spring为AI而推出的框架:Spring AI。小编会在网站上持续更新SpringAI的学习文章,跟着文章,一起学习。
首先从一个简单的整合DeepSeek开始

1.创建项目

SpringAI对JDK和springboot的版本是有要求的,JDK最低的版本是17,springboot必须使用springboot3。项目名:spring-ai-ds

2.在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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-ai-ds</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-ai-ds</name>
    <description>spring-ai-ds</description>

    <properties>
        <java.version>17</java.version>
        <!-- SpringAI版本-->
        <spring-ai.version>1.1.0</spring-ai.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--deepseek SDK包-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-deepseek</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
         <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <!--  dependencyManagement标签锁定SpringAI的版本,deepseek的版本取决于spring-ai-bom的版本  -->
    <dependencyManagement>
        <dependencies>
            <!-- Source: https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-bom -->
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</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.修改application.yml文件,填写deepSeek的api-key

spring:
  application:
    name: spring-ai-ds
  main:
    allow-bean-definition-overriding: true
  ai:
    deepseek:
      # 你的api key。这个api-key要在deepSeek官网注册,随便充几块钱,用来测试的话不会消耗很快,很耐用 。网址:https://platform.deepseek.com/api_keys
      api-key: sk-**** 
      chat:
        options:
          #  指定全局的模型,deepseek-chat没有推理  deepseek-reasoner是deepSeek的推理模型
          model: deepseek-chat
          # 模型的温度,温度的定义:温度(Temperature)是大模型生成文本时控制随机性和创造性的核心参数。值是在 0.0-2.0之间
          # 低温度:保守、确定、逻辑严密 高温度:发散、多样、富有创意。  但这也不会很绝对
          temperature: 0.8

4.创建一个controller,整合deepSeek(要点在注释里)

package com.example.springaids.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.deepseek.DeepSeekAssistantMessage;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.Objects;

@RestController
@RequestMapping("/ds")
@Slf4j
public class DeepSeekController {

    // deepSeek用于请求大模型的类
    private final DeepSeekChatModel chatModel;

    // SpringAI通用的ChatClient,同样是用于请求大模型
    private final ChatClient.Builder chatClientBuilder;

    public DeepSeekController(DeepSeekChatModel chatModel, ChatClient.Builder chatClientBuilder) {
        this.chatModel = chatModel;
        this.chatClientBuilder = chatClientBuilder;
    }

    /**
     * 最简单的聊天模式
     *
     * @param message 发送给deepSeek的提示词
     * @return deepSeek的回复
     */
    @GetMapping("/chat")
    public String chat(String message) {
        // 有两种方式可以请求deepSeek。1、使用deepSeek自己的类chatModel 2、使用SpringAI的ChatClient,这是通用的方式,不管引入的是什么大模型,都可以使用它
        // 我使用通用的方式
        ChatClient chatClient = ChatClient.builder(chatModel).build();
        log.info("-----------------1.简单的聊天模式--------------------");
        //prompt传入提示词
        String content = chatClient.prompt(message)
                .call()
                .content();
        log.info("deepSeek的回复:{}", content);

        log.info("-----------------2.使用推理模型聊天--------------------");
        //prompt传入提示词,并将本次请求的模型设为推理模型
        Prompt prompt = new Prompt(message, DeepSeekChatOptions.builder().model("deepseek-reasoner").build());
        // getOutput()方法返回的是AssistantMessage类,该类是springAI的类,不包含deepSeek的指定字段。因此需要将结果转换成DeepSeekAssistantMessage类
        DeepSeekAssistantMessage result = (DeepSeekAssistantMessage) chatClient.prompt(prompt)
                .call()
                .chatResponse()
                .getResult().getOutput();
        //推理内容
        String reasoningContent = result.getReasoningContent();
        log.info("推理内容:{}", reasoningContent);
        log.info("----------------分割线--------------------");
        //最终答案
        String finalContent = result.getText();
        log.info("最终答案:{}", finalContent);
        return content;
    }

    /**
     * 我们在使用deepSeek时,他返回的字是一个一个返回的,想古老的打印机一样。这个接口可以达到逐个返回结果,而不是一次性返回所有结果。
     * @param message 提示词
     * @return 逐个返回结果
     */
    @GetMapping(value = "/chatstream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamChat(@RequestParam String message) {

        DeepSeekChatOptions options = DeepSeekChatOptions.builder()
                .model("deepseek-reasoner")
                .build();
        Prompt prompt = new Prompt(message, options);
        // 使用的是stream而不是call方法
        Flux<ChatResponse> stream = chatModel.stream(prompt);
        // 将结果转换成ServerSentEvent返回给前端,可以用postman观察输出。要想达到deepSeek网页的效果,还需要前端支持
        return stream.mapNotNull(chatResponse -> {
                    DeepSeekAssistantMessage output = (DeepSeekAssistantMessage) chatResponse.getResult().getOutput();
                    String reasoning = output.getReasoningContent();
                    String text = output.getText();

                    if (reasoning != null && !reasoning.isEmpty()) {
                        return ServerSentEvent.<String>builder()
                                .event("reasoning")   // 事件类型:推理内容
                                .data(reasoning)
                                .build();
                    } else if (text != null && !text.isEmpty()) {
                        return ServerSentEvent.<String>builder()
                                .event("answer")      // 事件类型:最终答案
                                .data(text)
                                .build();
                    } else {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .doOnError(e -> System.err.println("Stream error: " + e.getMessage()))
                .onErrorResume(e -> Flux.just(
                        ServerSentEvent.<String>builder()
                                .event("error")
                                .data("An error occurred: " + e.getMessage())
                                .build()
                ));
    }
}

5.启动项目,使用postman测试接口

发送请求:http://localhost:8080/ds/chat?message=你是谁
idea控制台会打印如下内容:

发送请求:http://localhost:8080/ds/chatStream?message=你是谁
postman或者apiFox会显示逐个打印的回复,里面包含了推理部分和最终答案

以上就是Spring AI的初体验,用起来并没有多大难度。但这个例子的AI是没有上下记忆的,后面我们再补充如何让Spring AI在请求大模型是带上我们的上下文。

Post Views: 10
标签: SpringAI
最后更新:2026年3月17日

root-lsk

这个人很懒,什么都没留下

点赞

归档

  • 2026 年 3 月
  • 2026 年 2 月
  • 2026 年 1 月
  • 2025 年 12 月
  • 2025 年 11 月

分类

  • Java
  • RocketMq学习
  • SpringAI的学习之旅
  • 未分类
  • 编程之旅
  • 运维

COPYRIGHT © 2025 爱分享的伊莱娜. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备2020135038号-1