Spring Boot 集成 Spring AI OpenAI Starter最佳實(shí)踐指南
前言
隨著人工智能技術(shù)的快速發(fā)展,將AI能力集成到企業(yè)級(jí)應(yīng)用中變得越來(lái)越重要。Spring AI作為Spring生態(tài)系統(tǒng)中的新成員,為Java開(kāi)發(fā)者提供了標(biāo)準(zhǔn)化、開(kāi)箱即用的AI集成方案。本教程將詳細(xì)介紹如何使用Spring Boot集成Spring AI OpenAI Starter,快速為您的應(yīng)用添加智能對(duì)話(huà)功能。
一、環(huán)境準(zhǔn)備
1. 技術(shù)要求
- ??JDK??: 17 或更高版本
- ??構(gòu)建工具??: Maven 3.6+ 或 Gradle
- ??Spring Boot??: 3.2+ (推薦最新穩(wěn)定版)
- ??OpenAI賬號(hào)??: 需要在OpenAI平臺(tái)注冊(cè)并獲取API Key
2. 創(chuàng)建Spring Boot項(xiàng)目
您可以通過(guò)以下兩種方式之一創(chuàng)建項(xiàng)目:
??方式一:使用start.spring.io??
- 訪(fǎng)問(wèn) start.spring.io
- 選擇以下依賴(lài):
- Spring Web
- Spring AI (選擇對(duì)應(yīng)版本)
- 其他您可能需要的依賴(lài)(如Spring Security等)
??方式二:手動(dòng)添加依賴(lài)??
如果您已有Spring Boot項(xiàng)目,直接在pom.xml中添加以下依賴(lài):
<!-- Spring AI OpenAI Starter -->
<dependency>
<groupId>io.springboot.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0</version> <!-- 請(qǐng)使用最新版本 -->
</dependency>
<!-- Spring Boot Web Starter (如果尚未添加) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>二、配置OpenAI API
1. 獲取OpenAI API Key
- 登錄OpenAI平臺(tái)
- 進(jìn)入"API Keys"頁(yè)面
- 創(chuàng)建新的API Key并妥善保存
2. 配置application.yml
在src/main/resources/application.yml文件中添加以下配置:
spring:
ai:
openai:
api-key: "sk-your-openai-api-key-here" # 替換為您的實(shí)際OpenAI API Key
base-url: "https://api.openai.com/v1" # 默認(rèn)值,通常無(wú)需修改
chat:
options:
model: "gpt-4-turbo" # 您想使用的模型,如gpt-3.5-turbo, gpt-4等
temperature: 0.7 # 控制生成文本的隨機(jī)性(0-2)
max-tokens: 500 # 生成的最大token數(shù)??安全建議??:
為了安全起見(jiàn),建議不要將API Key直接硬編碼在配置文件中,而是使用環(huán)境變量:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY} # 從環(huán)境變量讀取然后,在運(yùn)行應(yīng)用前設(shè)置環(huán)境變量:
export OPENAI_API_KEY=sk-your-openai-api-key-here
或者在Windows命令提示符中:
set OPENAI_API_KEY=sk-your-openai-api-key-here
三、核心功能實(shí)現(xiàn)
1. 基礎(chǔ)對(duì)話(huà)功能
創(chuàng)建AI控制器
創(chuàng)建一個(gè)REST控制器來(lái)處理AI對(duì)話(huà)請(qǐng)求:
import org.springframework.ai.chat.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/ai")
public class AIController {
private final ChatClient chatClient;
@Autowired
public AIController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 基礎(chǔ)對(duì)話(huà)接口
* @param message 用戶(hù)輸入的消息
* @return AI的回復(fù)
*/
@GetMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient.call(message);
}
/**
* 基礎(chǔ)對(duì)話(huà)接口(POST方式)
* @param userInput 用戶(hù)輸入
* @return AI的回復(fù)
*/
@PostMapping("/chat")
public String generateText(@RequestBody String userInput) {
return chatClient.call(userInput);
}
}測(cè)試基礎(chǔ)對(duì)話(huà)
啟動(dòng)Spring Boot應(yīng)用后,您可以通過(guò)以下方式測(cè)試:
??方式一:瀏覽器訪(fǎng)問(wèn)??
http://localhost:8080/ai/chat?message=你好,請(qǐng)介紹一下你自己
??方式二:使用cURL測(cè)試??
curl -X GET "http://localhost:8080/ai/chat?message=請(qǐng)寫(xiě)一個(gè)簡(jiǎn)單的Java Hello World程序"
??方式三:使用Postman等工具發(fā)送POST請(qǐng)求??
- URL:
http://localhost:8080/ai/chat - Method: POST
- Body: raw, text/plain
- 內(nèi)容: "請(qǐng)解釋Spring Boot的核心特性"
2. 帶上下文的對(duì)話(huà)
為了讓對(duì)話(huà)更有連續(xù)性,我們可以實(shí)現(xiàn)帶上下文的對(duì)話(huà)功能:
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.message.Message;
import org.springframework.ai.chat.message.SystemMessage;
import org.springframework.ai.chat.message.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/ai")
public class AIContextController {
private final ChatClient chatClient;
// 簡(jiǎn)單的上下文存儲(chǔ)(生產(chǎn)環(huán)境應(yīng)使用更可靠的存儲(chǔ)方案)
private List<Message> conversationHistory = new ArrayList<>();
@Autowired
public AIContextController(ChatClient chatClient) {
this.chatClient = chatClient;
// 初始化系統(tǒng)消息
conversationHistory.add(new SystemMessage("你是一個(gè)專(zhuān)業(yè)的技術(shù)助手,擅長(zhǎng)Java開(kāi)發(fā)和人工智能相關(guān)知識(shí)。"));
}
/**
* 帶上下文的對(duì)話(huà)
* @param userInput 用戶(hù)輸入
* @return AI的回復(fù)
*/
@PostMapping("/chat/context")
public String chatWithContext(@RequestBody String userInput) {
// 添加用戶(hù)消息到歷史記錄
conversationHistory.add(new UserMessage(userInput));
// 創(chuàng)建包含歷史記錄的Prompt
Prompt prompt = new Prompt(conversationHistory);
// 調(diào)用AI服務(wù)
String response = chatClient.call(prompt).getResult().getOutput().getContent();
// 添加AI回復(fù)到歷史記錄
conversationHistory.add(new UserMessage(response)); // 注意:這里應(yīng)該是AssistantMessage,但Spring AI可能沒(méi)有這個(gè)類(lèi)
return response;
}
/**
* 清除對(duì)話(huà)上下文
*/
@PostMapping("/chat/context/clear")
public String clearContext() {
conversationHistory.clear();
conversationHistory.add(new SystemMessage("你是一個(gè)專(zhuān)業(yè)的技術(shù)助手,擅長(zhǎng)Java開(kāi)發(fā)和人工智能相關(guān)知識(shí)。"));
return "對(duì)話(huà)上下文已清除";
}
}??注意??:上面的代碼中使用了UserMessage來(lái)表示AI的回復(fù),這在實(shí)際情況中可能不太準(zhǔn)確。Spring AI可能提供了專(zhuān)門(mén)的AssistantMessage類(lèi),如果沒(méi)有,您可能需要自己創(chuàng)建或考慮使用其他方式管理上下文。
3. 高級(jí)參數(shù)控制
您可以通過(guò)自定義OpenAiChatOptions來(lái)更精細(xì)地控制AI的行為:
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/ai")
public class AIAdvancedController {
private final ChatClient chatClient;
@Autowired
public AIAdvancedController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 高級(jí)參數(shù)控制的對(duì)話(huà)
* @param message 用戶(hù)輸入
* @return AI的回復(fù)
*/
@PostMapping("/chat/advanced")
public String advancedChat(@RequestBody String message) {
// 自定義參數(shù)
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4") // 指定模型
.withTemperature(0.3) // 較低的隨機(jī)性,回復(fù)更確定
.withMaxTokens(1000) // 最大生成token數(shù)
// 可以添加更多選項(xiàng),如topP, frequencyPenalty, presencePenalty等
.build();
// 構(gòu)建 Prompt
Prompt request = new Prompt(message, options);
return chatClient.call(request).getResult().getOutput().getContent();
}
/**
* 使用不同模型的對(duì)話(huà)
* @param message 用戶(hù)輸入
* @param modelName 模型名稱(chēng)
* @return AI的回復(fù)
*/
@PostMapping("/chat/model/{modelName}")
public String chatWithSpecificModel(@RequestBody String message, @PathVariable String modelName) {
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel(modelName) // 動(dòng)態(tài)指定模型
.withTemperature(0.7)
.withMaxTokens(800)
.build();
Prompt request = new Prompt(message, options);
return chatClient.call(request).getResult().getOutput().getContent();
}
}4. 流式響應(yīng)(Server-Sent Events)
對(duì)于長(zhǎng)時(shí)間運(yùn)行的請(qǐng)求,流式響應(yīng)可以提供更好的用戶(hù)體驗(yàn):
import org.springframework.ai.chat.StreamingChatClient;
import org.springframework.ai.chat.message.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/ai")
public class AIStreamingController {
private final StreamingChatClient streamingChatClient;
@Autowired
public AIStreamingController(StreamingChatClient streamingChatClient) {
this.streamingChatClient = streamingChatClient;
}
/**
* 流式對(duì)話(huà)接口
* @param message 用戶(hù)輸入的消息
* @return 流式的AI回復(fù)
*/
@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return streamingChatClient.stream(prompt)
.map(content -> content.toString());
}
/**
* 流式對(duì)話(huà)接口(POST方式)
* @param message 用戶(hù)輸入
* @return 流式的AI回復(fù)
*/
@PostMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChatPost(@RequestBody String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return streamingChatClient.stream(prompt)
.map(content -> content.toString());
}
}??測(cè)試流式響應(yīng)??:
您可以使用支持SSE的客戶(hù)端(如Postman或?qū)iT(mén)的SSE客戶(hù)端)來(lái)測(cè)試流式接口,或者創(chuàng)建一個(gè)簡(jiǎn)單的前端頁(yè)面來(lái)展示流式效果。
四、進(jìn)階功能:提示詞工程
提示詞工程(Prompt Engineering)是通過(guò)精心設(shè)計(jì)提示詞來(lái)引導(dǎo)AI生成更準(zhǔn)確、更有用內(nèi)容的技術(shù)。
1. 創(chuàng)建自定義提示詞模板
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
// 假設(shè)有一個(gè)DTO類(lèi)用于封裝翻譯請(qǐng)求
record TranslationRequest(String sourceLang, String targetLang, String text) {}
@RestController
@RequestMapping("/ai")
public class AIPromptTemplateController {
private final ChatClient chatClient;
@Autowired
public AIPromptTemplateController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 翻譯功能 - 使用提示詞模板
* @param request 翻譯請(qǐng)求
* @return 翻譯結(jié)果
*/
@PostMapping("/translate")
public String translate(@RequestBody TranslationRequest request) {
// 創(chuàng)建提示詞模板
PromptTemplate promptTemplate = new PromptTemplate("""
將以下{sourceLang}文本翻譯成{targetLang}:
{text}
翻譯結(jié)果:
""");
// 設(shè)置模板變量
promptTemplate.add("sourceLang", request.sourceLang());
promptTemplate.add("targetLang", request.targetLang());
promptTemplate.add("text", request.text());
// 渲染提示詞并調(diào)用AI
return chatClient.call(promptTemplate.render()).getResult().getOutput().getContent();
}
/**
* 代碼生成 - 使用提示詞模板
* @param language 編程語(yǔ)言
* @param description 功能描述
* @return 生成的代碼
*/
@PostMapping("/generate-code")
public String generateCode(@RequestParam String language, @RequestParam String description) {
PromptTemplate promptTemplate = new PromptTemplate("""
用{language}編寫(xiě)一個(gè)程序,實(shí)現(xiàn)以下功能: {description}
請(qǐng)?zhí)峁┩暾目蛇\(yùn)行代碼,包括必要的導(dǎo)入語(yǔ)句和主函數(shù)。
代碼應(yīng)該有良好的注釋和結(jié)構(gòu)。
生成的代碼:
""");
promptTemplate.add("language", language);
promptTemplate.add("description", description);
return chatClient.call(promptTemplate.render()).getResult().getOutput().getContent();
}
}2. 測(cè)試提示詞模板
??測(cè)試翻譯功能??:
curl -X POST -H "Content-Type: application/json" \
-d '{"sourceLang":"English","targetLang":"Chinese","text":"Hello, how are you today?"}' \
http://localhost:8080/ai/translate??測(cè)試代碼生成功能??:
curl -X POST "http://localhost:8080/ai/generate-code?language=Java&description=一個(gè)簡(jiǎn)單的計(jì)算器,能夠進(jìn)行加減乘除運(yùn)算" \ -H "Content-Type: application/x-www-form-urlencoded"
五、完整示例項(xiàng)目結(jié)構(gòu)
src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── aiintegration/
│ │ ├── AiIntegrationApplication.java
│ │ ├── controller/
│ │ │ ├── AIController.java
│ │ │ ├── AIContextController.java
│ │ │ ├── AIAdvancedController.java
│ │ │ └── AIStreamingController.java
│ │ └── dto/
│ │ └── TranslationRequest.java
│ └── resources/
│ ├── application.yml
│ └── static/ # 可選:前端文件
└── test/
└── java/
└── com/
└── example/
└── aiintegration/
└── AiIntegrationApplicationTests.java主應(yīng)用類(lèi)
package com.example.aiintegration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AiIntegrationApplication {
public static void main(String[] args) {
SpringApplication.run(AiIntegrationApplication.class, args);
}
}六、測(cè)試與驗(yàn)證
1. 啟動(dòng)應(yīng)用
使用您的IDE或命令行啟動(dòng)Spring Boot應(yīng)用:
mvn spring-boot:run # 或 gradle bootRun
2. 測(cè)試接口
??基礎(chǔ)對(duì)話(huà)測(cè)試??:
- GET請(qǐng)求:
http://localhost:8080/ai/chat?message=你好,介紹一下Spring Boot - 或POST請(qǐng)求到
http://localhost:8080/ai/chat,body為"你好,介紹一下Spring Boot"
??高級(jí)參數(shù)測(cè)試??:
- POST請(qǐng)求到
http://localhost:8080/ai/chat/advanced,body為"解釋微服務(wù)架構(gòu)的優(yōu)缺點(diǎn)"
??流式響應(yīng)測(cè)試??:
- GET請(qǐng)求:
http://localhost:8080/ai/chat/stream?message=給我講一個(gè)笑話(huà) - 使用支持SSE的客戶(hù)端查看流式效果
??翻譯功能測(cè)試??:
curl -X POST -H "Content-Type: application/json" \
-d '{"sourceLang":"English","targetLang":"Chinese","text":"The quick brown fox jumps over the lazy dog."}' \
http://localhost:8080/ai/translate3. 單元測(cè)試
創(chuàng)建測(cè)試類(lèi)驗(yàn)證ChatClient的基本功能:
package com.example.aiintegration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.ai.chat.ChatClient;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@SpringBootTest
class AiIntegrationApplicationTests {
@Autowired
private ChatClient chatClient;
@Test
void contextLoads() {
}
@Test
void testChatClient() {
String response = chatClient.call("你好,你能做什么?");
System.out.println("AI 回復(fù): " + response);
assertNotNull(response);
}
}七、生產(chǎn)環(huán)境建議
1. 安全最佳實(shí)踐
- ??API密鑰管理??:永遠(yuǎn)不要將API密鑰硬編碼在代碼中,使用環(huán)境變量或密鑰管理服務(wù)
- ??訪(fǎng)問(wèn)控制??:為AI接口添加適當(dāng)?shù)恼J(rèn)證和授權(quán)
- ??輸入驗(yàn)證??:驗(yàn)證所有用戶(hù)輸入,防止濫用和注入攻擊
- ??速率限制??:實(shí)現(xiàn)API速率限制,防止濫用和超額費(fèi)用
2. 性能優(yōu)化
- ??連接池??:配置適當(dāng)?shù)木W(wǎng)絡(luò)連接池參數(shù)
- ??緩存??:對(duì)常見(jiàn)問(wèn)題的AI響應(yīng)實(shí)現(xiàn)緩存機(jī)制
- ??異步處理??:對(duì)復(fù)雜的AI請(qǐng)求考慮使用異步處理
- ??監(jiān)控??:監(jiān)控AI接口的性能和使用情況
3. 錯(cuò)誤處理與重試
- 實(shí)現(xiàn)健壯的錯(cuò)誤處理機(jī)制
- 對(duì)暫時(shí)性錯(cuò)誤實(shí)現(xiàn)重試邏輯
- 監(jiān)控API使用配額和限制
八、總結(jié)
通過(guò)本教程,您已經(jīng)學(xué)會(huì)了如何使用Spring Boot集成Spring AI OpenAI Starter,為您的應(yīng)用添加強(qiáng)大的AI能力。從基礎(chǔ)對(duì)話(huà)功能到高級(jí)的流式響應(yīng)和提示詞工程,Spring AI提供了豐富的功能來(lái)滿(mǎn)足各種AI集成需求。
Spring AI的優(yōu)勢(shì)在于其標(biāo)準(zhǔn)化的API設(shè)計(jì),使得您可以輕松切換不同的AI供應(yīng)商而無(wú)需大幅修改業(yè)務(wù)代碼。隨著AI技術(shù)的不斷發(fā)展,這種抽象層將為您的應(yīng)用提供更大的靈活性和未來(lái)保障。
到此這篇關(guān)于Spring Boot 集成 Spring AI OpenAI Starter最佳實(shí)踐指南的文章就介紹到這了,更多相關(guān)Spring Boot Spring AI OpenAI Starter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 根據(jù)經(jīng)緯度獲取地址實(shí)現(xiàn)代碼
這篇文章主要介紹了 java 根據(jù)經(jīng)緯度獲取地址實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05
spring?security?自定義Provider?如何實(shí)現(xiàn)多種認(rèn)證
這篇文章主要介紹了spring?security?自定義Provider實(shí)現(xiàn)多種認(rèn)證方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java java.lang.InstantiationException異常案例詳解
這篇文章主要介紹了Java java.lang.InstantiationException異常案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Netty分布式Server啟動(dòng)流程服務(wù)端初始化源碼分析
本章主要講解server啟動(dòng)的關(guān)鍵步驟,?讀者只需要了解server啟動(dòng)的大概邏輯,?知道關(guān)鍵的步驟在哪個(gè)類(lèi)執(zhí)行即可,?并不需要了解每一步的運(yùn)作機(jī)制,?之后會(huì)對(duì)每個(gè)模塊進(jìn)行深度分析2022-03-03
利用Intellij Idea連接遠(yuǎn)程服務(wù)器實(shí)現(xiàn)遠(yuǎn)程上傳部署功能
大家在使用Intellij Idea開(kāi)發(fā)程序的時(shí)候,是不是需要部署到遠(yuǎn)程SSH服務(wù)器運(yùn)行呢,當(dāng)然也可以直接在idea軟件內(nèi)容實(shí)現(xiàn)配置部署操作,接下來(lái)通過(guò)本文給大家分享利用Intellij Idea連接遠(yuǎn)程服務(wù)器實(shí)現(xiàn)遠(yuǎn)程上傳部署功能,感興趣的朋友跟隨小編一起看看吧2021-05-05
Java調(diào)用CXF WebService接口的兩種方式實(shí)例
今天小編就為大家分享一篇關(guān)于Java調(diào)用CXF WebService接口的兩種方式實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
Spring Boot中的@ConfigurationProperties注解解讀
在SpringBoot框架中,@ConfigurationProperties注解是處理外部配置的強(qiáng)大工具,它允許開(kāi)發(fā)者將配置文件中的屬性自動(dòng)映射到Java類(lèi)的字段上,實(shí)現(xiàn)配置的集中管理和類(lèi)型安全,通過(guò)定義配置類(lèi)并指定前綴,可以將配置文件中的屬性綁定到Java對(duì)象2024-10-10

