spring ai对接deepseek

一、前言

本文主要介绍采用spring ai对接deepseek。

以及采用spring ai alibaba做智能体的示例。

使用的是deepseek的在线的模型,采用openai的协议调用。

二、pom信息

现在使用spring ai,涉及spring boot ,spring framework等的版本对应关系,顾本文也给一下pom,免得阅读者再去找了。

本文使用的主要框架的版本

spring boot 版本3.5.8

spring-ai 版本1.1.2

spring ai alibaba版本1.1.2.0

parent-pom

xml 复制代码
<?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>
    <groupId>com.shenyun</groupId>
    <artifactId>ly-ai</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <java.version>21</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <skipTests>true</skipTests>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <maven.deploy.skip>true</maven.deploy.skip>
        <!--        <spring-framework.version>6.1.0+</spring-framework.version>-->
<!--        <spring-boot.version>3.2.0</spring-boot.version>-->
        <spring-boot.version>3.5.8</spring-boot.version>

    </properties>

    <modules>
        <module>ly-ai-web</module>
    </modules>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-bom</artifactId>
                <version>1.1.2.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.1.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-extensions-bom</artifactId>
                <version>1.1.2.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>2.0.48</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version> <!-- 推荐使用最新稳定版本 -->
                <!-- 或 optional=true,视模块用途而定 -->
                <!--                <scope>provided</scope> -->
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>21</source>
                    <target>21</target>
                    <encoding>UTF-8</encoding>
                    <compilerArgs>
                        <arg>-Xlint:-options</arg>
                        <!--                        <arg>-Xlint:-options</arg>-->
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

子模块pom

xml 复制代码
<?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>com.shenyun</groupId>
        <artifactId>ly-ai</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>ly-ai-web</artifactId>
    <name>ly-ai-web</name>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring AI Alibaba Agent Framework -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-agent-framework</artifactId>
<!--            <version>1.1.2.0</version>-->
        </dependency>
        <!-- DashScope-->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>1.1.2.0</version>
        </dependency>
        <!-- OpenAI-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- Ollama-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-ollama</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>

    <build>
    </build>
</project>

三、直接上代码

api调用deepseek的接口

因为deepseek的接口是兼容openai协议的,所以使用OpenAiApi 的SDK接口

注意apikey需要换成自己的

java 复制代码
package com.shenyun.agent;

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;

/**
 * openai sdk兼容调用deepseek
 * @author shenyun
 * @date 2023/9/27
 */
public class DeepSeekSimpleExample {
    public static void main(String[] args) {

        // 设置连接和读取超时为 5 分钟(根据模型大小调整)
        HttpClient httpClient = HttpClient.create()
                .responseTimeout(Duration.ofMinutes(5));
        // 1、创建 DeepSeek API
        OpenAiApi deepSeekApi = OpenAiApi.builder()
                .baseUrl("https://api.deepseek.com")
                .apiKey("sk-")
                .webClientBuilder(
                        //自定义连接超时配置,可以使用默认的就不设置
                        WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient))
                )
                .build();

        // 2、创建 ChatModel
        ChatModel chatModel = OpenAiChatModel.builder()
                .openAiApi(deepSeekApi)
                .defaultOptions(OpenAiChatOptions.builder()
                        .model("deepseek-chat")
                        .build())
                .build() ;

        // 3、调用模型
        ChatResponse response = chatModel.call(
                new Prompt("How many letter 'r' are in the word 'strawberry'?"));

        // 4、打印结果
//        String thinking = response.getResult().getMetadata().get("thinking");
//        System.out.println("thinking:\n"+ thinking);
        String answer = response.getResult().getOutput().getText();
        System.out.printf(answer);
    }
}

使用spring ai alibaba的框架创造智能体

注意apikey需要换成自己的

java 复制代码
package com.shenyun.agent;

import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import com.alibaba.cloud.ai.graph.exception.GraphRunnerException;
import lombok.Data;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.function.FunctionToolCallback;

import java.util.function.BiFunction;

