將 Groq Chat 與 Spring AI 結合使用
1.概述
在本教程中,我們將學習使用 Spring AI 與基於 LPU 的 Groq AI 推理引擎提供的模型集成,建立聊天機器人。
Groq 公開了 REST API ,應用程式可以呼叫這些 API 來使用其服務。此外,SDK 支援多種程式語言,例如 Python 和 JavaScript。在 Python 中,像 LangChain 和LiteLLM這樣的流行函式庫也支援 Groq。此外, Vercel AI SDK是一個基於 JavaScript 的函式庫,其中包含一個可與 Groq 整合的模組。
應用程式可以輕鬆地從 OpenAI 切換到 Groq AI 服務,因為 Groq 與 OpenAI 用戶端程式庫完全相容。因此,Spring AI 的 OpenAI 聊天用戶端只需進行少量配置變更即可連接到 Groq。此外,Spring AI 並沒有為 Groq 提供任何單獨的函式庫。
2. 先決條件
Spring AI 框架透過其對應的啟動庫提供與眾多 LLM 服務的整合。同樣,為了與 Groq 服務集成,Spring Boot 應用程式必須導入Spring AI OpenAI啟動庫:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
通常,我們使用Spring Initializr工具來最佳地導入必要的函式庫。
最後,我們必須在Groq 雲端上註冊並建立一個 API 金鑰以在 Spring AI 配置中使用:
用戶在 Groq 雲端註冊後,即可獲得 Groq API 的免費訂閱。不過,Groq 會根據特定型號對 API 請求施加速率限制,以確保公平使用和可用性。
3. Spring AI 的關鍵元件與配置
為了有效利用 Spring AI 的 OpenAI 庫存取 Groq 服務 API,必須了解其關鍵類,例如OpenAiChatModel
和OpenAiChatOptions
。 OpenAIChatModel
類別是使用Prompt
物件呼叫底層 OpenAI 服務的客戶端類別。
但是,在本文中,我們將示範如何連接到 Groq 服務。此外, OpenAiChatOptions
類別有助於指定 Groq 上可用的模型名稱、溫度、maxTokens 和其他基本屬性。當我們必須覆寫聊天客戶端的預設屬性時,我們會使用它,方法是將其作為參數傳遞給OpenAiChatModel#call()
方法。最後,還有一些更通用的 Spring AI 類,例如Prompt
和ChatResponse
,分別用於協助建立聊天提示和接收回應。
要自動設定OpenAiChatModel
,我們可以在spring.ai.openai.chat
命名空間下指定Spring AI 的 OpenAI 聊天配置。至少,我們必須覆蓋spring.ai.openai.chat.base-url
**配置,使其指向 Groq API 的端點,即api.groq.com/openai
** 。此外,我們還必須設定與spring.ai.openai.chat.api-key
屬性對應的 Groq API 金鑰。作為最佳實踐,我們建議從環境屬性或安全庫中讀取該金鑰,然後將其設定為配置金鑰。
我們也可以在spring.ai.openai.base-url
和spring.ai.openai.api-key
配置中設定 URL 和 API 金鑰。但是,命名空間spring.ai.openai.chat
下的密鑰優先。
4. 自動配置 Groq 用戶端
在本節中,我們將了解OpenAiAutoConfiguration
類別如何使用應用程式屬性檔案中的設定來建立OpenAiChatModel
bean。
首先,讓我們在application-groq.properties
檔案中建立一些重要的 OpenAI 設定條目:
spring.application.name=spring-ai-groq-demo
spring.ai.openai.base-url=https://api.groq.com/openai
spring.ai.openai.api-key=gsk_XXXX
spring.ai.openai.chat.base-url=https://api.groq.com/openai
spring.ai.openai.chat.api-key=gsk_XXXX
spring.ai.openai.chat.options.temperature=0.7
spring.ai.openai.chat.options.model=llama-3.3-70b-versatile
如前所述,在屬性檔案中,我們配置了 Groq API 端點、API 金鑰和一個大型語言模型。有趣的是,我們也在spring.ai.openai
命名空間中指定了 API 端點和金鑰。因為一些 Spring AI Bean 依賴它們,如果沒有它們,應用程式將無法啟動。
接下來,讓我們定義一個自訂的 Spring GroqChatService
類,負責呼叫 Groq 服務:
@Service
public class GroqChatService {
@Autowired
private OpenAiChatModel groqClient;
public String chat(String prompt) {
return groqClient.call(prompt);
}
public ChatOptions getChatOptions() {
return groqClient.getDefaultOptions();
}
}
OpenAiAutoConfiguration
bean 使用設定檔中的屬性以及一些預先定義的預設屬性來實例化OpenAiChatModel
類別。在服務類別中,我們自動組裝了 Spring OpenAiChatModel
bean。 GroqChatservice GroqChatservice#chat()
方法使用其call()
方法呼叫 Groq 服務。此外, GroqChatService#getChatOptions()
方法傳回包含聊天用戶端配置的ChatOptions
物件。
最後,讓我們藉助 Junit 測試來看一下 Groq 聊天客戶端的運作情況:
void whenCallOpenAIClient_thenReturnResponseFromGroq() {
String prompt = """
Context:
Support Ticket #98765:
Product: XYZ Wireless Mouse
Issue Description: The mouse connects intermittently to my laptop.
I've tried changing batteries and reinstalling drivers,
but the cursor still freezes randomly for a few seconds before resuming normal movement.
It affects productivity significantly.
Question:
Based on the support ticket, what is the primary technical issue
the user is experiencing with their 'XYZ Wireless Mouse'?;
""";
String response = groqChatService.chat(prompt);
logger.info("Response from Groq:{}", response);
assertThat(response.toLowerCase()).isNotNull()
.isNotEmpty()
.containsAnyOf("laptop", "mouse", "connect");
ChatOptions openAiChatOptions = groqChatService.getChatOptions();
String model = openAiChatOptions.getModel();
Double temperature = openAiChatOptions.getTemperature();
assertThat(openAiChatOptions).isInstanceOf(OpenAiChatOptions.class);
assertThat(model).isEqualTo("llama-3.3-70b-versatile");
assertThat(temperature).isEqualTo(Double.valueOf(0.7));
}
Spring groqChatService
bean 會自動組裝到包含測試方法的類別中。此方法呼叫groqChatService#chat()
,並發出一個包含問題及其相關上下文的提示。上下文包含滑鼠點擊產生的支援工單的資訊。在實際應用中,通常會從向量資料庫中檢索與使用者查詢對應的上下文。之後,Groq 服務會根據上下文回傳答案:
The primary technical issue the user is experiencing with their
'XYZ Wireless Mouse' is intermittent connectivity, resulting in the
cursor freezing randomly for a few seconds before resuming normal movement.
最後,此方法最後斷言聊天選項(例如模型和溫度)與屬性檔案中的配置值相符。
5. 自訂 Groq 用戶端
到目前為止,我們已經在應用程式屬性檔案中使用了 Spring AI 配置來幫助自動配置聊天用戶端。然而,在實際應用中,我們最終會對其進行自訂,以設定諸如模型、溫度等屬性。
首先,讓我們在 Spring 配置類別中定義這樣一個自訂OpenAiChatModel
bean:
@Configuration(proxyBeanMethods = false)
public class ChatAppConfiguration {
@Value("${groq.api-key}")
private String GROQ_API_KEY;
@Value("${groq.base-url}")
private String GROQ_API_URL;
@Bean
public OpenAiChatModel customGroqChatClient() {
OpenAiApi groqOpenAiApi = new OpenAiApi.Builder()
.apiKey(GROQ_API_KEY)
.baseUrl(GROQ_API_URL)
.build();
return OpenAiChatModel.builder()
.openAiApi(groqOpenAiApi)
.build();
}
}
該類別中的ChatAppConfiguration#customGroqChatClient()
方法使用低階OpenAiApi
類別建構一個OpenAiChatModel
bean。在這裡,我們從屬性檔案中讀取 API 金鑰和 URL。此外,我們還可以修改該類別以包含複雜的邏輯,並從下游系統讀取它們。當 Spring Boot 應用程式啟動時,聊天用戶端物件將作為名為customGroqChatClient
Spring bean 提供。
接下來,讓我們定義一個 Spring Boot 服務類,在其中我們可以自動組裝在 Spring 配置類別中建立的自訂OpenAIChatModel
bean:
@Service
public class CustomGroqChatService {
@Autowired
private OpenAiChatModel customGroqChatClient;
public String chat(String prompt, String model, Double temperature) {
ChatOptions chatOptions = OpenAiChatOptions.builder()
.model(model)
.temperature(temperature)
.build();
return customGroqChatClient.call(new Prompt(prompt, chatOptions))
.getResult()
.getOutput()
.getText();
}
}
在chat()
方法中,我們在ChatOptions
物件中設定聊天用戶端的配置,例如model
和temperature,
。此外,我們將提示符號和ChatOptions
物件傳遞給customGroqChatClient#call()
方法,最後從ChatResponse
物件中提取回應文字。
接下來,讓我們在 Junit 測試中看看自訂 Groq 用戶端的實際運作情況:
void whenCustomGroqClientCalled_thenReturnResponse() {
String prompt = """
Context:
The Eiffel Tower is one of the most famous landmarks
in Paris, attracting millions of visitors each year.
Question:
In which city is the Eiffel Tower located?
""";
String response = customGroqChatService.chat(prompt, "llama-3.1-8b-instant", 0.8);
assertThat(response)
.isNotNull()
.isNotEmpty()
.contains("Paris");
logger.info("Response from custom Groq client: {}", response);
}
此測試會呼叫自動組裝的customGroqChatService
bean 的chat()
方法,並傳遞prompt
(包含上下文和相關問題)、 model
和temperature
。然後, CustomGroqChatService#call()
方法會提供答案。隨後,我們驗證答案是否準確地回答了「 In which city is the Eiffel Tower located?
這個問題。
最後我們來看看Groq的回應:
The Eiffel Tower is located in Paris, France.
6. 結論
本文重點介紹 Groq 推理引擎與 Spring AI 的 OpenAI 庫的整合。此外,該程式庫還允許使用 Groq 的工具功能註冊並呼叫外部工具來執行操作。
遺憾的是,Groq 在支援多模態模型方面有其局限性,因此 Spring AI 也缺乏該功能。 Groq 本身並不完全相容於 OpenAI。因此,我們在使用其 API 時必須注意這些限制。
與往常一樣,本文中使用的程式碼可在 GitHub 上找到。