Spring AI与DeepSeek实战一:快速打造智能对话应用

news/2025/3/3 10:25:51/文章来源:https://www.cnblogs.com/zlt2000/p/18747435

一、概述

在 AI 技术蓬勃发展的今天,国产大模型 DeepSeek 凭借其 低成本高性能 的特点,成为企业智能化转型的热门选择。而 Spring AI 作为 Java 生态的 AI 集成框架,通过统一API、简化配置等特性,让开发者无需深入底层即可快速调用各类 AI 服务。本文将手把手教你通过 spring-ai 集成 DeepSeek 接口实现普通对话与流式对话功能,助力你的 Java 应用轻松接入 AI 能力!

 

二、申请DeepSeek的API-KEY

相较于直接调用 DeepSeek 官方的 API,阿里云百炼基于阿里云强大的云计算基础设施,提供了高可用性和稳定性的服务,并且支持程序运行时动态切换 模型广场 中的任意大模型。

登录阿里云,进入 阿里云百炼 的页面:

https://bailian.console.aliyun.com/?apiKey=1#/api-key

创建自己的 API-KEY

 

三、项目搭建

3.1. 开发环境要求

  • JDK 17+
  • Spring Boot 3.2.x及以上

3.2. maven配置

Spring Boot 项目的 pom.xml 中添加 spring-ai 依赖

<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId>
</dependency>

增加仓库的配置

<repositories><repository><id>alimaven</id><url>https://maven.aliyun.com/repository/public</url></repository><repository><id>spring-milestones</id><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><url>https://repo.spring.io/snapshot</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>

3.3. 配置 API-KEY

application.yml 中添加以下配置:

spring:ai:dashscope:api-key: sk-xxxxxx
  • api-key 配置在阿里云百炼里申请的api-key

3.4. 创建ChatClient对象

private final ChatClient chatClient;public ChatController(ChatClient.Builder builder) {String sysPrompt = """你是一个博学的智能聊天助手,请根据用户提问回答。请讲中文。今天的日期是 {current_date}。""";this.chatClient = builder.defaultSystem(sysPrompt).defaultOptions(DashScopeChatOptions.builder()/*** 值范围:[0, 2),系统默认值0.85。不建议取值为0,无意义*/.withTemperature(1.3).withModel("deepseek-v3").build()).build();
}
  • defaultSystem 指定系统 prompt 来约束大模型的行为或者提供一些上下文信息,如这里告诉大模型今天的日期是多少,支持占位符;
  • defaultOptions 配置模型的参数
    • withTemperature 用于控制随机性和多样性的程度,值越高大模型回复的内容越丰富越天马行空
    • withModel 配置模型广场中的模型名称,这里填写 deepseek-v3

模型广场的模型名称清单:https://help.aliyun.com/zh/model-studio/getting-started/models

3.5. 创建对话接口

@GetMapping(value = "/chat")
public String chat(@RequestParam String input, HttpServletResponse response) {// 设置字符编码,避免乱码response.setCharacterEncoding("UTF-8");return chatClient.prompt().user(input).system(s -> s.param("current_date", LocalDate.now().toString())).call().content();
}

每次调用接口时,通过 system 来给 current_date 占位符动态赋值。

调用示例

  • 问身份

  • 问日期

3.6. 切换模型

@GetMapping(value = "/chat")
public String chat(@RequestParam String input, @RequestParam(required = false) String model, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");if (StrUtil.isEmpty(model)) {model = "deepseek-v3";}return chatClient.prompt().user(input).system(s -> s.param("current_date", LocalDate.now().toString())).options(DashScopeChatOptions.builder().withModel(model).build()).call().content();
}

使用 withModel 来配置模型名称

调用示例

  • 切换deepseek-r1模型

  • 切换通义千问模型

3.7. 使用prompt模板

通过 PromptTemplate 可以编辑复杂的提示词,并且也支持占位符

@GetMapping(value = "/chatTemp")
public String chatTemp(@RequestParam String input, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");// 使用PromptTemplate定义提示词模板PromptTemplate promptTemplate = new PromptTemplate("请逐步解释你的思考过程: {input}");Prompt prompt = promptTemplate.create(Map.of("input", input));return chatClient.prompt(prompt).system(s -> s.param("current_date", LocalDate.now().toString())).call().content();
}

这里提出让 deepseek-v3 进行逐步拆分思考,并把思考过程返回。

调用示例

可以看到大模型会拆分多步来进行推论结果。

3.8. 使用流式对话

当前接口需等待大模型完全生成回复内容才能返回,这用户体验并不好。为实现类似 ChatGPT 的逐句实时输出效果,可采用流式传输技术(Streaming Response)。

@GetMapping(value = "/streamChat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String input, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");// 使用PromptTemplate定义提示词模板PromptTemplate promptTemplate = new PromptTemplate("请逐步解释你的思考过程: {input}");Prompt prompt = promptTemplate.create(Map.of("input", input));return chatClient.prompt(prompt).system(s -> s.param("current_date", LocalDate.now().toString())).stream().content().concatWith(Flux.just("[DONE]")).onErrorResume(e -> Flux.just("ERROR: " + e.getMessage(), "[DONE]"));
}
  • 调用时把 call() 改成 stream()
  • 并且遵循SSE协议最后发送[DONE]终止标识

调用示例

  • data: xxx 这种是 Server-Sent Events 的格式要求;
  • 需要前端搭配 EventSource 或 WebSocket 等方式来接收流式数据,并结合 marked.js 来正确显示 markdown 语法。

 

