Spring Boot 3整合Spring AI實戰:9輪面試對話解析AI應用開發

Spring Boot 3整合Spring AI實戰:9輪面試對話解析AI應用開發

第1輪:基礎配置與模型調用

周先生:cc,先聊聊Spring AI的基礎配置吧。如何在Spring Boot 3項目中集成Ollama?

cc:我們可以通過OllamaConfig.java實現基礎配置,示例代碼如下:

@Configuration
public class OllamaConfig {@Beanpublic OllamaChatModel ollamaChatModel(OllamaApi ollamaApi) {return new OllamaChatModel(ollamaApi, OllamaOptions.builder().model("llama3").build());}@Beanpublic OllamaApi ollamaApi(@Value("${spring.ai.ollama.base-url}") String baseUrl) {return new OllamaApi(baseUrl);}
}

周先生:那如何通過OpenAI進行文本生成呢?

cc:同樣,我們可以通過OpenAIConfig.java配置OpenAI客戶端:

@Configuration
public class OpenAIConfig {@Beanpublic OpenAiChatModel openAiChatModel(OpenAiApi openAiApi) {return new OpenAiChatModel(openAiApi,OpenAiChatOptions.builder().model("gpt-4o").build());}@Beanpublic OpenAiApi openAiApi(@Value("${spring.ai.openai.base-url}") String baseUrl,@Value("${spring.ai.openai.api-key}") String apiKey) {return new OpenAiApi(baseUrl, apiKey);}
}

周先生:很好,這樣我們就能靈活配置不同的AI模型了。

第2輪:多模型路由設計

周先生:在實際項目中,我們可能需要根據不同的查詢內容選擇不同的模型,如何實現這種智能路由?

cc:我們可以設計一個模型路由器,根據查詢內容的特點選擇合適的模型:

