1. 工程結構概覽
spring-ai-client-chat 是 Spring AI 的高級 API 模塊,提供了類似 WebClient 的流式 API,讓 AI 對話編程變得更加簡單和直觀。
spring-ai-client-chat/
├── ChatClient.java # 核心接口,流式 API
├── DefaultChatClient.java # 默認實現
├── ChatClientRequest.java # 請求對象
├── ChatClientResponse.java # 響應對象
│
└── advisor/ # Advisor 機制
├── api/ # Advisor 接口定義
│ ├── Advisor.java
│ ├── CallAdvisor.java
│ ├── StreamAdvisor.java
│ └── BaseAdvisor.java
├── ChatModelCallAdvisor.java # 調用模型的 Advisor
├── ChatModelStreamAdvisor.java # 流式調用的 Advisor
├── ToolCallAdvisor.java # 工具調用 Advisor
└── SimpleLoggerAdvisor.java # 日誌 Advisor
2. 技術體系與模塊關係
ChatClient 建立在 ChatModel 之上,通過 Advisor 機制提供了強大的擴展能力:
3. 關鍵場景示例代碼
3.1 基礎使用
ChatClient 提供了非常友好的流式 API:
@Autowired
private ChatModel chatModel;
public void basicUsage() {
ChatClient chatClient = ChatClient.create(chatModel);
String response = chatClient.prompt()
.user("什麼是 Spring AI?")
.call()
.content();
System.out.println(response);
}
3.2 流式調用
流式調用非常簡單:
public void streamUsage() {
ChatClient chatClient = ChatClient.create(chatModel);
chatClient.prompt()
.user("講一個故事")
.stream()
.content()
.doOnNext(chunk -> System.out.print(chunk))
.blockLast();
}
3.3 使用 Advisor
Advisor 是 ChatClient 的核心特性,可以增強請求和響應:
public void advisorUsage() {
// 創建 RAG Advisor
RetrievalAugmentationAdvisor ragAdvisor =
RetrievalAugmentationAdvisor.builder()
.documentRetriever(vectorStoreRetriever)
.build();
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(ragAdvisor)
.build();
String response = chatClient.prompt()
.user("查詢文檔中的信息")
.call()
.content();
}
3.4 結構化輸出
ChatClient 支持直接將響應轉換為 POJO:
public void structuredOutput() {
BeanOutputConverter<WeatherInfo> converter =
new BeanOutputConverter<>(WeatherInfo.class);
WeatherInfo weather = chatClient.prompt()
.user("查詢北京天氣,返回 JSON:" + converter.getFormat())
.call()
.entity(converter);
}
4. 核心時序圖
4.1 同步調用流程
4.2 流式調用流程
5. 入口類與關鍵類關係
6. 關鍵實現邏輯分析
6.1 流式 API 設計
ChatClient 的流式 API 設計非常巧妙,使用了 Builder 模式和函數式接口:
public interface ChatClient {
ChatClientRequestSpec prompt();
interface ChatClientRequestSpec {
PromptUserSpec user(String text);
PromptSystemSpec system(String text);
AdvisorSpec advisors(Advisor... advisors);
CallResponseSpec call();
StreamResponseSpec stream();
}
interface CallResponseSpec {
String content();
<T> T entity(Class<T> type);
ChatResponse chatResponse();
}
}
這種設計讓 API 既類型安全又易於使用。
6.2 Advisor 機制
Advisor 是 ChatClient 的核心擴展機制,類似於 Spring AOP 的切面:
public interface CallAdvisor extends Advisor {
ChatClientResponse adviseCall(
ChatClientRequest request,
CallAdvisorChain chain
);
}
Advisor 鏈的執行流程:
- Before 階段:每個 Advisor 可以在調用前修改請求
- Call 階段:調用下一個 Advisor 或最終調用模型
- After 階段:每個 Advisor 可以在調用後修改響應
public class DefaultAroundAdvisorChain implements CallAdvisorChain {
public ChatClientResponse nextCall(ChatClientRequest request) {
if (currentIndex >= advisors.size()) {
// 鏈的末尾,調用模型
return chatModelCallAdvisor.adviseCall(request, this);
}
CallAdvisor currentAdvisor = advisors.get(currentIndex);
return currentAdvisor.adviseCall(request,
new DefaultAroundAdvisorChain(currentIndex + 1, ...));
}
}
6.3 工具調用處理
ToolCallAdvisor 負責處理工具調用,它會在檢測到工具調用時自動執行:
public class ToolCallAdvisor implements CallAdvisor {
@Override
public ChatClientResponse adviseCall(...) {
boolean isToolCall = false;
do {
// 調用模型
chatClientResponse = callAdvisorChain.nextCall(request);
// 檢查是否有工具調用
isToolCall = chatClientResponse.chatResponse().hasToolCalls();
if (isToolCall) {
// 執行工具調用
ToolExecutionResult result =
toolCallingManager.executeToolCalls(...);
// 將工具結果作為新的請求再次調用
request = new Prompt(result.getConversationHistory());
}
} while (isToolCall);
return chatClientResponse;
}
}
這種設計實現了自動工具調用循環,直到模型不再請求工具調用。
6.4 流式處理實現
流式處理通過 ChatModelStreamAdvisor 實現:
public class ChatModelStreamAdvisor implements StreamAdvisor {
@Override
public Flux<ChatClientResponse> adviseStream(...) {
Flux<ChatResponse> responseFlux =
chatModel.stream(request.prompt());
return responseFlux.map(chunk ->
ChatClientResponse.builder()
.chatResponse(chunk)
.context(request.context())
.build()
);
}
}
流式 Advisor 鏈的處理更復雜,因為需要在流式響應中插入處理邏輯。
7. 外部依賴
spring-ai-client-chat 的依賴:
- spring-ai-model:核心模型抽象
- Reactor Core:響應式流式處理
- Spring Framework:IoC 和核心功能
- Jackson:JSON 處理(用於結構化輸出)
- MCP SDK:Model Context Protocol 支持
8. 工程總結
spring-ai-client-chat 模塊的設計體現了幾個重要的設計原則:
流式 API 設計。ChatClient 的 API 風格和 Spring WebClient 很像,用起來很順手。開發者不需要學習新的 API,就能快速上手。
Advisor 機制。這是 ChatClient 的核心能力。通過 Advisor,我們可以給請求和響應"加料",比如做 RAG、記錄對話歷史、打日誌、安全檢查等,而且不需要改核心代碼。
責任鏈模式。多個 Advisor 按順序執行,每個 Advisor 都能修改請求和響應,就像過濾器鏈一樣。
工具調用自動化。ToolCallAdvisor 會自動處理工具調用循環,模型説要調用工具,它就自動調用,然後把結果再傳給模型,直到模型不再需要工具。整個過程對用户是透明的。
類型安全。通過泛型和函數式接口,API 既靈活又安全,編譯期就能發現很多錯誤。
總的來説,spring-ai-client-chat 是一個設計得很好的高級 API。它讓 AI 對話編程變得簡單,同時通過 Advisor 機制提供了強大的擴展能力。簡單場景用起來很順手,複雜場景也能通過 Advisor 靈活擴展。