文章目錄
- Spring AI Alibaba
- 聊天模型
- 圖像模型
- Image Model API接口及相關類
- 實現生成圖像
- 語音模型
- Text-to-Speech API概述
- 實現文本轉語音
- 實現RAG
- 向量化
- RAG
- RAG工作流程概述
- 實現基本 RAG 流程
Spring AI Alibaba
Spring AI Alibaba實現了與阿里云通義模型的完整適配,如果需要對接國內一些大模型來生成圖像、語音,SpringAi官網目前支持模型有限,這時Spring AI Alibaba
可能更適用。
使用前請先申請api_key:
- 訪問阿里云百煉頁面并登錄賬號 https://www.aliyun.com/product/bailian
- 申請api_key
官方文檔:https://java2ai.com/docs/1.0.0-M6.1/get-started/?spm=4347728f.13ae80de.0.0.6fe5175cWxPTJZ
注意:因為 Spring AI Alibaba 基于 Spring Boot 3.x 開發,因此本地 JDK 版本要求為 17 及以上。
聊天模型
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>deepseek-apringai</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><spring-ai.version>1.0.0-M5</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M5.1</version></dependency></dependencies><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories>
</project>
@RestController
public class DeepSeekController {private static final String DEFAULT_PROMPT = "你是一個博學的智能聊天助手,請根據用戶提問回答!";@Autowiredprivate ChatClient dashScopeChatClient;public DeepSeekController(ChatClient.Builder chatClientBuilder) {this.dashScopeChatClient = chatClientBuilder.defaultSystem(DEFAULT_PROMPT)// 實現 Chat Memory 的 Advisor// 在使用 Chat Memory 時,需要指定對話 ID,以便 Spring AI 處理上下文。.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))// 實現 Logger 的 Advisor.defaultAdvisors(new SimpleLoggerAdvisor())// 設置 ChatClient 中 ChatModel 的 Options 參數.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build()).build();}@GetMapping("/simple/chat")public String simpleChat(String query) {return dashScopeChatClient.prompt(query).call().content();}
}
圖像模型
-
在Spring AI框架中,Image Model API旨在為與專注于圖像生成的各種AI模型進行交互提供一個簡單且可移植的接口,使開發者能夠以最小的代碼改動切換不同的圖像相關模型。這一設計符合Spring模塊化和互換性的理念,確保開發者可以快速調整其應用程序以適應不同的圖像處理相關的AI能力。
-
此外,通過支持像ImagePrompt這樣的輔助類來進行輸入封裝以及使用ImageResponse來處理輸出,圖像模型API統一了與致力于圖像生成的AI模型之間的通信。它管理請求準備和響應解析的復雜性,為圖像生成功能提供直接而簡化的API交互。
-
Image Model API建立在Spring AI通用模型API之上,提供了特定于圖像的抽象和實現。
Image Model API接口及相關類
ImageModel(圖像模型)
這里展示的是ImageModel接口定義:
@FunctionalInterface
public interface ImageModel extends Model<ImagePrompt, ImageResponse> {ImageResponse call(ImagePrompt request);
}
ImagePrompt(圖像提示)
ImagePrompt是一個封裝了ImageMessage對象列表及可選模型請求選項的ModelRequest。下面顯示的是ImagePrompt類的一個簡化版本,省略了構造函數和其他工具方法:
public class ImagePrompt implements ModelRequest<List<ImageMessage>> {private final List<ImageMessage> messages;private ImageOptions imageModelOptions;@Overridepublic List<ImageMessage> getInstructions() {...}@Overridepublic ImageOptions getOptions() {...}
}
ImageMessage(圖像消息)
ImageMessage類封裝了用于影響生成圖像的文本及其權重。對于支持權重的模型,它們可以是正數或負數。
public class ImageMessage {private String text; private Float weight;public String getText() {...}public Float getWeight() {...}
}
ImageOptions(圖像選項)
表示可以傳遞給圖像生成模型的選項。ImageOptions接口擴展了ModelOptions接口,并用于定義可以傳遞給AI模型的一些可移植選項。
public interface ImageOptions extends ModelOptions {Integer getN();String getModel();Integer getWidth();Integer getHeight();String getResponseFormat(); // openai - url or base64 : stability ai byte[] or base64
}
ImageResponse(圖像響應)
持有AI模型的輸出,每個ImageGeneration實例包含來自單一提示的可能多個輸出結果之一。
public class ImageResponse implements ModelResponse<ImageGeneration> {private final ImageResponseMetadata imageResponseMetadata;private final List<ImageGeneration> imageGenerations;@Overridepublic ImageGeneration getResult() {// get the first result}@Overridepublic List<ImageGeneration> getResults() {...}@Overridepublic ImageResponseMetadata getMetadata() {...}
}
ImageGeneration(圖像生成)
最終,ImageGeneration類擴展自ModelResult,代表輸出響應及有關此結果的元數據。
public class ImageGeneration implements ModelResult<Image> {private ImageGenerationMetadata imageGenerationMetadata;private Image image;@Overridepublic Image getOutput() {...}@Overridepublic ImageGenerationMetadata getMetadata() {...}
}。
實現生成圖像
@Autowired
private DashScopeImageModel imageModel;@GetMapping(value = "/getImage")public void getImage(@RequestParam(value = "msg",defaultValue = "生成一條龍")String msg, HttpServletResponse res) {ImageResponse response = imageModel.call(new ImagePrompt(msg,DashScopeImageOptions.builder().withModel(DashScopeImageApi.DEFAULT_IMAGE_MODEL).withN(1)//要生成的圖像數。必須介于 1 和 10 之間。.withHeight(1024)//生成的圖像的高寬度。.withWidth(1024).build()));//獲取生成圖像地址String imageUrl = response.getResult().getOutput().getUrl();try {//使用輸出流在瀏覽器輸出URL url = URI.create(imageUrl).toURL();InputStream in = url.openStream();res.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);res.getOutputStream().write(in.readAllBytes());res.getOutputStream().flush();}catch (Exception e) {}
}
語音模型
Text-to-Speech API概述
在Spring AI框架中,Text-to-Speech API提供了一個基于OpenAI的TTS(文本轉語音)模型的語音端點,
使用戶能夠:
-
朗讀寫好的博客文章。
-
生成多種語言的語音音頻。
-
使用流媒體實現實時音頻輸出。
這一功能強大的API讓用戶可以輕松地將文字內容轉化為語音內容,不僅支持多語言轉換,還能滿足實時語音輸出的需求,極大地提升了內容的可訪問性和用戶的體驗感。
實現文本轉語音
-
本示例基于spring ai alibaba開源框架
-
SpeechSynthesisModel 類是Spring AI Alibaba框架中用于表示和管理文本轉語音模型的核心組件之一。
-
DashScopeSpeechSynthesisOptions 類通常用于配置文本轉語音(TTS)服務的選項,這個類允許開發者指定一系列參數(比如:語速、音調、音量等)來定制化語音合成的結果,從而滿足不同的應用場景需求。
@Autowired
private DashScopeSpeechSynthesisModel speechSynthesisModel;private static final String TEXT = "床前明月光, 疑是地上霜。 舉頭望明月, 低頭思故鄉。";
private static final String FILE_PATH = "src/main/resources/tts";@GetMapping("/tts")
public void tts() throws IOException {// 使用構建器模式創建 DashScopeSpeechSynthesisOptions 實例并設置參數DashScopeSpeechSynthesisOptions options = DashScopeSpeechSynthesisOptions.builder().withSpeed(1.0) // 設置語速.withPitch(0.9) // 設置音調.withVolume(60) // 設置音量.build();SpeechSynthesisResponse response = speechSynthesisModel.call(new SpeechSynthesisPrompt(TEXT,options));File file = new File(FILE_PATH + "/output.mp3");try (FileOutputStream fos = new FileOutputStream(file)) {ByteBuffer byteBuffer = response.getResult().getOutput().getAudio();fos.write(byteBuffer.array());} catch (IOException e) {throw new IOException(e.getMessage());}
}
實現RAG
向量化
-
向量數據庫(Vector Database)是一種以數學向量的形式存儲數據集合的數據庫,通過一個數字列表來表示維度空間中的一個位置。在這里,向量數據庫的功能是可以基于相似性搜索進行識別,而不是精準匹配。比如說在使用一個商城系統的向量數據庫進行查詢的時候,用戶輸入“北京”,其可能返回的結果會是 “中國、北京、華北、首都、奧運會” 等信息;輸入“沈陽”,其返回結果可能會是“東北、遼寧、雪花、重工業”等信息。當然,返回的信息取決于向量數據庫中存在的數據。用戶可以通過參數的設置來限定返回的情況,進而適配不同的需求。
-
嵌入模型(Embedding Model)和向量數據庫(Vector Database/Vector Store)是一對親密無間的合作伙伴,也是 AI 技術棧中緊密關聯的兩大核心組件,兩者的協同作用構成了現代語義搜索、推薦系統和 RAG(Retrieval Augmented Generation,檢索增強生成)等應用的技術基礎。
RAG
? RAG,全稱 Retrieval-Augmented Generation ,中文叫做檢索增強生成。RAG是一種結合了檢索系統和生成模型的新型技術框架,其主要目的有:
- 利用外部知識庫
- 幫助大模型生成更加準確、有依據、最新的回答
? 通過使用RAG,解決了傳統LLM存在的兩個主要問題:
- 知識局限性:LLM的知識被固定在訓練數據中,無法知道最新消息。
- 幻覺現象:LLM有時候會編造出并不存在的答案。
? 通過檢索外部知識,RAG讓模型突破了知識局限性,也讓LLM(大語言模型)的幻覺現象得到解決。
RAG工作流程概述
第一,用戶輸入問題
? 用戶在輸入窗口輸入自己的問題,這一數據被接收,并作為后續處理的查詢入口
例如:用戶提問
“我的智能手表出現藍牙連接問題,怎么辦?”
第二,問題向量化
? 根據用戶初始輸入的問題,調用Embedding模型,將問題轉換為高維向量,以便于后續的想來那個相似度檢索。
文本:"我的智能手表出現藍牙連接問題,怎么辦?"
→ 向量:[0.123, 0.582, ..., 0.001]
第三,向量數據庫檢索
? 系統會連接到一個向量數據庫(如FAISS、Milvus、Pinecone、Weaviate)。然后用剛才生成的問題向量,檢索知識庫中與之最相似的文檔片段。
? 當檢索的時候,常見的檢索參數包括:
- Tok-K :檢索最相關的K條記錄
- 相似度閾值:控制檢索到內容的相關性
? 最后輸出的結果往往是K條知識片段
1. "藍牙連接問題通常可以通過重啟設備和重新配對解決。"
2. "如果手表固件版本較舊,請更新到最新版本以兼容藍牙。"
3. "某些環境下,如電磁干擾,也會導致連接失敗。"
第四,構建上下文
這一階段需要組織提示詞(Prompt),讓LLM更好地理解背景信息。
這一部分包括:
-
系統提示詞(System Prompt)
提前告訴LLM需要遵循的行為規范,比如
你是一個專業的智能手表客服助理。請基于提供的背景資料,準確回答用戶的問題。如果資料中沒有明確答案,請如實告訴用戶而不是編造。
系統提示詞可以有效地設定模型角色、控制回答風格、防止幻覺
-
構造最終輸入(Final Prompt)
一般會結合以上內容,按照如下格式進行組織
【背景資料】 1. 藍牙連接問題通常可以通過重啟設備和重新配對解決。 2. 如果手表固件版本較舊,請更新到最新版本以兼容藍牙。 3. 某些環境下,如電磁干擾,也會導致連接失敗。【用戶問題】 我的智能手表出現藍牙連接問題,怎么辦?【回答要求】 請結合以上資料,用簡潔明了的方式回答用戶的問題。如果答案無法直接從資料中找到,請禮貌告知用戶。
第五,調用LLM
? 將構造好的Prompt提交給LLM(比如Deepseek、Qwen、GPT-4o、Claude等)
- 模型讀取檢索到的內容和問題
- 組織自然、連貫、準確的回答
生成結果示例:
“您好! 根據我們的資料,您可以嘗試重啟智能手表并重新進行藍牙配對。如果問題仍未解決,請檢查手表固件是否為最新版本。如處于高電磁干擾環境,也可能影響連接質量,建議更換使用環境。”
第六,返回最終回答給用戶
? 最終系統將生成的回答返回前端,展示給用戶。
總結:
在RAG工作時,其運行流程大致為:
- 用戶輸入問題
- 問題向量化
- 向量數據庫檢索
- 構建上下文(含系統提示詞)
- 攜帶檢索內容,調用大模型進行回答
- 返回最終答案給用戶
實現基本 RAG 流程
創建配置類
@Configuration
public class RagConfig {@BeanChatClient chatClient(ChatClient.Builder builder) {return builder.defaultSystem("你將作為一名行天下公司的客服,對于用戶的使用需求作出解答").build();}@BeanVectorStore vectorStore(EmbeddingModel embeddingModel) {SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build();//1 提取文本內容String filePath="file.txt"; //resources目錄下TextReader textReader = new TextReader(filePath);textReader.getCustomMetadata().put("filePath",filePath);List<Document> documents = textReader.get();//2 文本切分段落TokenTextSplitter splitter =new TokenTextSplitter(1200,350, 5,100, true);splitter.apply(documents);//3 添加simpleVectorStore.add(documents);return simpleVectorStore;}}
file.txt
公司主營養豬業務,公司總部在山西省臨汾市
- 通過這個配置類,完成以下內容:
1、配置 ChatClient 作為 Bean,其中設置系統默認角色為Java開發語言專家, 負責處理用戶查詢并生成回答向量存儲配置。
2、初始化 SimpleVectorStore,加載Java開發語言說明文檔,將文檔轉換為向量形式存儲。
Controller
@Autowired
private ChatClient dashScopeChatClient;@Autowired
private VectorStore vectorStore;@GetMapping(value = "/chat", produces = "text/plain; charset=UTF-8")
public String generation(String userInput) {// 發起聊天請求并處理響應return dashScopeChatClient.prompt().user(userInput).advisors(new QuestionAnswerAdvisor(vectorStore)).call().content();
}
- 通過添加 QuestionAnswerAdvisor 并提供對應的向量存儲,可以將之前放入的文檔作為參考資料,并生成增強回答。
測試結果
通過RAG可以構建更專業的知識庫來讓AI模型回答更具體化,支持的文檔可以是word、pdf等其他格式,向量數據也可以持久化存儲在向量數據庫中。