在这里插入图片描述

Pre

大模型开发 - 01 Spring AI 核心特性一览

大模型开发 - 02 Spring AI Concepts

前言

在人工智能快速发展的今天,将 AI 能力集成到 Java 应用中已成为现代软件开发的重要需求。Spring AI 作为 Spring 生态系统的重要组成部分,为开发者提供了便捷的 AI 集成方案。本文将详细介绍如何使用 Spring AI 框架集成 DeepSeek AI 模型,并通过实际案例展示其强大功能。

项目概述

本项目是一个基于 Spring Boot 3.5.6 和 Spring AI 1.0.3 的快速入门示例,展示了如何将 DeepSeek AI 模型集成到 Spring 应用中,实现智能对话、流式响应、推理分析等多种 AI 功能。

技术栈

  • Java 版本:17
  • Spring Boot:3.5.6
  • Spring AI:1.0.3
  • AI 模型:DeepSeek (deepseek-reasoner)

项目结构

spring-ai-artisan/
├── pom.xml                          # 父项目POM
└── 01-quick-start/                  # 快速入门模块
    ├── pom.xml                      # 模块POM
    └── src/
        ├── main/
        │   ├── java/
        │   │   └── com/artisan/ai/quickstart/
        │   │       └── ArtisanAIQuickStartApplication.java
        │   └── resources/
        │       └── application.properties
        └── test/
            └── java/
                └── com.artisan.ai.quickstart/
                    └── SpringAIDeepSeekTest.java

项目配置

1. Maven 依赖管理

父 POM 配置

在父项目的 pom.xml 中,我们统一管理了项目的版本依赖:

<properties>
    <java.version>17</java.version>
    <spring-boot.version>3.5.6</spring-boot.version>
    <spring-ai.version>1.0.3</spring-ai.version>
</properties>

<dependencyManagement>
    <dependencies>
    
        <!-- 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>

        <!-- Spring Boot Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

关键点说明

  • 使用 BOM (Bill of Materials) 统一管理依赖版本,避免版本冲突
  • 同时集成了 Spring AI 官方版本
  • Java 17 作为基础版本,支持最新的语言特性

模块 POM 配置

01-quick-start 模块的 pom.xml 中,添加具体依赖:

<dependencies>
    <!-- DeepSeek AI 模型支持 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-deepseek</artifactId>
    </dependency>

    <!-- Spring Web 支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 单元测试支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
自动配置类 DeepSeekChatAutoConfiguration

其中

    <!-- DeepSeek AI 模型支持 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-deepseek</artifactId>
    </dependency>

会增加自动配置类, 其中DeepSeekChatModel这个就是专门负责智能对话的

在这里插入图片描述

package org.springframework.ai.model.deepseek.autoconfigure;



/**
 * {@link AutoConfiguration Auto-configuration} for DeepSeek Chat Model.
 *
 * @author Geng Rong
 */
@AutoConfiguration(after = { RestClientAutoConfiguration.class, WebClientAutoConfiguration.class,
		SpringAiRetryAutoConfiguration.class, ToolCallingAutoConfiguration.class })
@ConditionalOnClass(DeepSeekApi.class)
@EnableConfigurationProperties({ DeepSeekConnectionProperties.class, DeepSeekChatProperties.class })
@ConditionalOnProperty(name = SpringAIModelProperties.CHAT_MODEL, havingValue = SpringAIModels.DEEPSEEK,
		matchIfMissing = true)
@ImportAutoConfiguration(classes = { SpringAiRetryAutoConfiguration.class, RestClientAutoConfiguration.class,
		WebClientAutoConfiguration.class, ToolCallingAutoConfiguration.class })
