SpringBoot兩種方式接入DeepSeek的實(shí)現(xiàn)
方式一:基于HttpClient
步驟 1:準(zhǔn)備工作
獲取 DeepSeek API 密鑰:訪問 DeepSeek 的開發(fā)者平臺,注冊并獲取 API 密鑰。
步驟 2:引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
步驟 3:配置 DeepSeek API
配置參數(shù):在 application.yml 文件里,把 DeepSeek 的 API 端點(diǎn)和密鑰寫進(jìn)去:
在 application.properties 或 application.yml 中配置 DeepSeek 的 API 密鑰和端點(diǎn):
deepseek.api.key=sk-xxxxxxxxxx deepseek.api.url=https://api.deepseek.com/v1/chat/completions
步驟 4:自定義 DeepSeek Client Service
(1)自定義請求頭
public record DeepSeekRequest(
String model,
List<Message> messages,
double temperature,
int max_tokens
) {
public record Message(String role, String content) {}
}(2)自定義響應(yīng)體
public record DeepSeekResponse(
String id,
String object,
long created,
String model,
List<Choice> choices
) {
public record Choice(
int index,
Message message,
String finish_reason
) {
public record Message(String role, String content) {}
}
}(3)service
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class DeepSeekService {
@Value("${deepseek.api.url}")
private String apiUrl;
@Value("${deepseek.api.key}")
private String apiKey;
private final RestTemplate restTemplate;
public DeepSeekService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public String getChatResponse(String userMessage) {
// 構(gòu)造請求體
DeepSeekRequest request = new DeepSeekRequest(
"deepseek-chat",
List.of(new DeepSeekRequest.Message("user", userMessage)),
0.7,
1000
);
// 設(shè)置請求頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey);
HttpEntity<DeepSeekRequest> entity = new HttpEntity<>(request, headers);
// 發(fā)送請求
ResponseEntity<DeepSeekResponse> response = restTemplate.exchange(
apiUrl,
HttpMethod.POST,
entity,
DeepSeekResponse.class
);
// 處理響應(yīng)
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
return response.getBody().choices().get(0).message().content();
}
throw new RuntimeException("API請求失敗: " + response.getStatusCode());
}
}請求體中可以指定:調(diào)整模型、溫度、最大 token 數(shù)等
什么是溫度(Temperature)?
溫度是控制模型生成文本的“創(chuàng)造力”或“隨機(jī)性”的一個參數(shù)。你可以把它想象成調(diào)節(jié)模型的“腦洞大小”。
溫度低(比如 0.1):
模型會變得非常保守,傾向于選擇最確定、最安全的答案。
適合需要準(zhǔn)確性和一致性的任務(wù),比如回答事實(shí)性問題。
例子:問“1+1等于幾?”,模型會回答“2”,不會瞎編。
溫度高(比如 1.0 或更高):
模型會變得更有創(chuàng)造力,可能會給出一些意想不到的回答。
適合需要創(chuàng)意或多樣性的任務(wù),比如寫故事、生成詩歌。
例子:問“寫一首關(guān)于秋天的詩”,模型可能會生成一些充滿想象力的句子。
溫度適中(比如 0.7):
模型會在保守和創(chuàng)意之間找到一個平衡點(diǎn)。
適合大多數(shù)任務(wù),既能保證一定的準(zhǔn)確性,又能有一些變化。
總結(jié):
溫度低 → 模型像“學(xué)霸”,回答嚴(yán)謹(jǐn)?shù)赡軣o聊。
溫度高 → 模型像“藝術(shù)家”,回答有趣但可能不靠譜。
溫度適中 → 模型像“聰明人”,回答既靠譜又有趣。
最大 token 數(shù)(Max Tokens)
token 是模型處理文本的基本單位,可以理解為一個詞或一部分詞。
比如:
英文單詞“hello”是一個 token。
中文“你好”可能是兩個 token(每個字一個 token)。
長單詞或復(fù)雜字符可能會被拆成多個 token。
最大 token 數(shù)就是限制模型生成的文本長度??梢园阉胂蟪山o模型一個“字?jǐn)?shù)限制”。
設(shè)置較小的最大 token 數(shù)(比如 50):
模型生成的文本會非常短,可能只回答問題的核心部分。
例子:問“介紹一下太陽系”,模型可能只回答“太陽系包括太陽和八大行星”。
設(shè)置較大的最大 token 數(shù)(比如 500):
模型生成的文本會更長,可能會包含更多細(xì)節(jié)。
例子:問“介紹一下太陽系”,模型可能會詳細(xì)描述每顆行星的特點(diǎn)。
不設(shè)置最大 token 數(shù):
模型可能會一直生成文本,直到達(dá)到它的內(nèi)部限制(通常是幾千個 token)。
這可能會導(dǎo)致生成的文本過長,甚至跑題。
總結(jié):
最大 token 數(shù)小 → 模型像“話少的人”,回答簡短。
最大 token 數(shù)大 → 模型像“話多的人”,回答詳細(xì)。
不設(shè)置最大 token 數(shù) → 模型像“話癆”,可能會一直說個不停。
步驟 5:創(chuàng)建控制器
@RestController
@RequestMapping("/deepseek/chat")
public class DeepSeekController {
private final DeepSeekService deepSeekService;
public DeepSeekController(DeepSeekService deepSeekService) {
this.deepSeekService = deepSeekService;
}
@PostMapping
public ResponseEntity<?> chat(@RequestBody Map<String, String> request) {
try {
String response = deepSeekService.getChatResponse(request.get("message"));
return ResponseEntity.ok(Collections.singletonMap("response", response));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Collections.singletonMap("error", e.getMessage()));
}
}
}方式二:基于spring-ai-openai
步驟基本一致,這里羅列幾處實(shí)現(xiàn)代碼
依賴:
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-M5</spring-ai.version>
</properties>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>DeepSeekConfig:
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DeepSeekConfig {
@Bean
public ChatClient chatClient(OpenAiChatModel openAiChatModel) {
return ChatClient.builder(openAiChatModel).build();
}
}DeepSeekController:
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.ai.chat.model.ChatResponse;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api")
public class ChatController {
@Resource
private OpenAiChatModel chatModel;
private final List<Message> chatHistoryList = new ArrayList<>();
@PostConstruct
public void init() {
chatHistoryList.add(new SystemMessage("You are a helpful assistant."));
}
@PostMapping("/chat")
public ChatResponse test(@RequestBody String message) {
chatHistoryList.add(new UserMessage(message));
Prompt prompt = new Prompt(chatHistoryList);
ChatResponse chatResponse = chatModel.call(prompt);
if (chatResponse.getResult() != null && chatResponse.getResult().getOutput() != null) {
chatHistoryList.add(chatResponse.getResult().getOutput());
}
return chatResponse;
}
}到此這篇關(guān)于SpringBoot兩種方式接入DeepSeek的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot接入DeepSeek內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用FilenameFilter查找出目錄下指定后綴的文件示例
這篇文章主要介紹了Java使用FilenameFilter查找出目錄下指定后綴的文件,結(jié)合實(shí)例形式分析了java基于FilenameFilter類的文件遍歷、查找相關(guān)操作技巧,需要的朋友可以參考下2019-10-10
Java實(shí)戰(zhàn)之醫(yī)院管理系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java實(shí)現(xiàn)醫(yī)院管理系統(tǒng),文中用到的技術(shù)有:SpringBoot、Layui、Freemaker等,感興趣的同學(xué)可以了解一下2022-04-04
Java向數(shù)據(jù)庫中插入數(shù)據(jù)后獲取自增ID的常用方法
有時候因?yàn)樾略龅男枨笮枰@取剛剛新增的數(shù)據(jù)的自增的主鍵ID,下面這篇文章主要給大家介紹了關(guān)于Java向數(shù)據(jù)庫中插入數(shù)據(jù)后獲取自增ID的常用方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11
約定優(yōu)于配置_動力節(jié)點(diǎn)Java學(xué)院整理
以前做項目,總是寫Ant配置文件,滿足于自己更靈活的配置,而沒有去思考,這么做到底值不值得2017-08-08
Java 并發(fā)鎖ReentrantLock的實(shí)現(xiàn)
本文主要介紹了Java 并發(fā)鎖ReentrantLock的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-04-04
IDEA JarEditor編輯jar包方式(直接新增,修改,刪除jar包內(nèi)的class文件)
文章主要介紹了如何使用IDEA的JarEditor插件直接修改jar包內(nèi)的class文件,而不需要手動解壓、反編譯和重新打包,通過該插件,可以更方便地進(jìn)行jar包的修改和測試2025-01-01

