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这类注解。

相关推荐
大模型真好玩2 天前
大模型训练全流程实战指南工具篇(七)——EasyDataset文档处理流程
人工智能·langchain·deepseek
Rockbean2 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
爱吃的小肥羊3 天前
DeepSeek V4 细节曝光:100 万上下文 + 原生多模态
人工智能·aigc·deepseek
小小工匠3 天前
大模型开发 - SpringAI之MCP Client开发:让Agent动态调用远程工具服务
spring ai·mcp·mcp client
AC赳赳老秦4 天前
云原生AI故障排查新趋势:利用DeepSeek实现高效定位部署报错与性能瓶颈
ide·人工智能·python·云原生·prometheus·ai-native·deepseek
AI大模型..4 天前
Dify 本地部署安装教程(Windows + Docker),大模型入门到精通,收藏这篇就足够了!
人工智能·程序员·开源·llm·github·deepseek·本地化部署
AC赳赳老秦5 天前
预见2026:DeepSeek与云平台联动的自动化流程——云原生AI工具演进的核心引擎
人工智能·安全·云原生·架构·自动化·prometheus·deepseek
AC赳赳老秦5 天前
DeepSeek助力云原生AI降本:容器化部署资源优化与算力利用率提升技巧
网络·python·django·prompt·tornado·ai-native·deepseek
@SmartSi5 天前
Spring AI 实战:通过 ChatMemory 构建有记忆的智能对话应用
llm·spring ai
AC赳赳老秦6 天前
多模态 AI 驱动办公智能化变革:DeepSeek 赋能图文转写与视频摘要的高效实践
java·ide·人工智能·python·prometheus·ai-native·deepseek