找回密码
 立即注册
首页 业界区 业界 SpringAI接入DeepSeek大模型实现流式对话

SpringAI接入DeepSeek大模型实现流式对话

幽淆 2025-10-1 17:48:14
一、 环境配置

Spring AI 支持 Spring Boot 3.4.x,JDK支持需要17以上
添加快照存储库
  1. <repositories>
  2.   <repository>
  3.     <id>spring-snapshots</id>
  4.     <name>Spring Snapshots</name>
  5.     <url>https://repo.spring.io/snapshot</url>
  6.     <releases>
  7.       <enabled>false</enabled>
  8.     </releases>
  9.   </repository>
  10.   <repository>
  11.     <name>Central Portal Snapshots</name>
  12.     <id>central-portal-snapshots</id>
  13.     <url>https://central.sonatype.com/repository/maven-snapshots/</url>
  14.     <releases>
  15.       <enabled>false</enabled>
  16.     </releases>
  17.     <snapshots>
  18.       <enabled>true</enabled>
  19.     </snapshots>
  20.   </repository>
  21. </repositories>
复制代码
注意:
将 Maven 与 Spring AI 快照结合使用时,请注意 Maven 镜像配置。如果您已在项目中配置了镜像,settings.xml如下所示:
  1. <mirror>
  2.     <id>my-mirror</id>
  3.     <mirrorOf>*</mirrorOf>
  4.     <url>https://my-company-repository.com/maven</url>
  5. </mirror>
复制代码
通配符*会将所有仓库请求重定向到你的镜像,从而阻止访问 Spring 快照仓库。要解决此问题,请修改mirrorOf配置以排除 Spring 仓库:
此配置允许 Maven 直接访问 Spring 快照存储库,同时仍使用镜像来获取其他依赖项。
  1. <mirror>
  2.     <id>my-mirror</id>
  3.     <mirrorOf>*,!spring-snapshots,!central-portal-snapshots</mirrorOf>
  4.     <url>https://my-company-repository.com/maven</url>
  5. </mirror>
复制代码
依赖管理
  1. <dependencyManagement>
  2.     <dependencies>
  3.         <dependency>
  4.             <groupId>org.springframework.ai</groupId>
  5.             spring-ai-bom</artifactId>
  6.             <version>1.0.0-SNAPSHOT</version>
  7.             <type>pom</type>
  8.             <scope>import</scope>
  9.         </dependency>
  10.     </dependencies>
  11. </dependencyManagement>
复制代码
二、接入DeepSeek大模型

Spring AI 支持 DeepSeek 的各种 AI 语言模型。可以与 DeepSeek 语言模型进行交互,并基于 DeepSeek 模型创建多语言对话助手
先决条件

您需要使用 DeepSeek 创建 API 密钥才能访问 DeepSeek 语言模型。
在DeepSeek 注册页面创建一个帐户,并在API Keys 页面生成一个令牌。
Spring AI 项目定义了一个名为的配置属性,您应该将其设置为从 API Keys 页面获取spring.ai.deepseek.api-key的值。
  1. server:
  2.   port: 8080
  3. # In application.yml
  4. spring:
  5.   ai:
  6.     deepseek:
  7.       api-key: your-api-key
  8.       base-url: https://api.deepseek.com # DeepSeek 的请求 URL, 可不填,默认值为 api.deepseek.com
  9.       chat:
  10.         options:
  11.           model: deepseek-chat # 使用哪个模型
  12.           temperature: 0.8 # 温度值
复制代码
spring.ai.deepseek.chat.options.temperature: 使用的采样温度,介于 0 到 2 之间。较高的值(例如 0.8)会使输出更加随机,而较低的值(例如 0.2)会使输出更加集中且确定。我们通常建议更改此值或
top_p,但不要同时更改两者。
spring.ai.deepseek.chat.options.model: 目前deepseek模型有两种,deepseek-chat对话模型,deepseek-reasoner推理模型
自动配置

Spring AI 为 DeepSeek 聊天模型提供了 Spring Boot 自动配置功能。要启用此功能,请将以下依赖项添加到项目的 Mavenpom.xml文件中:
  1. <dependency>
  2.     <groupId>org.springframework.ai</groupId>
  3.     spring-ai-starter-model-deepseek</artifactId>
  4. </dependency>
