当前位置: 首页 > news >正文

SpringAI框架接入Deepseek和豆包实现智能聊天

一、SpringAI框架调用deepseek实现聊天功能

1.创建一个Springboot项目

注意:开发版本必须要JDK17以上(包含JDK17)

在进行创建springboot项目时,添加Spring Web和OpenAI两个依赖,不要添加lombok依赖,创建完项目后自己在maven中添加lombok的依赖,这是一个小小的bug,Springboot版本为3.2.x或者更高版本

手动添加下面代码到pom.xml文件中

<repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>

因为 DeepSeek API 使用与 OpenAI 兼容的 API 格式,通过修改配置,我们可以使用 OpenAI SDK 来访问 DeepSeek API。所以下一步我们只需在 application.yml 中将对应的秘钥和 URL 替换为 DeepSeek 的即可。

application.yml 文件:

spring:ai:openai:api-key: ${DEEPSEEK_API_KEY}base-url: https://api.deepseek.comembedding:enabled: falsechat:options:temperature: 0.8model: deepseek-chat
这里将嵌入功能禁用,因为 DeepSeek 的 API 暂不支持此功能,虽然其提供了类似于 Open AI 类似的接口,但未实现此功能。而 Spring AI 的模块化设计会自动初始化 Open AI 的相关模块(包括嵌入模块),所以如果不禁用会报错(404  Not Found)未找到模块。

temperature:采样温度,控制 AI 输出内容的创造性,值越高越具有随机性;越低则结果越集中和确定。

model:要使用的模型名。

ChatResponse response = chatModel.call(new Prompt(message,OpenAiChatOptions.builder().model("deepseek-chat").temperature(0.4).build()));

当然,也可以在运行时指定对应的模型和采样温度。其中的 Prompt 是封装用户输入请求的对象,由两部分组成:

组成部分说明
用户输入的消息内容要发送给 AI 模型的文本(例如 "你好!你是谁?"
模型配置选项通过 OpenAiChatOptions 定义的参数(如模型名称、温度值等)

2.测试 Spring AI 聊天模型

@RestController
public class ChatController {private final OpenAiChatModel chatModel;@Autowiredpublic ChatController(OpenAiChatModel chatModel) {this.chatModel = chatModel;}@GetMapping("/ai/generate")public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {return Map.of("generation", this.chatModel.call(message));}@GetMapping("/ai/generateStream")public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {Prompt prompt = new Prompt(new UserMessage(message));return this.chatModel.stream(prompt);}
}
同步生成接口:

流式生成接口

可以看到返回的结果是一段一段的,这就是流式响应。但这样的观赏性很差,所以我们可以将结果处理后再返回,这样就可以大大提高结果的观赏性。

@GetMapping(value = "/ai/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {return chatModel.stream(new Prompt(message)).map(chatResponse -> chatResponse.getResult().getOutput().getText());}

produces = MediaType.TEXT_EVENT_STREAM_VALUE:这个注解指定了响应的媒体类型为 text/event-stream,这是用于服务器推送事件(SSE)的标准媒体类型,适合流式输出。

二、SpringAI框架调用豆包实现聊天功能

1.引入maven依赖

<dependency><groupId>com.volcengine</groupId><artifactId>volcengine-java-sdk-ark-runtime</artifactId><version>LATEST</version></dependency>
​

2.配置类

package com.hpp.common.AIChat;
​
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
​
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
​
import com.google.gson.Gson;
import com.hpp.common.redisson.RedisCache;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
​
@Component
public class AIChatDouBao {private static final Logger LOGGER = LoggerFactory.getLogger(AIChatDouBao.class);@Autowiredprivate RedisCache redisCache;private Gson gson = new Gson();private String apiKey = "xxxxxxxxxxxxxxxx";public SseEmitter conversation(String question) {// 创建ArkService实例ArkService arkService = ArkService.builder().apiKey(apiKey).build();// 初始化消息列表List<ChatMessage> chatMessages = new ArrayList<>();// 创建用户消息ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER) // 设置消息角色为用户.content(question) // 设置消息内容.build();// 将用户消息添加到消息列表chatMessages.add(userMessage);// 创建聊天完成请求ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder().model("ep-xxxxxxxxxxxx")// 需要替换为您的推理接入点ID.messages(chatMessages) // 设置消息列表.build();// 发送聊天完成请求并打印响应// 获取响应并打印每个选择的消息内容SseEmitter emitter = new SseEmitter();try {new Thread(() -> {arkService.streamChatCompletion(chatCompletionRequest).doOnError(Throwable::printStackTrace).doFinally(() -> {LOGGER.info("完成");emitter.complete();}).blockingForEach(choice -> {if (choice.getChoices().size() > 0) {ChatMessage message = choice.getChoices().get(0).getMessage();// 判断是否触发深度推理,触发则打印模型输出的思维链内容if (message.getReasoningContent() != null && !message.getReasoningContent().isEmpty()) {LOGGER.info(message.getReasoningContent());emitter.send(message.getReasoningContent());}// 打印模型输出的回答内容emitter.send(message.getContent().toString());LOGGER.info(message.getContent().toString());}});
​}).start();} catch (Exception e) {LOGGER.error("ai回复异常", e);emitter.completeWithError(e); // 发生错误时,通知客户端} finally {
​}return emitter;}
​public String getAccessToken() throws IOException {return "";}
​
}
​
​

