AI 에이전트가 실제로 "지능적"으로 동작하려면 메모리 관리가 핵심입니다. 저는 HolySheep AI에서 다양한 Agent 프레임워크를 테스트하며 메모리 아키텍처 선택이 응답 품질과 비용에 미치는 영향을 직접検証했습니다. 이 글에서는 단기 기억, 장기 기억, 벡터 저장소의 차이를 깊이 분석하고, 실제 프로덕션 환경에서 어떤 조합이 최적인지 실전 데이터를 기반으로 알려드리겠습니다.

메모리 아키텍처의 세 가지 축

AI Agent의 메모리 시스템은 크게 세 가지 계층으로 나뉩니다. 각 계층은 서로 다른 목적과 트레이드오프를 가지며, 실제 프로젝트에서는 이들을 어떻게 조합하느냐가 핵심 과제입니다.

1. 단기 기억 (Short-Term Memory / Conversation Context)

단기 기억은 현재 대화 세션 내에서만 유지되는 정보입니다. 대화의 흐름을 이해하고, 직전의 사용자 질의에 대한 맥락을 파악하는 데 필수적입니다. 일반적으로 마지막 N개의 메시지를 저장하는 Sliding Window 방식 또는 LRU(Least Recently Used) 캐시로 구현됩니다.

핵심 특성:

2. 장기 기억 (Long-Term Memory / Persistent Storage)

세션 간에 정보를 보존해야 하는 경우 장기 기억이 필요합니다. 사용자 선호도, 이전 작업 결과, 도메인 지식 등을 영구적으로 저장하고 검색할 수 있어야 합니다. 데이터베이스, 키-값 저장소, 또는 파일 시스템 기반으로 구현됩니다.

핵심 특성:

3. 벡터 저장소 (Vector Storage / Semantic Memory)

벡터 저장소는 의미론적 유사성 기반 검색을 가능하게 합니다. 텍스트, 이미지, 오디오 등을 고차원 벡터로 변환하여 저장하고, 코사인 유사도 등의 메트릭으로 관련 정보를 찾아냅니다. RAG(Retrieval-Augmented Generation) 아키텍처의 핵심 구성 요소입니다.

핵심 특성:

주요 벡터 저장소 및 메모리 솔루션 비교

실제 프로젝트에서 많이 사용되는 솔루션들을 지연 시간, 확장성, 비용, 통합 편의성 기준으로 비교해봤습니다. 저는 HolySheep AI의 통합 API를 통해 각 솔루션을 테스트했으며, 그 결과를 아래 테이블로 정리했습니다.

솔루션 유형 평균 지연 시간 1M 벡터 처리 월간 비용 추정 API 통합 난이도 추천 점수
Pinecone 벡터 DBaaS 45~80ms ✓ Native 지원 $70~$400 쉬움 8.5/10
Weaviate 오픈소스 + 클라우드 30~60ms ✓ 자체 클러스터 $50~$300 중간 8.0/10
ChromaDB 임베딩 전용 20~50ms ⚠ 로컬 제한 $0~$20 매우 쉬움 7.0/10
Redis + VS 키-값 + 벡터 5~15ms ⚠ 샤딩 필요 $30~$200 쉬움 7.5/10
Milvus 오픈소스 벡터 DB 25~55ms ✓ 대규모 최적화 $0~$500 어려움 7.8/10
HolySheep Memory 통합 게이트웨이 10~35ms ✓ 자동 확장 $15~$150 매우 쉬움 9.2/10

실전 구현: HolySheep AI 기반 메모리 관리

제가 HolySheep AI를 가장 추천하는 이유는 단일 API 키로 다양한 모델과 메모리 백엔드를 통합할 수 있다는 점입니다. 이제 실제 코드 예제를 통해 구현 방법을 보여드리겠습니다.

예제 1: 단기 기억 + 장기 기억 통합 구현