public class DeepSeekAgentExample {
    public static void main(String[] args) {
        // 1、初始化 DeepSeek API
        OpenAiApi deepSeekApi = OpenAiApi.builder()
                .baseUrl("https://api.deepseek.com")
                .apiKey("sk-")
                .build()
                ;
        
        // 2、创建 DeepSeek ChatModel
        ChatModel chatModel = OpenAiChatModel.builder()
                .openAiApi(deepSeekApi)
                .defaultOptions(OpenAiChatOptions.builder()
                        .model("deepseek-chat")
                        .temperature(0.7)
                        .build())
                .build();


        // 3、创建工具
        // 创建天气查询工具
        ToolCallback weatherTool = FunctionToolCallback
                .builder("get_weather", new WeatherTool())
                .description("获取指定城市的天气信息")
                .inputType(WeatherTool.Input.class)
                .build();

        // 创建时间查询工具
        ToolCallback timeTool = FunctionToolCallback
                .builder("get_current_time", new TimeTool())
                .description("获取当前时间")
                .inputType(Void.class)
                .build();

        // 创建计算器工具
        ToolCallback calculatorTool = FunctionToolCallback
                .builder("calculate", new CalculatorTool())
                .description("执行数学计算,支持加减乘除")
                .inputType(CalculatorTool.Input.class)
                .build();

        // 4、创建 agent
        ReactAgent agent = ReactAgent.builder()
                .name("deepseek-chat")
                .model(chatModel)
                .tools(weatherTool, timeTool, calculatorTool)
                .systemPrompt("你是一个有用的助手,可以查询天气,获取时间,计算数学表达式")
                .saver(new MemorySaver())
                .build();

        // 5、测试调用
//        testAgent(agent, "[北京]今天天气怎么样?");
//        testAgent(agent, "现在几点了?");
        testAgent(agent, "计算 123 + 456 等于多少?");
//        testAgent(agent, "帮我查一下上海天气,然后告诉我现在时间,最后计算 100 * 50");
    }

    private static void testAgent(ReactAgent agent, String query) {
        System.out.println("\n用户提问: " + query);
        try {
            AssistantMessage response = agent.call(query);
            System.out.println("Agent 回复: " + response.getText());
        } catch (GraphRunnerException e) {
            System.err.println("调用失败: " + e.getMessage());
        }
        System.out.println("-".repeat(50));
    }

    public static class WeatherTool implements BiFunction<WeatherTool.Input, ToolContext, String> {
        @Data
        public static class Input {
            private String city;
        }
        @Override
        public String apply(Input input, ToolContext toolMetadata) {
            String city = input.city;
            System.out.println("WeatherTool called with city: " + city);
            if (city == null || city.trim().isEmpty()) {
                return "请提供有效的城市名称";
            }

            // 模拟天气数据
            String[] weatherConditions = {"晴天", "多云", "阴天", "小雨", "大雨", "雪"};
            int temp = (int) (Math.random() * 30) + 5; // 5-35度
            String condition = weatherConditions[(int) (Math.random() * weatherConditions.length)];

            return String.format("%s今天的天气是%s,温度为%d°C", city, condition, temp);
        }
    }


    // 时间查询工具
    public static class TimeTool implements BiFunction<Void, ToolContext, String> {
        @Override
        public String apply(Void unused, ToolContext toolMetadata) {
            return "当前时间: " + new java.util.Date().toString();
        }
    }

    // 计算器工具
    public static class CalculatorTool implements BiFunction<CalculatorTool.Input, ToolContext, String> {
        @Data
        public static class Input {
            private String expression;
        }
        @Override
        public String apply(Input input, ToolContext toolMetadata) {
            String expression = input.expression;
            if (expression == null || expression.trim().isEmpty()) {
                return "请提供有效的数学表达式";
            }
            
            try {
                // 简单的计算器实现
                expression = expression.trim();
                double result;
                
                if (expression.contains("+")) {
                    String[] parts = expression.split("\\+");
                    result = Double.parseDouble(parts[0].trim()) + Double.parseDouble(parts[1].trim());
                } else if (expression.contains("-")) {
                    String[] parts = expression.split("-");
                    result = Double.parseDouble(parts[0].trim()) - Double.parseDouble(parts[1].trim());
                } else if (expression.contains("*")) {
                    String[] parts = expression.split("\\*");
                    result = Double.parseDouble(parts[0].trim()) * Double.parseDouble(parts[1].trim());
                } else if (expression.contains("/")) {
                    String[] parts = expression.split("/");
                    result = Double.parseDouble(parts[0].trim()) / Double.parseDouble(parts[1].trim());
                } else {
                    return "不支持的表达式格式,请使用 +, -, *, / 进行计算";
                }
                
                return String.format("计算结果: %.2f", result);
            } catch (Exception e) {
                return "计算错误: " + e.getMessage();
            }
        }
    }
}

四、总结及踩坑(重点)

spring ai与spring ai alibaba的区别

Spring AI是(基础能力):

