聊天記憶
大型語言模型 (LLMs) 是無狀態的,這意味著它們不保留關於之前互動的資訊。當您希望在多次互動中保持上下文或狀態時,這可能是一個限制。為了解決這個問題,Spring AI 提供了一個 ChatMemory
抽象,允許您在與 LLM 的多次互動中儲存和檢索資訊。
快速入門
Spring AI 會自動配置一個 ChatMemory
bean,您可以直接在應用程式中使用它。預設情況下,它使用記憶體儲存庫 (InMemoryChatMemoryRepository
) 來儲存訊息,並使用 MessageWindowChatMemory
實現來管理對話歷史。如果已經配置了不同的儲存庫(例如 Cassandra、JDBC 或 Neo4j),Spring AI 將會使用它。
@Autowired
ChatMemory chatMemory;
以下章節將進一步描述 Spring AI 中可用的不同記憶體型別和儲存庫。
記憶體儲存
Spring AI 提供了 ChatMemoryRepository
抽象用於儲存聊天記憶。本節描述了 Spring AI 提供的內建儲存庫以及如何使用它們,但如果需要,您也可以實現自己的儲存庫。
記憶體儲存庫
InMemoryChatMemoryRepository
使用 ConcurrentHashMap
將訊息儲存在記憶體中。
預設情況下,如果尚未配置其他儲存庫,Spring AI 會自動配置一個型別為 InMemoryChatMemoryRepository
的 ChatMemoryRepository
bean,您可以直接在應用程式中使用它。
@Autowired
ChatMemoryRepository chatMemoryRepository;
如果您更願意手動建立 InMemoryChatMemoryRepository
,可以按照以下方式進行
ChatMemoryRepository repository = new InMemoryChatMemoryRepository();
JDBC 儲存庫
JdbcChatMemoryRepository
是一個內建實現,它使用 JDBC 將訊息儲存在關係資料庫中。它適用於需要持久儲存聊天記憶的應用程式。
首先,向您的專案新增以下依賴項
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-jdbc</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-chat-memory-jdbc'
}
Spring AI 為 JdbcChatMemoryRepository
提供了自動配置,您可以直接在應用程式中使用它。
@Autowired
JdbcChatMemoryRepository chatMemoryRepository;
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(10)
.build();
如果您更願意手動建立 JdbcChatMemoryRepository
,可以透過提供一個 JdbcTemplate
例項來完成
ChatMemoryRepository chatMemoryRepository = JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.build();
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(10)
.build();
Schema 初始化
自動配置將使用 JDBC 驅動程式自動建立 ai_chat_memory
表。目前,僅支援 PostgreSQL 和 MariaDB。
您可以透過將屬性 spring.ai.chat.memory.repository.jdbc.initialize-schema
設定為 false
來停用 schema 初始化。
如果您的專案使用 Flyway 或 Liquibase 等工具來管理資料庫 schema,您可以停用 schema 初始化,並參考 這些 SQL 指令碼 來配置這些工具以建立 ai_chat_memory
表。
在聊天客戶端中使用記憶
使用 ChatClient API 時,您可以提供一個 ChatMemory
實現,以便在多次互動中保持對話上下文。
Spring AI 提供了幾個內建的 Advisors,您可以根據需要使用它們來配置 ChatClient
的記憶行為。
當前,與大型語言模型進行工具呼叫時交換的中間訊息不會儲存在記憶中。這是當前實現的一個限制,將在未來的版本中解決。如果您需要儲存這些訊息,請參考 使用者控制的工具執行 的說明。 |
-
MessageChatMemoryAdvisor
. 此 Advisor 使用提供的ChatMemory
實現來管理對話記憶。在每次互動時,它會從記憶中檢索對話歷史,並將其作為訊息集合包含在 prompt 中。 -
PromptChatMemoryAdvisor
. 此 Advisor 使用提供的ChatMemory
實現來管理對話記憶。在每次互動時,它會從記憶中檢索對話歷史,並將其作為純文字附加到系統 prompt 中。 -
VectorStoreChatMemoryAdvisor
. 此 Advisor 使用提供的VectorStore
實現來管理對話記憶。在每次互動時,它會從向量儲存中檢索對話歷史,並將其作為純文字附加到系統訊息中。
例如,如果您想將 MessageWindowChatMemory
與 MessageChatMemoryAdvisor
一起使用,可以按如下方式配置它
ChatMemory chatMemory = MessageChatMemoryAdvisor.builder().build();
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.build();
呼叫 ChatClient
時,記憶將由 MessageChatMemoryAdvisor
自動管理。對話歷史將根據指定的對話 ID 從記憶中檢索。
String conversationId = "007";
chatClient.prompt()
.user("Do I have license to code?")
.advisors(a -> a.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
.call()
.content();
結構化輸出 工具呼叫
如果您直接使用 ChatModel
而不是 ChatClient
,可以顯式地管理記憶
// Create a memory instance
ChatMemory chatMemory = MessageWindowChatMemory.builder().build();
String conversationId = "007";
// First interaction
UserMessage userMessage1 = new UserMessage("My name is James Bond");
chatMemory.add(conversationId, userMessage1);
ChatResponse response1 = chatModel.call(new Prompt(chatMemory.get(conversationId)));
chatMemory.add(conversationId, response1.getResult().getOutput());
// Second interaction
UserMessage userMessage2 = new UserMessage("What is my name?");
chatMemory.add(conversationId, userMessage2);
ChatResponse response2 = chatModel.call(new Prompt(chatMemory.get(conversationId)));
chatMemory.add(conversationId, response2.getResult().getOutput());
// The response will contain "James Bond"