复制代码
此时的完整POM配置
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     <modelVersion>4.0.0</modelVersion>
  5.     <parent>
  6.         <groupId>org.springframework.boot</groupId>
  7.         spring-boot-starter-parent</artifactId>
  8.         <version>3.4.1</version>
  9.         <relativePath/>
  10.     </parent>
  11.     <groupId>com.mrsunn</groupId>
  12.     ai-robot</artifactId>
  13.     <version>0.0.1-SNAPSHOT</version>
  14.     <description>AI机器人</description>
  15.     <properties>
  16.         <java.version>17</java.version>
  17.         
  18.         <spring-ai.version>1.0.2</spring-ai.version>
  19.     </properties>
  20.     <dependencyManagement>
  21.         <dependencies>
  22.             <dependency>
  23.                 <groupId>org.springframework.ai</groupId>
  24.                 spring-ai-bom</artifactId>
  25.                 <version>${spring-ai.version}</version>
  26.                 <type>pom</type>
  27.                 <scope>import</scope>
  28.             </dependency>
  29.         </dependencies>
  30.     </dependencyManagement>
  31.     <dependencies>
  32.         <dependency>
  33.             <groupId>org.springframework.boot</groupId>
  34.             spring-boot-starter-web</artifactId>
  35.         </dependency>
  36.         <dependency>
  37.             <groupId>org.springframework.boot</groupId>
  38.             spring-boot-starter-test</artifactId>
  39.             <scope>test</scope>
  40.         </dependency>
  41.         <dependency>
  42.             <groupId>org.springframework.ai</groupId>
  43.             spring-ai-starter-model-deepseek</artifactId>
  44.         </dependency>
  45.         <dependency>
  46.             <groupId>org.apache.commons</groupId>
  47.             commons-lang3</artifactId>
  48.         </dependency>
  49.     </dependencies>
  50.     <build>
  51.         <plugins>
  52.             <plugin>
  53.                 <groupId>org.springframework.boot</groupId>
  54.                 spring-boot-maven-plugin</artifactId>
  55.             </plugin>
  56.         </plugins>
  57.     </build>
  58.     <repositories>
  59.         <repository>
  60.             <id>spring-snapshots</id>
  61.             <name>Spring Snapshots</name>
  62.             <url>https://repo.spring.io/snapshot</url>
  63.             <releases>
  64.                 <enabled>false</enabled>
  65.             </releases>
  66.         </repository>
  67.         <repository>
  68.             <name>Central Portal Snapshots</name>
  69.             <id>central-portal-snapshots</id>
  70.             <url>https://central.sonatype.com/repository/maven-snapshots/</url>
  71.             <releases>
  72.                 <enabled>false</enabled>
  73.             </releases>
  74.             <snapshots>
  75.                 <enabled>true</enabled>
  76.             </snapshots>
  77.         </repository>
  78.         
  79.         <repository>
  80.             <id>huaweicloud</id>
  81.             <name>huawei</name>
  82.             <url>https://mirrors.huaweicloud.com/repository/maven/</url>
  83.         </repository>
  84.         <repository>
  85.             <id>aliyunmaven</id>
  86.             <name>aliyun</name>
  87.             <url>https://maven.aliyun.com/repository/public</url>
  88.         </repository>
  89.     </repositories>
  90. </project>
复制代码
实现对话效果(deepseek-chat)
  1. @RestController
  2. @RequestMapping("/ai")
  3. public class ChatController {
  4.     @Resource
  5.     private DeepSeekChatModel chatModel;
  6.     @GetMapping("/generate")
  7.     public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
  8.         return Map.of("generation", chatModel.call(message));
  9.     }
  10.     /**
  11.      * 流式对话
  12.      * @param message
  13.      * @return
  14.      */
  15.     @GetMapping(value = "/generateStream", produces = "text/html;charset=utf-8")
  16.     public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
  17.         // 构建提示词
  18.         Prompt prompt = new Prompt(new UserMessage(message));
  19.         // 流式输出
  20.         return chatModel.stream(prompt)
  21.                 .mapNotNull(chatResponse -> chatResponse.getResult().getOutput().getText());
  22.     }
  23. }
复制代码
1.png