四、总结

虽然通过 Spring AI 能够快速完成 DeepSeek 大模型与 Spring Boot 项目的对接,实现基础的对话接口开发,但这仅是智能化转型的初级阶段。要将大模型能力真正落地为生产级应用,还是需实现以下技术:

  1. 能力扩展层:通过 智能体 实现意图理解与任务调度,结合 FunctionCall 实现结构化数据交互,实现AI与业务系统的无缝对接;
  2. 知识增强层:应用 RAG(检索增强生成)技术构建领域知识库,解决大模型幻觉问题,支撑专业场景的精准问答;
  3. 流程编排层:设计 Agent 工作流实现复杂业务逻辑拆解,支持多步骤推理与自动化决策;
  4. 模型优化层:基于业务数据实施模型微调 Fine-tuning 提升垂直场景的响应质量和可控性。

 

五、完整代码

  • Gitee地址:

https://gitee.com/zlt2000/zlt-spring-ai-app

  • Github地址:

https://github.com/zlt2000/zlt-spring-ai-app

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/892835.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习特征筛选:向后淘汰法原理与Python实现

向后淘汰法(Backward Elimination)是机器学习领域中一种重要的特征选择技术,其核心思想是通过系统性地移除对模型贡献较小的特征,以提高模型性能和可解释性。该方法从完整特征集出发,逐步剔除不重要的特征,最终保留对预测结果最具影响力的变量子集。 https://avoid.over…

模板设计模式--java进阶day03

1.模板设计模式说到模板,我们第一时间想到的可能就是写作文不过这样写就是一篇完整的作文,我们应该进行修改这样修改还会存在一个问题,每一个人写的作文不同,中间的body()无法描述清楚,所以我们要将其改为抽象方法这时模板就已经写好了,当我们想写作文时,继承该模板并…

Docker部署数据库--高斯DB(opengauss)

Docker部署高斯DB整体步骤: 1、获取镜像; 2、创建并配置容器; 3、连接使用;01、获取镜像 docker pull enmotech/opengauss:latest02、启动并配置容器 启动容器 docker run --name OpenGauss \ --privileged=true -idt \ --restart=always \ -u root \ -p 15432:5432 \ -e G…

74. 搜索二维矩阵(中)

目录题目题解:数组扁平化+二分查找 题目给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。题解:数组扁平…

储运效率翻倍!物联网技术让油库管理迈向新高度

随着物联网(IoT)、人工智能(AI)和大数据技术的快速发展,传统油库管理模式正在向高度自动化的方向转型。现代油库自动化系统通过传感器、智能设备、数据通信和云端平台的协同工作,实现了从储运管理到安全监控的全流程智能化。以下是油库自动化运行的核心机制和关键环节:数…

R语言中快速生成多个有色差的颜色

001、library(randomcoloR) palette <- randomColor(count = 54) #随机生成60种颜色,其实里面有重复的 palette <- distinctColorPalette(54) #差异明显的60种 palette plot(1:54, pch = 19, cex = 2, col = palette) 。

SAP ABAP里存在类似的集合工具类

实现方式-:传统的实现 "定义一个Table Line类型为通用的对象引用(TYPE REF TO OBJECT)的内表lt_shape,用于存放圆形和长方形的实例对象引用。TYPES:BEGIN OF TY_SHAPE, SHAPE TYPE REF TO OBJECT, END OF TY_SHAPE.TYPES:TT_SHPAE TYPE STANDARD TABLE OF T…

达梦数据库连接配置

官网下载 达梦官网驱动下载:DmJdbcDriver6、DmJdbcDriver7、DmJdbcDriver8、DmJdbcDriver11官网下载地址:https://eco.dameng.com/download/滑倒网页最下方有驱动下载 DBeaver工具连接达梦数据库添加驱动打开 DBeaver,选择“数据库”->“驱动管理器”->“新建”“创建…

适配器设计模式--java进阶day03

1.设计模式 通俗来讲,设计模式就是其他程序员遇到某些问题时的解决经验,我们学习设计模式,在遇到了同样的问题后便可解决2.适配器设计模式有人可能会感到疑惑,接口和实现类会有什么问题,我们举两个例子 刚学的键盘监听,我们要使用里面的一个方法,但另外两个方法对我们来…

以防你不知道书签还能玩出什么花来

说到书签,你可能会认为它不就是用来保存网址的嘛,还能有什么花头?其实不然,它能做的事有很多,包括运行 JS 代码、将网页变成记事本、前端编辑器、计算器......说到书签,你可能会认为它不就是用来保存网址的嘛,还能有什么花头? 其实不然,它能做的事有很多,包括运行 JS…

如何避开传统文件外发方式的坑,实现文件外发权限管理?

在数字化浪潮中,企业数据已然成为核心资产,其重要性不言而喻。但数据安全事件却频频发生,给企业带来了沉重的打击。就拿2024年美国思科公司的重大数据泄露事件来说,Verizon、AT&T、微软等全球多家大厂的源代码、机密文件和登录凭证均被泄露,这些数据甚至在暗网被公然售…

错误:无法下载版本1.1.20190528的Extensions模块。它是内置的模块吗?请尝试执行genexus.exe /install命令。否则,请将模块版本更新为可访问的版本。

报错—— 错误:无法下载版本1.1.20190528的Extensions模块。它是内置的模块吗?请尝试执行genexus.exe /install命令。否则,请将模块版本更新为可访问的版本。 解决方法—— 知识库管理——》管理引用模块 找到这个——》更新 然后重新编译就行了