统一抽象:ChatModel、EmbeddingModel、Prompt、Tool、VectorStore 等

支持多种国际模型:OpenAI、Gemini、Claude、Mistral、Ollama 等

支持主流向量数据库:PostgreSQL(pgvector)、Redis、Milvus 等

局限:仅提供原子组件,无内置工作流编排、无智能体框架、无状态管理

Spring AI Alibaba是(增强能力):

在完全兼容 Spring AI 的基础上,新增了些功能:
Agent Framework

内置 ReActAgent、SupervisorAgent、SequentialAgent 等模式

自动上下文工程、人机交互(Human-in-the-Loop)

开箱即用构建具备推理+工具调用能力的智能体
Graph(核心创新)

基于 DAG 的低代码工作流引擎(类似 LangGraph 的 Java 实现)

预置节点:LlmNode、RAGSearchNode、SecurityCheckNode、ToolNode 等

支持条件分支、并行执行、循环、全局状态管理
国内在线模型的协议

深度集成国内模型(通义千问、月之暗面、DeepSeek)+ 兼容国际模型

关于智能体中工具方法的定义

如WeatherTool,TimeTool,CalculatorTool这三个方法的定义。

1、如果有入参,一定要定义一个DTO对象,即便入参只有一个参数,不要直接使用String

下面代码是错误的示例

java 复制代码
// 天气查询工具
    public static class WeatherTool implements BiFunction<String, ToolContext, String> {
        @Override
        public String apply(String city, ToolContext toolMetadata) {
            // 模拟天气数据
            if (city == null || city.trim().isEmpty()) {
                return "请提供有效的城市名称";
            }

            // 这里可以接入真实的天气API
            String[] weatherConditions = {"晴天", "多云", "阴天", "小雨", "大雨", "雪"};
            int temp = (int) (Math.random() * 30) + 5; // 5-35度
            String condition = weatherConditions[(int) (Math.random() * weatherConditions.length)];

            return String.format("%s今天的天气是%s,温度为%d°C", city, condition, temp);
        }
    }

以下产生是错误日志

复制代码
19:13:36.208 [main] WARN org.springframework.ai.retry.RetryUtils -- Retry error. Retry count:1
org.springframework.ai.retry.NonTransientAiException: 400 - {"error":{"message":"Invalid schema for function 'calculate': schema must be a JSON Schema of 'type: \"object\"', got 'type: \"string\"'.","type":"invalid_request_error","param":null,"code":"invalid_request_error"}}
	at org.springframework.ai.retry.RetryUtils$1.handleError(RetryUtils.java:73)
	at org.springframework.ai.retry.RetryUtils$1.handleError(RetryUtils.java:57)
	at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71)
	at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
	at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:838)
	at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.lambda$readBody$4(DefaultRestClient.java:827)
	at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:216)
	at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:826)

2、入参定义的DTO一定要写get,set方法。或者使用@Data这类注解。

相关推荐
AC赳赳老秦12 小时前
2026国产算力新周期:DeepSeek实战适配英伟达H200,引领大模型训练效率跃升
大数据·前端·人工智能·算法·tidb·memcache·deepseek
callJJ16 小时前
Spring AI 文本聊天模型完全指南:ChatModel 与 ChatClient
java·大数据·人工智能·spring·spring ai·聊天模型
OPEN-Source17 小时前
大模型实战:搭建一张“看得懂”的大模型应用可观测看板
人工智能·python·langchain·rag·deepseek
AC赳赳老秦2 天前
代码生成超越 GPT-4:DeepSeek-V4 编程任务实战与 2026 开发者效率提升指南
数据库·数据仓库·人工智能·科技·rabbitmq·memcache·deepseek
小白狮ww2 天前
要给 OCR 装个脑子吗?DeepSeek-OCR 2 让文档不再只是扫描
人工智能·深度学习·机器学习·ocr·cpu·gpu·deepseek
hay_lee2 天前
Spring AI实现对话聊天-流式输出
java·人工智能·ollama·spring ai
realhuizhu2 天前
为什么程序员配出的颜色像"斑斓的灰"?因为你还在靠直觉
前端开发·ai工具·ui设计·deepseek·程序员提升
逐梦苍穹2 天前
速通DeepSeek论文mHC:给大模型装上物理阀门的架构革命
人工智能·deepseek·mhc
realhuizhu4 天前
你有多少次对着设计稿说"感觉不对,但说不上来"?
提示词工程·设计效率·deepseek·ai设计工具·品牌logo