Spring AI Image Model、TTS,RAG

文章目錄

    • 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工作時,其運行流程大致為:

  1. 用戶輸入問題
  2. 問題向量化
  3. 向量數據庫檢索
  4. 構建上下文(含系統提示詞)
  5. 攜帶檢索內容,調用大模型進行回答
  6. 返回最終答案給用戶

實現基本 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等其他格式,向量數據也可以持久化存儲在向量數據庫中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83314.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83314.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83314.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java進階---JVM

JVM概述 JVM作用&#xff1a; 負責將字節碼翻譯為機器碼&#xff0c;管理運行時內存 JVM整體組成部分&#xff1a; 類加載系統(ClasLoader)&#xff1a;負責將硬盤上的字節碼文件加載到內存中 運行時數據區(RuntimeData Area)&#xff1a;負責存儲運行時各種數據 執行引擎(Ex…

數據類型檢測有哪些方式?

typeof 其中數組 對象 null都會判斷為Object,其他正確 typeof 2 // number typeof true //bolean typeof str //string typeof [] //Object typeof function (){} // function typeof {} //object typeof undefined //undefined typeof null // nullinstanceof 判斷…

NodeJS全棧開發面試題講解——P6安全與鑒權

? 6.1 如何防止 SQL 注入 / XSS / CSRF&#xff1f; 面試官您好&#xff0c;Web 安全三大經典問題分別從不同層面入手&#xff1a; &#x1f538; SQL 注入&#xff08;Server端&#xff09; 原理&#xff1a;惡意用戶將 SQL 注入查詢語句拼接&#xff0c;導致數據泄露或破壞…

npm error Cannot find module ‘negotiator‘ 的處理

本想運行npm create vuelatest&#xff0c;但提示&#xff1a; npm error code MODULE_NOT_FOUND npm error Cannot find module negotiator npm error Require stack: npm error - C:\Users\Administrator\AppData\Roaming\nvm\v18.16.1\node_modules\npm\node_modules\tuf-j…

Python爬蟲:AutoScraper 庫詳細使用大全(一個智能、自動、輕量級的網絡爬蟲)

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、AutoScraper概述1.1 AutoScraper介紹1.2 安裝1.3 注意事項二、基本使用方法2.1 創建 AutoScraper 實例2.2 訓練模型2.3 保存和加載模型2.4 數據提取方法2.5 自定義規則三、高級功能3.1 多規則抓取3.2 分頁抓取3.3 代…

【Netty系列】解決TCP粘包和拆包:LengthFieldBasedFrameDecoder

目錄 如何使用&#xff1f; 1. 示例代碼&#xff08;基于Netty&#xff09; 2. 關鍵參數解釋 3. 協議格式示例 4. 常見配置場景 場景1&#xff1a;長度字段包含自身 場景2&#xff1a;長度字段在消息中間 5. 注意事項 舉個例子 完整示例&#xff1a;客戶端與服務端交互…

哈爾濱工業大學提出ADSUNet—紅外暗弱小目標鄰幀檢測新框架

ADSUNet: Accumulation-Difference-Based Siamese U-Net for inter-frame Infrared Dim and Small Target Detection 作者單位&#xff1a;哈爾濱工業大學空間光學工程研究中心 引用: Liuwei Zhang, Yuyang Xi, Zhipeng Wang, Wang Zhang, Fanjiao Tan, Qingyu Hou, ADSUNet: A…

Linux開發追蹤(IMX6ULL篇_第一部分)

前言 參數&#xff1a;cortex-A7 698Mhz flash 8GB RAM 512M DDR3 2個100M網口 單核 初期&#xff1a; 一、安裝完虛擬機之后&#xff0c;第一步先設置文件之間可以相互拷貝復制&#xff0c;以及通過CRT連接到虛擬機等 折磨死人了啊啊啊啊啊啊 1、關于SSH怎么安裝…

【萌筆趣棋】網頁五子棋項目測試報告

目錄 一.項目介紹 &#xff08;一&#xff09;項目簡介 &#xff08;二&#xff09;功能介紹 &#xff08;三&#xff09;頁面展示 1.注冊頁面 2.登錄頁面 3.游戲大廳頁面 4.游戲房間頁面&#xff08;對戰&#xff09; 二.功能測試 &#xff08;一&#xff09;出現的…

知識圖譜增強的大型語言模型編輯