3.controller层

@RestController
@RequestMapping(value = "chat")
public class ChatController {private static final Logger LOGGER = LoggerFactory.getLogger(ChatController.class);@Autowiredprivate AIChatDouBao aiChatDouBao;
​@GetMapping("/event-stream")public SseEmitter streamEvents(HttpServletRequest req, @RequestParam String question) {return aiChatDouBao.conversation(question);}
​
}

文章转载自:

http://sZxT9Ez4.pwfwk.cn
http://RyFd1bKG.pwfwk.cn
http://6lvSRsEF.pwfwk.cn
http://5YgzDqjQ.pwfwk.cn
http://Bt0cYupi.pwfwk.cn
http://KnRs7bwQ.pwfwk.cn
http://VAZPwGAL.pwfwk.cn
http://jpEZVEJj.pwfwk.cn
http://6RWUT2NE.pwfwk.cn
http://jjAXunbQ.pwfwk.cn
http://bJHTflKq.pwfwk.cn
http://5PTGEJKT.pwfwk.cn
http://jVhMkVp8.pwfwk.cn
http://mBRbwZjS.pwfwk.cn
http://mQpumApj.pwfwk.cn
http://4w1ju6tK.pwfwk.cn
http://NfGkfaEl.pwfwk.cn
http://UxfUygpq.pwfwk.cn
http://e9hsU3Jd.pwfwk.cn
http://KqbEtf3r.pwfwk.cn
http://9g7sQVNb.pwfwk.cn
http://CANGcnl8.pwfwk.cn
http://buDjUtry.pwfwk.cn
http://zy8cdr9W.pwfwk.cn
http://BlGiiB4S.pwfwk.cn
http://brEBKihu.pwfwk.cn
http://X3qRNznx.pwfwk.cn
http://329vOkVc.pwfwk.cn
http://CdGTNxhl.pwfwk.cn
http://jndOQk5x.pwfwk.cn
http://www.dtcms.com/a/385684.html

相关文章:

  • 江协科技STM32课程笔记(一) —GPIO
  • 江协科技STM32课程笔记(二)—外部中断EXTI
  • 科技信息差(9.15)
  • 龙珠KS6 10.5T矿机评测:性能、功耗、噪音与冷却分析
  • 打工人日报#20250915
  • 新一代车载诊断框架简介
  • 05-索引-性能分析
  • 【数据工程】 2. Unix 基础与文件操作
  • 第四课、 TypeScript 中 Cocos 的生命周期
  • 联邦学习论文分享:DPD-fVAE
  • Pairwise排序损失:让机器学会排序的艺术
  • 硬件开发—IMX6ULL裸机—UART通信
  • 蓝牙上位机开发指南
  • 【课堂笔记】复变函数-1
  • 谈谈人大金仓数据库
  • C#调用钉钉API发送通知教程
  • 电子电气架构 --- 产线EOL为何需要智能升级?
  • 无人机姿态控制系统详解与实现
  • 7.Redis 主从复制(重在理解)
  • 从零搭建RAG应用:跳过LangChain,掌握文本分块、向量检索、指代消解等核心技术实现
  • 从0开始做一个完整项目 -- 软件跨平台编译打包全流程
  • comfyUI实战——使用openArt的工作流
  • linux 之 struct attribute
  • 强化学习PPO-分类任务
  • 决策树模型全解析:从分类到回归(基于鸢尾花数据集)
  • shell脚本部署lamp
  • c语言6:static 关键字控制变量/函数的 “生命周期” 与 “可见性”
  • MySQL 数据库对象与视图:从概念到实战,掌握虚拟表的核心价值
  • 【VPX361】基于3U VPX总线架构的XCZU47DR射频收发子模块
  • 消火栓设备工程量计算 -【图形识别】秒计量