Claude Code의 기억력 문제에 지쳐서, 절대 휘발되지 않는 AST 기반 메모리 레이어를 직접 만들었습니다
I got tired of Claude Code's amnesia. So I built an always-fresh, AST-powered memory layer that never gets stale
핵심 요약
Claude Code의 잦은 기억 상실 문제를 해결하기 위해 AST를 활용한 실시간 메모리 레이어 'Memtrace'를 개발했습니다.
- 기억력 문제 해결 — Claude Code의 세션 간 문맥 손실을 방지하기 위해 AST 기반의 구조적 메모리 레이어를 구현함.
- 효율적 인덱싱 — LLM 대신 Tree-sitter를 사용하여 토큰 비용 없이 파일 저장 시마다 실시간으로 구조를 스냅샷함.
- 시점 복구 기능 — bi-temporal 그래프를 통해 특정 시점의 코드 상태를 정확히 추적하여 회귀 버그 디버깅을 지원함.
- 점진적 온보딩 — 사용자 피드백을 반영한 안정적인 버그 수정을 위해 현재 50명 단위로 제한적인 베타 테스트를 진행 중임.
이것은 제가 결국 직접 만들게 된 Claude Code 세션입니다.
코딩을 하면서 RRF 검색 가중치를 튜닝하는 데 3번의 세션을 보냈고, 0.5 BM25 / 0.3 벡터 / 0.2 그래프 가중치로 결정하고 테스트를 작성한 뒤 넘어갔습니다. 일요일 아침, 새로운 세션을 열고 Claude Code에게 기능을 추가해달라고 요청했습니다. 12번의 턴 안에 Claude Code는 이전 결정은 전혀 없었던 것처럼 자신 있게 다른 가중치 체계를 제안하더군요.
그 순간이었습니다. 저는 Claude Code를 사용하여 Claude Code를 위한 메모리 레이어를 만들고 있었는데, 바로 그 문제를 해결하려던 코드베이스 안에서 실시간으로 똑같은 문제가 발생하고 있었던 거죠.
이것은 무엇인가
Memtrace는 MCP 서버로 제공되는 AST 기반 메모리 레이어입니다. 벤치마크 하네스는 오픈 소스입니다. Claude Code, Cursor, Codex 및 기타 MCP 지원 클라이언트에 자동으로 등록됩니다.
제가 시도해본 다른 어떤 것보다 깔끔하게 처리하는 두 가지 기능이 있습니다:
항상 최신 상태인 구조적 메모리. 모든 파일 저장 시마다 수십 밀리초 내에 증분 스냅샷을 트리거합니다. 리팩토링 전에 에이전트는 코드 한 줄을 작성하기 전에 호출 그래프에서 영향 범위(호출자, 테스트, 소비자)를 쿼리합니다.
되감기(Rewind). 그래프는 이중 시간(bi-temporal) 구조입니다. 모든 노드와 엣지는 valid_at과 invalid_at 타임스탬프를 가집니다. "getUserById가 망가진 커밋 이전 월요일에는 어떤 모습이었나"라는 질문은 git-blame 휴리스틱이 아닌 실제 쿼리가 됩니다. 에이전트가 회귀 버그를 디버깅할 때, 현재 상태에서 추측하는 대신 함수가 어떻게 현재 형태로 변해왔는지 재생합니다.
아키텍처적 내기
대부분의 메모리 도구(Mem0, Graphiti)는 인덱싱 중에 LLM을 호출합니다. 그들은 LLM이 청크에서 구조를 "추출"하기를 원합니다. 제가 비교 실행했을 때 1,500개 파일에 31분이 걸렸고, 토큰당 API 비용이 발생하며, 매 편집마다 재인덱싱할 여유가 없습니다. 그래서 메모리는 항상 한 세션 뒤처져 있습니다.
저는 LLM을 인덱싱 경로에서 완전히 제거했습니다. Tree-sitter는 20개 이상의 언어를 AST로 파싱합니다. AST 자체가 구조적 표현입니다. 컴파일러가 이미 알고 있는 것을 다시 도출하기 위해 LLM에 비용을 지불할 필요가 없습니다.
검색은 쿼리 시점에 하이브리드 방식으로 이루어집니다: Tantivy BM25(어휘)와 HNSW를 통한 Jina-code 768차원 임베딩(의미론)을 k=60의 RRF로 융합합니다. Jina-code가 여기서 중요한 이유는 일반적인 산문이 아닌 코드에 대해 학습되었기 때문입니다. 의미론적 단계에서 "auth"라는 단어를 패턴 매칭하는 대신 "이것은 인증 핸들러다"라는 것을 실제로 이해합니다.
이 내기는 한 곳에서 성과를 거둡니다: 토큰당 비용이 없기 때문에 모든 편집을 스냅샷으로 남길 수 있습니다. 인덱싱은 OpenAI가 아닌 디스크 I/O에 의해 병목 현상이 발생합니다. 이것이 항상 최신 상태인 메모리를 실제로 작동하게 만드는 요소입니다. "되감기" 기능은 최신 상태를 유지하는 이중 시간 그래프를 가짐으로써 자연스럽게 따라오는 결과일 뿐입니다.


