LLM을 위한 장기 메모리 구축 방법 (RAG + FAISS 튜토리얼)
Source: Dev.to

Python, LangChain, FAISS, 그리고 SQLite를 사용하여 LLM이 대화 전반에 걸쳐 사용자 선호도를 기억할 수 있는 메모리 시스템을 구축합니다.
태그: ai, python, langchain, machinelearning
문제: 컨텍스트 윈도우 vs. 장기 기억
LLM은 컨텍스트 윈도우를 가지고 있습니다 — 한 번에 처리할 수 있는 텍스트 양이 제한되어 있죠. 사용자 히스토리를 이 윈도우에 집어넣을 수는 있지만, 금방 비용이 많이 들고 결국 공간이 부족해집니다. 또한 사용자의 이름이나 선호하는 프로그래밍 언어와 같은 정보를 떠올리기 위해 대화 전체를 다시 읽는 것은 비효율적입니다.
우리는 인간 뇌처럼 동작하는 시스템이 필요합니다:
- 단기 기억 – 현재 대화.
- 장기 기억 – 중요한 사실을 따로 저장해 두었다가 필요할 때만 꺼내는 방식.
솔루션: RAG + 의미 검색
우리는 특화된 Retrieval‑Augmented Generation (RAG) 파이프라인을 구축할 것입니다. 일반 문서를 검색하는 대신, 사용자에 대한 개인 메모리를 검색합니다.
핵심 구성 요소
| Component | Purpose |
|---|---|
| Memory Extractor | 채팅을 “청취”하고 저장할 가치가 있는 사실을 식별하는 LLM 에이전트. |
| Vector Store (FAISS) | 각 메모리의 의미 (임베딩)를 저장하여 퍼지 검색을 가능하게 함. |
| SQL Database | 구조화된 데이터(내용, 타임스탬프, 카테고리)를 저장하여 신뢰성을 보장. |
| Retrieval System | 현재 사용자 질의에 기반해 관련 메모리를 가져옴. |
Step 1: 메모리 정의
메모리는 단순히 원시 텍스트가 아니라 메타데이터도 포함합니다.
from dataclasses import dataclass
from typing import List, Dict, Optional
@dataclass
class Memory:
id: str
content: str
category: str # e.g., 'tools', 'personal', 'work'
importance: float # 0.0 to 1.0
timestamp: str
embedding: Optional[List[float]] = None
metadata: Optional[Dict] = None
Step 2: LangChain으로 기억 추출
우리는 나중에 유용한 정보만 유지합니다(예: “Python 개발에 VS Code를 사용합니다”). 신중하게 설계된 시스템 프롬프트가 LLM이 구조화된 JSON을 출력하도록 안내합니다.
# memory_system.py (Simplified)
prompt = ChatPromptTemplate.from_messages([
("system", """You are an expert at extracting factual information.
Focus on preferences, tools, personal info, habits.
Return a list of memories with an importance score (0‑1)."""),
("human", "Message: {message}")
])
# Example input:
# User: "I mostly code in Python but use Rust for side projects."
# Expected output:
# [
# {"content": "Codes primarily in Python", "category": "skills", "importance": 0.9},
# {"content": "Uses Rust for side projects", "category": "skills", "importance": 0.7}
# ]
Source: …
3단계: “뇌” (벡터 스토어 + 데이터베이스)
왜 FAISS인가?
벡터 검색은 “내가 사용하는 도구는 뭐야?”와 같은 질문에 메모가 “나는 NeoVim을 사용한다.”와 같이 표현돼 있어도 답할 수 있습니다. 키워드 검색은 이를 놓칠 수 있지만, 임베딩은 의미적 유사성을 포착합니다.
왜 SQLite인가?
벡터는 유사도 검색에 뛰어나지만 신뢰할 수 있는 읽기/업데이트에는 적합하지 않습니다. SQLite는 실제 텍스트, 타임스탬프, ID 및 기타 구조화된 필드를 저장합니다.
import faiss
import numpy as np
from langchain.embeddings import OpenAIEmbeddings
class VectorStore:
def __init__(self, openai_api_key: str):
self.embeddings = OpenAIEmbeddings(
model="text-embedding-3-small",
openai_api_key=openai_api_key
)
self.index = faiss.IndexFlatIP(1536) # Inner Product for Cosine Similarity
def add_memory(self, text: str):
vector = self.embeddings.embed_query(text)
self.index.add(np.array([vector]))
Step 4: 점들을 연결하기
메인 루프는 워크플로를 조정합니다:
- 사용자가 메시지를 보냅니다.
- Extractor 가 새로운 사실을 식별하고 저장합니다.
- Updater 가 수정 사항을 확인합니다 (예: “사실은, Java로 바꿨습니다”).
- Retriever 가 현재 질의에 기반해 관련 메모리를 가져옵니다.
- LLM 은 검색된 메모리를 컨텍스트로 사용해 응답을 생성합니다.
def answer_with_memory(self, question: str) -> str:
# 1. Search vector DB for similar memories
relevant_memories = self.vector_store.search_similar(question)
# 2. Build context from those memories
context = "\n".join([m.content for m in relevant_memories])
# 3. Prompt the LLM
prompt = f"Based on these memories:\n{context}\n\nAnswer: {question}"
return self.llm.invoke(prompt)
라이브 데모
I built a Streamlit app to visualise this “brain”. You can watch memories form in real‑time, search through them, and see how the system categorises your life.
이것이 중요한 이유
This isn’t just about remembering names. It’s about personalization.
- 당신이 선호하는 라이브러리를 기억하는 코딩 어시스턴트.
- 지난 주에 어려움을 겪었던 내용을 기억하는 튜터.
- 당신의 장기 목표를 기억하는 치료사 봇.
향후 개선 사항
- Graph Database – 메모리를 연결 (예: “Paris”는 “France”와 관련됨).
- Local LLMs – 프라이버시를 위해 Llama 3 실행.
- Time Decay – 시간이 지나면서 중요하지 않은 메모리를 천천히 “잊어버림”.
코드 확인하기
전체 코드는 GitHub에서 확인할 수 있습니다. 여기에는 메모리 추출기, 벡터‑스토어 관리 및 Streamlit UI에 대한 완전하고 상세한 구현이 포함되어 있습니다.
Repository: Devparihar5/llm-long-term-memory
대규모 언어 모델에 지속적이고 검색 가능한 장기 메모리 기능을 제공하는 정교한 메모리 저장 및 검색 시스템입니다. 이 시스템은 대화에서 메모리를 추출, 저장, 업데이트 및 검색할 수 있어 AI 에이전트가 여러 세션에 걸쳐 컨텍스트를 유지할 수 있도록 합니다.
🧠 LLM 에이전트를 위한 고급 장기 기억 시스템
LLM에 지속적이고 검색 가능한 장기 기억 기능을 제공하는 정교한 기억 저장 및 검색 시스템입니다. 이 시스템은 다음을 수행할 수 있습니다:
- 추출 대화에서 기억을.
- 저장 미래 참조를 위해 안전하게.
- 업데이트 새로운 정보가 제공될 때 기존 기억을.
- 검색 여러 세션에 걸쳐 컨텍스트를 유지하기 위해 관련 기억을.
이 시스템을 통합함으로써 AI 에이전트는 연속성을 유지하고, 개인화를 개선하며, 시간이 지남에 따라 의사결정을 향상시킬 수 있습니다.
✨ 기능
- 지능형 메모리 추출 – OpenAI GPT를 사용해 대화에서 사실 정보를 자동으로 추출합니다.
- 시맨틱 검색 – OpenAI 임베딩과 FAISS를 활용한 벡터 기반 유사도 검색.
- 메모리 관리 – 충돌 해결을 포함한 메모리 추가, 업데이트 및 삭제.
- 영구 저장소 – 안정적인 메모리 영속성을 위한 SQLite 데이터베이스.
- 카테고리 조직 – 메모리를 자동으로 카테고리화(도구, 선호도, 개인, 습관 등).
- 중요도 점수화 – 메모리 우선순위를 위한 가중치 기반 중요도 시스템.
- 실시간 업데이트 – 자연어로 된 메모리 업데이트 및 삭제를 감지하고 처리.
- 웹 인터페이스 – Streamlit 기반의 포괄적인 테스트 및 관리 인터페이스.
- LangChain 통합 – 강력한 LLM 상호작용을 위한 LangChain 사용.
- 모듈형 아키텍처 – 관심사의 명확한 분리.
LLM 앱에서 상태를 어떻게 관리하고 계신가요? 아래에 댓글을 남겨 주세요! 👇
원문은 Medium 에서 발행되었습니다.
