SpringAI框架接入Deepseek和豆包实现智能聊天
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder().model("ep-xxxxxxxxxxxx")// 需要替换为您的推理接入点ID。在进行创建springboot项目时,添加Spring Web和OpenAI两个依赖,不要添加lombok依赖,创建完项目后自己在maven中添加lombok的
一、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.com
embedding:
enabled: false
chat:
options:
temperature: 0.8
model: 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;
@Autowired
public 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);
@Autowired
private 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);
@Autowired
private AIChatDouBao aiChatDouBao;
@GetMapping("/event-stream")
public SseEmitter streamEvents(HttpServletRequest req, @RequestParam String question) {
return aiChatDouBao.conversation(question);
}
}
更多推荐
所有评论(0)