OptMem: 데이터베이스도 임베딩도 없이 로그와 이진 트리로 만든 AI 에이전트용 영속 메모리

OptMem 소개

코딩 에이전트에게 기억을 붙이는 방법은 대체로 한 방향으로 수렴해 왔습니다. 대화를 잘라 임베딩으로 바꾸고 벡터 데이터베이스에 넣은 뒤, 새 질문이 오면 비슷한 조각을 검색해 프롬프트에 끼워 넣는 방식입니다. 이 구조는 잘 동작하지만 붙이는 비용이 작지 않습니다. 임베딩 모델과 벡터 저장소를 고르고 운영해야 하고, 검색이 무엇을 가져왔는지가 사람 눈에 잘 보이지 않으며, 무엇이 왜 기억되었는지 확인하려면 다시 도구를 하나 더 열어야 합니다. 개인 작업 환경에 붙이기에는 무거운 편입니다.

OptMem은 그 반대 방향에서 출발한 프로젝트입니다. 임베딩도 벡터 데이터베이스도 쓰지 않고, 한 줄씩 덧붙이기만 하는 텍스트 기록과 그 위에 얹은 이진 요약 트리(binary merge tree)만으로 에이전트의 영속 기억을 만듭니다. 도구는 의존성 없는 단일 파이썬 파일이고, 에이전트 쪽에 붙는 것은 426개 토큰짜리 프롬프트 한 덩어리뿐입니다. 저자는 Victor Taelin으로, 자신을 증명 언어 Kind와 병렬 런타임(Runtime) HVM의 저자로 소개하고 있으며 Higher Order Company에 속해 있습니다.

OptMem의 기억이 시간에 따라 쌓이고 위로 갈수록 요약되는 이진 트리 구조 애니메이션

핵심 아이디어는 위 그림 한 장에 담겨 있습니다. 아래쪽 줄은 실제로 기록된 기억 하나하나이고, 위로 한 층 올라갈 때마다 인접한 두 개가 하나의 요약으로 합쳐집니다. 그래서 최근 기억은 원문 그대로 남고 오래된 기억일수록 점점 압축된 형태로만 남습니다. 요약본은 캐시일 뿐이고 원문은 LOG.txt에 덧붙이기 전용으로 그대로 남으므로, 필요하면 언제든 아래층으로 내려가 원래 문장을 꺼낼 수 있습니다.

OptMem이 기존 방식과 다른 점

벡터 검색 방식과 OptMem은 "무엇을 꺼내 올까"를 정하는 방법이 다릅니다. 벡터 검색은 질문과의 의미적 유사도로 조각을 고르므로, 관련 있어 보이는 것은 잘 찾아오지만 세션 시작 시점에 "지금까지 무슨 일이 있었는가"를 통째로 파악하기는 어렵습니다. OptMem은 반대로 세션 첫 명령인 memo wake가 트리의 위층부터 훑어 내려가며 전체 이력의 요약본을 한 번에 출력합니다. 특정 문구를 찾아야 할 때는 memo recall <regex>가 기록 전체를 정규표현식으로 문자 그대로 검색합니다.

또한 성능이 아니라 구조에서 오는 차이도 있습니다. 저장소는 기록이 고정 폭(fixed width)이라 위치 자체가 식별자가 되고 모든 조회가 한 번의 탐색(seek)으로 끝난다고 설명하며, 기억 100만 개(608MB) 기준으로 wake가 0.03초 걸린다는 수치를 함께 제시하고 있습니다. 색인을 따로 만들지 않아도 되는 이유가 여기에 있습니다.

주요 항목별로 두 방식의 차이는 다음과 같습니다:

항목 벡터 데이터베이스 방식 OptMem
저장 형태 임베딩 벡터와 원문 조각 한 줄씩 덧붙이는 텍스트 로그
필요한 구성 요소 임베딩 모델, 벡터 저장소 파이썬 3 실행 환경
회상 방식 질문과의 의미적 유사도 검색 트리 상위 요약 전체 출력, 정규표현식 검색
오래된 기억 조각 단위로 그대로 유지 요약으로 압축, 원문은 로그에 보존
사람이 읽을 수 있는가 벡터는 읽을 수 없음 로그와 요약 모두 텍스트 파일

OptMem이 맞는 사람과 맞지 않는 사람

혼자 또는 소규모로 코딩 에이전트를 오래 쓰면서 세션이 바뀔 때마다 같은 설명을 반복하는 것이 번거로웠던 사람에게 OptMem은 붙여 볼 만한 도구입니다. 설치가 한 줄이고 통합은 AGENTS.mdCLAUDE.md 상단에 프롬프트를 붙여 넣는 것으로 끝나며, 기억이 사람이 읽을 수 있는 텍스트 파일로 남아 무엇이 기억되었는지 직접 확인하고 손댈 수 있습니다.

