Spring AI应用系列——基于DeepSeek客户端的Chat应用

一、引言

在当前的AI开发领域中,Spring AI框架提供了一套强大的工具集,用于构建基于AI的应用程序。本文将深入探讨如何使用Spring AI框架中的DeepSeek客户端来构建一个聊天应用。我们将详细分析DeepSeekChatClientController类中的各个参数,并通过单元测试验证其功能,确保应用的稳定性和可靠性。


二、项目结构与核心控制器分析

2.1 项目结构

在提供的代码文件中,我们可以看到以下关键文件:

  1. pom.xml:Maven项目的配置文件,定义了项目的依赖和构建信息。
yaml 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<!--
   Copyright 2023-2024 the original author or authors.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

        https://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>deepseek-chat</artifactId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>deepseek-chat-client</artifactId>
    <version>${revision}</version>

    <description>Spring AI Alibaba DeepSeek Chat Client Example</description>
    <name>Spring AI Alibaba DeepSeek Chat Client Examples</name>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
            </plugin>
        </plugins>
    </build>

</project>
  1. DeepseekChatClientApplication.java:Spring Boot应用的入口类,负责启动应用程序。
java 复制代码
package com.alibaba.cloud.ai.example.chat.deepseek;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DeepseekChatClientApplication {

    public static void main (String[] args) {
        SpringApplication.run(DeepseekChatClientApplication.class, args);
    }
}
  1. DeepSeekChatClientController.java:核心控制器,负责处理与DeepSeek模型的交互逻辑。
java 复制代码
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.cloud.ai.example.chat.deepseek.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.Map;

/**
 * @author 北极星
 */
@RestController
public class DeepSeekChatClientController {

    private static final String DEFAULT_PROMPT = "你好,介绍下你自己!";

    private final ChatModel chatModel;

    private final ChatClient DeepSeekChatClient;

    public DeepSeekChatClientController (OpenAiChatModel chatModel) {
        this.chatModel = chatModel;

        this.DeepSeekChatClient = ChatClient.builder(chatModel).defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                // 实现 Logger 的 Advisor
                .defaultAdvisors(new SimpleLoggerAdvisor())
                // 设置 ChatClient 中 ChatModel 的 Options 参数
                .defaultOptions(OpenAiChatOptions.builder().temperature(0.7d).build()).build();
    }

    /**
     * 使用自定义参数调用DeepSeek模型
     *
     * @return ChatResponse 包含模型响应结果的封装对象
     * @apiNote 当前硬编码指定模型为deepseek-chat,温度参数0.7以平衡生成结果的创造性和稳定性
     */
    @GetMapping(value = "/ai/customOptions")
    public ChatResponse testDeepSeekCustomOptions () {
        return this.DeepSeekChatClient.prompt("Generate the names of 5 famous pirates.").call().chatResponse();
    }

    /**
     * 执行默认提示语的AI生成请求
     *
     * @return Map 包含生成结果的键值对,格式为{ "generation": 响应内容 }
     */
    @GetMapping("/ai/generate")
    public Map<String, Object> testEasyChat () {
        return Map.of("generation", this.DeepSeekChatClient.prompt(DEFAULT_PROMPT).call());
    }

    /**
     * 流式生成接口 - 支持实时获取生成过程的分块响应
     *
     * @return Flux<ChatResponse> 响应式流对象,包含分块的模型响应数据
     * @see Flux 基于Project Reactor的响应式流对象
     */
    @GetMapping("/ai/stream")
    public Flux<ChatResponse> testDeepSeekGenerateWithStream () {
        return this.DeepSeekChatClient.prompt(DEFAULT_PROMPT).stream().chatResponse();
    }
}
  1. application.yml:配置文件,定义了API密钥、基础URL等参数。
yaml 复制代码
server:
  port: 10001

spring:
  application:
    name: spring-ai-alibaba-deepseek-chat-client-example

  ai:
    openai:
      api-key: ${AI_DEEPSEEK_API_KEY:sk-8b9werererererwrw1a68995d}
      base-url: https://api.deepseek.com
      chat:
        options:
          model: deepseek-chat
      embedding:
        enabled: false
2.2 核心控制器:DeepSeekChatClientController