https://arxiv.org/pdf/2402.13593 摘要 大型語言模型&#xff08;LLM&#xff09;是推進自然語言處理&#xff08;NLP&#xff09;任務的關鍵&#xff0c;但其效率受到不準確和過時知識的阻礙。模型編輯是解決這些挑戰的一個有前途的解決方案。然而&#xff0c;現有的編輯方法…

數據庫,Spring Boot,數據源

您是對的&#xff0c;我之前的回答解釋了Spring Boot在操作MySQL時不一定需要顯式配置指定的數據源類型&#xff0c;因為它有自動配置機制&#xff0c;但沒有直接點明在自動配置情況下“數據源是什么”。 在Spring Boot自動配置機制下&#xff0c;這個“數據源”指的是一個連接…

數據結構測試模擬題(3)

1、兩個有序鏈表序列的合并 #include<bits/stdc.h> using namespace std;struct node{int num;node* next; };// 創建鏈表 node* CreatList(){int x;node *head new node(); // 創建頭節點head->next NULL;node *tail head; // 尾指針初始指向頭節點while…

LabVIEW Val (Sgnl) 屬性

在 LabVIEW 事件驅動架構中&#xff0c;Val (Sgnl) 屬性&#xff08;Value (Signaling)&#xff09;是實現編程觸發與用戶交互行為一致性的關鍵技術。與普通 Value 屬性不同&#xff0c;Val (Sgnl) 在修改控件值的同時強制生成值改變事件&#xff0c;確保程序邏輯與 UI 交互保持…

04.MySQL數據類型詳解

MySQL數據類型詳解 文章目錄 MySQL數據類型數據類型分類數值類型 tinyint類型bit類型float類型decimal類型 字符串類型 char類型varchar類型char和varchar比較 時間日期類型enum和set類型數據類型選擇的進階技巧常見誤區與解決方案性能優化與最佳實踐 MySQL數據類型 數據類型…

Spring AI 之對話記憶(Chat Memory)

大型語言模型&#xff08;LLMs&#xff09;是無狀態的&#xff0c;這意味著它們不會保留關于之前交互的信息。當想在多次交互中保持上下文或狀態時&#xff0c;這可能會成為一個限制。為了解決這一問題&#xff0c;Spring AI 提供了對話記憶功能&#xff0c;允許你在與大型語言…

H?lder Statistical Pseudo Divergence Proper H?lder Divergence

目錄 Hlder Statistical Pseudo DivergenceProper Hlder Divergence Hlder Statistical Pseudo Divergence Hlder Statistical Pseudo Divergence是一種度量兩個概率分布 p p p 和 q q q差異的方法&#xff0c;它基于Hlder不等式。定義如下&#xff1a; D α H ( p : q ) 1 …

時序數據庫IoTDB基于云原生的創新與實踐

概述 Apache IoTDB 是一款獨立自研的物聯網時序數據庫&#xff0c;作為 Apache 基金會的頂級項目&#xff0c;它融合了產學研的優勢&#xff0c;擁有深厚的科研基底。IoTDB 采用了端邊云協同的架構&#xff0c;專為物聯網設計&#xff0c;致力于提供極致的性能。 數據模型 I…

git 如何解決分支合并沖突(VS code可視化解決+gitLab網頁解決)

1、定義&#xff1a;兩個分支修改了同一文件的同一行代碼&#xff0c;無法自動決定如何合并代碼&#xff0c;需要人工干預的情況。&#xff08;假設A提交了文件a,此時B在未拉取代碼的情況下&#xff0c;直接提交是會報錯的&#xff0c;此時需要拉取之后再提交才會成功&#xff…

系統架構設計師(一):計算機系統基礎知識

系統架構設計師&#xff08;一&#xff09;&#xff1a;計算機系統基礎知識 引言計算機系統概述計算機硬件處理器處理器指令集常見處理器 存儲器總線總線性能指標總線分類按照總線在計算機中所處的位置劃分按照連接方式分類按照功能分類 接口接口分類 計算機軟件文件系統文件類…

聊一聊接口測試中緩存處理策略

目錄 一、強制繞過緩存 添加時間戳參數 修改請求頭 二、主動清除緩存 清除本地緩存 清除服務端緩存&#xff08;需權限&#xff09; 清除CDN緩存 三、測試緩存邏輯 首次請求獲取數據 記錄響應頭中的緩存標識????? 驗證緩存生效 測試緩存過期??????? 四…