public class DeepSeekChatAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public DeepSeekChatModel deepSeekChatModel(DeepSeekConnectionProperties commonProperties,
			DeepSeekChatProperties chatProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
			ObjectProvider<WebClient.Builder> webClientBuilderProvider, ToolCallingManager toolCallingManager,
			RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
			ObjectProvider<ObservationRegistry> observationRegistry,
			ObjectProvider<ChatModelObservationConvention> observationConvention,
			ObjectProvider<ToolExecutionEligibilityPredicate> deepseekToolExecutionEligibilityPredicate) {

		var deepSeekApi = deepSeekApi(chatProperties, commonProperties,
				restClientBuilderProvider.getIfAvailable(RestClient::builder),
				webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler);

		var chatModel = DeepSeekChatModel.builder()
			.deepSeekApi(deepSeekApi)
			.defaultOptions(chatProperties.getOptions())
			.toolCallingManager(toolCallingManager)
			.toolExecutionEligibilityPredicate(deepseekToolExecutionEligibilityPredicate
				.getIfUnique(DefaultToolExecutionEligibilityPredicate::new))
			.retryTemplate(retryTemplate)
			.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
			.build();

		observationConvention.ifAvailable(chatModel::setObservationConvention);

		return chatModel;
	}

	private DeepSeekApi deepSeekApi(DeepSeekChatProperties chatProperties,
			DeepSeekConnectionProperties commonProperties, RestClient.Builder restClientBuilder,
			WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) {

		String resolvedBaseUrl = StringUtils.hasText(chatProperties.getBaseUrl()) ? chatProperties.getBaseUrl()
				: commonProperties.getBaseUrl();
		Assert.hasText(resolvedBaseUrl, "DeepSeek base URL must be set");

		String resolvedApiKey = StringUtils.hasText(chatProperties.getApiKey()) ? chatProperties.getApiKey()
				: commonProperties.getApiKey();
		Assert.hasText(resolvedApiKey, "DeepSeek API key must be set");

		return DeepSeekApi.builder()
			.baseUrl(resolvedBaseUrl)
			.apiKey(new SimpleApiKey(resolvedApiKey))
			.completionsPath(chatProperties.getCompletionsPath())
			.betaPrefixPath(chatProperties.getBetaPrefixPath())
			.restClientBuilder(restClientBuilder)
			.webClientBuilder(webClientBuilder)
			.responseErrorHandler(responseErrorHandler)
			.build();
	}

}

2. 应用配置

application.properties 中配置 DeepSeek API 相关参数:

spring.application.name=quick-start

# DeepSeek API 配置
spring.ai.deepseek.api-key=${DEEPSEEK_API_KEY}
spring.ai.deepseek.chat.options.model=deepseek-reasoner

配置说明

  • api-key:使用环境变量 ${DEEPSEEK_API_KEY} 管理 API 密钥,提高安全性
  • model:指定使用 deepseek-reasoner 模型,该模型具有强大的推理能力

核心代码实现

1. 主应用类

@SpringBootApplication
public class ArtisanAIQuickStartApplication {
    public static void main(String[] args) {
        SpringApplication.run(ArtisanAIQuickStartApplication.class, args);
    }
}

这是一个标准的 Spring Boot 启动类,通过 @SpringBootApplication 注解自动配置 Spring AI 相关组件。

2. 功能测试类详解

功能一:基础对话调用

@Test
public void testDeepSeek(@Autowired DeepSeekChatModel deepSeekChatModel){
    // 调用聊天模型并获取响应内容
    String content = deepSeekChatModel.call("你好");
    System.out.println(content);
}

功能说明

  • 最简单的 AI 调用方式
  • 直接传入问题字符串,返回完整响应
  • 适合简单的问答场景

应用场景

  • 简单的智能问答
  • 文本生成
  • 内容总结

功能二:流式响应

@Test
public void testDeepSeekStream(@Autowired DeepSeekChatModel deepSeekChatModel){
    // 发起流式聊天请求,获取响应流
    Flux<String> stream = deepSeekChatModel.stream("你好");
    // 遍历响应流并打印每个响应片段
    stream.toIterable().forEach(System.out::println);
}

功能说明

  • 使用响应式编程模型 (Reactor)
  • 返回 Flux<String> 流式数据
  • 实时获取 AI 生成的内容片段

技术优势

  • 提升用户体验:逐步显示生成内容,减少等待感
  • 降低首字节时间 (TTFB)
  • 适合长文本生成场景

