포스트

Mem0를 장기 기억 계층으로 써도 될까: ADD, UPDATE, DELETE와 격리 조건

Mem0는 대화 전체를 매번 넣는 대신 장기적으로 남길 사실을 추출, 갱신하고 필요한 기억만 검색하는 계층입니다. token과 지연을 줄일 가능성은 있지만 LLM이 잘못된 사실을 저장하거나 다른 사용자의 기억을 섞을 수 있으므로, 일반 대화 기록보다 더 엄격한 provenance, 격리, 정정과 삭제가 필요합니다. 첫 pilot은 원장 정답이 있는 비민감 선호 정보에 제한하는 편이 좋습니다.

Mem0 저장소공식 사이트는 vector, graph를 포함한 agent memory 접근을 소개합니다. 본문에 제시된 비용, p95, benchmark 수치는 평가 조건이 없는 보장값으로 쓰지 말고 연결된 자료와 자체 workload에서 재현해야 합니다. References의 arXiv URL과 논문 서지 정보가 실제로 일치하는지도 사용 전에 확인해야 합니다.

ADD, UPDATE, DELETE, NOOP는 무엇을 판단하나

기존 RAG는 정보에 ‘모순(Contradiction)’이 발생해도 이를 구별하지 못합니다. 하지만 Mem0는 정보가 들어올 때 내부적으로 LLM을 한 번 더 호출하여 기존 메모리와의 의미론적 관계를 추론합니다.

  • ADD: 완전히 새로운 팩트면 새 노드로 저장합니다.
  • UPDATE: “내 직업은 개발자야”가 “나 시니어 개발자로 승진했어”로 바뀌면 기존 메모리를 덮어씁니다.
  • DELETE: 새로운 정보가 과거의 팩트를 완벽히 부정하면 과거 데이터를 삭제합니다.
  • NOOP: 이미 아는 내용이면 아무 작업도 하지 않아 비용을 아낍니다.

이 판단을 LLM에 위임하면 표현이 다른 사실을 합칠 수 있지만 결정적 규칙은 아닙니다. “커피를 줄인다”를 “커피를 완전히 끊었다”로 update하거나 과거 여행 이야기를 현재 주소로 저장할 수 있습니다. 각 memory에 source message, event, ingestion time, model, prompt version과 confidence를 남기고 사용자가 정정할 수 있어야 합니다.

vector와 graph memory는 언제 나눠 쓰나

Mem0는 기본적으로 Vector DB, Key-Value DB, 그리고 Graph DB를 혼합한 하이브리드 데이터스토어를 씁니다. 최근 도입된 Graph 모드(Mem0g)는 사실을 단순히 텍스트로 저장하는 것을 넘어, 노드(Entity)와 엣지(Relationship)로 구조화합니다. “철수는 카카오에 다닌다”라는 문장은 [철수] -> (works_at) -> [카카오] 라는 관계망으로 엮입니다.

비교 항목기존 Full-Context단순 RAG 시스템Mem0 (Vector + Graph)
컨텍스트 토큰 소모량원문 비교값 약 26,000원문 비교값 약 3,000~5,000원문 비교값 약 1,800
p95 지연 시간원문 비교값 17.12초원문 비교값 3~5초원문 비교값 1.44초(Graph 약 2.6초)
정보 모순/충돌 해결프롬프트 후반부 정보에 편향됨해결 불가 (둘 다 검색됨)A.U.D.N으로 자동 병합/삭제
다중 세션 일관성window 밖 기록 누락 가능검색, chunk 품질에 의존별도 장기 memory 평가 필요

[코드 스니펫: Mem0 초기화 및 Scope 설정]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from mem0 import Memory

# Graph DB를 포함한 하이브리드 메모리 설정
config = {
    "vector_store": {"provider": "chroma"},
    "graph_store": {"provider": "neo4j", "config": {"url": "bolt://localhost:7687", "password": "secret"}},
    "version": "v1.1"
}

m = Memory.from_config(config)

# User Scope를 활용한 컨텍스트 주입 (A.U.D.N 자동 실행)
m.add([
    {"role": "user", "content": "나는 평소에 AWS를 주로 썼는데, 이제 GCP로 전체 인프라를 마이그레이션 중이야."}
], user_id="senior_dev_001", metadata={"domain": "infrastructure"}) 

# Graph를 통한 다중 홉(Multi-hop) 추론 검색
results = m.search(
    "이 유저에게 추천할 만한 클라우드 아키텍처 문서는?", 
    user_id="senior_dev_001"
)

코드는 user_id scope와 graph 설정의 개념을 보여 주지만 package, API version, 인증, 오류와 삭제 처리가 빠진 시점별 예시입니다. ID field가 있다는 사실만으로 격리가 완성되지는 않습니다. application이 인증된 tenant ID를 강제로 주입하고 client가 다른 ID를 임의로 넘기지 못하게 하며 vector filter, graph traversal과 cache에서도 같은 scope를 적용해야 합니다.

어떤 기억부터 제한적으로 저장할까

장기 memory의 후보는 사용자가 명시한 비민감 선호, 반복 업무의 format과 확인 가능한 계정 설정입니다. 건강, 금융 심사, 신원, 고용 상태처럼 오류 피해가 큰 정보는 대화 추출값을 원장 대신 쓰지 않아야 합니다.

