들어가며
AI 에이전트를 운영하다 보면 한 가지 근본적인 문제에 부딪힙니다. “어제 한 대화를 오늘 기억하지 못한다.” ChatGPT에서 결정한 내용을 Claude가 모르고, Claude에서 논의한 맥락을 다시 ChatGPT에 설명해야 하죠.
이 문제를 해결하기 위해 Supermemory라는 SaaS 메모리 서비스를 도입했다가, 결국 걷어내고 OpenMemory를 Mac mini에 셀프호스팅하는 데 이르기까지의 여정을 공유합니다.
Supermemory, 왜 걷어냈나
기대했던 것
Supermemory는 AI 에이전트에 장기 기억을 부여하는 클라우드 서비스입니다. 대화에서 중요한 사실을 자동으로 추출하고, 다음 대화 시 관련 기억을 불러와 컨텍스트에 주입해주죠.
실제로 겪은 문제들
1. 범용 모델의 한계 — 엉뚱한 기억 추출
Supermemory는 내부적으로 범용 LLM을 사용해 대화에서 “사실(fact)”을 추출합니다. 문제는 이 과정이 생각보다 부정확하다는 것입니다.
실제 대화: "오늘 서버 이전 작업을 했는데 134.185.107.133 IP로 잘 붙었어"
추출된 기억: "서버 IP는 134.185.107.133이다" ← 이건 맞음
추출된 기억: "오늘 기분이 좋다" ← 이건 뭐지?
범용 모델이 대화의 뉘앙스를 과해석하면서, 실제로 기억할 가치가 없는 내용까지 저장했습니다.
2. 엉뚱한 기억의 주입
더 큰 문제는 recall(기억 불러오기) 단계에서 발생했습니다. “오늘 날씨 어때?”라고 물었는데 서버 설정 관련 기억이 튀어나오거나, 업무 대화 중에 전혀 관련 없는 취미 관련 기억이 컨텍스트에 주입되는 일이 잦았습니다.
이렇게 엉뚱한 기억이 컨텍스트에 섞이면, AI 에이전트가 혼란스러운 응답을 내놓게 됩니다. 차라리 기억이 없는 게 나은 상황이 벌어진 거죠.
3. 블랙박스 + 데이터 통제권 부재
- 어떤 기억이 저장되어 있는지 세밀하게 관리하기 어려움
- 기억 데이터가 외부 서버에 있어 프라이버시 우려
- 기억 품질을 직접 튜닝할 수 없음
결국 전면 제거를 결정했습니다.
OpenMemory를 선택한 이유
Mem0에서 만든 OpenMemory는 Supermemory와 비슷한 컨셉이지만 결정적인 차이가 있습니다:
| 항목 | Supermemory | OpenMemory |
|---|---|---|
| 호스팅 | 클라우드 (SaaS) | 셀프호스팅 (Docker) |
| LLM | 고정 (변경 불가) | 선택 가능 (Ollama, OpenAI 등) |
| 임베딩 | 고정 | 선택 가능 (nomic-embed-text 등) |
| 데이터 | 외부 서버 | 내 머신에 저장 |
| 비용 | 월 구독료 | 무료 (로컬 자원만 사용) |
| MCP 지원 | ❌ | ✅ 네이티브 |
| 커스터마이징 | 제한적 | 소스 코드 수정 가능 |
특히 MCP(Model Context Protocol) 네이티브 지원이 결정적이었습니다. MCP를 통해 Claude Desktop, Cursor, Windsurf, OpenClaw 등 다양한 AI 클라이언트가 하나의 기억 저장소를 공유할 수 있습니다.
구축 과정 (따라하기)
환경
- Mac mini M4 (24GB RAM)
- Docker Desktop
- Ollama (이미 설치됨)
- Tailscale (외부 접근용, 선택사항)
Step 1. 레포 클론
cd ~
git clone https://github.com/mem0ai/mem0.git
cd mem0/openmemory
Step 2. 환경변수 설정
api/.env — 핵심 설정 파일입니다:
cp api/.env.example api/.env
완전 로컬 운영을 위해 아래와 같이 수정합니다:
OPENAI_API_KEY=not-needed
USER=kk
# LLM — 기억 추출용 (Ollama 로컬)
LLM_PROVIDER=ollama
LLM_MODEL=llama3.1:8b
OLLAMA_BASE_URL=http://host.docker.internal:11434
# 임베딩 — 벡터 검색용 (Ollama 로컬)
EMBEDDER_PROVIDER=ollama
EMBEDDER_MODEL=nomic-embed-text
💡
host.docker.internal은 Docker 컨테이너에서 호스트 머신의 Ollama에 접근하기 위한 특수 주소입니다.
ui/.env:
cp ui/.env.example ui/.env
NEXT_PUBLIC_API_URL=http://localhost:8765
NEXT_PUBLIC_USER_ID=kk
Step 3. Ollama 모델 준비
# 기억 추출용 LLM (아직 없다면)
ollama pull llama3.1:8b
# 임베딩 모델 (아직 없다면)
ollama pull nomic-embed-text
Step 4. 벡터 차원 패치 (중요!)
OpenMemory 기본 코드는 OpenAI 임베딩(1536차원)을 기준으로 작성되어 있습니다. Ollama의 nomic-embed-text는 768차원이므로, 이 부분을 수정해야 합니다.
api/app/utils/memory.py 파일에서 Qdrant 기본 설정 부분을 찾습니다:
# 수정 전
else:
vector_store_provider = "qdrant"
vector_store_config.update({
"port": 6333,
})
아래와 같이 변경합니다:
# 수정 후
else:
vector_store_provider = "qdrant"
_embedder_prov = os.environ.get('EMBEDDER_PROVIDER',
os.environ.get('LLM_PROVIDER', 'openai')).lower()
_embedder_model = os.environ.get('EMBEDDER_MODEL', '')
if _embedder_prov == 'ollama' and 'nomic' in _embedder_model:
_embed_dims = 768
else:
_embed_dims = 1536
vector_store_config.update({
"port": 6333,
"embedding_model_dims": _embed_dims,
})
Step 5. UI Dockerfile 권한 패치
ui/Dockerfile에서 public 디렉토리 복사 시 권한 문제가 있습니다:
# 수정 전
COPY --from=builder /app/public ./public
# 수정 후
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
Step 6. 빌드 & 실행
make build
make up
첫 빌드는 Docker 이미지 다운로드 + 의존성 설치로 5~10분 정도 걸립니다.
Step 7. 동작 확인
빌드가 완료되면 세 개의 서비스가 올라옵니다:
docker ps
| 서비스 | 포트 | 역할 |
|---|---|---|
| Qdrant | :6333 | 벡터 데이터베이스 |
| OpenMemory MCP | :8765 | API + MCP 서버 |
| OpenMemory UI | :3000 | 웹 대시보드 |
브라우저에서 http://localhost:3000을 열면 OpenMemory 대시보드가 나타납니다.
MCP 연동하기
OpenMemory의 진짜 힘은 MCP 연동에서 나옵니다.
OpenClaw (텔레그램 AI 에이전트)
mcporter를 사용해 한 줄로 연동합니다:
mcporter config add openmemory \
--url "http://localhost:8765/mcp/openclaw/sse/kk"
연동 확인:
mcporter list openmemory --schema
5개 도구가 등록됩니다:
– add_memories — 기억 저장
– search_memory — 기억 검색
– list_memories — 전체 기억 조회
– delete_memories — 특정 기억 삭제
– delete_all_memories — 전체 초기화
Claude Desktop
~/.claude/claude_desktop_config.json에 추가:
{
"mcpServers": {
"openmemory": {
"url": "http://localhost:8765/mcp/claude/sse/kk"
}
}
}
Cursor / Windsurf
각 에디터의 MCP 설정에 동일한 패턴으로 추가하면 됩니다:
http://localhost:8765/mcp/<client-name>/sse/<user-id>
외부 접근 (Tailscale)
Tailscale을 사용 중이라면 별도 설정 없이 Tailscale 주소로 접근할 수 있습니다:
http://<your-tailscale-hostname>:8765/mcp/<client>/sse/<user-id>
이렇게 하면 아이폰, 다른 PC 등 어디서든 기억에 접근 가능합니다.
실제 테스트
기억 저장
mcporter call 'openmemory.add_memories(
text: "KK님은 영업1팀 팀장으로 7명의 팀원을 리드하며
기업용 PC 서버 워크스테이션 판매와 인프라 컨설팅을 담당한다",
infer: true
)'
결과 — llama3.1이 자동으로 핵심 사실을 추출합니다:
{
"results": [
{"memory": "KK님은 영업1팀 팀장", "event": "ADD"},
{"memory": "리드하는 팀원 수는 7명", "event": "ADD"},
{"memory": "영업1팀은 기업용 PC 서버 워크스테이션 판매와 인프라 컨설팅을 담당한다", "event": "ADD"}
]
}
기억 검색
mcporter call 'openmemory.search_memory(query: "KK님 직업이 뭐야")'
{
"results": [
{"memory": "KK님은 영업1팀 팀장", "score": 1.0},
{"memory": "리드하는 팀원 수는 7명", "score": 0.99},
{"memory": "영업1팀은 기업용 PC 서버 워크스테이션 판매와 인프라 컨설팅을 담당한다", "score": 0.92}
]
}
관련성 높은 순서로 정확하게 반환됩니다.
Docker 자동 시작 설정
재부팅 후에도 OpenMemory가 자동으로 올라오도록 docker-compose.yml에 restart 정책을 추가합니다:
services:
mem0_store:
image: qdrant/qdrant
restart: unless-stopped # 추가
...
openmemory-mcp:
restart: unless-stopped # 추가
...
openmemory-ui:
restart: unless-stopped # 추가
...
Docker Desktop만 로그인 시 자동 시작되도록 설정해두면 됩니다.
Supermemory vs OpenMemory — 체감 차이
| 체감 항목 | Supermemory | OpenMemory (셀프호스팅) |
|---|---|---|
| 기억 품질 | 범용 모델 → 엉뚱한 추출 빈번 | LLM 직접 선택 가능 → 품질 조절 가능 |
| 기억 오염 | 관련 없는 기억 주입됨 | 벡터 검색 튜닝 가능 |
| 응답 속도 | 네트워크 지연 발생 | 로컬이라 빠름 |
| 데이터 보안 | 외부 서버 | 내 머신에서만 동작 |
| 비용 | 월 구독료 | 무료 (전기세만) |
| 디버깅 | 불가능 | 소스코드 수준에서 가능 |
| 크로스 플랫폼 | 제한적 | MCP로 어디든 연결 |
최종 아키텍처
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ ChatGPT │ │ Claude │ │ OpenClaw │
│ (웹/앱) │ │ (Desktop) │ │ (텔레그램) │
└──────┬──────┘ └──────┬──────┘ └──────┬───────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────┐
│ OpenMemory (Mac mini M4 · Docker) │
│ MCP Server :8765 │
│ ┌────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ Qdrant │ │ nomic-embed │ │ llama3.1 │ │
│ │ 벡터DB │ │ (768차원) │ │ (8B·추출) │ │
│ └────────┘ └──────────────┘ └────────────┘ │
└──────────────────────────────────────────────┘
Tailscale VPN으로 어디서든 접근
ChatGPT에서 “다음 프로젝트는 B2B SaaS로 가자”라고 결정하면 → OpenMemory에 저장 → 다음날 OpenClaw에 “프로젝트 방향 뭐였지?” → 바로 답변.
플랫폼 간 기억 장벽이 사라집니다.
마치며
AI 에이전트의 기억 시스템은 아직 초기 단계입니다. 클라우드 SaaS가 편리하지만, 실제 운영 환경에서 기억 품질을 직접 통제하고 싶다면 셀프호스팅이 현실적인 선택지입니다.
OpenMemory + Ollama + MCP 조합은:
– 무료이고
– 프라이빗하며
– 확장 가능합니다
Docker 하나면 누구나 자신만의 AI 기억 레이어를 구축할 수 있습니다.
이 글은 KK의 개인 AI 에이전트 클로이(Chloe)와 함께 작업한 실제 구축 기록입니다.