应用场景

  • 实时对话系统
  • 长文章生成
  • 代码生成
  • 实时翻译

功能三:获取推理功能分析

@Test
public void testDeepSeekReasoning(@Autowired DeepSeekChatModel deepSeekChatModel){
    // 创建提示信息
    Prompt prompt = new Prompt("你好,你是谁");
    // 调用模型获取聊天响应
    ChatResponse chatResponse = deepSeekChatModel.call(prompt);

    // 获取助手消息并转换为DeepSeek助手消息类型
    DeepSeekAssistantMessage assistantMessage = 
        (DeepSeekAssistantMessage)chatResponse.getResult().getOutput();

    // 打印推理内容
    System.out.println(assistantMessage.getReasoningContent());
    System.out.println("-----------------------------");
    // 打印文本内容
    System.out.println(assistantMessage.getText());
}

功能说明

  • 使用 deepseek-reasoner 模型的特殊能力
  • 不仅返回答案,还返回推理过程
  • 通过 getReasoningContent() 获取 AI 的思考过程

核心价值

  • 透明性:了解 AI 如何得出结论
  • 可解释性:提高 AI 决策的可信度
  • 调试能力:帮助开发者理解模型行为

应用场景

  • 需要解释的决策系统
  • 教育场景(展示解题过程)
  • 复杂问题分析
  • AI 行为审计

功能四:高级选项配置

@Test
public void testChatOptions(@Autowired DeepSeekChatModel deepSeekChatModel){
    // 构建聊天选项配置,设置模型参数
    DeepSeekChatOptions deepSeekChatOptions = DeepSeekChatOptions.builder()
            .model("deepseek-chat")
            .maxTokens(1024)
            // .stop(Arrays.asList(","))  // 可选:设置停止词
            .temperature(2.0)
            .build();

    // 创建聊天提示,包含用户请求和配置选项
    Prompt prompt = new Prompt("请作一首关于中秋节的诗", deepSeekChatOptions);
    // 调用模型获取响应
    ChatResponse chatResponse = deepSeekChatModel.call(prompt);
    // 输出模型生成的文本结果
    System.out.println(chatResponse.getResult().getOutput().getText());
}
spring:
  ai:
    deepseek:
      api-key: ${DEEP_SEEK_KEY}
      chat:
        options:
          model: deepseek-chat
          max-tokens: 20
          stop:
              - "\n"    #只想一行
              - "。"    #只想一句话
              - "政治"  #敏感词
              - "最后最总结一下"  #这种AI惯用的模板词, 减少AI词汇, 让文章更拟人

配置参数详解

参数 说明 取值范围 影响
model 指定使用的模型 deepseek-chat, deepseek-reasoner 等 决定模型能力
maxTokens 最大生成令牌数 正整数(如 1024) 控制输出长度
temperature 温度参数 0.0 - 2.0 控制创造性:
- 低值(0-0.7):更确定、保守
- 高值(0.8-2.0):更随机、创造性
stop 停止词列表 字符串数组 遇到特定词时停止生成

应用场景

  • 需要精确控制输出格式的场景
  • 创意写作(高 temperature)
  • 精确回答(低 temperature)
  • 结构化数据生成

在这里插入图片描述

实战应用场景

1. 智能客服系统

public String handleCustomerQuery(String query) {
    DeepSeekChatOptions options = DeepSeekChatOptions.builder()
            .model("deepseek-chat")
            .temperature(0.3)  // 低温度,保证回答准确性
            .maxTokens(512)
            .build();
    
    Prompt prompt = new Prompt(query, options);
    ChatResponse response = deepSeekChatModel.call(prompt);
    return response.getResult().getOutput().getText();
}

2. 代码生成助手

public Flux<String> generateCode(String requirement) {
    String prompt = "根据以下需求生成Java代码:" + requirement;
    return deepSeekChatModel.stream(prompt);  // 流式返回,实时展示生成过程
}

3. 内容审核系统

