AI 코딩 도구들이 모든 것을 잊어버리지 않도록 작은 CLI를 만들었습니다
요약
여러 AI 코딩 도구(Claude Code, Codex, Gemini CLI 등) 간의 컨텍스트 파편화 문제를 해결하기 위해 개발된 CLI 도구 'Mythicator'를 소개합니다. 이 도구는 단일 메모리 파일을 유지하고 이를 각 도구의 컨텍스트 파일로 동기화하여 도구 간 결정 사항을 공유합니다.
핵심 포인트
- AI 코딩 도구 간 컨텍스트 공유 부재로 인한 반복 설명 문제 해결
- Mythicator CLI를 통해 결정 사항을 CLAUDE.md, .cursorrules 등에 자동 동기화
- 복잡한 벡터 검색 대신 단순한 JSON 파일과 플랫 파일 방식 채택
- 기존 수동 편집 내용을 보호하는 안전한 동기화 로직 구현
저는 그날의 상황과 작업에 따라 Claude Code, Codex, 그리고 Gemini CLI 사이를 전환하며 사용합니다. 각각의 도구는 진정으로 훌륭합니다. 하지만 각각의 도구는 다른 도구가 무엇을 알고 있는지 전혀 모릅니다.
저는 Claude Code에게 "우리는 동시 쓰기 (concurrent writes)가 필요하기 때문에 여기서 Postgres를 사용하고 있으니, 다시는 SQLite를 제안하지 마세요"라고 결정을 설명하곤 했습니다. 그러면 Claude Code는 CLAUDE.md를 읽기 때문에 이를 기억합니다. 그러다 같은 저장소(repo)에서 Codex로 전환하면, Codex는 또다시 SQLite를 제안합니다. 제가 Claude Code에게 말한 그 어떤 내용도 Codex가 읽고 있는 컨텍스트 (context)에 전달되지 않았기 때문입니다.
"X를 시도해 봤지만 작동하지 않았으니 다시는 제안하지 마세요"와 같은 대화가 반복될 때마다, 매주 세 가지의 서로 다른 도구에게 똑같은 세 가지 내용을 반복해서 설명해야 하는 상황이 발생합니다. 이는 금방 지치는 일이 되었습니다.
제가 실제로 만든 것
Mythicator는 mythicator라고 불리는 CLI입니다. 이 도구는 단 한 가지 일만 수행합니다. 저장소당 하나의 메모리 파일 (memory file)을 유지하고, 각 AI 도구가 이미 읽고 있는 컨텍스트 파일 (context file)로 그 내용을 밀어 넣는 것입니다.
mythicator init
mythicator add "SQLite 대신 Postgres를 선택함" --type decision --reason "여러 워커 (workers)로부터의 동시 쓰기가 필요함"
mythicator sync
그 sync 명령은 동일한 메모리를 CLAUDE.md, AGENTS.md, GEMINI.md, 그리고 .cursorrules에 기록합니다. 이때 마커 블록 (marker block)으로 감싸져 있어, 제가 해당 파일들에 직접 작성한 내용에는 전혀 영향을 주지 않습니다. 메모리를 한 번만 업데이트하면 모든 도구가 이를 공유하게 됩니다.
표준 데이터 (canonical data)는 저장소에 커밋되는 .agent-memory/memory.json에 저장됩니다. 거창한 것은 없습니다. 결정 사항, 거부된 접근 방식, 버그, 컨벤션 (conventions), 노트 등이 포함되며, 각각 선택적인 이유와 태그를 가질 수 있습니다. 벡터 검색 (vector search), 임베딩 (embeddings), 호스팅 서비스 (hosted service)도 없습니다. 그저 JSON 파일 하나와 동기화 (sync) 단계가 있을 뿐입니다.
왜 기존의 메모리 프레임워크를 사용하지 않았는가
이미 "AI를 위한 메모리"를 수행하는 견고한 도구들인 Mem0, Zep 같은 것들이 있습니다. 이것을 만들기 전에 저도 그것들을 살펴보았습니다. 하지만 그것들은 방대한 사실 더미 위에서 유사도 검색 (similarity search)을 수행하며, 런타임 (runtime)에 장기 기억 (long-term memory)이 필요한 에이전트 (agents)를 구축하는 개발자들을 대상으로 합니다. 그것은 제가 가진 문제와는 다른 문제입니다.
저에게는 시맨틱 검색 (semantic search)이 필요하지 않았습니다. 제가 필요했던 것은 "내가 개인적으로 전환하며 사용하는 네 가지 도구가 이 하나의 리포지토리 (repo)에 대해 동일한 다섯 가지 결정 사항에 대해 모두 동의하는 것"이었습니다. 훨씬 더 작은 문제였고, 훨씬 더 단순한 해결책 — 플랫 파일 (flat file)과 동기화 (sync) 명령어를 사용하는 것이었습니다.
실제로 가장 많은 주의를 기울였던 부분
가장 까다로운 부분은 메모리 저장소가 아니었습니다. 그것은 ID 카운터가 포함된 JSON 파일일 뿐이니까요. 진짜 까다로웠던 것은 제가 수동으로 편집한 파일들을 손상시키지 않는 동기화 (sync) 로직이었습니다.
만약 sync가 매번 AGENTS.md를 통째로 덮어쓴다면, 제가 그곳에 수동으로 작성한 모든 내용을 날려버릴 것입니다. 그래서 생성된 블록은 마커 (markers) 사이에 위치합니다:
<!-- AGENT-MEMORY:START (auto-generated by mythicator, do not edit) -->
...
<!-- AGENT-MEMORY:END -->
동기화는 오직 저 두 줄 사이에 있는 내용만 건드립니다. 열 번을 실행해도 똑같은 결과가 열 번 나옵니다. 만약 어떤 파일에 START 마커는 있는데 END 마커가 없는 경우 (절반만 손상된 경우), 시스템은 추측하여 잠재적으로 파일을 망가뜨리는 대신 해당 파일을 건너뛰고 경고를 보냅니다.
작은 디테일이지만, 이것이 사람들이 자동으로 실행할 만큼 신뢰하는 도구와, 한 번 실행했다가 피해를 입고 삭제해 버리는 도구 사이의 차이를 만듭니다.
실제로 이것을 어떻게 만들었나
이 모든 것을 직접 타이핑했다고 거짓말하지는 않겠습니다. 저는 상당히 상세한 명세 (spec)를 바탕으로 구현 코드를 작성하기 위해 Codex를 사용했고, 그 후 storage.ts와 sync.ts를 직접 한 줄씩 검토했습니다. 특히 제가 이전에 AI 생성 코드(AI-generated code)로 인해 피해를 보았던 두 가지 사항을 중점적으로 확인했습니다: 항목 삭제 후 발생하는 ID 충돌 (id collisions), 그리고 마커 교체 로직이 취약한 정규 표현식 (regex)인지 아니면 실제로 재실행 시에도 견딜 수 있는 구조인지였습니다. 첫 번째 패스 (pass)에서는 실제 버그가 있었습니다 (배열 길이에 기반한 ID 설정이었는데, 이는 무언가를 삭제하고 다시 추가하는 순간 깨지게 됩니다). 이를 발견하여 영구적인 카운터 (persistent counter)를 사용하는 방식으로 수정했고, 신뢰하기 전에 직접 검증을 마쳤습니다.
또한 분명히 말해둘 점이 있습니다. Codex가 테스트를 수행한 샌드박스(sandbox)는 실제 npm 레지스트리(registry)에 접근할 수 없었기 때문에, 자체적인 "테스트 통과" 주장은 의존성 심(dependency shim)을 기반으로 한 것이었습니다. 저는 그것을 액면 그대로 받아들이지 않았습니다. 제 Ubuntu 노트북으로 클론(clone)하여 실제로 npm install을 실행했고, 새로운 빌드(build)를 통해 init → add → sync → list → remove → sync-again 흐름 전체를 직접 검증한 후에야 작동하는 것으로 간주했습니다.
현재 상태
이것은 작동하는 작은 v1 버전입니다. Node.js, TypeScript, 하나의 런타임 의존성(commander)으로 구성되어 있으며, MIT 라이선스를 따릅니다. 만약 동일한 코드베이스에서 여러 AI 코딩 도구들을 번갈아 사용하며 매번 같은 말을 반복하는 것에 지쳤다면, 이 도구가 여러분의 수고를 덜어줄 수 있을 것입니다.
Repo: github.com/Jeffrin-dev/Mythicator
다음 세대의 Mem0를 만들려는 것이 아닙니다. 그저 매주 Codex에게 SQLite에 대해 다시 설명하는 일을 멈추고 싶을 뿐입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기