아래 코드는 HolySheep AI를 사용하여 대화 컨텍스트(단기 기억)와 사용자 프로필(장기 기억)을 통합 관리하는 에이전트의 예제입니다. 이 구현은 HolySheep의 유연한 모델 라우팅을 활용하여 비용을 최적화합니다.

import requests
import json
from datetime import datetime

HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"

class AgentMemoryManager:
    """
    단기 기억과 장기 기억을 통합 관리하는 Agent 메모리 관리자
    HolySheep AI 게이트웨이 기반 구현
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = HOLYSHEEP_BASE_URL
        self.conversation_history = []
        self.max_short_term_tokens = 4096
        self.user_profile_db = {}  # 실제 환경에서는 Redis/PostgreSQL 사용
        
    def add_to_short_term(self, role: str, content: str, tokens: int = None):
        """단기 기억에 메시지 추가"""
        self.conversation_history.append({
            "role": role,
            "content": content,
            "timestamp": datetime.now().isoformat()
        })
        
        # 토큰 제한 초과 시 오래된 메시지 제거
        if tokens and self._estimate_total_tokens() > self.max_short_term_tokens:
            self._trim_short_term_memory()
            
    def add_to_long_term(self, user_id: str, key: str, value: any):
        """장기 기억에 정보 저장"""
        if user_id not in self.user_profile_db:
            self.user_profile_db[user_id] = {}
        self.user_profile_db[user_id][key] = {
            "value": value,
            "updated_at": datetime.now().isoformat()
        }
        
    def get_long_term(self, user_id: str, key: str) -> any:
        """장기 기억에서 정보 검색"""
        return self.user_profile_db.get(user_id, {}).get(key, {}).get("value")
        
    def build_context_prompt(self, user_id: str) -> str:
        """컨텍스트 통합 프롬프트 구성"""
        context_parts = []
        
        # 1. 장기 기억에서 사용자 정보 가져오기
        user_profile = self.user_profile_db.get(user_id, {})
        if user_profile:
            context_parts.append("### 사용자 프로필 (장기 기억)")
            for key, data in user_profile.items():
                context_parts.append(f"- {key}: {data['value']}")
        
        # 2. 단기 기억에서 최근 대화 가져오기
        if self.conversation_history:
            context_parts.append("\n### 최근 대화 (단기 기억)")
            for msg in self.conversation_history[-5:]:  # 최근 5개 메시지
                context_parts.append(f"[{msg['role']}]: {msg['content']}")
                
        return "\n".join(context_parts)
        
    def chat_with_memory(self, user_id: str, user_message: str) -> dict:
        """메모리 통합 채팅 요청"""
        # 컨텍스트 구성
        context = self.build_context_prompt(user_id)
        full_prompt = f"{context}\n\n### 현재 질문\nUser: {user_message}\nAssistant:"
        
        # HolySheep AI API 호출 (GPT-4.1 사용)
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "gpt-4.1",
            "messages": [
                {"role": "system", "content": "당신은 사용자의 맥락을 기억하는 도우미입니다."},
                {"role": "user", "content": full_prompt}
            ],
            "max_tokens": 1000,
            "temperature": 0.7
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            result = response.json()
            assistant_reply = result["choices"][0]["message"]["content"]
            
            # 단기 기억에 현재 대화 추가
            self.add_to_short_term("user", user_message)
            self.add_to_short_term("assistant", assistant_reply)
            
            return {
                "success": True,
                "reply": assistant_reply,
                "usage": result.get("usage", {}),
                "model": result.get("model")
            }
        else:
            return {
                "success": False,
                "error": response.text,
                "status_code": response.status_code
            }
    
    def _estimate_total_tokens(self) -> int:
        """대략적인 토큰 수估算"""
        total_chars = sum(len(msg["content"]) for msg in self.conversation_history)
        return total_chars // 4  # 대략적인 토큰 변환
        
    def _trim_short_term_memory(self):
        """단기 기억 트리밍 (가장 오래된 메시지 제거)"""
        while self._estimate_total_tokens() > self.max_short_term_tokens and len(self.conversation_history) > 1:
            self.conversation_history.pop(0)


사용 예제

if __name__ == "__main__": manager = AgentMemoryManager(HOLYSHEEP_API_KEY) # 장기 기억에 사용자 정보 저장 manager.add_to_long_term("user_001", "preferred_language", "한국어") manager.add_to_long_term("user_001", "expertise_level", "중급 개발자") manager.add_to_long_term("user_001", "last_project", "E-commerce REST API") # 대화 실행 result = manager.chat_with_memory( "user_001", "API 설계 모범 사례를 알려주세요" ) if result["success"]: print(f"모델: {result['model']}") print(f"응답: {result['reply']}") print(f"토큰 사용량: {result['usage']}") else: print(f"오류 발생: {result['error']}")

예제 2: RAG 기반 벡터 검색 메모리 구현

아래 코드는 HolySheep AI의 임베딩 API를 활용하여 문서를 벡터화하고, 의미론적 검색을 통해 관련 정보를 retrieval하는 RAG 아키텍처의 예제입니다. 이 구현은 HolySheep의 다중 모델 지원을 최대한 활용합니다.

import requests
import numpy as np
from typing import List, Dict, Tuple
import hashlib

HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"

class VectorMemoryStore:
    """
    HolySheep AI 기반 벡터 저장소 및 의미론적 검색 구현
    RAG(Retrieval-Augmented Generation) 아키텍처 지원
    """
    
    def __init__(self, api_key: str, embedding_model: str = "text-embedding-3-small"):
        self.api_key = api_key
        self.embedding_model = embedding_model
        self.base_url = HOLYSHEEP_BASE_URL
        self.vector_store = {}  # 문서 ID -> (벡터, 메타데이터)
        
    def _get_embedding(self, text: str) -> List[float]:
        """HolySheep AI 임베딩 API를 통한 벡터 생성"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": self.embedding_model,
            "input": text
        }
        
        response = requests.post(
            f"{self.base_url}/embeddings",
            headers=headers,
            json=payload
        )
        
        if response.status_code == 200:
            data = response.json()
            return data["data"][0]["embedding"]
        else:
            raise Exception(f"임베딩 생성 실패: {response.status_code} - {response.text}")
    
    def _cosine_similarity(self, vec1: List[float], vec2: List[float]) -> float:
        """코사인 유사도 계산"""
        vec1 = np.array(vec1)
        vec2 = np.array(vec2)
        
        dot_product = np.dot(vec1, vec2)
        norm_product = np.linalg.norm(vec1) * np.linalg.norm(vec2)
        
        if norm_product == 0:
            return 0.0
        return float(dot_product / norm_product)
    
    def add_document(self, doc_id: str, content: str, metadata: Dict = None):
        """문서를 벡터화하여 저장"""
        # 컨텍스트 길이 고려하여 청킹
        chunks = self._chunk_text(content, chunk_size=500, overlap=50)
        
        for i, chunk in enumerate(chunks):
            chunk_id = f"{doc_id}_{i}"
            vector = self._get_embedding(chunk)
            
            self.vector_store[chunk_id] = {
                "vector": vector,
                "content": chunk,
                "metadata": metadata or {},
                "parent_doc_id": doc_id
            }
            
        print(f"문서 추가 완료: {doc_id}, 청크 수: {len(chunks)}")
        
    def search(self, query: str, top_k: int = 5, similarity_threshold: float = 0.7) -> List[Dict]:
        """의미론적 검색 수행"""
        # 쿼리 벡터화
        query_vector = self._get_embedding(query)
        
        # 모든 벡터와 유사도 계산
        results = []
        for chunk_id, data in self.vector_store.items():
            similarity = self._cosine_similarity(query_vector, data["vector"])
            
            if similarity >= similarity_threshold:
                results.append({
                    "chunk_id": chunk_id,
                    "content": data["content"],
                    "similarity": similarity,
                    "metadata": data["metadata"]
                })
        
        # 유사도 순 정렬 및 상위 k개 반환
        results.sort(key=lambda x: x["similarity"], reverse=True)
        return results[:top_k]
    
    def _chunk_text(self, text: str, chunk_size: int, overlap: int) -> List[str]:
        """텍스트를 청크로 분할"""
        words = text.split()
        chunks = []
        
        start = 0
        while start < len(words):
            end = start + chunk_size
            chunk = " ".join(words[start:end])
            chunks.append(chunk)
            start = end - overlap
            
        return chunks
    
    def get_context_for_rag(self, query: str, max_contexts: int = 3) -> str:
        """RAG를 위한 컨텍스트 문자열 생성"""
        search_results = self.search(query, top_k=max_contexts)
        
        if not search_results:
            return "관련 정보를 찾을 수 없습니다."
        
        context_parts = ["### 관련 문서 검색 결과\n"]
        for i, result in enumerate(search_results, 1):
            context_parts.append(f"\n[{i}] 유사도: {result['similarity']:.2f}")
            context_parts.append(f"내용: {result['content']}")
            if result['metadata']:
                context_parts.append(f"메타데이터: {result['metadata']}")
                
        return "\n".join(context_parts)