반대로 여러 사람이 하나의 기억을 공유해야 하는 팀에게 OptMem은 맞지 않습니다. OptMem의 저장소는 사용자 홈 아래의 로컬 디렉토리이고, 프롬프트가 서브에이전트에게는 아예 memo를 실행하지 말라고 못 박고 있을 만큼 쓰기 주체를 단일하게 유지하는 설계입니다. 검색이 정규표현식 기반이라 표현이 다른 같은 개념을 찾아 주지도 않으므로, 의미 기반 회상이 필요하면 다른 선택지를 봐야 합니다.

OptMem 설치 및 사용법

설치는 설치 스크립트 한 줄입니다:

curl -fsSL https://raw.githubusercontent.com/VictorTaelin/OptMem/main/install.sh | sh

실행하면 ## Memory로 시작하는 프롬프트 블록이 출력됩니다. 그 블록을 에이전트의 AGENTS.md(또는 CLAUDE.md) 맨 위에 붙여 넣으면 통합이 끝납니다. 같은 명령을 다시 실행하면 갱신됩니다. 도구는 ~/.optmem/memo에 설치되므로, ~/.optmem을 PATH에 추가하면 memo만 입력해도 됩니다.

주요 명령은 다음과 같습니다:

명령 하는 일
memo wake 기억을 읽습니다. 모든 세션의 첫 명령입니다
memo note "..." 기억 하나를 기록합니다. 한 줄, 최대 280바이트입니다
memo nap 차례가 된 병합 작업을 처리합니다
memo recall <regex> 기록된 모든 기억을 문자 그대로 검색합니다
memo zoom <lo>-<hi> 트리 노드 하나를 그 아래 두 부분으로 펼칩니다
memo forget <lo>-<hi> 잘못된 요약을 버립니다. 다음 nap에서 다시 만들어집니다

병합 요청은 note 명령의 출력에 하나씩 실려 오며, 배경에서 도는 프로세스는 없습니다. 저장 구조는 다음과 같습니다:

~/.optmem/
  memo          도구 본체: 파이썬 3 파일 하나, 의존성 없음
  memory/
    LOG.txt     모든 기억, 한 줄에 하나, 덧붙이기 전용, 수정하지 않음
    TREE/       요약본: 캐시이며 로그만으로 다시 만들 수 있음
    config      크기 설정, `memo config`가 기록

크기 설정 중 실제로 손댈 만한 것은 WAKE_LINES 하나입니다. wake가 출력할 줄 수를 정하며 저장 용량이 아니라 읽기 예산이므로, 아무 때나 양방향으로 바꿔도 다시 계산되는 것이 없습니다. 설정은 다음 명령으로 확인하고 바꿉니다:

memo config                  # 현재 설정 확인
memo config WAKE_LINES=300   # wake가 출력할 줄 수 (96줄이 약 8k 토큰)
memo config WAKE_LINES=      # 기본값으로 되돌리기

$MEMORY_DIR 환경 변수로 memory/ 위치를 옮길 수 있어서, 동기화 폴더나 Git 저장소 안에 두는 것도 가능합니다.

OptMem이 에이전트에게 주는 프롬프트

이 프로젝트에서 통합의 전부에 해당하는 것이 설치 스크립트가 출력하는 프롬프트입니다. 저장소는 이 블록의 전문을 README에 그대로 공개하고 있으며, 지시는 네 부분으로 나뉩니다.

시작 시점에는 다른 도구를 호출하기 전에 ~/.optmem/memo wake를 실행하고 그 출력이 지시하는 대로 끝까지 따르도록 합니다. 작업 중에는 새로 배운 것이나 남길 만한 일이 생길 때마다 memo note로 한 줄을 기록하게 하고, 중복된 기억은 남기지 말라고 덧붙입니다. 옛 기억이 필요할 때는 memo recall로 검색하거나 memo zoom으로 트리를 내려가도록 안내합니다.

마지막 부분이 이 프롬프트에서 가장 실용적인 대목입니다. 서브에이전트는 memo를 아예 실행하지 말라고 지시하는데, 서브에이전트는 무엇이 이미 알려진 내용인지 판단할 수 없어 중복되고 부정확한 기록을 남기게 되기 때문입니다. 대신 서브에이전트를 띄울 때 "You are a subagent. Don't run memo."라는 문장을 함께 넘기라고 안내합니다. 같은 기계에서 병렬로 도는 일반 세션들은 모두 같은 주체로 보고 기록을 허용한다는 점과 대비되는 부분입니다.

병렬 쓰기는 실제로 검증된 항목입니다. 저장소의 WINDOWS.md는 네이티브 Windows에서 8개의 memo note 프로세스가 동시에 1,600건을 기록했을 때 1,600건이 모두 저장되었다고 잠금 동작 검증 결과를 적어 두었습니다. Windows에서는 fcntl 대신 msvcrt 기반 잠금으로 대체되며, WSL(Windows Subsystem for Linux) 없이 동작합니다.

:github: OptMem 프로젝트 GitHub 저장소

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

이 도구를 직접 설치해 사용해보셨다면, :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 경험이나 팁을 댓글로 남겨주세요! :folded_hands:

1개의 좋아요