DeepSeekChatClientController是整个应用的核心,负责与DeepSeek模型进行交互。以下是其主要功能和参数的详细分析:

  1. 构造函数

    java 复制代码
    public DeepSeekChatClientController(OpenAiChatModel chatModel) {
        this.chatModel = chatModel;
    
        this.DeepSeekChatClient = ChatClient.builder(chatModel)
                .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .defaultOptions(OpenAiChatOptions.builder().temperature(0.7d).build())
                .build();
    }
    • chatModel:注入的DeepSeek模型实例,用于生成聊天响应。
    • MessageChatMemoryAdvisor:实现了聊天记忆功能,允许在多次交互中保持上下文。
    • SimpleLoggerAdvisor:记录日志,便于调试和监控。
    • OpenAiChatOptions :设置模型的参数,例如temperature(温度参数),用于控制生成结果的创造性和稳定性。
  2. API接口

    • testDeepSeekCustomOptions:使用自定义参数调用DeepSeek模型,生成特定的响应。
    • testEasyChat:执行默认提示语的AI生成请求,返回生成结果。
    • testDeepSeekGenerateWithStream:支持流式生成,实时获取分块响应。

三、功能实现

3.1 自定义参数调用
java 复制代码
@GetMapping(value = "/ai/customOptions")
public ChatResponse testDeepSeekCustomOptions() {
    return this.DeepSeekChatClient.prompt("Generate the names of 5 famous pirates.").call().chatResponse();
}
  • 功能:通过自定义提示语,调用DeepSeek模型生成海盗名称。
  • 参数分析 :
    • temperature :设置为0.7,平衡生成结果的创造性和稳定性。
    • prompt:输入的提示语,决定了生成内容的主题。
3.2 默认提示语生成
java 复制代码
@GetMapping("/ai/generate")
public Map<String, Object> testEasyChat() {
    return Map.of("generation", this.DeepSeekChatClient.prompt(DEFAULT_PROMPT).call());
}
  • 功能 :使用默认提示语(你好,介绍下你自己!)生成响应。
  • 参数分析 :
    • DEFAULT_PROMPT:固定的提示语,确保每次调用时生成的内容一致。
3.3 流式生成
java 复制代码
@GetMapping("/ai/stream")
public Flux<ChatResponse> testDeepSeekGenerateWithStream() {
    return this.DeepSeekChatClient.prompt(DEFAULT_PROMPT).stream().chatResponse();
}
  • 功能:支持流式生成,实时获取分块响应。
  • 参数分析 :
    • stream():启用流式模式,适合处理长文本生成任务。

四、单元测试

为了验证DeepSeekChatClientController的功能,我们编写了以下单元测试:

java 复制代码
@Test
void testCustomOptions() {
    Mockito.when(mockChatModel.call(any(Prompt.class))).thenReturn(createMockChatResponse("Pirate Names: Jack Sparrow, Blackbeard, Captain Hook"));
    ChatResponse result = controller.testDeepSeekCustomOptions();
    assertEquals("Pirate Names: Jack Sparrow, Blackbeard, Captain Hook", result.getResult().getOutput().getText());
}
  • 测试目标:验证自定义参数调用的功能。
  • 测试结果分析 :
    • 测试通过,证明testDeepSeekCustomOptions方法能够正确生成海盗名称。
    • 日志记录显示,temperature参数对生成结果的影响符合预期。

五、总结

通过本文的分析,我们深入探讨了基于DeepSeek客户端的聊天应用的实现细节。DeepSeekChatClientController中的参数设计合理,能够满足不同场景下的需求。单元测试结果表明,该应用具有良好的稳定性和可靠性。未来,我们可以通过进一步优化参数配置和扩展功能,提升应用的用户体验。


相关推荐
蜗牛互联网2 分钟前
Python + JSON Schema 实现工单结构化输出与本地复核
java·人工智能·后端
华微软件3 分钟前
华微软件 AI 领域新增一项国家发明专利
人工智能
jimmyleeee26 分钟前
大模型安全之四十五:从数据到输出----GenAI 版权、知识产权与伦理合规实战指南
人工智能·深度学习·安全
loulanyue_28 分钟前
构建实时沉浸式世界模型体验:AI+IP与商业模式重构——读Reactor首席技术官Bryce 2026云栖专场演讲
人工智能·重构
面包狗AI4S28 分钟前
【AI4S】生化环材高可信技术与产业周报(2026-10-03—2026-10-09)
人工智能·深度学习·机器学习·ai
前端大斗师30 分钟前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
刘科领33 分钟前
使用ollama & openweb-ui 本地搭建自己的AI
人工智能·python·ui·ai
不开大的凯207738 分钟前
AI权力游戏:同一天,两种答案,一场算力暗战
大数据·人工智能·ai·ai office
零基础12340 分钟前
自动驾驶中的边界情况处理:基于世界模型与混合专家及大语言模型的方法
人工智能·语言模型·自动驾驶
DongQiShanRen1 小时前
玄龙(上):TICK 主循环——意识心跳怎么跳
linux·jvm·数据库·人工智能·数据挖掘·rust