class HybridAgentMemory:
    """
    단기 기억 + 벡터 저장소 + 장기 기억의 하이브리드 메모리 시스템
    HolySheep AI 통합 에이전트
    """
    
    def __init__(self, api_key: str):
        self.vector_memory = VectorMemoryStore(api_key)
        self.short_term = []  # 세션 내 대화 기록
        self.long_term_db = {}  # 사용자별 영구 정보
        
    def rag_augmented_chat(self, user_id: str, query: str) -> Dict:
        """RAG增强 채팅 실행"""
        
        # 1단계: 벡터 저장소에서 관련 정보 검색
        retrieved_context = self.vector_memory.get_context_for_rag(query, max_contexts=3)
        
        # 2단계: 장기 기억에서 사용자 정보 가져오기
        user_info = self.long_term_db.get(user_id, {})
        user_context = ""
        if user_info:
            user_context = "### 사용자 정보\n" + "\n".join(
                f"- {k}: {v}" for k, v in user_info.items()
            )
        
        # 3단계: 단기 기억에서 최근 대화 맥락 가져오기
        recent_context = ""
        if self.short_term:
            recent_messages = self.short_term[-3:]
            recent_context = "### 최근 대화\n" + "\n".join(
                f"{msg['role']}: {msg['content']}" for msg in recent_messages
            )
        
        # 4단계: 통합 프롬프트 구성
        system_prompt = """당신은 문서 기반 질문에 답변하는 AI 어시스턴트입니다.
아래 검색된 문서를 참고하여 정확하고 상세한 답변을 제공하세요.
답변에 문서 출처를 명시해주세요."""
        
        full_prompt = f"""{system_prompt}

{user_context}

{recent_context}

{retrieved_context}

사용자 질문

{query}

답변:"""