produces = "text/html;charset=utf-8",把返回的对象设置成html格式,并且设置编码,不然会乱码返回
如果你只是直接在浏览器地址栏输入接口地址(如
http://localhost:8080/generateStream?message=你好),那么无论你的后端返回的是
Flux 还是什么流,浏览器都只会一次性接收最终的响应内容,或者根本无法逐步显示,无法实现“打字机效果”。​
推理模型(deepseek-reasoner)

这deepseek-reasoner是 DeepSeek 开发的推理模型。在得出最终答案之前,该模型会首先生成思维链 (CoT),以提高其响应的准确性。我们的 API 允许用户访问 生成的 CoT 内容deepseek-reasoner
,以便他们查看、显示和提取这些内容。
修改DeepSeek模型
  1. spring:
  2.   ai:
  3.     deepseek:
  4.       api-key: your-api-key
  5.       base-url: https://api.deepseek.com # DeepSeek 的请求 URL, 可不填,默认值为 api.deepseek.com
  6.       chat:
  7.         options:
  8.           model: deepseek-reasoner # 使用深度思考模型
  9.           temperature: 0.8 # 温度值
复制代码
  1. @Resource
  2. private DeepSeekChatModel chatModel;
  3. @GetMapping(value = "/generateStream", produces = "text/html;charset=utf-8")
  4. public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "你是谁?") String message) {
  5.     Prompt prompt = new Prompt(new UserMessage(message));
  6.     AtomicBoolean hasSentSeparator = new AtomicBoolean(false);
  7.     return chatModel.stream(prompt)
  8.             .mapNotNull(chatResponse -> {
  9.                 DeepSeekAssistantMessage assistantMessage = (DeepSeekAssistantMessage) chatResponse.getResult().getOutput();
  10.                 String content = null;
  11.                 boolean isFinalAnswer = false;
  12.                 // 优先处理思考内容
  13.                 if (assistantMessage.getReasoningContent() != null) {
  14.                     content = assistantMessage.getReasoningContent();
  15.                 }
  16.                 // 处理正式回答
  17.                 else if (assistantMessage.getText() != null) {
  18.                     content = assistantMessage.getText();
  19.                     isFinalAnswer = true;
  20.                 }
  21.                 if (StringUtils.isBlank(content)) {
  22.                     return null;
  23.                 }
  24.                 // 添加分隔符(思考到回答的过渡)
  25.                 if (isFinalAnswer && !hasSentSeparator.get()) {
  26.                     hasSentSeparator.set(true);
  27.                     return "<br>--- 思考过程结束 ---<br>" + content;
  28.                 }
  29.                 return content;
  30.             });
  31. }
复制代码
2.png

您可以使用DeepSeekAssistantMessage来获取由 生成的 CoT 内容deepseek-reasoner。
assistantMessage.getReasoningContent() 思考内容
assistantMessage.getText() 正式回答
使用ChatClient实现对话

ChatClient和ChatModel的区别
维度ChatModelChatClient交互方式直接调用模型,需手动处理请求/响应链式调用,自动封装提示词和解析响应功能扩展弱强,内置 Advisor 机制(如对话历史管理、RAG)结构化输出需手动解析响应文本支持自动映射为 Java 对象(如 entity(Recipe.class))适用场景实现简单功能和场景快速开发复杂功能的场景,如企业级智能客服、连接外部工具等

  • ChatClient:若追求开发效率、需要内置高级功能(如记忆、RAG)或标准化交互使用 ChatClient。
  • ChatModel:若实现简单的大模型对接场景使用 ChatModel。
ChatClient使用对象创建。ChatClient.Builder您可以获取ChatClient.Builder任何ChatModelSpring Boot 自动配置的自动配置实例,也可以通过编程方式创建一个。
  1. @Configuration
  2. public class ChatClientConfig {
  3.    
  4.     @Bean
  5.     public ChatClient deepSeekChatClient(DeepSeekChatModel chatModel) {
  6.         return ChatClient.create(chatModel);
  7.     }
  8.    
  9. }
复制代码
  1. @Autowired
  2. private ChatClient deepSeekChatClient;
  3. @GetMapping(value = "/generate", produces = "text/html;charset=utf-8")
  4. public String generation(@RequestParam(value = "message", defaultValue = "你是谁?") String message) {
  5.     return this.deepSeekChatClient.prompt()
  6.             .user(message)
  7.             .call()
  8.             .content();
  9. }
复制代码
具有单一模型类型的多个 ChatClients

本节介绍一个常见的用例,您需要创建多个 ChatClient 实例,它们都使用相同的底层模型类型但具有不同的配置。
  1. @Autowired
  2. private DeepSeekChatModel deepSeekChatModel;
  3. ChatClient chatClient = ChatClient.create(deepSeekChatModel);
  4. chatClient.mutate().defaultOptions(ChatOptions.builder().build());
  5. ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);
  6. ChatClient customChatClient = builder
  7.         .defaultOptions(ChatOptions.builder().build())
  8.         .defaultSystem("You are a helpful assistant.")
  9.         .build();
复制代码
使用同一个deepSeekChatModel模型,可以配置不同参数的ChatClient
​延伸阅读​:如需更深入的技术解析或学习资源,欢迎访问 Mr.Sun的博客(专注Java领域干货分享,持续更新中~)
3.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册