public AuditResult auditContent(String content) {
    Prompt prompt = new Prompt("请分析以下内容是否合规:" + content);
    ChatResponse response = deepSeekChatModel.call(prompt);
    
    DeepSeekAssistantMessage message = 
        (DeepSeekAssistantMessage)response.getResult().getOutput();
    
    return new AuditResult(
        message.getText(),           // 审核结论
        message.getReasoningContent() // 审核理由
    );
}

技术要点总结

1. 依赖注入的便捷性

Spring AI 通过自动配置,开发者只需:

  • 添加依赖
  • 配置 API 密钥
  • 直接使用 @Autowired 注入 DeepSeekChatModel

无需手动初始化客户端,大大简化了开发流程。

2. 响应式编程支持

Spring AI 原生支持 Project Reactor:

  • call() 方法返回同步结果
  • stream() 方法返回 Flux<String> 异步流
  • 可以轻松集成到 WebFlux 应用中

3. 模型可配置性

提供灵活的配置方式:

  • 全局配置:在 application.properties 中设置默认参数
  • 运行时配置:通过 DeepSeekChatOptions 动态调整参数
  • 多模型切换:支持在不同场景使用不同模型

4. 类型安全

通过强类型 API 设计:

  • DeepSeekAssistantMessage 提供特定的方法访问推理内容
  • ChatResponse 结构化返回结果
  • 编译时即可发现类型错误

性能优化建议

1. 合理使用流式响应

//  推荐:长文本使用流式响应
Flux<String> stream = deepSeekChatModel.stream(longPrompt);

//  不推荐:长文本使用同步调用(可能超时)
String result = deepSeekChatModel.call(longPrompt);

2. 控制 Token 消耗

DeepSeekChatOptions options = DeepSeekChatOptions.builder()
        .maxTokens(512)  // 限制最大token数,控制成本
        .build();

3. 异步处理

@Async
public CompletableFuture<String> processAsync(String query) {
    String result = deepSeekChatModel.call(query);
    return CompletableFuture.completedFuture(result);
}

安全最佳实践

1. API 密钥管理

#  推荐:使用环境变量
spring.ai.deepseek.api-key=${DEEPSEEK_API_KEY}

#  不推荐:硬编码(安全风险)
# spring.ai.deepseek.api-key=sk-xxxxx

2. 输入验证

public String safeCall(String userInput) {
    // 验证输入长度
    if (userInput.length() > 1000) {
        throw new IllegalArgumentException("输入过长");
    }
    
    // 过滤敏感信息
    String sanitizedInput = sanitize(userInput);
    
    return deepSeekChatModel.call(sanitizedInput);
}

3. 错误处理

public String robustCall(String query) {
    try {
        return deepSeekChatModel.call(query);
    } catch (Exception e) {
        log.error("AI调用失败", e);
        return "抱歉,服务暂时不可用";
    }
}

学习路线建议

  1. 入门阶段

    • 理解基础的 call() 方法调用
    • 掌握配置文件的设置
    • 完成简单的问答功能
  2. 进阶阶段

    • 学习流式响应的使用
    • 掌握各种配置参数的作用
    • 实现复杂的对话逻辑
  3. 高级阶段

    • 利用推理功能构建可解释系统
    • 集成到微服务架构
    • 实现 AI 能力的监控和优化

扩展阅读

总结

本文通过一个完整的示例项目,详细介绍了如何使用 Spring AI 集成 DeepSeek AI 模型。主要收获包括:

  1. 简单易用:Spring AI 提供了开箱即用的 AI 集成能力
  2. 功能丰富:支持同步调用、流式响应、推理分析等多种模式
  3. 高度可配置:灵活的参数配置满足不同场景需求
  4. 生产就绪:完善的错误处理和安全机制

通过本文的学习,相信你已经掌握了 Spring AI 与 DeepSeek 集成的核心技术,可以在实际项目中应用这些知识,构建智能化的 Java 应用。


源码戳这里

我们这里先体会DeepSeekChatModel, 真正开发时,会使用更高级的封装 Chat Client API

在这里插入图片描述

Logo

更多推荐