領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多
Spring AI ChatClient 提供了一個流暢的 API,用於與 AI 模型進行通訊。流暢的 API 提供了構建提示的組成部分的方法,這些組成部分作為輸入傳遞給 AI 模型。
顧問是流暢 API 的關鍵組成部分,它們攔截、修改和增強 AI 驅動的互動。其主要優點包括封裝常見的生成式 AI 模式、轉換髮送到和來自大型語言模型 (LLM) 的資料,以及為各種模型和用例提供可移植性。
顧問會處理 ChatClientRequest 和 ChatClientResponse 物件。框架會根據顧問的 getOrder() 值(值越低越先執行)將顧問串聯起來,最後一個顧問會呼叫 LLM。
Spring AI 提供內建顧問,用於對話記憶、檢索增強生成 (RAG)、日誌記錄和護欄。開發人員還可以建立自定義顧問。
典型顧問結構
public class MyAdvisor implements CallAdvisor {
// 1. Sets the advisor orders
public int getOrder() { return MY_ADVISOR_ORDER; }
// 2. Sets the advisor name
public String getName() { return MY_ADVISOR_NAME; }
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
// 3. Pre-process the request (modify, validate, log, etc.)
request = preProcess(request);
// 4. Call the next advisor in the chain
ChatClientResponse response = chain.nextCall(request);
// 5. Post-process the response (modify, validate, log, etc.)
return postProcess(response);
}
}
從版本 1.1.0-M4 開始,Spring AI 引入了遞迴顧問,支援多次迴圈執行顧問鏈,以支援迭代工作流
傳統的單次執行顧問模式無法充分處理這些場景。
遞迴顧問會多次迴圈執行下游顧問鏈,重複呼叫 LLM,直到滿足某個條件。
CallAdvisorChain.copy(CallAdvisor after) 方法會建立一個只包含下游顧問的子鏈,從而在保持適當的順序和可觀測性的同時實現受控迭代,並防止上游顧問重複執行。
該圖說明了遞迴顧問如何透過允許流程多次迴圈返回顧問鏈來啟用迭代處理。與傳統的單次執行不同,遞迴顧問可以根據響應條件重新訪問先前的顧問,從而在客戶端、顧問和 LLM 之間建立複雜的迭代工作流。
以下是實現遞迴顧問的基本模式
public class MyRecursiveAdvisor implements CallAdvisor {
@Override
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
// Call the chain initially
ChatClientResponse response = chain.nextCall(request);
// Check if we need to retry
while (!isConditionMet(response)) {
// Modify the request based on the response
ChatClientRequest modifiedRequest = modifyRequest(request, response);
// Create a sub-chain and recurse
response = chain.copy(this).nextCall(modifiedRequest);
}
return response;
}
}
與非遞迴顧問的關鍵區別在於使用 chain.copy(this).nextCall(...) 而不是 chain.nextCall(...) 來迭代內部鏈的副本。這確保了每次迭代都透過完整的下游鏈,允許其他顧問觀察和攔截,同時保持適當的可觀測性。
⚠️ 重要提示
遞迴顧問是 Spring AI 1.1.0-M4 中一個新的實驗性功能。它們僅支援非流式傳輸,需要仔細的顧問排序,並且由於多次 LLM 呼叫而可能增加成本。
對於維護外部狀態的內部顧問要特別小心——它們可能需要額外關注以在迭代過程中保持正確性。
始終設定終止條件和重試限制,以防止無限迴圈。
考慮您的用例是更受益於遞迴顧問,還是更受益於在您的應用程式程式碼中圍繞 ChatClient 呼叫實現顯式 while 迴圈。
Spring AI 1.1.0-M4 提供兩個遞迴顧問
預設的工具呼叫支援
預設情況下,Spring AI 工具執行在每個 ChatModel 實現內部使用 ToolCallingManager 實現。這意味著工具呼叫請求和響應流程對於 ChatClient 顧問是不透明的,因為它發生在顧問執行鏈之外。
ToolCallAdvisor
ToolCallAdvisor 利用使用者控制的工具執行,在顧問鏈中實現工具呼叫迴圈,提供對工具執行的顯式控制,而不是委託給模型的內部工具執行。
示例用法
var toolCallAdvisor = ToolCallAdvisor.builder()
.toolCallingManager(toolCallingManager)
.advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 300)
.build();
public record Request(String location) {}
var weatherTool = FunctionToolCallback.builder("getWeather", (Request request) -> "15.0°C")
.description("Gets the weather for a location")
.inputType(Request.class)
.build();
var chatClient = ChatClient.builder(chatModel)
.defaultToolCallbacks(weatherTool) // Tools registration
.defaultAdvisors(toolCallAdvisor) // Tool Call Execution as Advisor
.build();
String response = chatClient.prompt()
.user("What's the weather in Paris and Amsterdam and convert the temperature to Fahrenheit?")
.call()
.content();
注意:預設情況下,ToolCallAdvisor 的順序設定為接近 Ordered.HIGHEST_PRECEDENCE,以確保顧問在鏈中首先執行(請求處理時首先執行,響應處理時最後執行),從而允許內部顧問攔截和處理工具請求和響應訊息。
當工具執行具有 returnDirect=true 時,顧問會執行該工具,檢測到該標誌,中斷迴圈,並直接將輸出返回給客戶端,而無需將其傳送給 LLM。當工具的輸出是最終答案時,這可以減少延遲。
💡 演示專案:請參閱 遞迴顧問演示專案中的 ToolCallAdvisor 的完整工作示例。
StructuredOutputValidationAdvisor 會根據生成的模式驗證結構化 JSON 輸出,並在驗證失敗時重試
ObjectMapper示例用法
public record ActorFilms(String actor, List<String> movies) {}
var validationAdvisor = StructuredOutputValidationAdvisor.builder()
.outputType(ActorFilms.class)
.maxRepeatAttempts(3)
.build();
var chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(validationAdvisor)
.build();
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for Tom Hanks")
.call()
.entity(ActorFilms.class);
當驗證失敗時,顧問會使用錯誤詳細資訊增強提示,並重試,直到達到配置的最大嘗試次數。
注意:預設情況下,StructuredOutputValidationAdvisor 的順序設定為接近 Ordered.LOWEST_PRECEDENCE,以確保顧問在鏈的末尾執行(但在模型呼叫之前),這意味著它在請求處理時最後執行,在響應處理時首先執行。
遞迴顧問會增加 LLM 呼叫的次數,從而影響:
為了最佳化,請設定合理的重試限制並監控迭代次數。儘可能快取中間結果。