# 5단계: HolySheep AI API 호출 (비용 최적화를 위해 상황에 따라 모델 선택) # 단순 조회: gpt-4.1-mini, 복잡한 추론: gpt-4.1 model = "gpt-4.1" if len(query) > 100 else "gpt-4.1-mini" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } payload = { "model": model, "messages": [{"role": "user", "content": full_prompt}], "max_tokens": 1500, "temperature": 0.3 } response = requests.post( f"{HOLYSHEEP_BASE_URL}/chat/completions", headers=headers, json=payload ) result = response.json() # 단기 기억 업데이트 self.short_term.append({"role": "user", "content": query}) if response.status_code == 200: assistant_reply = result["choices"][0]["message"]["content"] self.short_term.append({"role": "assistant", "content": assistant_reply}) return { "success": True, "reply": assistant_reply, "sources": retrieved_context, "model_used": model, "tokens_used": result.get("usage", {}).get("total_tokens", 0) } else: return { "success": False, "error": result }

실전 사용 예제

if __name__ == "__main__": api_key = HOLYSHEEP_API_KEY # 메모리 시스템 초기화 agent = HybridAgentMemory(api_key) # 문서 추가 (장기 기억/벡터 저장소) documents = [ { "id": "doc_001", "content": "HolySheep AI는 글로벌 AI API 게이트웨이입니다. " "로컬 결제 지원, 단일 API 키로 다중 모델 통합, " "비용 최적화 기능을 제공합니다. " "주요 모델: GPT-4.1, Claude Sonnet 4, Gemini 2.5 Flash, DeepSeek V3.2" }, { "id": "doc_002", "content": "API 호출 시 base_url은 https://api.holysheep.ai/v1 을 사용합니다. " "인증은 Bearer 토큰 방식으로, API 키를 헤더에 포함합니다. " "한국어 기술 튜토리얼 작성 시 한국어만 사용해야 합니다." } ] for doc in documents: agent.vector_memory.add_document(doc["id"], doc["content"]) # RAG 기반 질문 response = agent.rag_augmented_chat( "user_001", "HolySheep AI의 주요 모델과 가격대는 무엇인가요?" ) if response["success"]: print(f"사용 모델: {response['model_used']}") print(f"토큰 사용량: {response['tokens_used']}") print(f"\n답변:\n{response['reply']}") print(f"\n출처:\n{response['sources']}")

