session-indexer: Claude Code에 프로젝트가 끝나도 사라지지 않는 메모리 부여하기
요약
Claude Code 세션의 트랜스크립트를 로컬 SQLite에 인덱싱하여 프로젝트 간 연속적인 메모리를 제공하는 Go 기반 도구인 session-indexer를 소개합니다. 세션 종료 시 데이터를 마이닝하고 시작 시 관련 컨텍스트를 자동으로 주입하여 개발 흐름을 유지합니다.
핵심 포인트
- 프로젝트별 로컬 SQLite 기반의 독립적인 메모리 저장 방식 채택
- 세션 종료 시 자동 인덱싱 및 시작 시 관련 컨텍스트 자동 주입
- 중앙 집중식 저장소의 단일 장애점(SPOF) 문제 해결
- Ollama(bge-m3)를 활용한 의미론적 유사성 기반 검색 지원
일주일간의 휴가를 마치고 프로젝트로 돌아오면, 처음 10분은 항상 똑같은 방식으로 흘러갑니다. 예전 세션들을 스크롤하며 'X에 대해 우리가 실제로 무엇을 결정했었지'를 기억해내려고 애쓰는 것이죠.
"어제 우리가 무엇을 했는지"를 보여주는 단순한 롤링 로그(rolling log)는 그 문제의 절반을 해결해 줍니다. 하지만 "모든 세션에 걸쳐 이 주제에 대해 우리가 지금까지 무엇을 논의했는가?"라는 문제는 해결하지 못합니다.
session-indexer는 그 나머지 절반을 해결하기 위한 저의 시도입니다.
이것은 각 프로젝트의 Claude Code 세션 트랜스크립트(transcript)를 로컬 SQLite 데이터베이스로 인덱싱하고, 새로운 세션이 시작될 때 의미론적 유사성(semantic similarity)에 따라 관련 청크(chunk)를 검색하는 작은 Go 도구입니다.
왜 중앙 집중식 메모리 도구를 사용하지 않나요?
mempalace나 agentmemory와 같은 도구들은 모든 프로젝트와 모든 에이전트에 대해 하나의 공유 저장소를 유지합니다. 이러한 아키텍처에는 한 가지 치명적인 결함이 있습니다: **중앙 저장소가 망가지면 모든 것이 망가진다는 점입니다. **** 손상된 벡터 인덱스(vector index)나 충돌이 발생한 MCP 서버는 당신이 가진 모든 프로젝트의 메모리를 동시에 중단시키며, 복구는 결코 간단하지 않습니다.
session-indexer는 그 반대로 동작합니다. .claude/sessions.db는 프로젝트 자체의 .claude/ 디렉토리 내에 존재합니다. 추가 전용(Append-only) 방식입니다. 만약 한 프로젝트의 DB가 손상되면, 해결 방법은 그것을 삭제하고 이미 디스크에 있는 JSONL 트랜스크립트에 대해 mine을 다시 실행하는 것입니다. 다른 것에는 아무런 영향을 주지 않습니다.
작동 방식
Claude Code의 라이프사이클(lifecycle)에 연결된 두 개의 훅(hook)이 있습니다:
- Stop hook (
session-index.sh) — 세션이 종료될 때, JSONL 트랜스크립트를.claude/sessions.db로 마이닝(mine)하며,bge-m3(Ollama)를 사용할 수 있는 경우 각 청크를 임베딩(embedding)합니다. - SessionStart hook (
session-recall.sh) — 새로운 세션이 열릴 때, 현재 git 브랜치 이름과 최근 커밋 메시지로부터 검색 쿼리를 도출하고, 인덱스를 검색하여 가장 잘 일치하는 상위 청크들을 컨텍스트(context)로 주입합니다. 수동 쿼리가 필요 없습니다. 당신이 무엇을 작업하려 하는지 대략적으로 알고 있습니다.
수동 검색도 언제든 가능합니다:
session-indexer search "config validation approach" --db .claude/sessions.db
# 또는 Claude Code 내부에서:
/recall config validation approach
CLI
session-indexer mine <jsonl-path> --db .claude/sessions.db
session-indexer search <query> --db .claude/sessions.db [--limit N] [--json]
session-indexer embed --db .claude/sessions.db
...
mine 명령어는 50초의 제한 시간(deadline) 내에 실행됩니다. 저장(storage)은 빠르고 무조건적으로 이루어지며, 임베딩(embedding)은 제한 시간을 준수하므로 Claude Code의 중단 훅(Stop-hook) 타임아웃을 초과하지 않습니다. 제한 시간을 맞추지 못한 청크(chunks)는 저장되지만 embed를 통해 나중에 채워넣을 수 있도록 플래그(flag)가 지정됩니다. 즉, 아무것도 조용히 사라지지 않습니다.
검색 품질 (Search quality)
Ollama와 bge-m3를 사용할 수 있는 경우, 검색은 1024차원 다국어 임베딩 (multilingual embeddings)에 대한 코사인 유사도 (cosine similarity)를 기준으로 순위를 매깁니다. 영어와 우크라이나어 모두 높은 점수를 기록하는데, 이는 제 세션의 절반은 한 언어로, 나머지 절반은 다른 언어로 되어 있는 상황에서 매우 중요합니다.
Ollama가 실행 중이 아니거나 저장소에 임베딩이 아직 없는 경우, 검색은 자동으로 FTS5 BM25 키워드 매칭으로 폴백(fallback)됩니다. 별도의 설정이나, 실행 중이지 않을 수도 있는 외부 서비스에 대한 강한 의존성이 필요 없습니다.
스택 (Stack)
- Go 1.26 — 단일 정적 바이너리 (single static binary)
- SQLite (
modernc.org/sqlite, 순수 Go, CGO 미사용) — 프로젝트당 파일 하나 - Ollama + bge-m3 — 선택 사항인 벡터 임베딩 (vector embeddings)
- Cobra — CLI
- FTS5 — 자동 폴백 (automatic fallback)
설정 (Setup)
go install ./cmd/session-indexer
# 훅 연결 (프로젝트당 1회 수행)
...
전체적인 훅 연결 단계는 README에 설명되어 있습니다. settings.local.json에 몇 가지 JSON 항목을 추가하는 것뿐이며, 특별히 복잡한 과정은 아닙니다.
이것이 나에게 중요한 이유
대부분의 AI 코딩 어시스턴트는 세션이 종료되는 즉시 모든 것을 잊어버리거나, 전체 워크플로우의 단일 장애점 (single point of failure)이 될 수 있는 중앙 집중식 메모리 서비스를 덧붙입니다. 저는 지루하지만 확실한 옵션을 원했습니다. 바로 프로젝트별로 관리되는 추가 전용 (append-only) SQLite입니다. Git 자체를 신뢰할 수 있게 만드는 것과 동일한 아키텍처적 본능입니다. 즉, 문제가 발생하더라도 해당 프로젝트에만 국한되며, 이미 디스크에 있는 트랜스크립트 (transcripts)를 다시 마이닝 (re-mining)함으로써 복구할 수 있습니다.
오픈 소스이며, MIT 라이선스를 따릅니다.
GitHub: https://github.com/valpere/session-indexer
만약 여러분이 이미 프로젝트당 몇 주 분량의 Claude Code 세션을 쌓아두고 있으며, 다시 돌아올 때마다 매번 동일한 결정을 처음부터 다시 도출하고 있다면, 이 도구가 스크롤을 올리며 허비하는 10분의 시간을 아껴줄 수 있을 것입니다.
Valentyn Solomko — 우크라이나 소프트웨어 엔지니어
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기