Chat Memory
이전 대화를 저장하고 프롬프트에 포함시키는 역할을 수행
-> LLM의 무상태성을 극복하여 LLM이 맥락을 이해하도록 하는 핵심 기술
undefined
Spring AI의 Chat Memory 구조
classDiagram
class ChatMemoryAdvisor {
<>
프롬프트에 기억을 추가하는 전략
}
class ChatMemory {
<>
메시지 윈도우 관리
}
class ChatMemoryRepository {
<>
실제 저장소 구현
}
class MessageChatMemoryAdvisor {
메시지 모음으로 추가
}
class PromptChatMemoryAdvisor {
텍스트 형태로 시스템 메시지에 추가
}
class VectorStoreChatMemoryAdvisor {
유사도 검색으로 관련 기억만 추가
}
class MessageWindowChatMemory {
최대 메시지 수 제한
}
class InMemoryChatMemoryRepository {
메모리 저장 (휘발성)
}
class JdbcChatMemoryRepository {
PostgreSQL 저장 (영구)
}
ChatMemoryAdvisor <|.. MessageChatMemoryAdvisor
ChatMemoryAdvisor <|.. PromptChatMemoryAdvisor
ChatMemoryAdvisor <|.. VectorStoreChatMemoryAdvisor
ChatMemory <|.. MessageWindowChatMemory
ChatMemoryRepository <|.. InMemoryChatMemoryRepository
ChatMemoryRepository <|.. JdbcChatMemoryRepository
MessageWindowChatMemory --> ChatMemoryRepository
ChatMemory, Advisor, Repository 3계층으로 구성
Advisor : 기억을 프롬프트에 추가하는 전략 담당
ChatMemory : 메시지 윈도우 관리 (최대 개수 제한)
Repository : 실제 저장소
3가지 Chat Memory 비교
| 항목 | InMemory | Jdbc | VectorStore |
| 저장소 | JVM 메모리 | PostgreSQL 테이블 | PgVector 테이블 |
| 영속성 | 서버 재시작 시 사라짐 | 영구 저장 | 영구 저장 |
| 기억 전략 | 최근 N개 전체 | 최근 N개 전체 | 의미적으로 유사한 N개 |
| Advisor | MessageChatMemoryAdvisor | PromptChatMemoryAdvisor | VectorStoreChatMemoryAdvisor |
| 프롬프트 추가 방식 | Message 객체 모음 | 시스템 메시지 텍스트 | 유사 대화 텍스트 |
| 속도 | 가장 빠름 | 빠름 | 임베딩 변환으로 다소 느림 |
| 적합한 상황 | 개발/테스트, 단기 대화 | 프로덕션, 대화 이력 보존 | 대화 양이 많고 관련 기억만 필요 |
1. InMemory (InMemoryChatService)
특징
- 서버 재시작 시 대화 기억이 사라집니다 (휘발성).
- 빠른 응답 속도
- InMemoryChatMemoryRepository 직접 생성 필요(new) -> Spring AI의 auto-config에 의해 JDBC 설정이 있으면 JDBC 기반 Repository를 자동으로 등록해 InMemory 동작이 보장되지 않음
- MessageWindowChatMemory : maxMessages(20)으로 최근 20개 메시지만 유지 (오래된 메시지는 자동 제거)

2. JDBC (JdbcChatService)
특징
- PostgreSQL에 영구 저장됨
- Spring이 자동으로 JdbcChatMemoryRepository를 주입해 줌 (파라미터 부분)

3. VectorStore (VectorStoreChatService)
특징
- 별도 VectorStore 생성 : chat_memory_vector_store 테이블을 사용, 메인 vector_store 테이블과 분리
- 분리의 이유 : 메인 vector_store 테이블에는 Document 검색용 데이터를, chat_memory_vector_store에는 대화 기억용 데이터를 저장하여 검색 시 서로 간섭하는 것을 막기 위해
-- docker/postgres/init/01-create-extension.sql
-- 1. DB 선택
\connect app_vector_db;
-- 2. pgvector extension 생성
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- 3. VectorStore 대화 기억용 테이블 생성
CREATE TABLE IF NOT EXISTS chat_memory_vector_store (
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
content text,
metadata json,
embedding vector(1536)
);
CREATE INDEX IF NOT EXISTS chat_memory_vector_store_embedding_idx
ON chat_memory_vector_store
USING hnsw (embedding vector_cosine_ops);
- 대화의 양이 매우 많을 때, 관련 있는 대화만 선별적으로 활용함. 임베딩 변환 과정이 추가되므로 다른 방식보다 응답이 다소 느릴 수 있음

공통 채팅 메서드
위 3개 채팅 서비스 모두 동일 구조의 chat() 메서드를 제공
conversationId : 이 값이 같으면 이전 대화가 이어지고, ID가 다르면 새로운 대화가 시작됨. 사용자별, 세션별 대화를 구분하는 핵심 파라미터.
public String chat(String userText, String conversationId) {
return chatClient.prompt()
.user(userText)
.advisors(advisorSpec -> advisorSpec.param(
ChatMemory.CONVERSATION_ID, conversationId
))
.call()
.content();
}'Career Development > AI' 카테고리의 다른 글
| 하네스 엔지니어링 (0) | 2026.05.26 |
|---|---|
| 운동 관리 앱 만들기[Levio] DAY 1 (0) | 2026.05.16 |
| 클로드는 업무 운영 시스템이다 (0) | 2026.05.16 |
| [Spring AI] Advisor 패턴 (0) | 2026.04.02 |