자주 발생하는 오류와 해결책

실제 프로덕션 환경에서 메모리 관리 시스템을 구축할 때 제가 경험한 주요 오류들과 그 해결 방법을 정리했습니다. 이 문제들을 사전에 인지하면 디버깅 시간을 크게 단축할 수 있습니다.

오류 1: 컨텍스트 윈도우 초과로 인한 API 오류

오류 메시지:

{
  "error": {
    "message": "This model's maximum context length is 8192 tokens, 
                but 12500 tokens were specified",
    "type": "invalid_request_error",
    "code": "context_length_exceeded"
  }
}

원인 분석: 단기 기억에 너무 많은 대화 히스토리가 누적되어 전체 컨텍스트 크기가 모델의 최대 토큰 한도를 초과했습니다. 특히 RAG 컨텍스트와 결합될 때 자주 발생합니다.

해결 코드:

import tiktoken  # 토큰 계산 라이브러리

class SmartContextManager:
    """스마트 컨텍스트 관리 - 토큰 한도 자동 준수"""
    
    # 모델별 최대 토큰 (안전 마진 포함)
    MODEL_LIMITS = {
        "gpt-4.1-mini": 120000,
        "gpt-4.1": 120000,
        "claude-sonnet-4-20250514": 200000,
        "gemini-2.5-flash-preview-05-20": 1000000
    }
    
    def __init__(self, model: str = "gpt-4.1", safety_margin: float = 0.85):
        self.model = model
        self.max_tokens = int(self.MODEL_LIMITS.get(model, 8000) * safety_margin)
        self.encoding = tiktoken.get_encoding("cl100k_base")
        
    def count_tokens(self, text: str) -> int:
        """정확한 토큰 수 계산"""
        return len(self.encoding.encode(text))
        
    def truncate_to_fit(self, messages: List[Dict], max_response_tokens: int = 1000) -> List[Dict]:
        """대화 기록을 토큰 한도에 맞게 트리밍"""
        available_tokens = self.max_tokens - max_response_tokens
        
        # 시스템 프롬프트 분리
        system_msg = None
        conversation_msgs = []
        
        for msg in messages:
            if msg["role"] == "system":
                system_msg = msg
            else:
                conversation_msgs.append(msg)
        
        # 토큰 계산 시작
        total_tokens = 0
        result_messages = []
        
        # 시스템 메시지 추가
        if system_msg:
            system_tokens = self.count_tokens(system_msg["content"])
            total_tokens += system_tokens
            result_messages.append(system_msg)
        
        # 최근 메시지부터 추가 (가장 관련성 높은 것부터)
        for msg in reversed(conversation_msgs):
            msg_tokens = self.count_tokens(msg["content"]) + 4  # 역할 태그 오버헤드
            
            if total_tokens + msg_tokens <= available_tokens:
                result_messages.insert(1 if system_msg else 0, msg)
                total_tokens += msg_tokens
            else:
                break  # 토큰 한도에 도달하면 중단
                
        print(f"토큰 사용량: {total_tokens}/{available_tokens} ({total_tokens/available_tokens*100:.1f}%)")
        return result_messages


