장기기억은 저장보다 선택이다: 상태 저장·벡터 검색 분리 아키텍처
장기기억은 “많이 저장하는 기능"이 아니라
지연·비용·일관성을 동시에 맞추는 설계 문제다.
이 글은 캐릭터 서비스에서 장기 컨텍스트를 구현할 때 왜 저장 계층과 검색 계층을 분리했는지 설명한다.
문제 정의
대화가 쌓일수록 세 가지 문제가 커졌다.
- 응답 시 필요한 기억만 빠르게 찾아야 함
- 저장 비용과 조회 비용을 동시에 관리해야 함
- 캐릭터 일관성을 깨지 않는 컨텍스트 선택이 필요함
선택
운영 구조를 다음처럼 분리했다.
- 상태 저장: SQLite
- 기억 검색: Vectorize
이 분리는 단순 기술 취향이 아니라 운영 요구에서 나온 결정이었다.
왜 분리가 유효했나
- 상태 저장은 정합성 중심으로 관리 가능
- 검색은 성능 중심으로 독립 최적화 가능
- 장애가 나도 영향 범위를 계층별로 격리 가능
데이터 흐름
conversation -> memory write -> retrieval -> prompt/context -> response
핵심은 모든 기록을 프롬프트에 넣는 것이 아니라
상황에 맞는 기억만 선택해서 넣는 전략이다.
선택 품질을 올리는 규칙
저장보다 어려운 부분은 retrieval 후보를 고르는 단계였다.
- 최신성 가중치
- 사용자 의도(intent) 유사도
- 신뢰도/중요도 태그
- 최대 토큰 예산
이 규칙을 고정하지 않으면 같은 질문에도 매번 다른 기억이 선택된다.
실무 교훈
장기기억의 핵심은 “정확한 저장"이 아니라 “정확한 선택"과 “운영 가능한 비용 구조"였다.
운영 지표
retrieval_precision_at_kcontext_token_budget_usagememory_selection_consistencystate_sync_conflict_count
이 지표를 같이 보지 않으면, 기억을 많이 넣는 방향으로만 튜닝되어 응답 일관성이 오히려 깨진다.
비용 관리 기준
- 상위 N개 후보만 재랭킹
- 세션 길이에 따른 retrieval depth 동적 조정
- 장기 보관과 단기 캐시의 TTL 분리
장기기억은 저장 공간보다 검색 비용이 먼저 커진다. 따라서 retrieval 비용 상한을 먼저 고정해야 운영이 안정된다.
정합성 검증 포인트
- 상태 저장 성공 후에만 검색 인덱스 갱신 이벤트 발행
- 검색 인덱스 지연이 발생해도 상태 저장을 기준 진실(source of truth)로 유지
이 원칙을 지키면 검색 지연이 있어도 대화 상태 정합성이 먼저 보장된다.
참고 및 인용
참고: RAG 접근은 장기 기억을 저장과 검색으로 분리해 모델 입력 부담을 줄이는 근거가 된다. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
참고: SQLite는 임베디드 상태 저장 계층에서 단순성과 신뢰성을 동시에 제공한다. SQLite Documentation
참고: Cloudflare Vectorize 문서는 임베딩 저장/유사도 검색을 위한 벡터 인덱스 운영 모델을 제공한다. Cloudflare Vectorize Docs