보험 심사 같은 업무에서는 과거 병력, 심사 결과와 회사 정책을 memory가 아니라 권한 있는 원장, 문서에서 조회합니다. Mem0는 최근 상호작용의 탐색 pointer나 사용자가 확인한 선호를 보조적으로 제공할 수 있습니다. 비동기 write를 쓰더라도 저장 지연 동안 오래된 memory가 검색될 수 있으므로 update status와 as_of를 표시하고 중요한 답은 원장으로 재확인합니다.

트래픽이 커질 때는 full context, recent-window+summary, vector RAG와 Mem0를 같은 conversation set에서 비교합니다. 본문에 언급된 1,000~2,000 token, 26%와 1/10 같은 수치는 자체 비용 계획에 그대로 쓰지 않습니다. memory 추출 write token, embedding, graph, retry와 false memory를 사람이 수정한 비용까지 포함해 성공한 답 한 건당 비용을 계산합니다.

write, graph, data governance 비용은 무엇인가

  1. write latency와 model 호출: ADD, UPDATE 판단에 model을 사용하면 단순 insert보다 느리고 비쌉니다. 비동기 queue에는 중복 message, 순서 역전과 실패 재처리가 생깁니다. idempotent event ID와 per-user order를 유지하고 backlog가 길면 stale memory를 최신처럼 쓰지 않습니다.
  2. graph 운영: 관계 질의가 실제로 필요한지 먼저 확인합니다. Neo4j node, edge type, entity merge와 schema drift, backup, index 운영이 추가됩니다. 단순 사용자 선호 조회에는 key-value, vector만으로 충분할 수 있으며 graph를 켰다는 이유로 multi-hop 답이 정확해지지는 않습니다.
  3. data governance와 종속성: managed, self-hosted 어느 쪽이든 memory export, 사용자 열람, 정정, 삭제와 retention을 제공해야 합니다. 원본 message를 지운 뒤 vector, graph, cache, backup에 파생 memory가 남는지 추적합니다. provider를 바꿀 수 있도록 stable ID, source와 timestamp가 포함된 export, restore를 시험합니다.

충돌, 격리, 삭제를 어떻게 평가할까

golden conversation에 새 사실, 정정, 부정, 과거 회상, 농담과 모호한 날짜를 넣고 예상 ADD, UPDATE, DELETE, NOOP를 표시합니다. action 정확도뿐 아니라 최종 현재 사실, 과거 provenance와 잘못 삭제한 memory를 측정합니다. model, prompt를 바꾸면 같은 set을 replay해 행동 분포가 달라지는지 확인합니다.

tenant A와 B가 같은 이름, 질문을 사용하게 한 뒤 search, graph multi-hop, list, delete에서 교차 결과가 0인지 negative test합니다. session, agent scope 조합과 privileged support account도 포함합니다. authorization은 model instruction이 아니라 API와 storage query에서 강제해야 합니다.

사용자 삭제 요청은 원본, vector, graph edge, derived summary와 cache를 따라가며 완료 증거를 남깁니다. 삭제 중 일부 storage가 실패하면 성공 응답을 보내지 않고 재시도, 격리합니다. backup retention이 즉시 삭제와 어떻게 다른지 사용자 정책에 명확히 설명합니다.

평가표에는 현재, 과거 질문 정확도, 근거 회수, false memory, write, search p95, token, storage, backlog와 삭제 완료 시간을 둡니다. full context와 recent-window summary라는 단순 기준선을 포함해야 Mem0의 운영 복잡성이 실제 개선으로 돌아오는지 알 수 있습니다.

결론: 더 긴 context와 더 좋은 memory는 다른 문제다

context window가 길어져도 모든 과거를 매번 보내는 비용과 충돌 우선순위는 남습니다. 반대로 memory layer가 있어도 잘못 추출한 사실과 privacy 책임은 사라지지 않습니다. Mem0는 장기 사실을 별도 수명 주기로 관리할 후보이지 모든 RAG, 최근 대화나 원장 시스템의 대체물이 아닙니다.

정답이 있는 작은 domain에서 기준선보다 정확도, 비용이 반복 개선되고 격리, 정정, 삭제를 설명할 수 있을 때만 범위를 넓히십시오. 기억을 많이 저장하는 것보다 무엇을 저장하지 않고 언제 원문으로 돌아갈지를 설계하는 것이 더 중요합니다.

원문과 버전 확인

함께 읽으면 이해가 이어지는 글

자주 묻는 질문

Mem0를 붙이면 AI가 사용자 사실을 정확히 기억하나요?

보장하지 않습니다. LLM의 fact 추출, 충돌 판단과 검색이 틀릴 수 있어 원문 provenance, 정정, 삭제와 원장 확인 경로가 필요합니다.

user_id를 지정하면 tenant data가 완전히 격리되나요?

아닙니다. application auth, storage filter, cache, graph query와 backup까지 tenant key가 강제되는지 negative test로 확인해야 합니다.

긴 대화 전체 대신 Mem0만 context에 넣으면 되나요?

항상 그렇지 않습니다. 장기 선호, 사실에는 유용할 수 있지만 현재 task의 최근 대화와 원장 데이터는 별도 source로 유지해야 합니다.

THE END / OPSOAI

여기까지 읽었습니다

핵심 장면을 한 번 더 떠올려 보세요. 이해가 남았다면 이 책은 제 역할을 다했습니다.

다른 책 고르기
표지 1

키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.

CONTENTS

이 책의 목차

    10개 장 16 분읽는 시간