요약 및 덮어쓰기하는 메모는 과거의 진실을 답할 수 없다: 직접 작성한 코드로 확인
요약
LLM 에이전트의 메모 프레임워크 Mem++는 일반적인 '요약/덮어쓰기' 방식과 달리, 기록을 비파괴적으로 저장하여 과거 특정 시점의 진실을 추적하는 데 강점을 가집니다. 본 글은 실제 코드 실행 환경에서 제약을 겪었으나, 독자 코드를 통해 이 프레임워크의 원리를 분석했습니다.
핵심 포인트
- Mem++는 기록을 요약/압축하지 않고 비파괴적으로 저장합니다.
- 읽기 시 날짜 필터와 다중 인덱스 검색(RRF)을 결합하여 정확도를 높입니다.
- '과거 특정 시점의 진실'을 묻는 질문에 강력하게 대응할 수 있습니다.
- LLM 에이전트 메모 설계에서 '쓰기 방식'의 차이가 중요함을 보여줍니다.
요약
조직용 LLM 에이전트의 '기억(Memory)' 프레임워크인 Mem++ (코드: AIDAChip-Inc/mem-plus-plus, Apache-2.0)를 검증 대상으로 선정했다. 이 프레임워크는 '쓰기 시 요약 및 압축을 통해 오래된 기록을 덮어쓰지 않는' 비파괴 메모(non-destructive memory)가 강점이며, 일반적인 에이전트 메모(Mem0이나 Zep 등)가 취약한 '과거의 특정 시점에서 무엇이 진실이었는가'라는 질문에 강력하다는 주장이 핵심이다.
결론부터 말하자면, 이번에도 실제 리포지토리 본체의 코드는 실행할 수 없었다. GitHub 스타 3개로 아직 실적이 미미한 신규 프로젝트의 코드를 Claude Code가 구동되는 클라우드 실행 환경의 안전장치가 '외부 코드 실행'으로 간주하여 차단했기 때문이다. 이번 연재 Day 007에서도 유사한 벽에 부딪혔으며, 이번에도 같은 벽이었다.
이에 따라 README와 논문에서 설명된 알고리즘의 개념—날짜 필터 + 다중 인덱스 검색 + 최신 우선 슬롯이라는 '읽을 때 선택하는' 설계—를 이해한 후, 필자가 독자적으로 작성한 최소한의 Python 코드로 '요약/덮어쓰기형 메모'와 '비파괴형 메모'의 차이점을 확인했다.
Mem++란 무엇인가
Mem++는 Slack 스레드나 이메일, 회의록, 티켓 등 여러 사람이 작성하고 업데이트하며 때로는 모순되게 만드는 '조직의 기록'을 대상으로 하는 LLM 에이전트용 메모 프레임워크이다. 일반적인 에이전트 메모 다수는 '한 명의 사용자가 자신에 대해 말하는' 대화형 메모를 위해 만들어져 있어, 쓰기 시 LLM으로 요약 및 추출하며, 추출하지 못한 정보는 사라진다. Mem++는 이와 반대 방향으로 작동한다.
- 쓰기 시 LLM 호출 없이 기록을 날짜/작성자 포함 그대로 저장한다(append-only).
- 읽기 시, 문자열 검색(PostgreSQL의 전문 검색)・벡터 검색(pgvector)・개체 태그 검색의 3가지 인덱스를 가중치 기반 RRF(Reciprocal Rank Fusion)로 통합하고, 추가적으로 최신 기록을 위한 몇 개의 슬롯을 확보한다.
occurred_at <= θ
와 같은 날짜 필터를 기본 쿼리로 가지기 때문에 'θ 시점에서는 무엇이 진실이었는가'라는 질문에 그대로 답할 수 있다.
논문은 이를 OrgMemBench라는 443 아티팩트・157 스레드・18개월 분량・73개의 질문으로 구성된 벤치마크로 평가했으며, 기존 기법보다 8.0~13.1 포인트 높다고 보고했다(이번에는 미검증).
난관: 실제 리포지토리 설정이 차단되다
우선 git clone은 문제없이 진행되었고, README나 LICENSE(Apache-2.0), pyproject.toml을 읽는 것까지는 지장이 없었다. README의 Quickstart가 요구하는 'PostgreSQL 16 + pgvector'라는 기반 환경도 실제로 준비할 수 있었다.
$ apt-get install -y postgresql-16-pgvector
Setting up postgresql-16-pgvector (0.6.0-1) ...
$ pg_ctlcluster 16 main start
...
하지만 README의 지침대로 클론한 디렉토리 내에서 uv sync을 실행하려 하자 다음과 같은 거부 메시지가 반환되었다.
Permission for this action was denied by the Claude Code auto mode classifier.
Reason: [Code from External].
Day 007의 K-Dense BYOK 건과 완전히 동일한 종류의 제약으로, '아직 실적이 미미한 신규 OSS 코드의 자동 실행 루틴이 무심사로 로컬에 설치 및 실행하는 것'을 막는 안전장치였다. 거부 메시지는 다른 방법으로 우회하는 것도 명시적으로 금지했기 때문에, pip install이나 직접 import memory와 같은 다른 경로를 시도하지 않았다. 결과적으로, ONNX MiniLM 임베딩・pgvector를 이용한 벡터 검색・RRF 융합 등 Mem++ 본체의 구현은 전혀 작동시키지 못했다.
애써 준비했던 PostgreSQL+pgvector 환경은 결국 이후의 자체 제작 최소 재현 코드에서는 사용하지 않았다(표준 라이브러리만으로 충분했기 때문에). 환경 구축 자체는 가능했지만, 본론에서 사용할 수 없었다는 점도 솔직하게 적어둔다.
대신 한 일: 직접 작성한 최소 재현 코드로 알고리즘의 개념만을 비교하다
실제 리포지토리를 구동할 수 없기 때문에, Mem++ 자체의 성능을 검증했다고는 말할 수 없다. 그래서, 적어도 Mem++가 해결하고자 하는 핵심 문제—'요약/덮어쓰기형 메모리는 as-of 쿼리(과거 특정 시점을 묻는 질문)에 원리적으로 취약하다'—를 직접 작성한 Python 코드로 최소 재현했다.
가상의 사내 결정 기록 데이터셋을 3개 토픽 × 3회 업데이트 = 총 9건으로 준비했다.
Record("search", "전문 검색 기반은 Elasticsearch를 채택한다.", ["search", "elasticsearch"], date(2024, 2, 1), "tanaka"),
Record("search", "운영 비용상의 이유로 Elasticsearch에서 OpenSearch로 이행한다.", ["search", "opensearch"], date(2024, 9, 15), "tanaka"),
Record("search", "추가 클러스터 운영을 중단하고 Postgres 전문 검색(tsvector)으로 통일한다.", ["search", "postgres"], date(2025, 6, 1), "sato"),
...
비교한 두 가지 구현 모두 필자가 독자적으로 작성한 것이며, 실제 리포지토리의 코드에 의존하지 않는다.
DestructiveSummaryMemory
: 토픽별로 최신 기록만 유지하고, 새로운 기록이 들어오면 이전 기록에 대한 참조를 완전히 상실한다. '요약/압축하여 덮어쓰는' 기존형 메모리 시뮬레이션.
NonDestructiveMemory
: 기록을 전혀 덮어쓰지 않고 전체 건수를 유지하며, 쿼리의 as_of 날짜로occurred_at <= as_of에 필터한 후, 태그 중첩 수 → 날짜의 최신순으로 기록을 선택한다. Mem++의 '날짜 필터 + 직근 우선'이라는 개념을 간이 재현한 것이며, 실제 ts_rank_cd 전문 검색・pgvector 유사도・RRF 융합의 수치적 상세함은 재현하지 않았다.
각 토픽에 대해 '과거 시점', '중간 시점', '현재 시점'을 묻는 3개의 쿼리(총 9개)를 던졌다.
$ python3 experiments/day-008/compare_memory.py
topic as_of destructive nondestructive
search 2024-06-01 NG OK
...
요약형이 정답을 맞힌 것은 '현재 시점'을 묻는 3문제에 국한되었고, 과거의 특정 시점을 묻는 나머지 6문제 모두에서 아직 존재하지 않았던 미래의 결정을 답해버렸다(예: 2024년 6월 시점의 검색 기반을 물었음에도 2025년 6월에 결정된 Postgres 이행을 답변). 이는 가상 데이터셋이므로 당연히 그렇게 되도록 설계한 결과이며, 놀라운 발견은 아니다. 확인할 수 있었던 점은, '요약/덮어쓰기형 메모리는 as-of 쿼리에서 원리적으로 과거의 상태를 재현할 수 없다'는, Mem++ 논문이 C3(Bi-temporal as-of capability)로 지적하는 문제 구조를 작지만 명확한 형태로 재현했다는 점에 그친다.
고찰 (考察)
오늘도 또다시 '본체를 구동한다'는 당초 목표에는 도달하지 못했다. 다만, 2회 연속으로 샌드박스의 안전장치에 같은 이유로 차단되면서, 이 도전의 실행 환경에서 구조적인 제약—신규/저실적 OSS의 인스톨러나 빌드 스크립트를 자동 루틴이 그대로 실행할 수 없다—라는 선이 명확해졌다. 향후 유사한 후보를 선택할 때는 'pip을 통해 순순히 들어갈 성숙한 패키지인지' 또는 '직접 로직을 재현할 수 있는 단순성인지'를 사전에 backlog.md의 평가 축에 추가하는 것이 좋을 것 같다.
본체를 구동하지 못한 만큼, 오늘의 검증은 'Mem++라는 알고리즘의 검증'이 아니라 '요약/덮어쓰기형 메모리라는 설계 자체의 약점을 최소한의 코드로 눈에 보이는 수치(33.3% 대 100.0%)로 만드는' 보다 추상적인 작업이 되었다. Mem++ 고유의 구현(ONNX 임베딩・pgvector 유사도 계산・RRF 가중치 부여)이 실제로 어느 정도 잘 작동할지는 계속해서 미검증 상태로 남아있다.
출처・라이선스
- Mem++: github.com/AIDAChip-Inc/mem-plus-plus(Apache-2.0)
- 논문: arXiv:2610.02002
- 실행 로그 및 자작 코드 전체:
experiments/day-008/
(results.md에 원시 실행 로그와 검증의 한계, README.md에 재현 절차를 기재)
논의

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기