AI 에이전트를 위한 공유 브레인 구축하기 — 그리고 그 과정에서 망가진 모든 것들
요약
여러 AI 코딩 에이전트(Claude Code, Cursor, Codex 등) 간의 컨텍스트 단절 문제를 해결하기 위한 공유 메모리 계층인 'Passport'를 소개합니다. MCP를 기반으로 출처 추적, 충돌 감지, 사용자 격리 기능을 갖춘 견고한 메모리 시스템 구축 과정을 다룹니다.
핵심 포인트
- 에이전트 간 컨텍스트 공유를 위한 통합 메모리 계층의 필요성
- Passport의 핵심 기능: 출처(Provenance), 충돌 감지, 사용자 격리
- 안정성을 위해 브라우저 확장 프로그램 대신 MCP 전용 방식 채택
- 도구 간의 기억 상실 문제를 해결하여 개발 생산성 향상
Passport 🧳를 소개합니다 — 당신의 AI 코딩 에이전트를 위한 공유 메모리 계층입니다.
저는 지금 세 개의 AI 코딩 에이전트를 띄워 놓았습니다. 한 터미널에는 Claude Code, 한 창에는 Cursor, 또 다른 곳에는 Codex가 있습니다. 그런데 이들 모두가 기억상실증에 걸린 상태입니다.
Claude Code에게 제 스택을 설명하는 데 10분을 씁니다 — 우리는 pytest를 사용하고, DB는 Postgres이며, 인증(auth)은 JWT를 사용하고, 기존(legacy) 결제 모듈은 건드리지 말라고 말이죠. 그러면 Claude Code는 작업을 완벽하게 수행합니다. 그러다 다른 작업을 위해 Cursor로 전환하면, 저는 다시 원점으로 돌아갑니다. 똑같은 설명. 다른 도구. 멍한 시선. 새로운 채팅창에 **"unittest가 아니라 pytest를 사용합니다"**라고 세 번째 타이핑했을 때, 제 안의 무언가가 끊어지는 기분이었습니다.
이 도구들은 매우 훌륭합니다.
하지만 금붕어 같기도 하죠.
그리고 이상하게도, 이들 중 어느 것도 서로 대화하지 않습니다.
Claude Code가 제 코드베이스에 대해 배운 내용은 탭을 닫는 순간 사라지며, Cursor는 그런 일이 일어났다는 사실조차 전혀 모릅니다.
그래서 Cognee의 해커톤 — 말 그대로 **"내 컨텍스트(Context)는 어디에 있는가?"**라는 주제 — 을 보았을 때, 저는 브레인스토밍을 할 필요조차 없었습니다.
저는 이미 몇 달 동안 이 문제를 온몸으로 겪어오고 있었으니까요.
아이디어 (그리고 그와 함께 찾아온 의구심)
제안은 간단했습니다:
모든 에이전트가 읽고 쓸 수 있는 하나의 공유 메모리.
하나에게 가르치면, 모두가 알게 됩니다.
저는 이것을 Passport라고 불렀습니다 — 당신의 메모리가 당신과 함께 이동하여, 다음에 여는 어떤 도구로든 따라가야 하기 때문입니다.
하지만 제가 솔직하게 인정할 첫 번째 사실이 있습니다:
약 한 시간 동안, 저는 이것이 가짜(fake)일까 봐 두려웠습니다.
Cognee는 이미 MCP 서버를 출시했습니다. 제 심사위원들은 Cognee입니다. 만약 제가 한 일이 그들의 메모리 도구를 몇몇 에이전트에 연결하는 것뿐이라면, 저는 메모리 계층을 만든 사람들에게 튜토리얼을 건네주고 그것을 프로젝트라고 부르는 셈이 될 것입니다.
그 두려움이 첫날 내내 제 가슴을 짓눌렀습니다.
탈출할 수 있는 유일한 방법은 그 누구의 튜토리얼에도 없는 무언가를 만드는 것이었습니다:
- 출처(Provenance) (어떤 에이전트가 무엇을 가르쳤는가)
- 충돌 감지(Conflict detection) (두 에이전트의 의견이 다를 때 어떤 일이 발생하는가)
- 사용자 간의 실제 격리(Real isolation)
이 세 가지가 핵심이 되었습니다.
그 외의 모든 것은 기본 요건(table stakes)이었습니다.
저는 또한 수십 번씩 스스로 의심했던 결정을 내리기도 했습니다:
화려한 브라우저 확장 프로그램(browser extension)은 건너뛰고, MCP 전용으로 가기로 했습니다.
ChatGPT를 캡처하는 브라우저 확장 프로그램이 있었다면, 사용자의 메모리가 웹으로 따라다니는 아주 멋진 데모가 되었을 것입니다.
하지만 그것은 취약합니다. 라이브 데모 중에 깨져버리는 데모는, 마법 같은 느낌이 약간 덜하더라도 안정적인 데모보다 훨씬 나쁩니다.
저는 지루하지만 견고한(robust) 길을 선택했습니다.
(스포일러: 저는 다시 선택해도 똑같은 결정을 내릴 것입니다. 마법 같은 길은 깨지기 마련입니다. 제가 어떻게 아는지 궁금하시면 물어보세요.)
실제로 작동했던 순간
이 순간을 저는 결코 잊지 못할 것입니다.
저는 Anthropic의 에이전트인 Claude Code에게 이렇게 말했습니다:
"우리는 인증(auth)을 위해 JWT를 사용하고 프론트엔드(frontend)는 React라는 점을 기억해줘."
그런 다음 저는 Codex — OpenAI의 에이전트이자, 완전히 다른 회사의 모델이며, 해당 대화의 단 한 마디도 본 적 없는 새로운 세션인 — 를 열고 물었습니다:
"우리의 인증(auth)과 프론트엔드(frontend)는 뭐야?"
그것은 이렇게 답했습니다:
JWT와 React.
저는 빈 방에서 실제로 **"말도 안 돼"**라고 소리 내어 말했습니다.
두 개의 경쟁 관계인 AI 시스템이, 제가 그날 오후에 연결해 둔 메모리 레이어(memory layer)를 통해 뇌를 공유하고 있었습니다.
그 순간 프로젝트는 단순한 아이디어에서 벗어나 현실이 되기 시작했습니다.
교차 벤더 메모리 (Cross-vendor memory).
감정적으로 느낄 일이 아니어야 합니다.
하지만 저는 느꼈습니다.
그리고 당연하게도...
모든 것이 깨지기 시작했습니다.
장애 #1: Codex가 충돌했고 원인을 알 수 없었습니다
Claude Code는 잘 작동했습니다.
하지만 Codex는 모든 회상(recall) 시마다 다음과 같은 오류를 던졌습니다:
[Errno 22] Invalid argument
왜 그런지 전혀 알 수 없었습니다.
동일한 서버.
동일한 코드.
다른 클라이언트.
하나는 작동하고, 하나는 죽습니다.
저는 이 문제로 한 시간을 허비했습니다.
돌파구는 거의 바보 같을 정도로 단순했습니다:
MCP는 stdout을 통해 통신하고, Cognee는 회상(recall) 중에 stderr로 많은 로그를 남깁니다.
Windows에서는 클라이언트가 해당 stderr 파이프(pipe)를 비워주지 않으면, 파이프가 가득 차게 되어(~64KB) 다음 쓰기 작업 시 도구 전체가 충돌합니다.
remember는 조용해서 몰래 통과할 수 있었습니다.
recall은 너무 수다스러워서 파이프를 터뜨려 버린 것입니다.
해결책은 세 줄뿐이었습니다 — Cognee가 임포트(import)되기 전에 stderr를 로그 파일로 라우팅하는 것이었습니다.
하지만 그 세 줄을 찾아내기 위해서는 파이프(pipe), 버퍼링(buffering), 그리고 MCP의 전송(transport) 방식이 실제로 어떻게 작동하는지 정확히 이해해야 했습니다.
이런 버그들에 대해 아무도 말해주지 않는 사실이 바로 이것입니다:
해결책은 아주 작지만, 그에 대한 이해는 그렇지 않습니다.
결함 #2: 사라져 버린 기능
Cognee의 메모리 라이프사이클(lifecycle)은 다음과 같습니다:
- 기억하기 (remember)
- 회상하기 (recall)
- 개선하기 (improve)
- 잊기 (forget)
저는 그래프의 가중치를 재조정하는 "memify" 단계인 improve()를 기반으로 저의 모든 충돌 조정(conflict-reconciliation) 스토리를 구축했습니다.
클라우드 환경에서 이를 호출했으나, 다음과 같은 응답을 받았습니다:
404 Not Found
제가 사용 중이던 클라우드 티어(cloud tier)에서는 memify가 노출되지 않았습니다.
제가 설계의 핵심으로 삼았던 기능이 사라진 것입니다.
순간 발밑이 꺼지는 듯한 기분이 들었습니다.
그러고 나서 저는 해커톤에서 실제로 해야만 하는 일을 했습니다:
이게 정말로 필요한가?
결론은, 필요하지 않았습니다.
조정(Reconciliation)은 그래프의 가중치를 재조정할 필요가 없습니다. 권위 있는 결정(authoritative decision)을 기록하고, 회상(recall) 시 그 결정을 준수하도록 만드는 것이 필요할 뿐입니다.
저는 improve()를 try/except 문으로 감싸고, 이를 솔직하게 **"OSS 전용(OSS-only)"**이라고 로그를 남긴 뒤 다음 단계로 넘어갔습니다.
데모는 더 단순해졌습니다.
그리고 더 정직해졌습니다.
때로는 제약 사항이 선물이 되기도 합니다.
결함 #3: 늑대 Doug가 모든 곳에 유출되었던 밤
이것은 저를 거의 무너뜨릴 뻔했던 사건입니다.
멀티 테넌시(Multi-tenancy) — 사용자 간의 진정한 격리 — 는 이 프로젝트의 핵심 보석이 되어야 했습니다.
alice와 bob이라는 두 사용자가 각각 자신만의 프라이빗 브레인(private brain)을 갖는 구조입니다.
저는 다음과 같이 테스트를 작성했습니다:
- alice는 비밀을 저장한다
- bob은 다른 비밀을 저장한다
- 어느 쪽도 상대방의 비밀을 봐서는 안 된다
테스트를 실행했습니다.
alice는 자신의 사실을 완벽하게 회상했습니다.
그리고 bob은...
회상했습니다.
"마스코트는 Doug라는 이름의 늑대입니다."
Doug.
그.
늑대.
Doug는 몇 시간 전의 테스트 데이터였습니다. 다른 문제를 디버깅하는 동안 수십 번 저장했던, 버려도 되는 사실이었죠.
그런데 그가, 완전히 격리되어 있어야 할 새로운 테넌트(tenant)의 메모리 내부에서 실체화되어 나타난 것입니다.
저의 격리는 환상이었습니다.
만약 이것이 실제 사용자였다면, 한 회사의 비밀이 다른 회사로 흘러 들어가고 있었을 것입니다.
그것은 출시할 수 있는 버그가 아닙니다.
그것은 제품을 끝장내는 버그입니다.
저는 테넌트의 태그(tags)로 필터링하는 명백한 해결책을 시도했지만, 상황은 더 악화되었습니다.
이제 두 사용자 모두 Doug를 보게 되었습니다.
새벽 1시, 죽지 않는 늑대를 빤히 바라보며 앉아 있는 동안, 나는 멀티 테넌트 (multi-tenant) 전제 조건 자체가 잘못된 것은 아닌지 진심으로 의문이 들었습니다.
그래서 추측을 멈추고 체계적으로 접근하기로 했습니다.
나는 하나의 고유한 사실을 저장했습니다 —
"사무실 마스코트는 Ember라는 이름의 불사조입니다."
— 그리고 Cognee가 제공하는 모든 검색 (retrieval) 모드를 하나씩 통해 쿼리하며, 어떤 모드에서 정보가 유출되고 어떤 모드가 유지되는지 관찰했습니다.
GRAPH_COMPLETION → Doug 유출
RAG_COMPLETION → Doug 유출
...
깨끗합니다.
격리되었습니다.
정확합니다.
그래프 완성 (graph-completion) 모드들은 전체 공유 지식 그래프 (shared knowledge graph)를 검색하고 있었고, Doug와 같이 강력하게 강화된 노드 (node)가 데이터셋 경계를 넘어 흘러나오게 만들고 있었습니다.
원시 청크 검색 (Raw chunk retrieval)은 데이터셋 범위를 준수했습니다.
해결책은 필터가 아니었습니다.
올바른 종류의 회상 (recall) 방식을 선택하는 것이었습니다.
나는 청크 범위 검색 (chunk-scoped retrieval)으로 전환하여 격리 테스트를 다시 실행했고, 지난 두 시간 동안 갈구해온 두 단어를 얻었습니다:
격리 통과 (ISOLATION PASSED)
나도 모르게 주먹을 불끈 쥐었을지도 모릅니다.
늑대를 보면서 말이죠.
괜찮습니다.
그리고 아름다운 점은:
이 해결책이 설계를 더 낫게 만들었다는 것입니다.
이제 Passport는 각 테넌트의 충실한 사실만을 반환하며, 호출하는 에이전트 (agent)가 추론을 수행할 수 있게 합니다 — 이는 블랙박스 완성 (black-box completion) 방식보다 더 깔끔하고, 더 정확하며, 더 정직합니다.
버그가 더 나은 아키텍처 (architecture)를 강제했습니다.
보통 버그는 그렇습니다.
내가 가장 묻기 두려워했던 질문
개발 후반부에, 팀원이 내가 피해왔던 질문을 던졌습니다:
"이게 정말 지능적인 건가요, 아니면 그냥 키워드를 하드코딩해서 스스로를 속이고 있는 건가요?"
그 질문은 정당했기에 뼈아팠습니다.
내 랭킹 (ranking) 시스템의 일부는 "중요도"를 판단하기 위해 키워드 휴리스틱 (keyword heuristic)을 사용하고 있었습니다.
나는 if-문들을 AI인 것처럼 꾸미고 있었던 걸까요?
그래서 나는 정직하게 행동했습니다.
만약 가짜라면 실패하도록 설계된 적대적 테스트 (adversarial test)를 실행했습니다.
나는 다음과 같이 저장했습니다:
"분기별 이사회 회의는 매월 첫 번째 화요일입니다."
그런 다음 다음과 같이 쿼리했습니다:
"고위 경영진이 회사 실적을 검토하기 위해 언제 모입니까?"
공유되는 단어가 전혀 없었습니다.
키워드 시스템이라면 즉시 실패할 것입니다.
하지만 시스템은 회의에 대해 반환했습니다.
왜냐하면 회상(Recall)은 실제 의미론적 이해(Semantic understanding)이기 때문입니다. 즉, **"성과 검토를 위한 경영진 모임"**이 **"이사회 회의"**를 의미한다는 것을 아는 임베딩(Embeddings)을 사용하는 것입니다.
이것은 문자열 매칭(String matching)이 아닙니다.
이것이 진짜입니다.
하지만 저는 스스로를 방관하지도 않았습니다.
중요도 점수(Importance score)는 키워드 휴리스틱(Keyword heuristic)이었고, 그것은 지능이 아닙니다.
그래서 저는 이를 업그레이드했습니다:
이제 Cognee의 자체 LLM이 각 메모리의 중요도를 1~10점으로 평가합니다.
테스트를 해보니, 회사 정책은 9점을 받았고, 한가한 잡담은 2점을 받았습니다.
진정한 판단입니다.
그리고 저는 유일하게 정직한 비(非) AI 요소인 신뢰 가중치(Trust weights)를 정확히 명시적인 설정(Explicit config)으로 남겨두었습니다. 왜냐하면 **"이 출처를 얼마나 신뢰할 것인가"**를 결정하는 것은 거버넌스(Governance)의 문제이며, 모델이 이를 추측하게 만드는 것이 바로 메모리 오염 공격(Memory-poisoning attacks)을 초래하는 방식이기 때문입니다.
무엇이 AI가 되어서는 안 되는지를 아는 것 자체가 하나의 엔지니어링입니다.
그것이 무엇이 되었는가
결과적으로, Passport는 단순한 래퍼(Wrapper)가 아니었습니다.
그것은 다음과 같았습니다:
- Claude Code, Cursor, Codex를 가로지르는 공유 브레인 — 벤더 간 호환성(Cross-vendor) 입증.
- 모든 메모리에 대한 출처(Provenance) — 어떤 에이전트가 무엇을 가르쳤는지에 따라 색상이 지정된 라이브 그래프.
- Cognee의 LLM을 통한 충돌 탐지(Conflict detection) — "Postgres vs MySQL"과 같은 충돌을 포착하고 이를 조정함.
- 실제 멀티 테넌트 격리(Multi-tenant isolation) — 측정된 결과, 유출 제로.
- 지능형 회상(Intelligent recall) — 의미론적 검색(Semantic retrieval), LLM 점수 기반 중요도, 최신성, 출처 신뢰도.
그리고 저는 단순히 느낌(Vibe)에 의존하는 대신 직접 측정했습니다:
- ✅ 에이전트 간 회상(Cross-agent recall) 100%
- ✅ 격리(Isolation) 100%
- ✅ 키워드가 없는 쿼리에 대한 의미론적 회상(Semantic recall) 입증
형용사가 아닌 숫자입니다.
한계에 대해서도 솔직해지겠습니다. 자랑만 늘어놓는 블로그는 거짓말이기 때문입니다:
- memify는 셀프 호스팅(Self-hosted)으로만 실행됨
- 저의 충돌 탐지는 신호 강도는 높지만 완전하지는 않음
- 신뢰 가중치는 학습되는 것이 아니라 정적임
모두 수정 가능합니다.
모두 로드맵에 있습니다.
그 어떤 것도 숨기지 않았습니다.
제가 실제로 얻은 교훈
제가 계획하지 않았던 시적인 아이러니가 있습니다:
저는 AI 에이전트와 페어 프로그래밍(Pair-programming)을 하는 동안(Claude Code를 사용했으며, 이는 공개된 사실이며 솔직히 제가 이렇게 빠르게 움직일 수 있었던 이유 전체입니다), AI 에이전트를 위한 메모리를 구축했습니다.
망각하는 도구가,
제가 구축하는 것을 돕고 있습니다.
기억하는 도구입니다.
하지만 진짜 교훈은 메모리에 관한 것이 아니었습니다.
그것은 모든 어려운 버그들 — Codex를 충돌시킨 파이프, 404 오류를 일으킨 기능, 죽지 않던 늑대 — 가 단순히 제 시간만을 앗아간 것이 아니었다는 점입니다.
각각의 버그는 더 나은 결정을 내리도록 강제했습니다.
충돌(Crash)은 전송(Transport)이 실제로 어떻게 작동하는지 가르쳐 주었습니다.
404 오류는 설계를 더 단순하게 만들었습니다.
늑대 Doug는 제가 스스로 작성했을 것보다 더 깔끔하고 정확한 아키텍처 (Architecture)를 저에게 안겨주었습니다.
우리는 계속해서 AI에게 그 컨텍스트 (Context)가 어디로 갔는지 묻습니다.
알고 보니 정답은 더 큰 컨텍스트 윈도우 (Context Window)가 아니었습니다.
그것은 AI에게 메모리를 부여하는 것이었습니다 —
AI가 소유하고,
AI와 함께 이동하며,
누가 무엇을 가르쳤는지 기억하는 메모리 말입니다.
Passport가 바로 그 메모리입니다.
Doug는 마침내 떠났습니다.
그리고 제 에이전트 (Agents)들은, 마침내, 어젯밤을 기억합니다.
🔗 Live Demo
https://memlayer.streamlit.app/
💻 GitHub
https://github.com/ShivenduShivu/MemoryLayer_for_Agents
💓를 담아 제작되었으며, Cognee의 그래프-벡터 메모리 (Graph-vector memory)를 기반으로 한 Cognee의 "Where's My Context?" 해커톤을 위해 구축되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기