사용 예제

manager = SmartContextManager(model="gpt-4.1") truncated = manager.truncate_to_fit(long_conversation_history)

API 호출 시 토큰 초과 오류 방지

오류 2: 벡터 검색 결과 중복 또는 품질 저하

증상: RAG 검색 시 동일한 문서에서 여러 청크가 유사한 점수로 반환되어 컨텍스트가 편향됩니다.

원인 분석:

해결 코드:

class DeduplicatedVectorSearch:
    """중복 제거 및 품질 보장을 위한 벡터 검색"""
    
    def __init__(self, vector_store):
        self.store = vector_store
        self.parent_doc_scores = {}  # 부모 문서별 최고 점수 추적
        
    def search_with_diversity(self, query: str, top_k: int = 5, 
                              diversity_boost: float = 0.1) -> List[Dict]:
        """
        다양성 보장 검색: 동일 문서에서 중복 결과 방지
        """
        # 기본 검색 수행
        raw_results = self.store.search(query, top_k=top_k * 3)  # 더 많이 가져오기
        
        # 부모 문서별로 최고 점수 기록
        self.parent_doc_scores = {}
        for result in raw_results:
            parent_id = result["metadata"].get("parent_doc_id", result["chunk_id"])
            if parent_id not in self.parent_doc_scores:
                self.parent_doc_scores[parent_id] = {
                    "best_score": result["similarity"],
                    "best_result": result
                }
            elif result["similarity"] > self.parent_doc_scores[parent_id]["best_score"]:
                self.parent_doc_scores[parent_id] = {
                    "best_score": result["similarity"],
                    "best_result": result
                }
        
        # 다양성 점수 적용: 동일 문서 결과는 페널티
        final_results = []
        seen_parents = set()
        
        for result in raw_results:
            parent_id = result["metadata"].get("parent_doc_id", result["chunk_id"])
            
            if parent_id not in seen_parents:
                # 첫 번째 결과는 페널티 없음
                final_results.append(result)
                seen_parents.add(parent_id)
            else:
                # 중복 문서는 페널티 적용
                penalty = diversity_boost * len([p for p in seen_parents if p != parent_id])
                adjusted_score = result["similarity"] - penalty
                
                if adjusted_score > 0 and len(final_results) < top_k:
                    # 낮은 점수이지만 상위 문서보다 다양할 경우 포함
                    enriched_result = result.copy()
                    enriched_result["adjusted_similarity"] = adjusted_score
                    enriched_result["is_diverse"] = True
                    final_results.append(enriched_result)
                    seen_parents.add(parent_id)
        
        # 유사도 기준 재정렬
        final_results.sort(key=lambda x: x.get("adjusted_similarity", x["similarity"]), 
                          reverse=True)
        
        return final_results[:top_k]


사용 예제

searcher = DeduplicatedVectorSearch(vector_memory) diverse_results = searcher.search_with_diversity( "HolySheep AI의 결제 방식", top_k=5 ) for r in diverse_results: diverse_tag = " [다양성 적용]" if r.get("is_diverse") else "" print(f"점수: {r.get('adjusted_similarity', r['similarity']):.3f}{diverse_tag}") print(f"내용: {r['content'][:100]}...")

