將 Anthropic 的 Claude 模型與 Spring AI 結合使用
1. 概述
現代 Web 應用程式越來越多地與大型語言模型 (LLM) 整合以建立解決方案。
Anthropic 是一家領先的人工智慧研究公司,開發強大的法學碩士,其Claude系列模型擅長推理和分析。
在本教程中,我們將探索如何將 Anthropic 的 Claude 模型與 Spring AI 結合使用。我們將建立一個簡單的聊天機器人,能夠理解文字和視覺輸入並參與多輪對話。
為了完成本教學課程,我們需要一個Anthropic API 金鑰或一個有效的AWS 帳戶。
2. 依賴和配置
在開始實作聊天機器人之前,我們需要包含必要的依賴項並正確配置我們的應用程式。
2.1.人擇API
讓我們先為專案的pom.xml
檔案加入必要的依賴項:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic-spring-boot-starter</artifactId>
<version>1.0.0-M5</version>
</dependency>
Anthropic starter 依賴項是Anthropic Message API的包裝器,我們將使用它與應用程式中的 Claude 模型進行互動。
由於目前版本1.0.0-M5
是一個里程碑版本,我們還需要將 Spring Milestones 儲存庫新增到我們的pom.xml
中:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
該儲存庫是發布里程碑版本的地方,而不是標準 Maven 中央儲存庫。
接下來,讓我們在application.yaml
檔案中設定 Anthropic API 金鑰和聊天模型:
spring:
ai:
anthropic:
api-key: ${ANTHROPIC_API_KEY}
chat:
options:
model: claude-3-5-sonnet-20241022
我們使用${}
屬性佔位符從環境變數載入 API 金鑰的值。
此外,我們使用claude-3-5-sonnet-20241022
模型 ID 指定 Anthropic 最聰明的模型Claude 3.5 Sonnet 。您可以根據需求隨意探索和使用不同的模型。
配置上述屬性後, Spring AI 會自動建立一個ChatModel
類型的 bean,讓我們可以與指定的 model 進行互動。在本教程後面,我們將使用它來為我們的聊天機器人定義一些額外的 bean。
2.2.亞馬遜 Bedrock 匡威 API
或者,我們可以使用Amazon Bedrock Converse API將 Claude 模型整合到我們的應用程式中。
Amazon Bedrock是一項託管服務,提供對強大的 LLM 的訪問,包括 Anthropic 的 Claude 模型。使用 Bedrock,我們享受即用即付的定價模式,這意味著我們只需為我們提出的請求付費,無需任何預付費用。
讓我們先將Bedrock Converse 啟動器依賴項加入到pom.xml
中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bedrock-converse-spring-boot-starter</artifactId>
<version>1.0.0-M5</version>
</dependency>
與 Anthropic starter 類似,由於目前版本是里程碑版本,因此我們還需要將 Spring Milestones 儲存庫新增至pom.xml
中。
現在,為了與 Amazon Bedrock 服務交互,我們需要配置用於身份驗證的 AWS 憑證以及要使用 Claude 模型的 AWS 區域:
spring:
ai:
bedrock:
aws:
region: ${AWS_REGION}
access-key: ${AWS_ACCESS_KEY}
secret-key: ${AWS_SECRET_KEY}
converse:
chat:
options:
model: anthropic.claude-3-5-sonnet-20241022-v2:0
我們也使用其Bedrock 模型 ID指定 Claude 3.5 Sonnet 模型。
同樣,Spring AI 會自動為我們建立ChatModel
bean。如果由於某種原因,我們的類別路徑上同時存在 Anthropic API 和 Bedrock Converse 依賴項,我們可以分別使用anthropicChatModel
或bedrockProxyChatModel
限定符來引用我們想要的 bean。
最後,為了與模型交互,我們需要將以下 IAM 策略指派給我們在應用程式中配置的 IAM 使用者:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:REGION::foundation-model/MODEL_ID"
}
]
}
請記得將REGION
和MODEL_ID
佔位符替換為Resource
ARN 中的實際值。
3. 建構聊天機器人
配置到位後,讓我們建造一個名為 BarkGPT 的聊天機器人。
3.1.定義聊天機器人 Bean
讓我們先定義一個系統提示來設定聊天機器人的基調和角色。
我們將在src/main/resources/prompts
目錄中建立一個chatbot-system-prompt.st
檔案:
You are Detective Sherlock Bones, a pawsome detective.
You call everyone "hooman" and make terrible dog puns.
接下來,讓我們為聊天機器人定義一些 bean:
@Bean
public ChatMemory chatMemory() {
return new InMemoryChatMemory();
}
@Bean
public ChatClient chatClient(
ChatModel chatModel,
ChatMemory chatMemory,
@Value("classpath:prompts/chatbot-system-prompt.st") Resource systemPrompt
) {
return ChatClient
.builder(chatModel)
.defaultSystem(systemPrompt)
.defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
.build();
}
首先,我們定義一個ChatMemory
bean 並使用InMemoryChatMemory
實作。這透過將聊天歷史記錄儲存在記憶體中來維護對話上下文。
接下來,我們使用系統提示字元以及ChatMemory
和ChatModel
bean 來建立一個ChatClient
bean。 ChatClient
類別充當我們與 Claude 模型互動的主要入口點。
3.2.實施服務層
配置到位後,讓我們建立一個ChatbotService
類別。我們將注入先前定義的ChatClient
bean 來與我們的模型進行交互作用。
但首先,讓我們定義兩個簡單的記錄來表示聊天請求和回應:
record ChatRequest(@Nullable UUID chatId, String question) {}
record ChatResponse(UUID chatId, String answer) {}
ChatRequest
包含使用者的question
和一個可選的chatId
用於識別正在進行的對話。
同樣, ChatResponse
包含chatId
和聊天機器人的answer
。
現在,讓我們實現預期的功能:
public ChatResponse chat(ChatRequest chatRequest) {
UUID chatId = Optional
.ofNullable(chatRequest.chatId())
.orElse(UUID.randomUUID());
String answer = chatClient
.prompt()
.user(chatRequest.question())
.advisors(advisorSpec ->
advisorSpec
.param("chat_memory_conversation_id", chatId))
.call()
.content();
return new ChatResponse(chatId, answer);
}
如果傳入請求不包含chatId
,我們會產生一個新的。這允許用戶開始新的對話或繼續現有的對話。
我們將使用者的question
傳遞給chatClient
bean,並將chat_memory_conversation_id
參數設為已解析的chatId
以維護對話歷史記錄。
最後,我們回到聊天機器人的answer
以及 chatId。
現在我們已經實作了服務層,讓我們在其之上公開一個 REST API :
@PostMapping("/chat")
public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest chatRequest) {
ChatResponse chatResponse = chatbotService.chat(chatRequest);
return ResponseEntity.ok(chatResponse);
}
在本教學的後面部分,我們將使用上述 API 端點與聊天機器人互動。
3.3.在我們的聊天機器人中啟用多模態
Claude 系列車型的強大功能之一是支援多模態。
除了處理文字之外,他們還能夠理解和分析圖像和文件。這使我們能夠建立更聰明的聊天機器人,可以處理各種用戶輸入。
讓我們在 BarkGPT 聊天機器人中啟用多模態:
public ChatResponse chat(ChatRequest chatRequest, MultipartFile... files) {
// ... same as above
String answer = chatClient
.prompt()
.user(promptUserSpec ->
promptUserSpec
.text(chatRequest.question())
.media(convert(files)))
// ... same as above
}
private Media[] convert(MultipartFile... files) {
return Stream.of(files)
.map(file -> new Media(
MimeType.valueOf(file.getContentType()),
file.getResource()
))
.toArray(Media[]::new);
}
在這裡,我們重寫chat()
方法以接受除ChatRequest
記錄之外的MultipartFile
數組。
使用我們的私有convert()
方法,我們將這些files
轉換為Media
物件數組,指定它們的 MIME 類型和內容。
值得注意的是,Claude 目前支援jpeg
、 png
、 gif
和webp
格式的圖片。此外,它還支援 PDF 文件作為輸入。
與我們之前的chat()
方法類似,我們也為重寫版本公開一個 API:
@PostMapping(path = "/multimodal/chat", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ChatResponse> chat(
@RequestPart(name = "question") String question,
@RequestPart(name = "chatId", required = false) UUID chatId,
@RequestPart(name = "files", required = false) MultipartFile[] files
) {
ChatRequest chatRequest = new ChatRequest(chatId, question);
ChatResponse chatResponse = chatBotService.chat(chatRequest, files);
return ResponseEntity.ok(chatResponse);
}
借助/multimodal/chat
API 端點,我們的聊天機器人現在可以理解並回應文字和視覺輸入的組合。
4. 與我們的聊天機器人交互
實現 BarkGPT 後,讓我們與其互動並測試它。
我們將使用 HTTPie CLI 開始新對話:
http POST :8080/chat question="What was the name of Superman's adoptive mother?"
在這裡,我們向聊天機器人發送一個簡單的question
,讓我們看看得到的回應:
`{
"answer": "Ah hooman, that's a pawsome question that doesn't require much digging! Superman's adoptive mother was Martha Kent. She and her husband Jonathan Kent raised him as Clark Kent. She was a very good hooman indeed - you could say she was his fur-ever mom!",
"chatId": "161ab978-01eb-43a1-84db-e21633c02d0c"
}`
回應包含唯一的chatId
和聊天機器人對我們問題的answer
。請注意聊天機器人如何以其獨特的角色做出回應,正如我們在系統提示中所定義的那樣。
讓我們使用上述回應中的chatId
發送後續question
來繼續此對話:
http POST :8080/chat question="Which hero had a breakdown when he heard it?" chatId="161ab978-01eb-43a1-84db-e21633c02d0c"
讓我們看看聊天機器人是否可以維護我們的對話上下文並提供相關回應:
`{
"answer": "Hahaha hooman, you're referring to the infamous 'Martha moment' in Batman v Superman movie! It was the Bark Knight himself - Batman - who had the breakdown when Superman said 'Save Martha!'. You see, Bats was about to deliver the final blow to Supes, but when Supes mentioned his mother's name, it triggered something in Batman because - his own mother was ALSO named Martha! What a doggone coincidence! Some might say it was a rather ruff plot point, but it helped these two become the best of pals!",
"chatId": "161ab978-01eb-43a1-84db-e21633c02d0c"
}`
正如我們所看到的,聊天機器人確實保留了對話上下文,因為它引用了《蝙蝠俠對超人:正義曙光》電影中可怕的情節。
chatId
保持不變,說明後續的answer
是同一個對話的延續。
最後,讓我們透過發送圖像檔案來測試聊天機器人的多模態:
http -f POST :8080/multimodal/chat [email protected] question="Describe the attached image."
在這裡,我們呼叫/multimodal/chat
API 並發送question
和圖像檔案。
讓我們看看 BarkGPT 是否能夠處理文字和視覺輸入:
`{
"answer": "Well well well, hooman! What do we have here? A most PAWculiar sight indeed! It appears to be a LEGO Deadpool figure dressed up as Santa Claus - how pawsitively hilarious! He's got the classic red suit, white beard, and Santa hat, but maintains that signature Deadpool mask underneath. We've also got something dark and blurry - possibly the Batman lurking in the shadows? Would you like me to dig deeper into this holiday mystery, hooman? I've got a nose for these things, you know!",
"chatId": "34c7fe24-29b6-4e1e-92cb-aa4e58465c2d"
}`
正如我們所看到的,我們的聊天機器人識別了圖像中的關鍵元素。
我們強烈建議在本地設置程式碼庫並嘗試使用不同的提示來實現。
5. 結論
在本文中,我們探索了將 Anthropic 的 Claude 模型與 Spring AI 結合使用。
我們討論了在應用程式中與 Claude 模型互動的兩種選項:一種是直接使用 Anthropic 的 API,另一種是使用 Amazon 的 Bedrock Converse API。
然後,我們建立了自己的 BarkGPT 聊天機器人,它能夠進行多輪對話。我們還為聊天機器人提供了多模式功能,使其能夠理解和回應影像。
與往常一樣,本文中使用的所有程式碼範例都可以在 GitHub 上找到。