@Service
public class ModelRouter {private final Map<String, ChatModel> models;public ModelRouter(Map<String, ChatModel> models) {this.models = models;}public ChatModel getPreferredModel(String query) {// 根據查詢內容選擇模型if (query.contains("code") || query.contains("technical")) {return models.get("ollama"); // 本地技術問題用Ollama}return models.get("openai"); // 復雜問題用OpenAI}
}

周先生:這個設計很實用,能夠根據查詢內容的特點選擇最適合的模型。

第3輪:RAG架構實現

周先生:如何在Spring AI中實現RAG(Retrieval-Augmented Generation)架構?

cc:我們可以通過向量存儲實現RAG架構,以下是一個基于PgVectorStore的示例:

@Service
public class DocumentService {private final PgVectorStore vectorStore;private final OllamaEmbeddingModel embeddingModel;public DocumentService(PgVectorStore vectorStore, OllamaEmbeddingModel embeddingModel) {this.vectorStore = vectorStore;this.embeddingModel = embeddingModel;}public void uploadDocument(String content) {// 創建文檔Document document = new Document(content);// 分詞處理TokenTextSplitter textSplitter = new TokenTextSplitter();List<Document> splitDocuments = textSplitter.apply(List.of(document));// 存儲到向量數據庫vectorStore.add(splitDocuments);}public List<Document> searchRelevantDocs(String query) {// 相似性搜索return vectorStore.similaritySearch(query, 5);}
}

周先生:非常棒!這樣就能讓AI在回答問題時參考相關文檔內容了。

第4輪:可觀測性實現

周先生:在生產環境中,我們需要監控AI服務的性能,如何實現可觀測性?

cc:Spring AI支持與Micrometer集成,實現監控:

@Configuration
public class ObservabilityConfig {@Beanpublic ObservationRegistry observationRegistry() {return ObservationRegistry.create();}@Beanpublic ChatClient.Builder chatClientBuilder(ChatModel chatModel) {return new DefaultChatClientBuilder(chatModel, observationRegistry(), ChatClientObservationConvention.DEFAULT);}
}

并在application.yml中添加配置:

management:endpoints:web:exposure:include: "*"tracing:sampling:probability: 1.0

周先生:這樣我們就能監控AI服務的請求響應時間、token消耗等指標了。

第5輪:模型版本管理

周先生:如何管理不同版本的AI模型?

cc:我們可以通過配置類管理不同版本的模型:

@Configuration
public class ModelVersionConfig {@Bean("ollamaLlama3_1")public OllamaChatModel ollamaLlama3_1(OllamaApi ollamaApi) {return new OllamaChatModel(ollamaApi,OllamaOptions.builder().model("llama3:latest").build());}@Bean("ollamaLlama3_2")public OllamaChatModel ollamaLlama3_2(OllamaApi ollamaApi) {return new OllamaChatModel(ollamaApi,OllamaOptions.builder().model("llama3:70b").build());}@Bean("openAiGpt4")public OpenAiChatModel openAiGpt4(OpenAiApi openAiApi) {return new OpenAiChatModel(openAiApi,OpenAiChatOptions.builder().model("gpt-4").build());}@Bean("openAiGpt4Turbo")public OpenAiChatModel openAiGpt4Turbo(OpenAiApi openAiApi) {return new OpenAiChatModel(openAiApi,OpenAiChatOptions.builder().model("gpt-4-turbo").build());}
}

周先生:這樣就可以靈活切換和比較不同版本的模型了。

第6輪:錯誤處理與重試機制

周先生:在調用AI服務時可能會出現網絡問題或服務不可用,如何處理這些異常情況?

cc:我們可以使用Spring Retry實現重試機制:

@Service
public class AiService {private final ChatClient chatClient;public AiService(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@Retryable(value = {Exception.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))public String generateText(String prompt) {return chatClient.prompt(prompt).call().content();}@Recoverpublic String recover(Exception ex, String prompt) {return "抱歉,AI服務暫時不可用,請稍后再試。";}
}

周先生:這個重試機制很重要,能提高服務的穩定性。

第7輪:流式響應處理

周先生:對于較長的AI響應,如何實現流式輸出以提升用戶體驗?

cc:Spring AI支持流式響應,我們可以這樣實現:

@RestController
public class AiController {private final ChatClient chatClient;@GetMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamResponse(@RequestParam String prompt) {return chatClient.prompt(prompt).stream().map(chatResponse -> chatResponse.getResult().getOutput().getContent());}
}

周先生:流式響應能讓用戶更快看到部分結果,體驗更好。

第8輪:多模態處理

周先生:如何處理圖像等非文本輸入?

cc:Spring AI支持多模態輸入,可以處理圖像:

@Service
public class MultimodalService {private final OllamaChatModel ollamaChatModel;public String analyzeImage(Resource imageResource, String prompt) {UserMessage userMessage = new UserMessage(prompt,new Media(MimeType.valueOf("image/png"), imageResource));Prompt aiPrompt = new Prompt(userMessage,OllamaOptions.builder().model("llava").build());ChatResponse response = ollamaChatModel.call(aiPrompt);return response.getResult().getOutput().getContent();}
}

周先生:多模態處理能力讓AI應用更加豐富。

第9輪:性能優化

周先生:在高并發場景下,如何優化AI服務的性能?

cc:我們可以從多個方面進行優化:

  1. 使用連接池管理AI服務連接
  2. 實現結果緩存
  3. 異步處理請求
@Service
public class OptimizedAiService {private final ChatClient chatClient;private final Cache<String, String> cache = Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(10, TimeUnit.MINUTES).build();public OptimizedAiService(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@Asyncpublic CompletableFuture<String> generateTextAsync(String prompt) {return CompletableFuture.supplyAsync(() -> {String cached = cache.getIfPresent(prompt);if (cached != null) {return cached;}String result = chatClient.prompt(prompt).call().content();cache.put(prompt, result);return result;});}
}

周先生:這些優化措施能顯著提升AI服務的性能和響應速度。


通過這9輪的深入對話,我們系統地探討了Spring AI在Spring Boot 3項目中的各種應用場景和實現方式。從基礎配置到高級特性,涵蓋了實際開發中可能遇到的大部分問題。希望這些內容能幫助你在面試中脫穎而出,也能在實際項目中發揮作用。

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

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

相關文章

標準SQL語句示例

一、基礎操作1. 數據庫操作-- 1. 創建數據庫 CREATE DATABASE 數據庫名稱 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;-- 2. 刪除數據庫 DROP DATABASE IF EXISTS 數據庫名稱;-- 3. 選擇數據庫 USE 數據庫名稱;-- 4. 顯示所有數據庫 SHOW DATABASES;-- 5. 查看數據庫創…

STM32-基本定時器

一.基本定時器簡介 STM32F1 系列共有 8 個定時器&#xff0c;分別為&#xff1a;基本定時器、通用定時器、高級定時器。基本定時器 TIM6 和 TIM7 是一個 16 位的只能向上計數的定時器&#xff0c;只能定時&#xff0c;沒有外部IO。 二.基本定時器功能 上圖為基本定時器的功能框…

ofd文件轉pdf

主要后端使用Java實現&#xff0c;前端可隨意搭配http請求添加依賴&#xff1a;<!-- OFD解析與轉換庫 --><dependency><groupId>org.ofdrw</groupId><artifactId>ofdrw-converter</artifactId><version>1.17.9</version></…

4.應用層自定義協議與序列化

1.應用層程序員寫的一個個解決我們實際問題, 滿足我們日常需求的網絡程序, 都是在應用層1.1再談“協議”協議是一種 "約定". socket api 的接口, 在讀寫數據時, 都是按 "字符串" 的方式來發送接收的. 如果我們要傳輸一些 "結構化的數據" 怎么辦呢…

【QT搭建opencv環境】

本文參考以下文章&#xff1a; https://blog.csdn.net/weixin_43763292/article/details/112975207 https://blog.csdn.net/qq_44743171/article/details/124335100 使用軟件 QT 5.14.2下載地址&#xff1a;download.qt.io 選擇版本&#xff1a;Qt 5.14.2 Qt 5.14.2百度網盤鏈接…

golang--函數棧

一、函數棧的組成結構&#xff08;棧幀&#xff09; 每個函數調用對應一個棧幀&#xff0c;包含以下核心部分&#xff1a; 1. 參數區 (Arguments) 位置&#xff1a;棧幀頂部&#xff08;高地址端&#xff09;內容&#xff1a; 函數調用時傳入的參數按從右向左順序壓棧&#xff…

【FAQ】創建Dynamics 365 Sales環境

參考文章&#xff1a;5 分鐘內安裝 Dynamics 365 Sales 步驟 1&#xff1a;訪問 Power Platform 管理中心 導航到make.powerapps.com&#xff0c;然后點擊右上角的齒輪圖標。選擇管理中心&#xff0c;或者訪問aka.ms/ppac訪問 Power Platform 管理中心。 第 2 步&#xff1a…

【數據庫】使用Sql Server將分組后指定字段的行數據轉為一個字段顯示,并且以逗號隔開每個值,收藏不迷路

大家好&#xff0c;我是全棧小5&#xff0c;歡迎來到《小5講堂》。 這是《Sql Server》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。 溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01; 目錄前言示例數據集數…

7.項目起步(1)

1&#xff0c;項目起步-初始化項目并使用git管理創建項目并精細化配置src目錄調整git 管理項目2項目起步-配置別名路徑聯想提示什么是別名路徑聯想提示如何進行配置 &#xff08;自動配置了&#xff09;{"compilerOptions" : {"baseUrl" : "./",…

【C++詳解】深入解析繼承 類模板繼承、賦值兼容轉換、派生類默認成員函數、多繼承與菱形繼承

文章目錄一、繼承概念二、繼承定義定義格式繼承后基類成員訪問方式的變化類模板的繼承三、基類和派?類間的轉換(賦值兼容轉換)四、繼承中的作用域隱藏規則兩道筆試常考題五、派生類的默認成員函數四個常見默認成員函數實現?個不能被繼承的類六、繼承與友元七、繼承與靜態成員…

加法器 以及ALU(邏輯算術單元)

加法器框架&#xff0c;首先介紹原理&#xff0c;然后引入一位加法器最后再引入多位加法器最后引入帶符號的加法器這一節涉及到的硬件電路的知識理解就好&#xff0c;實在看不懂就跳過&#xff0c;但是封裝以后的功能必須看懂。這是一個一般的加法過程涉及到的必要元素圖中已經…

設計模式實戰:自定義SpringIOC(親手實踐)

上一篇&#xff1a;設計模式實戰&#xff1a;自定義SpringIOC&#xff08;理論分析&#xff09; 自定義SpringIOC&#xff08;親手實踐&#xff09; 上一篇文章&#xff0c;我們介紹了SpringIOC容器的核心組件及其作用&#xff0c;下面我們來動手仿寫一個SpringIOC容器&#…

力扣面試150(42/150)

7.28 20. 有效的括號 給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判斷字符串是否有效。 有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。左括號必須以正確的順序閉合。每個右括號都有一…

基于黑馬教程——微服務架構解析(二):雪崩防護+分布式事務

之前的兩篇文章我們介紹了微服務的基礎概念及其服務間通信機制。本篇將深入探討微服務的核心保障&#xff1a;服務保護與分布式事務。一、微服務保護問題描述&#xff1a; 在一個購物車的微服務中&#xff0c;倘若某一項服務&#xff08;服務A&#xff09;同一時刻訪問的數據十…

LeetCode: 429 N叉樹的層序遍歷

題目描述給定一個 N 叉樹&#xff0c;返回其節點值的層序遍歷&#xff08;即從左到右&#xff0c;逐層訪問每一層的所有節點&#xff09;。示例輸入格式&#xff08;層序序列化&#xff09;&#xff1a;輸入示意&#xff1a;1/ | \3 2 4/ \5 6輸出&#xff1a;[[1], [3,2,4…

使用phpstudy極簡快速安裝mysql

使用 phpStudy 極簡快速安裝 MySQL 的完整指南&#xff1a; 一、phpStudy 簡介 phpStudy 是一款 Windows 平臺下的 PHP 環境集成包&#xff0c;包含&#xff1a; Apache/Nginx PHP 5.x-7.x MySQL 5.5-8.0 phpMyAdmin 二、安裝步驟 1. 下載安裝包 訪問官網下載&#xf…

git lfs使用

apt install git lfs 或者下載二進制文件加到環境變量 https://github.com/git-lfs/git-lfs/releases git lfs install git lfs clone huggingface文件路徑 如果訪問不了hugggingface.co用hf-mirror.com替代&#xff0c;國內下載速度還是挺快的 先按照pip install modelscope m…

6、CentOS 9 安裝 Docker

&#x1f433; CentOS 9 安裝 Docker 最全圖文教程&#xff08;含鏡像源優化與常見問題解決&#xff09;標簽&#xff1a;CentOS 9、Docker、容器技術、開發環境、國內鏡像源 適合讀者&#xff1a;后端開發、運維工程師、Linux 初學者&#x1f4cc; 前言 在 CentOS 9 上安裝 Do…

SystemV消息隊列揭秘:原理與實戰

目錄 一、消息隊列的基本原理 1、基本概念 2、基本原理 3、消息類型的關鍵作用 4、重要特性總結 5、生命周期管理 6、典型應用場景 二、System V 消息隊列的內核數據結構 1、消息隊列的管理結構 msqid_ds&#xff08;消息隊列標識符結構&#xff09; 關鍵字段解析 2…

5 分鐘上手 Firecrawl

文章目錄Firecrawl 是什么&#xff1f;本地部署驗證mcp安裝palyground&#x1f525; 5 分鐘上手 FirecrawlFirecrawl 是什么&#xff1f; 一句話&#xff1a; 開源版的 “最強網頁爬蟲 清洗引擎” ? 自動把任意網頁 → 結構化 Markdown / JSON ? 支持遞歸整站抓取、JS 渲染…