메모리 시스템 설계
메모리는 에이전트가 세션 간 연속성을 유지하고 축적된 지식을 바탕으로 추론할 수 있도록 하는 지속성 계층을 제공합니다. 단순한 에이전트는 메모리를 전적으로 컨텍스트에 의존하여 세션이 종료되면 모든 상태를 잃습니다. 정교한 에이전트는 즉각적인 컨텍스트 요구와 장기 지식 보존의 균형을 맞추는 계층형 메모리 아키텍처를 구현합니다. 벡터 저장소에서 지식 그래프, 시간적 지식 그래프로의 진화는 검색 및 추론 개선을 위한 구조화된 메모리에 대한 투자 증가를 나타냅니다.
활성화 시기
다음과 같은 경우 이 스킬을 활성화하십시오:
- 세션 간 지식을 유지해야 하는 에이전트 구축
- 메모리 프레임워크(Mem0, Zep/Graphiti, Letta, LangMem, Cognee) 중에서 선택
- 대화 전반에 걸쳐 엔터티 일관성 유지 필요
- 축적된 지식에 대한 추론 구현
- 프로덕션에서 확장 가능한 메모리 아키텍처 설계
- 벤치마크(LoCoMo, LongMemEval, DMR)를 기준으로 메모리 시스템 평가
- 자동 엔터티/관계 추출 및 자체 개선 메모리(Cognee)를 사용한 동적 메모리 구축
다른 스킬의 인접 작업에는 이 스킬을 활성화하지 마십시오:
- 파일 기반 스크래치패드, 실행 로그 및 도구 출력 오프로딩:
filesystem-context. - 대화 압축 또는 사람이 읽을 수 있는 핸드오프 요약:
context-compression. - 마스킹, 프리픽스 캐싱, 토큰 예산 또는 단일 궤적 내 검색 범위 지정:
context-optimization. - RDF 상태에 대한 형식적 신념/욕구/의도 모델:
bdi-mental-states.
핵심 개념
메모리를 휘발성 컨텍스트 창에서 영구 저장소까지의 스펙트럼으로 생각하십시오. 검색 요구 사항을 충족하는 가장 단순한 계층을 기본값으로 사용하십시오. 벤치마크 증거에 따르면 일부 메모리 워크로드(claim-memory-locomo-filesystem-baseline)의 경우 도구 복잡성보다 안정적인 검색이 덜 중요하기 때문입니다. 검색 품질이 저하되거나 에이전트가 다중 홉 추론, 관계 탐색 또는 시간 이동 쿼리가 필요한 경우에만 구조(그래프, 시간적 유효성)를 추가하십시오.
세부 주제
프로덕션 프레임워크 환경
에이전트가 필요로 하는 지배적인 검색 패턴을 기반으로 프레임워크를 선택하십시오. 이 테이블을 사용하여 후보 목록을 좁힌 다음 아래 벤치마크 데이터로 검증하십시오.
| 프레임워크 | 아키텍처 | 최적 사용 사례 | 트레이드오프 |
|---|---|---|---|
| Mem0 | 벡터 저장소 + 그래프 메모리, 플러그형 백엔드 | 다중 테넌트 시스템, 광범위한 통합 | 다중 에이전트에 특화되지 않음 |
| Zep/Graphiti | 시간적 지식 그래프, 이중 시간 모델 | 관계 모델링 + 시간적 추론이 필요한 엔터프라이즈 | 고급 기능 클라우드 종속 |
| Letta | 계층형 저장소(인컨텍스트/코어/아카이브)를 사용한 자체 편집 메모리 | 전체 에이전트 내성, 상태 저장 서비스 | 단순 사용 사례에 복잡함 |
| Cognee | 사용자 정의 가능한 ECL 파이프라인 및 작업을 통한 다중 계층 시맨틱 그래프 | 진화하고 학습하는 에이전트 메모리; 다중 홉 추론 | 수집 시간 처리 부담 증가 |
| LangMem | LangGraph 워크플로우를 위한 메모리 도구 | 이미 LangGraph를 사용하는 팀 | LangGraph에 밀접하게 결합됨 |
| 파일 시스템 | 명명 규칙이 있는 일반 파일 | 단순 에이전트, 프로토타이핑 | 시맨틱 검색 불가, 관계 없음 |
에이전트가 이중 시간 모델링(이벤트 발생 시간과 수집 시간 모두 추적)이 필요한 경우 Zep/Graphiti를 선택하십시오. 3계층 지식 그래프(에피소드, 시맨틱 엔터티, 커뮤니티 하위 그래프)가 시간적 쿼리에 탁월하기 때문입니다. 관리형 인프라로 빠른 프로덕션 시간이 우선순위인 경우 Mem0을 선택하십시오. 에이전트가 에이전트 개발 환경을 통해 심층적인 자기 내성이 필요한 경우 Letta를 선택하십시오. 에이전트가 조밀한 다중 계층 시맨틱 그래프를 구축해야 하는 경우 Cognee를 선택하십시오. 텍스트 청크와 엔터티 유형을 세부 관계 엣지가 있는 노드로 계층화하며 모든 핵심 부분(수집, 엔터티 추출, 후처리, 검색)을 사용자 정의할 수 있습니다.
벤치마크 성능 비교
이러한 벤치마크를 참조하여 기대치를 설정하되, 절대적인 순위보다는 검색 차원에 대한 소스별 신호로 취급하십시오. 어떤 단일 벤치마크도 결정적이지 않습니다.
| 시스템 | DMR 정확도 | LoCoMo | HotPotQA(다중 홉) | 지연 시간 |
|---|---|---|---|---|
| Cognee | — | — | 게시된 높은 점수 | 가변적 |
| Zep (시간적 KG) | 게시된 높은 점수 | — | 지표 전반 중간 범위 | 낮은 지연 시간 보고됨 |
| Letta (파일 시스템) | — | 게시된 파일 시스템 기준 | — | — |
| Mem0 | — | 게시된 특수 도구 기준 | 한 비교에서 낮음 | — |
| MemGPT | 게시된 높은 점수 | — | — | 가변적 |
| GraphRAG | 게시된 중간/높은 범위 | — | — | 가변적 |
| 벡터 RAG 기준 | 게시된 낮은 범위 | — | — | 빠름 |
핵심 요점: 메모리 시스템을 브랜드가 아닌 검색 형태로 비교하십시오. 벤치마크 수치는 제품 주장을 하기 전에 재확인해야 하는 날짜가 있는 증거로 사용하십시오. 안정적인 설계 규칙은 얕게 시작하고, 검색 품질을 측정한 다음, 더 간단한 계층이 실패할 때만 시맨틱 또는 그래프 구조를 추가하는 것입니다.
메모리 계층(결정 포인트)
지속성 요구 사항을 충족하는 가장 얕은 메모리 계층을 선택하십시오. 각각의 더 깊은 계층은 인프라 비용과 운영 복잡성을 추가하므로, 더 얕은 계층이 검색 또는 내구성 요구를 충족할 수 없는 경우에만 계층을 높이십시오.
| 계층 | 지속성 | 구현 | 사용 시기 |
|---|---|---|---|
| 작업 | 컨텍스트 창만 | 시스템 프롬프트의 스크래치패드 | 항상 — 주의 선호 위치로 최적화 |
| 단기 | 세션 범위 | 파일 시스템, 인메모리 캐시 | 중간 도구 결과, 대화 상태 |
| 장기 | 세션 간 | 키-값 저장소 → 그래프 DB | 사용자 선호도, 도메인 지식, 엔터티 레지스트리 |
| 엔터티 | 세션 간 | 엔터티 레지스트리 + 속성 | ID 유지("John Doe" = 대화 전반 동일 인물) |
| 시간적 KG | 세션 간 + 기록 | 유효성 간격이 있는 그래프 | 시간에 따라 변하는 사실, 시간 이동 쿼리, 컨텍스트 충돌 방지 |
검색 전략
검색 전략을 쿼리 형태에 맞추십시오. 시맨틱 검색은 직접적인 사실 조회에 잘 작동하지만 다중 홉 추론에서는 성능이 저하됩니다. 엔터티 기반 탐색은 "X에 대한 모든 것" 쿼리를 처리하지만 그래프 구조가 필요합니다. 시간적 필터링은 변화하는 사실을 처리하지만 유효성 메타데이터가 필요합니다. 정확도가 가장 중요하고 인프라 예산이 허용될 때 전략을 결합하여 하이브리드 검색을 만드십시오.
| 전략 | 사용 시기 | 제한 사항 |
|---|---|---|
| 시맨틱(임베딩 유사도) | 직접적인 사실 쿼리 | 다중 홉 추론에서 성능 저하 |
| 엔터티 기반(그래프 탐색) | "X에 대한 모든 것을 알려줘" | 그래프 구조 필요 |
| 시간적(유효성 필터) | 시간에 따라 변하는 사실 | 유효성 메타데이터 필요 |
| 하이브리드(시맨틱 + 키워드 + 그래프) | 최고의 전체 정확도 | 가장 많은 인프라 |
하이브리드 접근 방식은 관련 하위 그래프 또는 메모리만 검색하여 활성 컨텍스트를 줄입니다. Cognee는 그래프, 벡터 및 관계형 저장소에서 여러 검색 모드를 통해 하이브리드 검색을 구현하여 에이전트가 일률적인 접근 방식 대신 쿼리 유형에 맞는 검색 전략을 선택할 수 있도록 합니다.
메모리 통합
무한한 메모리 축적은 시간이 지남에 따라 검색 품질을 저하시키므로 주기적으로 통합을 실행하여 무한한 성장을 방지하십시오. 무효화하되 폐기하지 마십시오 — 과거 상태를 재구성해야 하는 시간적 쿼리를 위해 기록을 보존하는 것이 중요합니다. 메모리 개수 임계값, 검색 품질 저하 또는 예약된 간격에 따라 통합을 트리거하십시오. 작동하는 통합 코드는 구현 참조를 참조하십시오.
실용적인 지침
메모리 아키텍처 선택
가장 간단한 실행 가능 계층으로 시작하고 검색 품질이 저하될 때만 복잡성을 추가하십시오. 대부분의 에이전트는 첫날부터 시간적 지식 그래프가 필요하지 않습니다. 다음 에스컬레이션 경로를 따르십시오:
- 프로토타입: 파일 시스템 메모리를 사용합니다. 사실을 타임스탬프가 있는 구조화된 JSON으로 저장합니다. 이를 통해 인프라에 투자하기 전에 에이전트 동작을 검증할 수 있습니다.
- 확장: 에이전트가 시맨틱 검색과 다중 테넌트 격리가 필요할 때 Mem0 또는 메타데이터가 있는 벡터 저장소로 이동합니다. 파일 기반 조회는 유사성 쿼리를 처리할 수 없기 때문입니다.
- 복잡한 추론: 에이전트가 관계 탐색, 시간적 유효성 또는 세션 간 합성이 필요할 때 Zep/Graphiti를 추가합니다. Graphiti는 일반 관계와 구조화된 연결을 사용하여 그래프를 단순하고 추론하기 쉽게 유지합니다. Cognee는 세부 관계 엣지가 있는 더 조밀한 다중 계층 시맨틱 그래프를 구축합니다. 에이전트에 시간적 이중 모델링(Graphiti)이 필요한지 더 풍부한 상호 연결된 지식 구조(Cognee)가 필요한지에 따라 선택하십시오.
- 전체 제어: 에이전트가 심층 내성을 통해 자체 메모리를 자체 관리해야 할 때 Letta 또는 Cognee를 사용합니다. 이러한 프레임워크는 메모리 작업을 일급 에이전트 작업으로 노출하기 때문입니다.
컨텍스트와의 통합
모든 것을 미리 로드하지 말고 적시에 메모리를 로드하십시오. 큰 컨텍스트 페이로드는 비용이 많이 들고 주의 품질을 저하시키기 때문입니다. 검색된 메모리를 컨텍스트의 주의 선호 위치(시작 또는 끝)에 배치하여 생성에 미치는 영향을 최대화하십시오.
오류 복구
메모리 시스템은 본질적으로 노이즈가 있으므로 검색 실패를 정상적으로 처리하십시오. 다음 복구 전략을 순서대로 적용하십시오:
- 빈 검색: 더 넓은 검색으로 대체(엔터티 필터 제거, 시간 범위 확장). 그래도 비어 있으면 사용자에게 설명을 요청합니다.
- 오래된 결과:
valid_until타임스탬프를 확인합니다. 대부분의 결과가 만료된 경우 재시도 전에 통합을 트리거합니다. - 충돌하는 사실: 가장 최근
valid_from이 있는 사실을 선호합니다. 신뢰도가 낮으면 충돌을 사용자에게 표시합니다. - 저장소 오류: 재시도를 위해 쓰기를 대기열에 넣습니다. 메모리 쓰기로 인해 에이전트의 응답을 차단하지 마십시오.
예제
예제 1: Mem0 통합
from mem0 import Memory
m = Memory()
m.add("사용자는 다크 모드와 Python 3.12를 선호합니다", user_id="alice")
m.add("사용자가 라이트 모드로 전환했습니다", user_id="alice")
# 현재 선호도(라이트 모드)를 검색하고 오래된 것은 검색하지 않음
results = m.search("사용자는 어떤 테마를 선호합니까?", user_id="alice")
예제 2: 시간적 쿼리
# 유효성 기간으로 엔터티 추적
graph.create_temporal_relationship(
source_id=user_node,
rel_type="LIVES_AT",
target_id=address_node,
valid_from=datetime(2024, 1, 15),
valid_until=datetime(2024, 9, 1), # 이사 감
)
# 쿼리: 사용자는 2024년 3월 1일에 어디에 살았습니까?
results = graph.query_at_time(
{"type": "LIVES_AT", "source_label": "User"},
query_time=datetime(2024, 3, 1)
)
예제 3: Cognee 메모리 수집 및 검색
import cognee
from cognee.modules.search.types import SearchType
# 수집 및 지식 그래프 구축
await cognee.add("./docs/")
await cognee.add("모든 데이터")
await cognee.cognify()
# 메모리 강화
await cognee.memify()
# 에이전트가 관계를 인식하는 컨텍스트 검색
results = await cognee.search(
query_text="메모리에 대한 모든 쿼리",
query_type=SearchType.GRAPH_COMPLETION,
)
지침
- 파일 시스템 메모리로 시작하고 검색 품질이 요구할 때만 복잡성을 추가하십시오.
- 시간이 지남에 따라 변할 수 있는 모든 사실에 대해 시간적 유효성을 추적하십시오.
- 최상의 정확도를 위해 하이브리드 검색(시맨틱 + 키워드 + 그래프)을 사용하십시오.
- 메모리를 주기적으로 통합하십시오. 무효화하되 폐기하지 마십시오.
- 검색 실패에 대비하십시오. 메모리 조회가 아무것도 반환하지 않을 때 항상 대체 계획이 있어야 합니다.
- 지속적인 메모리의 개인정보 영향을 고려하십시오(보존 정책, 삭제 권리).
- 변경 전후에 LoCoMo 또는 LongMemEval에 대해 메모리 시스템을 벤치마킹하십시오.
- 프로덕션에서 메모리 증가 및 검색 지연 시간을 모니터링하십시오.
주의 사항
- 모든 것을 컨텍스트에 집어넣기: 사용 가능한 모든 메모리를 프롬프트에 로드하는 것은 비용이 많이 들고 주의 품질을 저하시킵니다. 관련성 필터링과 함께 적시 검색을 사용하십시오.
- 시간적 유효성 무시: 사실은 오래됩니다. 유효성 추적이 없으면 오래된 정보가 컨텍스트를 오염시키고 에이전트가 잘못된 가정에 따라 행동합니다.
- 초기 과도한 엔지니어링: 단순한 파일 시스템 기반 메모리가 일부 벤치마크(claim-memory-locomo-filesystem-baseline)에서 더 특수한 도구보다 성능이 뛰어날 수 있습니다. 단순한 접근 방식이 명백히 실패할 때만 정교함을 추가하십시오.
- 통합 전략 부재: 무제한 메모리 증가는 시간이 지남에 따라 검색 품질을 저하시킵니다. 메모리 개수 임계값 또는 예약된 간격을 설정하여 통합을 트리거하십시오.
- 임베딩 모델 불일치: 하나의 임베딩 모델로 메모리를 쓰고 다른 모델로 읽으면 벡터 공간이 상호 교환 가능하지 않기 때문에 검색 성능이 저하됩니다. 각 메모리 저장소에 단일 임베딩 모델을 고정하고 모델이 변경되면 모든 항목을 다시 임베딩하십시오.
- 그래프 스키마 경직성: 과도하게 구조화된 그래프 스키마(고정 노드 유형, 고정 관계 레이블)는 도메인이 진화할 때 깨집니다. 새로운 엔터티 종류가 스키마 마이그레이션을 필요로 하지 않도록 일반 관계 유형과 유연한 속성 모음을 선호하십시오.
- 오래된 메모리 오염: 현재 상태와 모순되는 오래된 메모리는 에이전트 동작을 조용히 손상시킵니다. 에이전트가 오래된 사실의 우선순위를 낮추도록 만료 정책이나 신뢰도 감쇠를 구현하고, 감지 시 모순을 명시적으로 표시하십시오.
- 메모리-컨텍스트 불일치: 주제적으로 관련이 있지만 컨텍스트상 잘못된 메모리 검색(예: 에이전트가 Python 언어를 논의할 때 "Python" 뱀에 대한 메모리). 메모리 항목에 세션 또는 도메인 메타데이터를 포함하고 검색 중에 필터링하여 완화하십시오.
통합
이 스킬은 지속적인 시맨틱 메모리를 담당합니다. 인접 스킬은 스크래치 저장소, 압축 및 컨텍스트 전략을 담당합니다:
filesystem-context: 파일 기반 스크래치패드, 로그 및 단순 실행