서론: 지능의 기초로서의 기억
기억력이 없는 대규모 언어 모델은 기억상실증에 걸린 전문가와 같습니다. 단일 질문에 훌륭하게 답변하고, 그러나 지속적인 관계를 구축하거나, 과거 상호 작용에서 배우거나, 축적할 수 없습니다. 시간이 지남에 따라 지식. 거기 메모리 이것이 무국적 LLM을 대리인 끈질긴, 당신이 누구인지, 무엇을 논의했는지, 어떤 결정을 함께 내렸는지 기억할 수 있습니다.
기억 시스템이 없으면 모든 상호작용은 처음부터 시작됩니다. 상담원은 귀하가 어제 버그를 수정했다는 사실을 모릅니다. 인증 모듈에서는 JavaScript보다 Python을 선호한다는 사실을 기억하지 못하며 어떤 프로젝트가 어느 프로젝트에 있는지 전혀 모릅니다. 당신은 일하고 있고 마감일이 2주 남았습니다. 그러나 기억을 통해 에이전트는 진정한 협력자가 됩니다. 맥락을 축적하고, 반복되는 패턴을 인식하고, 시간이 지남에 따라 반응을 개선합니다.
이 기사에서는 다음과 같은 가장 간단한 전략부터 AI 에이전트를 위한 메모리 시스템을 살펴보겠습니다. 벡터 임베딩, 지식 그래프 및 하이브리드 패턴을 사용한 고급 접근 방식까지의 대화 기록 2026년 모범사례로 떠오르고 있는 Mem0. 완성도와 비용의 트레이드오프를 분석하여, 정확성과 대기 시간 사이에서 의사 코드와 구체적인 아키텍처를 제공하여 각 접근 방식을 구현합니다.
이 기사에서 배울 내용
- AI 에이전트의 네 가지 유형의 기억: 감각 기억, 단기 기억, 장기 기억, 일화 기억
- 대화 내역 관리 전략: 슬라이딩 윈도우, 요약, 중요도 샘플링
- 벡터 임베딩과 RAG(Retrieval-Augmented Generation) 패턴의 작동 방식
- 관계형 추론을 위한 Neo4j를 사용한 지식 그래프
- Mem0 하이브리드 패턴: 벡터 저장소 + 지식 그래프 결합
- 컨텍스트 창 최적화 및 토큰 예산
- 다양한 메모리 접근 방식 간의 벤치마킹 및 절충
AI 에이전트의 메모리 유형
AI 에이전트를 위한 메모리 시스템에 대한 연구는 인간의 인지 심리학에서 영감을 받아 개념을 적용합니다. 언어 모델의 맥락에 대한 단기 및 장기 기억으로 사용됩니다. 우리는 4가지를 식별할 수 있습니다. 각각 고유한 특성과 사용 사례가 있는 기본 유형의 메모리입니다.
네 가지 유형의 기억
| 유형 | 설명 | 지속 | Esempio |
|---|---|---|---|
| 감각기억 | 즉각적인 입력: 현재 프롬프트와 방금 실행한 도구의 결과 | 단일 반복 | 사용자의 메시지, SQL 쿼리의 출력 |
| 단기 기억 | 현재 세션의 컨텍스트: 누적된 대화 내역 | 단일 세션 | 채팅의 이전 메시지, 결정 |
| 장기 기억 | 외부 저장소에 저장되는 다양한 세션 간의 지속적인 지식 | 영구적인 | 사용자 기본 설정, 비즈니스 문서, 소스 코드 |
| 에피소드 기억 | 관계적 맥락과의 과거 상호작용에 대한 구체적인 기억 | 영구적인 | "JSON 파서의 버그를 수정한 시간" |
감각 기억: 즉각적인 입력
감각 기억은 현재 순간에 에이전트가 "인식하는" 모든 것, 즉 메시지를 나타냅니다. 사용자의, 방금 실행한 도구의 결과, 호출된 API의 응답. 가장 높은 수준이에요 루프가 한 번 반복되는 동안에만 존재하는 낮고 일시적인 메모리 대리인. 현재 프롬프트에서 완전히 실행되므로 지속성 메커니즘이 필요하지 않습니다.
실제적인 측면에서 감각 기억은 단일 모델에 전달된 매개변수에 해당합니다. 호출: 시스템 프롬프트, 사용자 및 보조자 메시지, 도구 호출 결과. 이는 처리할 수 있는 최대 토큰 수를 정의하는 모델의 컨텍스트 창에 의해 제한됩니다. 한 번의 추론으로.
단기 기억: 세션의 맥락
단기 기억은 단일 대화 세션 내에서 맥락을 유지합니다. 결과를 포함하여 사용자와 에이전트 간에 교환된 메시지 목록으로 구현됩니다. 중간 도구 호출의 이 메모리를 통해 에이전트는 무엇을 참조할 수 있는지 문맥상의 모호성을 해결하고 대화의 일관성을 유지하기 위해 이전에 언급한 바 있습니다.
단기기억의 가장 큰 문제는 선형 성장: 더 대화가 계속되면 더 많은 토큰이 소비됩니다. 컨텍스트 창이 있는 모델의 경우 128K-200K 토큰, 강렬한 기술 대화는 몇 시간의 작업만으로 한계에 도달할 수 있습니다. 따라서 압축 및 우선순위 지정 전략을 구현하는 것이 필수적입니다.
장기 기억: 지속적인 지식
장기 기억은 에이전트가 서로 다른 세션 간의 정보를 기억할 수 있게 해주는 것입니다. 대화 속에 살아 있는 단기 기억과 달리 장기 기억에는 외부 저장소: 벡터 데이터베이스, 관계형 데이터베이스, 구조화된 파일 시스템. 에이전트는 상호 작용 중에 관련 정보를 저장하고 필요할 때 검색합니다. 향후 세션.
장기 기억의 예는 다음과 같습니다. 사용자 기본 설정(프로그래밍 언어) 선호, 코드 스타일, 명명 규칙), 색인화된 회사 문서, 지식 프로젝트의 기초, 기술 사양 및 요구 사항. 이러한 유형의 기억은 변형됩니다. 일반 비서에서 개인화되고 상황에 맞는 협력자로 에이전트를 전환합니다.
에피소드 기억: 특정 기억
일화 기억은 가장 정교한 유형입니다. 이는 단순히 사실을 기억하는 것이 아니라 기억하다 구체적인 경험 그들의 관계적 맥락과 함께. 상담원은 기억한다 "파서에 버그가 있다"는 것뿐만 아니라 "1월 15일에 우리는 잘못된 인코딩으로 인해 발생한 JSON 파서(사용자가 유효성 검사를 추가하여 해결함) 전처리 중 UTF-8".
에피소드 기억은 일반적으로 지식 그래프로 구현됩니다. 여기서 엔터티(사람, 프로젝트, 버그, 결정)은 노드와 이들 사이의 관계(has_solved, has_caused, 의존)은 호입니다. 이를 통해 에이전트는 이벤트 간의 연결을 탐색할 수 있습니다. 풍부하고 관련성이 높은 컨텍스트를 제공합니다.
대화 이력 관리
대화 기록은 가장 즉각적인 형태의 기억입니다. 메시지의 전체 목록입니다. 현재 세션에서 거래되었습니다. 상황에 따라 효율적으로 관리하는 것이 중요합니다. 창에는 고정된 제한이 있으며 이를 초과하면 정보를 잃거나 더 나쁘게는 정보를 받는 것을 의미합니다. 모델의 오류. 세 가지 주요 전략이 있으며 각각 고유한 장단점이 있습니다.
전략 1: 슬라이딩 윈도우
가장 간단한 접근 방식: 마지막 항목만 유지 N 메시지를 삭제하고 오래된 메시지를 삭제합니다. 구현하기 쉽고 토큰 소비를 예측할 수 있으며 추가 모델 호출이 필요하지 않습니다. 단점은 대화의 초기 맥락을 완전히 상실한다는 것입니다. 에이전트가 대화 시작 시 내린 결정을 언급할 때 불일치가 발생합니다.
class SlidingWindowMemory:
def __init__(self, max_messages: int = 20):
self.max_messages = max_messages
self.messages: list[dict] = []
def add_message(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
# Mantieni sempre il system prompt (indice 0)
if len(self.messages) > self.max_messages:
system = self.messages[0]
self.messages = [system] + self.messages[-(self.max_messages - 1):]
def get_context(self) -> list[dict]:
return self.messages.copy()
def token_count(self) -> int:
return sum(len(m["content"]) // 4 for m in self.messages)
전략 2: 점진적 요약
오래된 메시지를 버리는 대신 점진적으로 요약합니다. 대화가 나올 때 토큰 임계값을 초과하면 오래된 메시지가 보존 요약으로 압축됩니다. 핵심 정보: 내린 결정, 중요한 사실, 표현된 선호도. 요약 너무 많은 토큰을 소비하지 않고 컨텍스트를 유지하면서 활성 대화를 담당합니다.
이 전략에는 요약을 생성하기 위한 추가 모델 호출이 필요합니다. 비용과 대기 시간이 늘어납니다. 그러나 컨텍스트를 훨씬 더 효과적으로 보존합니다. 슬라이딩 윈도우와 비교하면 중요한 정보가 완전히 손실되지 않기 때문입니다.
class SummarizationMemory:
def __init__(self, max_tokens: int = 4000, summary_threshold: int = 3000):
self.max_tokens = max_tokens
self.summary_threshold = summary_threshold
self.summary: str = ""
self.active_messages: list[dict] = []
def add_message(self, role: str, content: str):
self.active_messages.append({"role": role, "content": content})
if self._count_tokens(self.active_messages) > self.summary_threshold:
self._compress()
def _compress(self):
# Prendi i messaggi più vecchi (prima meta)
half = len(self.active_messages) // 2
old_messages = self.active_messages[:half]
self.active_messages = self.active_messages[half:]
# Genera un riassunto dei messaggi vecchi
prompt = f"Riassumi i punti chiave di questa conversazione:\n"
for msg in old_messages:
prompt += f"{msg['role']}: {msg['content']}\n"
new_summary = llm_call(prompt) # Chiamata al modello
self.summary = f"{self.summary}\n{new_summary}".strip()
def get_context(self) -> list[dict]:
context = []
if self.summary:
context.append({
"role": "system",
"content": f"Riassunto conversazione precedente:\n{self.summary}"
})
context.extend(self.active_messages)
return context
전략 3: 중요도 샘플링
가장 정교한 접근 방식: 각 메시지는 자체적으로 평가됩니다. 중요성 관련 항목만 컨텍스트에 포함됩니다. 중요성은 다음에 의해 결정될 수 있습니다. 여러 가지 요소: 명시적인 결정의 존재, 프로젝트의 주요 엔터티에 대한 참조, 선호 표현, 제약 조건 또는 요구 사항 정의.
이 전략은 컨텍스트 품질 측면에서 최상의 결과를 제공하지만 구현하기가 가장 복잡합니다. 중요성을 평가하려면 모델(또는 경험적 방법)이 필요합니다. 겉으로는 관련이 없어 보이지만 중요한 정보를 제거하는 위험 항상 존재합니다.
class ImportanceSamplingMemory:
def __init__(self, max_tokens: int = 4000):
self.max_tokens = max_tokens
self.messages: list[dict] = []
self.importance_scores: list[float] = []
def add_message(self, role: str, content: str):
score = self._evaluate_importance(content)
self.messages.append({"role": role, "content": content})
self.importance_scores.append(score)
self._prune()
def _evaluate_importance(self, content: str) -> float:
score = 0.5 # Base score
# Decisioni esplicite
if any(kw in content.lower() for kw in ["deciso", "scelta", "usero", "implemento"]):
score += 0.3
# Vincoli e requisiti
if any(kw in content.lower() for kw in ["deve", "requisito", "vincolo", "deadline"]):
score += 0.2
# Errori e bug
if any(kw in content.lower() for kw in ["errore", "bug", "fix", "problema"]):
score += 0.2
# Messaggi recenti hanno un bonus
score = min(score, 1.0)
return score
def _prune(self):
while self._count_tokens() > self.max_tokens:
# Rimuovi il messaggio con l'importanza più bassa
# (escludi system prompt e ultimo messaggio)
min_idx = min(
range(1, len(self.importance_scores) - 1),
key=lambda i: self.importance_scores[i]
)
self.messages.pop(min_idx)
self.importance_scores.pop(min_idx)
전략 간의 절충
| 전략 | 복잡성 | 추가 비용 | 품질 컨텍스트 | 사용 사례 |
|---|---|---|---|---|
| 슬라이딩 윈도우 | 낮은 | Zero | 평균 | 짧은 대화, 프로토타입 |
| 요약 | 평균 | 1-2 LLM 통화 | 높은 | 긴 세션, 복잡한 작업 |
| 중요도 샘플링 | 높은 | 휴리스틱스 또는 LLM | 매우 높음 | 전문 에이전트, 생산 |
벡터 임베딩 및 검색 증강 생성
I 벡터 임베딩 공간에 있는 텍스트를 밀집된 숫자로 표현한 것입니다. 다차원. 각 문장, 단락 또는 문서는 숫자 벡터로 변환됩니다. (일반적으로 768 또는 1536 차원) 여기서 벡터 간의 기하학적 거리는 해당 텍스트 간의 의미론적 유사성. 비슷한 의미를 가진 두 문장은 벡터를 갖습니다. 완전히 다른 단어를 사용하더라도 공간적으로 가깝습니다.
임베딩 작동 방식
임베딩 프로세스는 특수 신경 모델(예: text-embedding-3-small
OpenAI 또는 all-MiniLM-L6-v2 문자열을 입력으로 사용하는 문장 변환기)
텍스트로 변환하고 숫자형 벡터를 생성합니다. 이 모델은 엄청난 양의 텍스트를 학습합니다.
의미상 유사한 문장을 벡터 공간에 서로 가깝게 배치하는 것을 목표로 합니다.
유사성 검색은 다음을 계산하여 발생합니다. 약간의 유사성 또는 유클리드 거리 쿼리 벡터와 인덱싱된 문서 벡터 사이. 거리가 가장 짧거나 유사성이 가장 높은 문서가 쿼리와 가장 관련성이 높습니다.
import numpy as np
def cosine_similarity(vec_a: np.ndarray, vec_b: np.ndarray) -> float:
"""Calcola la similarità coseno tra due vettori."""
dot_product = np.dot(vec_a, vec_b)
norm_a = np.linalg.norm(vec_a)
norm_b = np.linalg.norm(vec_b)
return dot_product / (norm_a * norm_b)
# Esempio: embedding di due frasi
embedding_1 = embed("Come risolvere un bug nel parser JSON")
embedding_2 = embed("Fix di un errore nel parsing di file JSON")
embedding_3 = embed("Ricetta per la torta al cioccolato")
# Le prime due frasi avranno alta similarità (~0.85-0.95)
# La terza sarà molto distante (~0.05-0.15)
print(cosine_similarity(embedding_1, embedding_2)) # ~0.91
print(cosine_similarity(embedding_1, embedding_3)) # ~0.08
벡터 데이터베이스: 주요 옵션
벡터 데이터베이스는 벡터를 저장하고 검색하는데 최적화된 저장 시스템입니다. 고차원. B-트리 인덱스를 사용하는 관계형 데이터베이스와 달리 벡터 데이터베이스는 다음과 같은 알고리즘을 사용합니다. HNSW (계층적으로 탐색 가능한 작은 세계) o IVF (Inverted File Index)를 사용하여 준선형 시간으로 대략적인 검색을 수행합니다.
벡터 데이터베이스 비교
| 데이터베이스 | 유형 | 강점 | 사용 사례 |
|---|---|---|---|
| 솔방울 | 관리형(클라우드) | 확장성, 제로 ops, 서버리스 인덱스 | 대규모 생산, 인프라 없는 팀 |
| 위비에이트 | 자체 호스팅/클라우드 | 하이브리드 검색(벡터 + BM25), GraphQL API | 필터를 이용한 고급검색, 전자상거래 |
| 크로마 | 임베디드/자체 호스팅 | 경량, 기본 Python API, 로컬 개발 | 프로토타입, 로컬 애플리케이션, 개발 |
| Qdrant | 자체 호스팅/클라우드 | 성능, 고급 필터, 풍부한 페이로드 | 고성능 애플리케이션 |
| pg벡터 | PostgreSQL 확장 | 기존 스택, SQL과 통합 | 이미 PostgreSQL을 사용하고 있는 팀 |
RAG 파이프라인: 검색-증강 생성
패턴 조각 (Retrieval-Augmented Generation)은 검색을 위한 기본 기술입니다. 장기 기억을 AI 에이전트에 통합합니다. 아이디어는 간단합니다. 질문에 답하기 전에 질문이 있으면 상담원은 지식 기반에서 가장 관련성이 높은 문서를 검색하여 프롬프트에 포함시킵니다. 추가 컨텍스트로. 이를 통해 모델은 정보를 기반으로 응답할 수 있습니다. 구체적이고 업데이트되어 환각을 줄입니다.
class RAGPipeline:
def __init__(self, vector_db, embedding_model, llm):
self.vector_db = vector_db
self.embedding_model = embedding_model
self.llm = llm
def ingest(self, documents: list[str], metadata: list[dict] = None):
"""Indicizza documenti nella knowledge base."""
for i, doc in enumerate(documents):
# 1. Chunking: dividi il documento in frammenti
chunks = self._chunk_document(doc, chunk_size=512, overlap=50)
for chunk in chunks:
# 2. Embedding: genera il vettore
vector = self.embedding_model.embed(chunk)
# 3. Store: salva nel vector database
self.vector_db.upsert(
id=f"doc_{i}_{hash(chunk)}",
vector=vector,
text=chunk,
metadata=metadata[i] if metadata else {}
)
def query(self, question: str, top_k: int = 5) -> str:
"""Rispondi a una domanda usando RAG."""
# 1. Embedding della query
query_vector = self.embedding_model.embed(question)
# 2. Retrieval: cerca i documenti più simili
results = self.vector_db.search(
vector=query_vector,
top_k=top_k,
threshold=0.7 # Soglia minima di similarità
)
# 3. Context assembly: costruisci il contesto
context = "\n\n---\n\n".join([r.text for r in results])
# 4. Generation: genera la risposta
prompt = f"""Rispondi alla domanda basandoti SOLO sul contesto fornito.
Se il contesto non contiene la risposta, dillo esplicitamente.
Contesto:
{context}
Domanda: {question}
Risposta:"""
return self.llm.generate(prompt)
def _chunk_document(self, doc: str, chunk_size: int, overlap: int) -> list[str]:
"""Dividi un documento in chunk con overlap."""
words = doc.split()
chunks = []
for i in range(0, len(words), chunk_size - overlap):
chunk = " ".join(words[i:i + chunk_size])
chunks.append(chunk)
return chunks
청킹 모범 사례
- 청크 크기: 256-1024 토큰. 너무 작으면 맥락을 잃고, 너무 크면 노이즈가 발생합니다.
- 중복: 개념이 중간에 깨지는 것을 피하기 위해 청크 크기의 10-20%
- 의미론적 청킹: 문자 수보다는 단락이나 논리적 섹션으로 나누는 것을 선호합니다.
- 메타데이터: 소스, 날짜 및 문서 유형을 각 청크에 연결하여 결과를 필터링합니다.
- 순위 재지정: 검색 후 크로스 인코더 모델을 사용하여 관련성에 따라 결과를 재정렬합니다.
관계형 기억에 대한 지식 그래프
I 지식 그래프 지식을 실체(노드)의 네트워크로 표현 관계(호)로 연결되며 각각 관련 속성이 있습니다. 벡터 데이터베이스와 달리 의미적 유사성 검색에 탁월한 지식 그래프는 관계 추론: 엔터티가 서로 어떻게 연결되는지 이해하고 따르십시오. 관계 사슬을 연결하고 기존 연결에서 새로운 지식을 추론합니다.
지식 그래프의 구조
지식 그래프는 세 가지 기본 요소로 구성됩니다.
- 노드(엔티티): 도메인 객체를 나타냅니다. 각 노드에는 유형(레이블)이 속성 집합입니다. 예:
(:User {name: "Federico", role: "developer"}) - 문자열(관계): 두 개의 노드를 연결하며 유형과 방향이 있습니다. 각 호에는 속성이 있을 수 있습니다. 예:
[:RESOLVED {date: "2026-01-15", time_spent: "2h"}] - 재산: 세부 정보와 컨텍스트를 추가하는 노드 또는 에지와 연결된 키-값 쌍
Neo4j는 암호 언어입니다
네오4j 선언적 쿼리 언어를 갖춘 가장 널리 사용되는 그래프 데이터베이스입니다.
전화하다 사이퍼 그래프 탐색을 직관적으로 만듭니다. 사이퍼는
그래프의 구조를 반영하는 시각적 구문: 노드는 괄호 안에 표시됩니다.
둥근 () 그리고 대괄호 안의 관계는 [] 방향에 대한 화살표가 있습니다.
// Creare nodi e relazioni per la memoria episodica
CREATE (u:User {name: "Federico", role: "developer"})
CREATE (p:Project {name: "E-commerce API", language: "Python"})
CREATE (b:Bug {id: "BUG-142", description: "Parser JSON crash on UTF-8"})
CREATE (s:Session {date: "2026-01-15", duration: "45min"})
// Relazioni con proprietà
CREATE (u)-[:WORKS_ON {since: "2025-11-01"}]->(p)
CREATE (b)-[:FOUND_IN]->(p)
CREATE (u)-[:RESOLVED {method: "UTF-8 validation", time: "2h"}]->(b)
CREATE (s)-[:DISCUSSED]->(b)
CREATE (s)-[:INVOLVED]->(u)
// Query: Trova tutti i bug risolti da Federico con il contesto
MATCH (u:User {name: "Federico"})-[r:RESOLVED]->(b:Bug)-[:FOUND_IN]->(p:Project)
RETURN b.description, r.method, r.time, p.name
// Query: Ricostruisci la timeline di una sessione
MATCH (s:Session {date: "2026-01-15"})-[:DISCUSSED]->(topic)
MATCH (s)-[:INVOLVED]->(participant)
RETURN s.date, collect(topic.description), collect(participant.name)
// Query: Trova bug correlati per progetto e tipo
MATCH (b1:Bug)-[:FOUND_IN]->(p:Project)<-[:FOUND_IN]-(b2:Bug)
WHERE b1 <> b2 AND b1.description CONTAINS "parser"
RETURN b1.description, b2.description, p.name
기억력에 대한 지식 그래프의 장점
지식 그래프는 벡터 데이터베이스보다 AI 에이전트의 메모리에 고유한 이점을 제공합니다. 응답할 수 없습니다:
- 관계 추론: 에이전트는 엔터티 간의 관계를 탐색하여 명확하지 않은 연결을 발견할 수 있습니다. "Federico는 전자 상거래 프로젝트에 있던 버그 BUG-142를 수정했으며 동일한 프로젝트에는 또 다른 유사한 버그 BUG-198이 있습니다."
- 효율적인 컨텍스트: 에이전트는 프롬프트에 전체 기록을 포함하는 대신 현재 쿼리와 관련된 하위 그래프만 추출하여 토큰을 저장합니다.
- 추론: 기존 관계로부터 새로운 지식을 도출하는 추론 규칙을 정의할 수 있습니다. A가 B에 의존하고 B가 C에 의존하는 경우 A는 C에 전이적으로 의존합니다.
- 증분 업데이트: 전체 인덱스를 재구축할 필요 없이 새로운 정보가 새로운 노드와 에지로 추가됩니다.
- 설명 가능성: 에이전트는 그래프를 통해 추론 경로를 추적하여 투명한 설명을 제공할 수 있습니다.
하이브리드 접근 방식: Mem0 패턴
Mem0 패턴: 모범 사례 2026
2026년 AI 에이전트 메모리 시스템의 새로운 패턴은 다음과 같습니다. 벡터 저장소 e 지식 그래프 하나의 응집력 있는 시스템으로. "Mem0"이라는 이름("mem-zero"로 발음)은 동일한 이름의 오픈 소스 프로젝트를 나타냅니다. 그리고 그것이 도입한 아키텍처 패턴: 처음부터 시작하여 성장하는 메모리 각 상호작용을 유기적으로 수행합니다.
Mem0 패턴의 아키텍처
기본 아이디어는 간단합니다. 에이전트가 새로운 정보를 받으면 이를 저장합니다. 동시에 두 스토리지 시스템 모두에서. 그가 회복해야 할 때 컨텍스트, 검색 수행 잡종 두 가지 결과를 결합한 것입니다. 검색 품질을 극대화하는 시스템입니다.
class HybridMemory:
"""Pattern Mem0: Vector Store + Knowledge Graph combinati."""
def __init__(self, vector_db, graph_db, embedding_model, llm):
self.vector_db = vector_db
self.graph_db = graph_db
self.embedding_model = embedding_model
self.llm = llm
def store(self, interaction: str, metadata: dict):
"""Salva una nuova memoria in entrambi i sistemi."""
# 1. Estrai entità e relazioni dal testo
entities, relations = self._extract_knowledge(interaction)
# 2. Vector Store: salva l'embedding del testo completo
vector = self.embedding_model.embed(interaction)
self.vector_db.upsert(
id=metadata.get("id", str(hash(interaction))),
vector=vector,
text=interaction,
metadata=metadata
)
# 3. Knowledge Graph: salva entità e relazioni
for entity in entities:
self.graph_db.merge_node(entity.label, entity.properties)
for relation in relations:
self.graph_db.merge_relation(
relation.source, relation.type, relation.target,
properties=relation.properties
)
def retrieve(self, query: str, top_k: int = 5) -> dict:
"""Recupera contesto da entrambi i sistemi."""
# 1. Vector similarity search
query_vector = self.embedding_model.embed(query)
vector_results = self.vector_db.search(query_vector, top_k=top_k)
# 2. Estrai entità dalla query per il graph traversal
query_entities = self._extract_entities(query)
# 3. Graph traversal: espandi il contesto relazionale
graph_context = []
for entity in query_entities:
neighbors = self.graph_db.get_neighbors(
entity, depth=2, limit=10
)
graph_context.extend(neighbors)
# 4. Combina e deduplica i risultati
return {
"vector_results": vector_results,
"graph_context": graph_context,
"combined_context": self._merge_results(
vector_results, graph_context
)
}
def _extract_knowledge(self, text: str):
"""Usa un LLM per estrarre entità e relazioni."""
prompt = f"""Estrai le entità e le relazioni dal seguente testo.
Formato output:
ENTITIES: [tipo:nome:proprietà, ...]
RELATIONS: [source-TIPO_RELAZIONE->target, ...]
Testo: {text}"""
response = self.llm.generate(prompt)
return self._parse_extraction(response)
하이브리드 검색 흐름
하이브리드 검색은 두 시스템의 장점을 활용하는 2단계 프로세스를 따릅니다.
- 축소를 위한 벡터 유사성: 벡터 검색은 의미상 관련 있는 문서를 신속하게 필터링하여 검색 공간을 수천 개에서 수십 개로 줄입니다.
- 강화를 위한 그래프 순회: 그래프 순회는 벡터 결과에서 발견된 엔터티부터 시작하여 지식 그래프의 관계를 따라 컨텍스트를 확장하고 의미적 유사성만으로는 찾을 수 없는 관련 정보를 추가합니다.
- 재순위 및 합병: 결합된 결과는 그래프에서 의미적 유사성과 거리를 모두 고려하여 전반적인 관련성에 따라 재정렬됩니다.
- 컨텍스트 어셈블리: 최종 컨텍스트는 토큰 예산 내에서 조립되며, 가장 관련성이 높은 결과가 우선순위를 갖습니다.
컨텍스트 창 최적화
컨텍스트 창은 AI 에이전트의 가장 귀중한 자산입니다. 컨텍스트에서 낭비되는 모든 토큰 유용한 답변에 대한 관련성이 없고 토큰이 하나 적습니다. 컨텍스트 창의 최적화 이용 가능한 정보의 양과 정보의 균형을 맞추는 체계적인 접근 방식이 필요합니다. 선택한 컨텍스트의 품질과 관련성.
토큰 계산 및 예산 할당
첫 번째 단계는 토큰 예산 프롬프트의 각 구성 요소에 대해. 128K 컨텍스트 창 토큰이 있는 에이전트에 대한 일반적인 할당은 다음과 같습니다.
구성요소당 토큰 예산
| 요소 | 할당된 토큰 | 백분율 | 메모 |
|---|---|---|---|
| 시스템 프롬프트 | 2,000 - 4,000 | 2~3% | 지시사항, 성격, 제약사항 |
| 도구 정의 | 3,000 - 8,000 | 3~6% | 사용 가능한 도구에 대한 설명 및 다이어그램 |
| 장기 기억 | 5,000 - 15,000 | 5-12% | RAG 결과, 지식 그래프의 컨텍스트 |
| 대화 기록 | 20,000 - 50,000 | 15-40% | 최근 메시지, 요약 |
| 응답을 위해 예약됨 | 8,000 - 16,000 | 6~12% | 모델 응답을 위한 공간 |
| 보안 버퍼 | 5,000 - 10,000 | 4-8% | 예상치 못한 도구 결과에 대한 여유 |
의미론적 캐싱
Il 의미론적 캐싱 재계산을 피하는 최적화 기술입니다. 이미 처리된 질문과 유사한 질문에 대한 임베딩 및 쿼리. 대리인이 문자를 받았을 때 쿼리의 경우, 먼저 최근에 이미 의미상 유사한 쿼리가 처리되었는지 확인합니다. 유사성이 임계값(일반적으로 0.95)을 초과하면 결과가 캐시에서 반환됩니다. 벡터 데이터베이스에서 새로운 검색을 수행하지 않고.
이 접근 방식은 검색 작업의 대기 시간과 비용을 크게 줄여줍니다. 특히 사용자가 동일한 질문을 다른 방식으로 재구성하거나 후속 쿼리는 동일한 주제의 변형입니다.
계층적 검색
접근 방식 계층적 검색 여러 수준에서 지식 기반을 구성합니다. 세분성. 가장 높은 수준에는 전체 문서에 대한 일반 요약이 있습니다. 수준에서 중간에는 섹션 요약이 있습니다. 가장 낮은 수준에는 원본 청크가 있습니다. 모든 세부 사항.
검색은 가장 높은 수준에서 시작됩니다. 일반 요약에 문서가 있음을 나타내는 경우 관련성이 있는 경우 섹션 수준으로 이동한 다음 섹션에 대해서만 청크 수준으로 이동합니다. 더 관련성이 높습니다. 이 접근 방식은 임베딩 비교 횟수를 대폭 줄입니다. 필요하며 노이즈를 제거하여 결과의 품질을 향상시킵니다.
벤치마킹과 장단점
올바른 메모리 시스템을 선택하는 것은 애플리케이션의 특정 상황에 따라 달라집니다. 보편적으로 가장 좋은 솔루션은 없습니다. 각 접근 방식에는 고유한 장점이 있습니다. 약점과 최적의 선택은 대기 시간, 비용 및 정확도 요구 사항에 따라 달라집니다. 구현 복잡성.
메모리 접근 방식의 종합적인 비교
| 접근하다 | 숨어 있음 | 정확성 | 비용 | 복잡성 | 이상적인 대상 |
|---|---|---|---|---|---|
| 슬라이딩 윈도우 | ~0ms | 낮은 | Zero | 최소한의 | 간단한 채팅, 프로토타입 |
| 요약 | 200-500ms | 중간-높음 | 중간 | 낮은 | 긴 세션, 코딩 |
| 벡터 DB(RAG) | 50-200ms | 높은 | 중간 | 평균 | 기술 자료, 문서 |
| 지식 그래프 | 100-500ms | 매우 높음 | 높은 | 높은 | 관계 추론 |
| 하이브리드(Mem0) | 200-800ms | 훌륭한 | 높은 | 매우 높음 | 엔터프라이즈 에이전트, 프로덕션 |
언제 무엇을 사용해야 하는가?
- 슬라이딩 윈도우만: 간단한 챗봇, 짧은 상호작용, 지속성이 필요하지 않은 신속한 프로토타입
- 슬라이딩 윈도우 + 요약: 긴 코딩 세션, 대화의 맥락이 충분한 개인 비서
- 벡터 DB(RAG): 에이전트가 외부 지식 베이스(문서, 소스 코드, 회사 FAQ)에 액세스해야 하고 쿼리가 독립적인 경우
- 지식 그래프: 엔터티 간의 관계가 중요하고(프로젝트 관리, CRM, 진단 시스템) 멀티 홉 추론이 필요한 경우
- 하이브리드(Mem0): 의미 검색과 관계 추론이 모두 필요하고 예산이 허용하는 생산 기업 에이전트
실제 구현: 생산 고려 사항
프로덕션 환경에서 메모리 시스템을 구현하려면 다음과 같은 여러 측면에 주의가 필요합니다. 단순한 알고리즘 선택 그 이상입니다. 동시성 관리, 일관성 데이터, 모니터링 및 개인 정보 보호는 모두 중요한 측면입니다.
- 개인 정보 보호 및 GDPR: 추억에는 개인정보가 포함될 수 있습니다. 항상 선택적 삭제 및 명시적 동의 메커니즘을 구현합니다.
- 시간 가치 하락: 오래된 추억은 관련성을 잃습니다. 액세스되지 않은 메모리의 무게를 점진적으로 줄이는 붕괴 시스템을 구현합니다.
- 충돌 및 업데이트: 새로운 정보가 기존 기억과 모순되는 경우 에이전트는 어떤 버전을 유지할지 결정해야 합니다. 업데이트 로그를 통해 항상 최신 정보를 우선시하세요.
- 모니터링: 검색 적중률, 평균 대기 시간, 구성 요소당 토큰 배포, 인식된 응답 품질 등의 지표를 추적합니다.
- 대체 우아함: 메모리 시스템에 장애가 발생하면(벡터 DB 다운, 그래프 손상) 에이전트는 계속 작동해야 하며 현재 대화로만 성능이 저하됩니다.
결론
메모리는 상태 비저장 LLM을 진정한 지능형 에이전트로 전환하는 구성 요소입니다. 그리고 끈질긴. 단순한 대화 기록부터 벡터를 활용한 정교한 하이브리드 시스템까지 데이터베이스와 지식 그래프, 각 접근 방식은 복잡성과 지식 간의 서로 다른 균형을 제공합니다. 컨텍스트의 비용과 품질.
벡터 스토어와 지식 그래프를 결합한 Mem0 패턴이 모범 사례로 떠오르고 있습니다. 2026년 생산 에이전트를 위한. 핵심은 하나의 접근 방식을 선택하는 것이 아니라, 장단점을 이해하고 사용 사례에 적합한 조합을 선택합니다. 간단하게 시작하고 필요한 경우에만 복잡성을 추가합니다.
다음 기사에서는 고급 통화 도구: 에이전트처럼 REST API, 웹 서비스 및 맞춤형 도구를 통합하여 실제 세계에서 작동합니다. 우리는 보자 도구 정의, 입력 검증 및 삭제 전략을 위한 JSON 스키마 재사용 가능한 도구의 프레임워크를 구축하는 방법을 알아보세요.