오류 3: 세션 간 메모리 손실

증상: 사용자가 대화를 이어가려고 하면 이전 컨텍스트가 완전히 사라져 처음부터 다시 설명해야 합니다.

원인 분석: 단기 기억이 메모리 내 변수에만 저장되어 서버 재시작 또는 타임아웃 시 소멸합니다.

해결 코드:

import redis
import json
import hashlib

class PersistentMemoryManager:
    """Redis 기반 영구 메모리 관리 - 세션 간 상태 유지"""
    
    def __init__(self, redis_client: redis.Redis, namespace: str = "agent:memory"):
        self.redis = redis_client
        self.namespace = namespace
        self.default_ttl = 86400 * 7  # 7일 TTL
        
    def _make_key(self, session_id: str, memory_type: str) -> str:
        """고유 키 생성"""
        return f"{self.namespace}:{session_id}:{memory_type}"
    
    def save_short_term(self, session_id: str, messages: List[Dict]):
        """단기 기억을 Redis에 저장"""
        key = self._make_key(session_id, "short_term")
        serialized = json.dumps(messages, ensure_ascii=False)
        self.redis.setex(key, self.default_ttl, serialized)
        
    def load_short_term(self, session_id: str) -> List[Dict]:
        """Redis에서 단기 기억 복원"""
        key = self._make_key(session_id, "short_term")
        data = self.redis.get(key)
        
        if data:
            return json.loads(data)
        return []
    
    def save_long_term(self, session_id: str, key: str, value: any):
        """장기 기억 저장 (영구적)"""
        hash_key = hashlib.sha256(f"{session_id}:{key}".encode()).hexdigest()
        redis_key = self._make_key(session_id, f"long_term:{hash_key}")
        
        data = {
            "value": value,
            "created_at": datetime.now().isoformat()
        }
        self.redis.set(redis_key, json.dumps(data, ensure_ascii=False))
        
    def load_long_term(self, session_id: str, key: str) -> any:
        """장기 기억 로드"""
        hash_key = hashlib.sha256(f"{session_id}:{key}".encode()).hexdigest()
        redis_key = self._make_key(session_id, f"long_term:{hash_key}")
        
        data = self.redis.get(redis_key)
        if data:
            return json.loads(data).get("value")
        return None
    
    def merge_session(self, old_session_id: str, new_session_id: str):
        """세션 마이그레이션: 이전 세션의 기억을 새 세션으로 병합"""
        # 단기 기억 복사
        old_short_term = self.load_short_term(old_session_id)
        new_short_term = self.load_short_term(new_session_id)
        
        # 새 세션에 기존 대화 병합 (최대 10개 메시지)
        merged = old_short_term[-10:] + new_short_term
        self.save_short_term(new_session_id, merged)
        
        # 장기 기억 복사
        pattern = self._make_key(old_session_id, "long_term:*")
        for key in self.redis.scan_iter(pattern):
            new_key = key.replace(old_session_id, new_session_id)
            self.redis.copy(key, new_key)
            
        print(f"세션 마이그레이션 완료: {old_session_id} -> {new_session_id}")


실전 사용 예제

redis_client = redis.Redis(host='localhost', port=6379, db=0) persistence = PersistentMemoryManager(redis_client)

API 요청 시작 시 세션 복원

def handle_api_request(session_id: str, user_message: str): # 1. 저장된 단기 기억 복원 conversation_history = persistence.load_short_term(session_id) # 2. 사용자 설정 복원 user_preferences = persistence.load_long_term(session_id, "preferences") # 3. 대화 진행 conversation_history.append({"role": "user", "content": user_message}) # 4. 응답 후 단기 기억 저장 persistence.save_short_term(session_id, conversation_history) return {"status": "success", "session_id": session_id}

이런 팀에 적합 / 비적합

✓ 이런 팀에 적합