OpenClaw (구 Moltbot, 구 Clawdbot) 리뷰(5) : Memory 시스템 살펴보기 - OpenClaw는 어떻게 대화를 기억할까?
- -
안녕하세요! 갓대희 입니다.
이번에는 "Personal AI"의 핵심인 Memory 시스템을 살펴보자.
너무 빨리 변하고 있다보니 따라 가기도 벅차다. clawdBot부터 나의 경우 계속 migration 해오다 보니 잘못된 내용이 있을 것 같다. 잘못된 내용이 있다면 댓글 남겨주시면, 수정하도록 하겠습니다.!

이 글의 정보는 2026년 1월 31일 기준입니다. OpenClaw(구 Moltbot)은 활발히 개발 중이므로, 최신 정보는 공식 문서에서 확인하시기 바랍니다.
OpenClaw의 Memory 시스템은 평문 마크다운 기반의 영속적 기억 저장소다:
1) 2레이어 구조: MEMORY.md (장기 기억) + memory/YYYY-MM-DD.md (일일 로그)
2) Vector + BM25 하이브리드 검색으로 의미 기반 + 키워드 기반 검색 결합
3) 자동 Memory Flush: 컴팩션 전 중요 정보 자동 저장
4) 고급 기능: extraPaths(외부 문서 통합), 배치 임베딩, 임베딩 캐시, 세션 메모리 검색(실험)
핵심 원칙: "파일이 진실의 원천(Source of Truth)" — 모델은 디스크에 저장된 것만 기억한다
목차
- Memory 아키텍처 이해하기
- MEMORY.md 작성법
- Daily Log 시스템
- Memory Search 기능
- 임베딩 설정
- Memory Flush (자동 저장)
- 실전 활용 예제
- 보안 고려사항
- 트러블슈팅
1. Memory 아키텍처 이해하기
OpenClaw의 Memory는 작업 공간(Workspace)에 저장된 평문 마크다운이다.
파일 자체가 정보의 원천이며, 모델은 디스크에 저장된 내용만 "기억"한다.
"Gave @moltbot a long-term memory system so they remember all the Discord lore. Super basic, just a file they can edit as they see fit, but it works."
— 단순하지만 효과적인 파일 기반 메모리 시스템
1.1 2레이어 메모리 구조
┌─────────────────────────────────────────────────────────────┐
│ OpenClaw Memory System │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Layer 1: MEMORY.md │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ • 장기 기억 (Long-term Memory) │ │ │
│ │ │ • 결정사항, 선호도, 지속적 사실 │ │ │
│ │ │ • 개인 세션에서만 로드 (그룹 제외) │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ 중요 정보 승격 │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Layer 2: memory/YYYY-MM-DD.md │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ • 일일 로그 (Daily Log) │ │ │
│ │ │ • 추가 전용 (Append-only) │ │ │
│ │ │ • 세션 시작 시 오늘+어제 데이터 로드 │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
| 레이어 | 저장 내용 | 로드 시점 |
|---|---|---|
| MEMORY.md | 결정사항, 선호도, 지속적 사실 | 개인 세션 시작 시 (그룹 컨텍스트 제외) |
| memory/YYYY-MM-DD.md | 일상 노트, 실행 컨텍스트 | 세션 시작 시 오늘 + 어제 데이터 |
1.2 Workspace 파일 구조
OpenClaw의 작업 공간에는 메모리 외에도 다양한 설정 파일이 있다:
~/.openclaw/workspace/ # 기본 워크스페이스 (agents.defaults.workspace로 변경 가능)
├── AGENTS.md # 에이전트 설정
├── BOOTSTRAP.md # 초기화 프롬프트
├── HEARTBEAT.md # 주기적 체크 작업
├── IDENTITY.md # 에이전트 정체성
├── MEMORY.md # ⭐ 장기 기억 (핵심)
├── SOUL.md # 성격 및 태도
├── TOOLS.md # 도구 설정
├── USER.md # 사용자 정보
├── canvas/ # 작업 디렉토리
└── memory/ # ⭐ 일일 로그 디렉토리
├── 2026-01-26.md
├── 2026-01-27.md
└── 2026-01-28.md
ex) openClaw로 설치 직후 폴더 구조

1.3 핵심 원칙
OpenClaw는 RAM에 정보를 유지하지 않는다. 누군가 "이거 기억해"라고 하면, 반드시 파일에 기록해야 한다.
대화 세션이 끝나거나 컴팩션되면, 파일에 저장되지 않은 정보는 사라진다.
2. MEMORY.md 작성법
MEMORY.md는 선별된 장기 기억을 저장하는 파일이다.
결정사항, 선호도, 지속적으로 참조해야 할 사실을 기록한다.
2.1 기본 구조
# MEMORY.md 예시
## 사용자 프로필
- 이름: 홍길동
- 직업: 소프트웨어 엔지니어
- 관심사: AI, 자동화, 생산성 도구
- 선호 언어: 한국어 (기술 문서는 영어 OK)
## 프로젝트 컨텍스트
### 현재 진행 중인 프로젝트
- **AI 블로그 시리즈**: OpenClaw 튜토리얼 작성 중
- 완료: Part 1-4
- 진행: Part 5 (Memory)
### 기술 스택
- 언어: Python 3.11, TypeScript
- 프레임워크: FastAPI, Next.js
- 데이터베이스: PostgreSQL, Redis
## 선호도 및 결정사항
### 코딩 스타일
- Python: Black 포매터 사용
- 함수형 프로그래밍 선호
- 타입 힌트 필수
### 커뮤니케이션
- 간결한 답변 선호
- 코드 예시 포함 권장
- 확실하지 않으면 "추정"임을 명시
## 중요 정보
### API 키 위치
- OpenAI: ~/.config/openai/key
- Anthropic: 환경변수 ANTHROPIC_API_KEY
### 자주 사용하는 경로
- 프로젝트: ~/work/py/dev
- 블로그: ~/work/py/dev/ai-tools-series
2.2 무엇을 기록해야 하는가?
| 분류 | MEMORY.md (장기) | Daily Log (일일) |
|---|---|---|
| O | • 영구적인 선호도 • 중요한 결정사항 • 프로젝트 컨텍스트 • 자주 참조하는 정보 |
• 오늘 진행한 작업 • 임시 메모 • 대화 중 나온 아이디어 • 디버깅 과정 |
| X | • 일시적인 정보 • 자주 변경되는 상태 • 민감한 자격증명 |
• 영구 보관할 결정사항 • 장기적으로 필요한 설정 |
2.3 그룹 컨텍스트 주의사항
MEMORY.md는 개인(private) 세션에서만 로드된다.
그룹 채팅(Discord 서버, Slack 채널 등)에서는 MEMORY.md가 로드되지 않아 민감한 개인 정보가 노출되지 않는다.
3. Daily Log 시스템
memory/YYYY-MM-DD.md 파일은 일일 로그를 저장한다.
각 날마다 새 파일이 생성되며, 해당 날의 맥락과 작업 기록을 추가한다.
3.1 Daily Log 예시
# memory/2026-01-28.md
## 오늘의 작업
### 09:00 - OpenClaw Part 5 작성 시작
- 주제: Memory 시스템
- 참고: 공식 문서 docs.openclaw.ai/concepts/memory
- 목표: 2레이어 메모리 구조 설명, 실전 예제 포함
### 11:30 - 공식 문서 검증
- Memory Search 기능 확인
- sqlite-vec 가속화 설명 추가 필요
- 하이브리드 검색 설정 옵션 정리
### 14:00 - X(Twitter) 커뮤니티 조사
- @steipete: 파일 기반 메모리 시스템 철학
- @pepicrft: 가족 공유 어시스턴트 "Moltis" 사례
## 메모
- [ ] Part 6 주제 확정 필요 (Hybrid LLM)
- [x] Memory Flush 메커니즘 이해 완료
## 내일 할 일
- Part 5 최종 검토 및 발행
- Part 6 공식 문서 조사 시작
3.2 로드 동작
세션이 시작되면 OpenClaw는 자동으로 다음을 로드한다:
- 오늘 날짜의 Daily Log:
memory/2026-01-28.md - 어제 날짜의 Daily Log:
memory/2026-01-27.md - MEMORY.md: 장기 기억 (개인 세션 한정)

대화가 자정을 넘어 이어질 수 있고, 어제 작업의 연속인 경우가 많다.
2일치 로그를 로드함으로써 최근 맥락을 충분히 유지한다.
3.3 Daily Log vs MEMORY.md 승격
Daily Log에 기록된 정보 중 장기적으로 중요한 것은 MEMORY.md로 승격시킨다:
# 사용자 요청 예시
> "방금 결정한 코딩 컨벤션을 장기 기억에 저장해줘"
# OpenClaw가 수행하는 작업:
1. Daily Log에서 해당 내용 확인
2. MEMORY.md의 적절한 섹션에 추가
3. 사용자에게 저장 완료 알림
- 물론 이런 메모리 파일은 있지만, 그냥 여기까지온 경우 단순하게 읽을 순 없을 것 이다.
ex) 현재 별돌의 검색 기능활성화 되지 않은 상태에서 파일 읽기 요청


- 메모리 활성화 방법도 알려주는데 간단히 살펴보고 하기 내용들을 이어가보자.
찾았다! 메모리 검색 활성화하는 방법은 크게 **2가지**야:
---
## 방법 1: API 키 설정 (쉬움)
**OpenAI 쓰기:**
```bash
# 환경변수로 설정
export OPENAI_API_KEY="sk-xxx..."
```
또는 설정에 추가:
```json5
{
"agents": {
"defaults": {
"memorySearch": {
"provider": "openai",
"remote": {
"apiKey": "sk-xxx..."
}
}
}
}
}
```
**Gemini 쓰기:**
```bash
export GEMINI_API_KEY="AIza..."
```
> ⚠️ Codex OAuth는 임베딩 API를 지원 안 해서, 별도 API 키가 필요해
---
## 방법 2: 로컬 모드 (API 키 없이)
```json5
{
"agents": {
"defaults": {
"memorySearch": {
"provider": "local",
"fallback": "none"
}
}
}
}
```
단, 첫 실행 시:
```bash
pnpm approve-builds # node-llama-cpp 빌드 승인
pnpm rebuild node-llama-cpp
```
→ 모델 자동 다운로드됨 (~0.6GB)
---
## 어떤 거 하고 싶어?
1. **OpenAI API 키 있으면** → 환경변수 설정하면 바로 됨
2. **Gemini 키 있으면** → 환경변수 설정
3. **키 없이 로컬로** → 설정 변경 + 빌드
원하는 방식 알려줘, 설정 적용해줄게! 🐻
- 벡터 검색을 하겠다는 것 같다. 단순히 시키면 되겠지만 이론적인 내용을 하기 정리해 두려고 한다.
4. Memory Search 기능
OpenClaw는 MEMORY.md와 memory/*.md 파일에 대해 Vector 인덱스를 구축한다.
이를 통해 단어가 다르더라도 의미적으로 관련된 정보를 찾을 수 있다.
4.1 하이브리드 검색 구조
┌─────────────────────────────────────────────────────────────┐
│ Hybrid Search │
├─────────────────────────────────────────────────────────────┤
│ │
│ 검색 쿼리: "gateway 호스트 머신 설정" │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Vector Search │ │ BM25 Search │ │
│ │ (의미론적 검색) │ │ (키워드 검색) │ │
│ │ │ │ │ │
│ │ "Mac Studio에서 │ │ "gateway" 정확히 │ │
│ │ 게이트웨이 실행" │ │ 포함된 문서 찾기 │ │
│ │ 도 매칭됨 │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │ │ │
│ └────────┬────────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 결과 병합 (Fusion) │ │
│ │ vectorWeight: 0.7 │ │
│ │ textWeight: 0.3 │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
| 검색 방식 | 강점 | 약점 |
|---|---|---|
| Vector Search | 의미적 유사성 이해 (다른 표현도 매칭) |
정확한 키워드 검색에 약함 |
| BM25 (Full-text) | 정확한 토큰 매칭 (needle-in-haystack) |
패러프레이즈에 약함 |
| Hybrid | 두 방식의 장점 결합 | 설정 튜닝 필요 |
4.2 Memory Search 도구
OpenClaw는 메모리 플러그인을 통해 다음 도구를 제공한다:
| 도구 | 설명 |
|---|---|
memory_search |
의미론적 쿼리로 관련 메모리 검색 → 파일명 + 라인 범위가 포함된 스니펫 반환 |
memory_get |
경로로 메모리 파일 내용 직접 읽기 (라인 범위 지정 가능) |
4.2.1 Memory Search 실제 사용 예시
실제 대화에서 Memory Search 도구가 어떻게 활용되는지 살펴보자:
# 예시 1: 과거 문제 해결 방법 검색
> 예전에 Redis 연결 문제 어떻게 해결했었지?
# OpenClaw가 memory_search 도구 호출:
memory_search("Redis 연결 타임아웃 문제 해결")
# 반환 결과 (스니펫 ~700자):
{
"file": "memory/2026-01-15.md",
"lines": "45-62",
"score": 0.87,
"snippet": "## 디버깅: Redis 연결 타임아웃\n원인: 로컬 Redis 미실행...\n해결: connectTimeout: 1000 설정..."
}
# OpenClaw 응답:
"1월 15일에 비슷한 문제를 해결했네요. 원인은 로컬 Redis가 실행되지 않아
fallback 대기 중이었고, connectTimeout: 1000으로 설정해서 해결했습니다."
# 예시 2: 특정 파일 내용 읽기
> 오늘 Daily Log 전체 보여줘
# OpenClaw가 memory_get 도구 호출:
memory_get("memory/2026-01-28.md")
# 특정 라인 범위만 읽을 수도 있음:
memory_get("memory/2026-01-28.md", lines="1-50")
# 예시 3: CLI에서 직접 메모리 검색
$ openclaw memory search "API 응답 지연"
# 출력 예시:
Found 3 matches:
1. memory/2026-01-28.md:45-62 (score: 0.92)
"## 디버깅: API 응답 지연 이슈..."
2. memory/2026-01-15.md:20-35 (score: 0.78)
"### API 성능 최적화 메모..."
3. MEMORY.md:112-118 (score: 0.65)
"## 자주 발생하는 이슈 - API 관련..."
# 특정 에이전트의 메모리만 검색:
$ openclaw memory search --agent my-assistant "프로젝트 마감일"
• 구체적인 키워드 + 맥락을 함께 사용하면 정확도 향상
• 예: "Redis 에러" → "Redis 연결 타임아웃 해결 방법"
• Vector 검색은 의미적 유사성을 찾으므로, 동의어나 관련 표현도 매칭됨
4.3 sqlite-vec 가속화
OpenClaw는 sqlite-vec 확장을 사용하여 Vector 검색을 가속화한다:
// sqlite-vec가 사용 가능하면:
- 임베딩이 SQLite virtual table (vec0)에 저장됨
- Vector distance 쿼리가 데이터베이스 내에서 수행됨
- 모든 임베딩을 JS로 로드하지 않아 빠름
// sqlite-vec가 없으면:
- JS in-process cosine similarity로 폴백
- 작동은 하지만 대규모 메모리에서 느림
인덱스는 에이전트별 SQLite 파일에 저장된다:~/.openclaw/memory/<agentId>.sqlite
경로는 agents.defaults.memorySearch.store.path로 변경 가능 ({agentId} 토큰 지원)
5. 임베딩 설정
Memory Search는 텍스트를 벡터 임베딩으로 변환하여 의미적 검색을 수행한다.
로컬 또는 원격 임베딩 제공자를 선택할 수 있다.
5.1 임베딩 모드 비교
| 모드 | 장점 | 단점 |
|---|---|---|
| 원격 (Remote) | • 설정 간편 (기본값) • 고품질 임베딩 • CPU/GPU 부담 없음 |
• API 비용 발생 • 네트워크 지연 • 데이터가 외부로 전송 |
| 로컬 (Local) | • 비용 무료 • 데이터 로컬 유지 • 네트워크 불필요 |
• 초기 모델 다운로드 필요 • CPU/GPU 리소스 사용 • 설정 복잡 |
5.2 원격 임베딩 설정 (기본)
memorySearch.provider를 설정하지 않으면 기본적으로 원격 임베딩을 사용한다.
OpenClaw는 설정된 API 키에 따라 OpenAI 또는 Gemini를 자동 선택한다.
// ~/.openclaw/openclaw.json - 원격 임베딩 (기본 - 자동 선택)
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true
// provider 미설정 시 자동 선택:
// 1) local (modelPath 설정 + 파일 존재 시)
// 2) OpenAI (API 키 있으면)
// 3) Gemini (API 키 있으면)
}
}
}
}
// Gemini 명시적 설정
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"provider": "gemini",
"model": "gemini-embedding-001",
"remote": {
"apiKey": "YOUR_GEMINI_API_KEY"
}
}
}
}
}
// OpenAI 호환 엔드포인트 설정
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"provider": "openai",
"model": "text-embedding-3-small",
"remote": {
"baseUrl": "https://api.openai.com/v1/",
"apiKey": "YOUR_OPENAI_API_KEY"
}
}
}
}
}
5.3 로컬 임베딩 설정
로컬 모드는 node-llama-cpp를 사용하여 기기에서 직접 임베딩을 생성한다.
# 1. node-llama-cpp 빌드 승인 (처음 한 번)
pnpm approve-builds
# 2. 로컬 임베딩 모델 다운로드 (선택)
# 기본 모델: embeddinggemma-300M-Q8_0.gguf
# 모델 경로를 직접 지정하거나 자동 다운로드
// ~/.openclaw/openclaw.json - 로컬 임베딩 (로컬 파일 경로)
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"provider": "local",
"local": {
"modelPath": "~/.openclaw/models/embeddinggemma-300M-Q8_0.gguf",
"modelCacheDir": "~/.cache/openclaw/embeddings" // 선택
},
"fallback": "openai" // 로컬 실패 시 폴백 (선택)
}
}
}
}
// HuggingFace URL 형식 (자동 다운로드)
{
"agents": {
"defaults": {
"memorySearch": {
"provider": "local",
"local": {
// hf:owner/repo/filename 형식 → 자동 다운로드
"modelPath": "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf"
}
}
}
}
}
memorySearch.provider가 설정되지 않은 경우, OpenClaw는:
1. local.modelPath 설정 + 파일 존재 → 로컬 모드
2. OpenAI API 키 존재 → OpenAI
3. Gemini API 키 존재 → Gemini
4. 모두 없으면 → 비활성화fallback 옵션: "openai", "gemini", "local", "none"
로컬 임베딩 설정 확인 예시
# 설정 후 동작 확인
$ openclaw memory status --deep
# 예상 출력 (로컬 모드 정상 동작):
Agent: default
Provider: local
Model: embeddinggemma-300M-Q8_0.gguf
Model cache: ~/.cache/openclaw/embeddings
Vector store: sqlite-vec (active)
Indexed files: 15
Total chunks: 234
# HuggingFace URL 사용 시 첫 실행에서 자동 다운로드:
[local] Downloading model from hf:ggml-org/embeddinggemma-300M-GGUF...
[local] Model cached at ~/.cache/openclaw/embeddings/embeddinggemma-300M-Q8_0.gguf
[local] Model loaded successfully
ex) 나의 경우 로컬 세팅을 오픈 클로에게 요청
> 응답 : 좋아! 로컬 모드로 설정할게 🔧
임베딩 모델 다운로드 중! (~328MB, 현재 21%) ⏳
잠시만 기다려줘, 1~2분 정도 걸릴 거야. 완료되면 알려줄게!
CLI에서는 로컬 모드로 완벽하게 작동 중! 🎉
```
Provider: local (requested: local)
Indexed: 3/3 files · 3 chunks ✅
Vector: ready ✅
FTS: ready ✅
```
다만 현재 세션의 `memory_search` 도구가 이전 설정을 캐싱하고 있는 것 같아.
**해결 방법:**
게이트웨이 재시작하면 바로 적용돼! 재시작할까?
아니면 CLI로 먼저 테스트해볼 수도 있어:
```bash
openclaw memory search "타로"
```
어떻게 할래? 🐻
ex) CLI 테스트 요청
> 응답
**완벽! 🎉🎉🎉**
`memory_search` 도구도 완벽하게 작동해!
```
provider: "local"
model: "embeddinggemma-300M-Q8_0.gguf"
score: 0.707
```
✅ **로컬 메모리 검색 설정 완료!**
- API 키 없이 로컬 임베딩 모델 사용
- 3개 파일 인덱싱 완료
- 세션 내 `memory_search` 도구 작동 확인
이제 앞으로 메모리에서 맥락 검색할 때 자유롭게 쓸 수 있어! 🐻
5.4 하이브리드 검색 튜닝
// ~/.openclaw/openclaw.json - 하이브리드 검색 설정
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"query": {
"hybrid": {
"enabled": true, // 기본값: true
"vectorWeight": 0.7, // 기본값: 0.7
"textWeight": 0.3, // 기본값: 0.3
"candidateMultiplier": 4 // 기본값: 4
}
}
}
}
}
}
// 점수 계산: finalScore = vectorWeight × vectorScore + textWeight × textScore
가중치 튜닝 예시
# 검색 쿼리: "CVE-2024-1234 취약점"
═══════════════════════════════════════════════════════════════════
# 기본 설정 (vectorWeight: 0.7, textWeight: 0.3)
═══════════════════════════════════════════════════════════════════
1. memory/2026-01-15.md (score: 0.82)
"보안 취약점 분석 - 인증 우회 이슈..." ← 의미적 유사
2. memory/2026-01-10.md (score: 0.71)
"CVE-2024-1234 패치 적용 완료..." ← 정확한 키워드
═══════════════════════════════════════════════════════════════════
# 키워드 우선 (vectorWeight: 0.3, textWeight: 0.7)
═══════════════════════════════════════════════════════════════════
1. memory/2026-01-10.md (score: 0.89)
"CVE-2024-1234 패치 적용 완료..." ← 정확한 키워드 우선!
2. memory/2026-01-15.md (score: 0.65)
"보안 취약점 분석 - 인증 우회 이슈..."
| 사용 케이스 | vectorWeight | textWeight | 이유 |
|---|---|---|---|
| 기본값 (권장) | 0.7 | 0.3 | 일반적인 자연어 검색 |
| 코드/에러 검색 | 0.3 | 0.7 | 정확한 토큰 매칭 필요 (CVE, 에러코드) |
| 개념/아이디어 검색 | 0.9 | 0.1 | 의미적 유사성 우선 |
5.5 sqlite-vec 설정
// ~/.openclaw/openclaw.json - sqlite-vec 설정
{
"agents": {
"defaults": {
"memorySearch": {
"store": {
"vector": {
"enabled": true, // 기본값: true
"extensionPath": "/path/to/sqlite-vec" // 선택
}
}
}
}
}
}
// enabled: false 시 JS cosine similarity로 폴백
// 확장 로드 실패 시에도 자동 폴백 (하드 실패 없음)
5.6 추가 메모리 경로 (extraPaths)
워크스페이스 외부의 마크다운 파일도 메모리 검색 대상에 포함할 수 있다:
// ~/.openclaw/openclaw.json - 추가 메모리 경로
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"extraPaths": [
"~/Documents/notes", // 절대 경로 (디렉토리는 재귀 스캔)
"../shared-knowledge", // 상대 경로 (workspace 기준)
"~/Obsidian/dev-vault" // 디렉토리 내 .md 파일 자동 스캔
]
}
}
}
}
• Obsidian/Notion 내보내기: 기존 노트 앱의 마크다운 파일을 검색 대상에 포함
• 프로젝트 문서: 여러 프로젝트의 README, 위키 파일 통합 검색
• 공유 지식 베이스: 팀 공용 문서를 개인 에이전트가 참조
extraPaths 실제 검색 예시
# 설정: extraPaths에 Obsidian vault 추가
"extraPaths": ["~/Obsidian/dev-vault"]
# CLI로 인덱싱 상태 확인
$ openclaw memory status --deep
Agent: default
Workspace: ~/.openclaw/workspace
Memory files: 15
extraPaths:
- ~/Obsidian/dev-vault (42 files) ← 외부 경로도 인덱싱됨
Total indexed: 57 files, 456 chunks
# 대화에서 Obsidian 노트 검색
> 예전에 정리해둔 Docker 네트워크 설정 방법 찾아줘
# OpenClaw가 memory_search 호출 → extraPaths도 검색됨
memory_search("Docker 네트워크 설정")
# 결과 (Obsidian vault에서 찾음):
Found in: ~/Obsidian/dev-vault/DevOps/docker-networking.md:15-45
"## Docker 네트워크 모드
- bridge: 기본 모드, 컨테이너 간 통신
- host: 호스트 네트워크 직접 사용
- none: 네트워크 비활성화..."
# CLI에서 직접 검색
$ openclaw memory search "Docker 네트워크"
1. ~/Obsidian/dev-vault/DevOps/docker-networking.md:15-45 (score: 0.91)
2. ~/.openclaw/workspace/memory/2026-01-20.md:30-42 (score: 0.67)
• 디렉토리는 재귀적으로 스캔됨 (.md 파일만)
• 심볼릭 링크는 무시됨
• 대규모 디렉토리 추가 시 초기 인덱싱 시간 증가
• openclaw memory status로 인덱싱 상태 확인 가능
5.7 배치 임베딩 (Batch Embedding)
대규모 메모리를 처음 색인할 때 배치 임베딩을 사용하면 API 호출을 최적화하고 비용을 절감할 수 있다:
// ~/.openclaw/openclaw.json - 배치 임베딩 설정 (전체 옵션)
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"remote": {
"batch": {
"enabled": true, // 기본값: true
"concurrency": 2, // 병렬 배치 작업 수 (기본: 2)
"wait": true, // 배치 완료까지 대기
"pollIntervalMs": 5000, // 상태 확인 주기 (ms)
"timeoutMinutes": 60 // 최대 대기 시간 (분)
}
}
}
}
}
}
| 설정 | 설명 |
|---|---|
batch.enabled |
배치 처리 활성화 (기본값: true) |
batch.concurrency |
동시에 제출할 배치 작업 수 (기본값: 2) |
batch.wait |
배치 완료까지 대기 여부 (기본값: true) |
batch.pollIntervalMs |
배치 상태 폴링 주기 (밀리초) |
batch.timeoutMinutes |
배치 완료 최대 대기 시간 (분) |
OpenAI Batch API를 사용하면 할인된 가격으로 대규모 임베딩을 처리할 수 있다.
배치 작업은 비동기로 처리되며, 여러 작업을 병렬로 제출할 수 있다.
5.8 임베딩 캐시
변경되지 않은 텍스트의 재임베딩을 방지하여 API 비용과 시간을 절약한다:
// ~/.openclaw/openclaw.json - 임베딩 캐시 설정
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"cache": {
"enabled": true, // 기본값: true
"maxEntries": 50000 // 기본값: 50000
},
"watch": true // 파일 변경 감시 (기본값: true, 1.5초 디바운스)
}
}
}
}
// 캐시 동작 원리
1. 텍스트 청크의 해시값 계산
2. 캐시에 동일 해시 존재 시 → 저장된 임베딩 재사용
3. 캐시에 없으면 → API 호출 후 캐시에 저장
// 저장 위치: SQLite 인덱스 파일 내 (~/.openclaw/memory/<agentId>.sqlite)
• 파일 일부만 수정해도 변경된 청크만 재임베딩
• Gateway 재시작 시에도 캐시 유지
• 대규모 메모리 운영 시 API 비용 대폭 절감
5.9 세션 메모리 검색 (실험 기능)
파일 기반 메모리뿐 아니라 세션 대화 내용도 검색 대상에 포함할 수 있다:
// ~/.openclaw/openclaw.json - 세션 메모리 (실험 기능, 전체 옵션)
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": true,
"experimental": {
"sessionMemory": true // 기본값: false (실험 기능)
},
"sources": ["memory", "sessions"], // 기본값: ["memory"]
"sync": {
"sessions": {
"deltaBytes": 100000, // 기본값: 100000 (~100KB)
"deltaMessages": 50 // 기본값: 50
}
}
}
}
}
}
| 설정 | 설명 |
|---|---|
experimental.sessionMemory |
세션 트랜스크립트 색인 활성화 (기본값: false) |
sources |
검색 대상 지정 (기본값: ["memory"]) |
sync.sessions.deltaBytes |
동기화 트리거 바이트 임계값 (기본값: 100000) |
sync.sessions.deltaMessages |
동기화 트리거 메시지 수 임계값 (기본값: 50) |
• 비동기 처리: 대화 중 백그라운드에서 색인 (best-effort)
• 델타 기반: 임계값 도달 시에만 동기화 실행
• 약간의 지연: memory_search는 인덱싱 완료를 기다리지 않음 — 결과가 약간 오래될 수 있음
• 실험 기능이므로 향후 변경될 수 있음
6. Memory Flush (자동 저장)
OpenClaw는 세션이 길어지면 자동으로 컴팩션(Compaction)을 수행한다.
컴팩션 전에 중요 정보가 사라지지 않도록 Memory Flush 메커니즘이 작동한다.
6.1 Memory Flush 동작
세션 토큰 사용량 증가
│
▼
┌─────────────────────────────────────────────────────────────┐
│ softThreshold 도달 (contextWindow - reserve - soft) │
│ 예: 200k - 20k - 4k = 176k 토큰 시점 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Silent Agentic Turn 트리거 │
│ "지금 바로 중요한 정보를 메모리에 저장하세요" │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 모델이 MEMORY.md / Daily Log에 중요 정보 기록 │
│ (사용자에게 보이지 않음 - NO_REPLY 응답) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Auto-Compaction 수행 │
│ 오래된 대화 내용 정리, 요약만 유지 │
└─────────────────────────────────────────────────────────────┘
6.2 Memory Flush 설정
// ~/.openclaw/openclaw.json - Memory Flush 설정
{
"agents": {
"defaults": {
"compaction": {
"reserveTokensFloor": 20000, // 예약 토큰 (기본 20k)
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 4000, // 소프트 임계값 (기본 4k)
"systemPrompt": "Session nearing compaction. Store durable memories now.",
"prompt": "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."
}
}
}
}
}
| 설정 | 설명 |
|---|---|
memoryFlush.enabled |
Memory Flush 활성화 여부 (기본값: true) |
reserveTokensFloor |
컨텍스트 윈도우 끝에서 예약할 토큰 수 (기본값: 20000) |
softThresholdTokens |
이 임계값에 도달하면 Memory Flush 트리거 (기본값: 4000) |
systemPrompt |
시스템 레벨 메모리 저장 안내 프롬프트 |
prompt |
모델에게 전달할 구체적인 저장 지시 프롬프트 |
memoryFlush 블록을 설정하지 않아도 기본적으로 활성화되어 있다.
별도 설정 없이도 컴팩션 전 자동으로 중요 정보를 저장한다.
Memory Flush가 작동하려면 작업 공간이 쓰기 가능해야 한다.
읽기 전용 작업 공간에서는 이 기능이 비활성화된다.
7. 실전 활용 예제
Memory 시스템을 실제로 활용하는 다양한 시나리오를 살펴보자.
7.1 개인 취향 기억하기
# 사용자 대화 예시
> 나는 코드에서 세미콜론 없는 스타일을 선호해. 기억해둬.
# OpenClaw가 MEMORY.md에 추가:
## 코딩 선호도
- JavaScript/TypeScript: 세미콜론 생략 스타일 선호
# 이후 대화에서...
> 이 TypeScript 코드 리팩토링해줘
# OpenClaw: 자동으로 세미콜론 없는 스타일로 코드 제공
7.2 프로젝트 컨텍스트 유지
# 프로젝트 시작 시 MEMORY.md 작성
## 현재 프로젝트: AI 블로그 시리즈
- 목표: OpenClaw 튜토리얼 9부작 완성
- 기술 스택: HTML, CSS (인라인 스타일)
- 톤앤매너: 친근하지만 전문적
- 대상 독자: 개발자, AI 도구에 관심 있는 일반인
## 완료된 글
- Part 1-4: 기본 시리즈 완료 (2026-01-28)
## 진행 중
- Part 5: Memory 시스템 (현재)
# 언제 세션을 시작해도 프로젝트 맥락 유지
7.3 홈 어시스턴트 통합
• Home Assistant 박스에서 가족용 AI 어시스턴트 운영
• 이메일, 홈랩(SSH), 할일 목록, 쇼핑 목록 등을 Telegram 단일 채팅으로 통합
— Discord, Reddit에서 다양한 활용 사례 공유 중
# MEMORY.md - 홈/가족 어시스턴트 예시
## 가족 구성원
- 홍길동 (아빠): Telegram @honggildong
- 김영희 (엄마): iMessage
- 홍철수 (아들): Discord hong#1234
## 중요 일정
- 김영희 생일: 3월 15일
- 홍철수 학교 방학: 7월 20일 - 8월 31일
## 스마트 홈 연동
- Home Assistant 주소: http://homeassistant.local:8123
- 조명 자동화: 일몰 30분 전 거실 조명 켜기
## 선호도
- 저녁 추천 시: 홍길동은 매운 음식 선호, 홍철수는 파스타 선호
7.4 일정 및 할 일 관리
# Daily Log 예시 - memory/2026-01-28.md
## 오늘의 할 일
- [x] 09:00 팀 스탠드업 미팅
- [x] 11:00 PR 리뷰 (#142, #145)
- [ ] 14:00 디자인 팀 미팅 (새 대시보드 논의)
- [ ] 17:00 Part 5 블로그 마무리
## 완료된 작업
- PR #142 리뷰 완료 - 몇 가지 코멘트 남김
- PR #145 승인 및 머지
## 내일 예정
- 09:00 팀 스탠드업
- Part 6 블로그 시작
# OpenClaw에게 질문:
> 오늘 남은 일정이 뭐야?
# OpenClaw: Daily Log를 검색하여 미완료 항목 응답
7.5 디버깅 히스토리 추적
# Daily Log에 디버깅 과정 기록
## 디버깅: API 응답 지연 이슈 (2026-01-28)
### 증상
- /api/users 엔드포인트 응답 시간 5초 이상
- 로컬 환경에서만 발생
### 시도한 것들
1. DB 쿼리 확인 → 정상 (100ms 이내)
2. 네트워크 지연 확인 → 정상
3. 미들웨어 로깅 추가 → auth 미들웨어에서 4초 소요 발견
### 원인
- Redis 연결 타임아웃 설정 누락
- 로컬 Redis가 실행되지 않아 fallback 대기
### 해결
```js
// redis.config.js
connectTimeout: 1000, // 1초 후 fallback
```
# 다음에 비슷한 이슈 발생 시:
> 예전에 API 응답 느렸던 이슈 어떻게 해결했었지?
# OpenClaw: Memory Search로 관련 기록 찾아 응답
8. 보안 고려사항
Memory에는 개인 정보가 포함될 수 있으므로 보안에 주의해야 한다.
8.1 민감 정보 처리
- 비밀번호, API 키, 토큰
- 신용카드 번호, 계좌 정보
- 주민등록번호, 여권 번호
- 의료 기록
# 잘못된 예 (절대 금지)
## API 키
- OpenAI: sk-proj-abc123...
- Stripe: sk_live_xyz789...
# 올바른 예
## API 키 위치
- OpenAI: 환경변수 OPENAI_API_KEY
- Stripe: ~/.config/stripe/key (chmod 600)
8.2 그룹 vs 개인 세션
| 세션 유형 | MEMORY.md 로드 | Daily Log 로드 |
|---|---|---|
| 개인 DM | ✓ 로드됨 | ✓ 로드됨 |
| 그룹 채팅 | ✗ 로드 안됨 | △ 설정에 따라 |
8.3 원격 임베딩 시 데이터 전송
원격 임베딩(OpenAI, Gemini)을 사용하면 메모리 텍스트가 외부 API로 전송된다.
민감한 데이터가 포함된 경우 로컬 임베딩 사용을 권장한다.
8.4 파일 권한 설정
# 작업 공간 권한 설정
chmod 700 ~/.openclaw/workspace
chmod 600 ~/.openclaw/workspace/MEMORY.md
chmod 700 ~/.openclaw/workspace/memory
# SQLite 인덱스 권한
chmod 600 ~/.openclaw/memory/*.sqlite
9. 트러블슈팅
OpenClaw는 메모리 관리를 위한 CLI 명령어를 제공한다. 문제 해결 전에 먼저 이 도구들을 활용하자.
9.0 메모리 CLI 명령어 (진단 도구)
# ═══════════════════════════════════════════════════════════════════
# 메모리 상태 확인
# ═══════════════════════════════════════════════════════════════════
# 기본 상태 확인
$ openclaw memory status
# 출력 예시:
Agent: default
Workspace: ~/.openclaw/workspace
Memory files: 15
extraPaths: ~/Documents/notes, ~/Obsidian/vault
# 상세 상태 확인 (벡터/임베딩 가용성 포함)
$ openclaw memory status --deep
# 출력 예시:
Agent: default
Provider: openai
Model: text-embedding-3-small
Vector store: sqlite-vec (active)
Indexed files: 15
Total chunks: 234
Cache entries: 189
# 상태 확인 + 필요 시 재인덱싱 트리거
$ openclaw memory status --deep --index
# ═══════════════════════════════════════════════════════════════════
# 인덱싱
# ═══════════════════════════════════════════════════════════════════
# 인덱싱 실행
$ openclaw memory index
# 상세 로그와 함께 인덱싱 (provider, model, batch 진행 상황 표시)
$ openclaw memory index --verbose
# 출력 예시:
[index] Provider: openai (text-embedding-3-small)
[index] Scanning: ~/.openclaw/workspace/memory/*.md
[index] Scanning: ~/.openclaw/workspace/MEMORY.md
[index] Found 15 files, 234 chunks
[batch] Processing 234 chunks in 3 batches...
[batch] Batch 1/3: 100 chunks ✓
[batch] Batch 2/3: 100 chunks ✓
[batch] Batch 3/3: 34 chunks ✓
[index] Complete: 234 embeddings stored
# ═══════════════════════════════════════════════════════════════════
# 메모리 검색 (CLI)
# ═══════════════════════════════════════════════════════════════════
# 메모리 검색
$ openclaw memory search "release checklist"
# 특정 에이전트의 메모리만 검색
$ openclaw memory search --agent my-assistant "API 설정"
| 명령어 | 용도 |
|---|---|
openclaw memory status |
기본 메모리 상태 확인 |
openclaw memory status --deep |
벡터/임베딩 가용성 상세 확인 |
openclaw memory index |
메모리 인덱싱 실행 |
openclaw memory search "쿼리" |
CLI에서 직접 메모리 검색 |
--agent <id> |
특정 에이전트 지정 (공통 옵션) |
--verbose |
상세 로그 출력 (공통 옵션) |
9.1 메모리가 로드되지 않음
| 증상 | 해결 방법 |
|---|---|
| MEMORY.md 내용을 모름 | 그룹 세션인지 확인, 개인 DM에서 테스트 |
| Daily Log가 비어있음 | 파일이 존재하는지 확인, 날짜 형식 확인 (YYYY-MM-DD.md) |
| 예전 기록을 못 찾음 | 오늘/어제만 자동 로드됨, memory_search 도구 사용 |
9.2 Memory Search가 작동하지 않음
# Step 1: CLI로 메모리 상태 확인 (가장 먼저!)
$ openclaw memory status --deep
# 정상 출력 예시:
Agent: default
Provider: openai
Model: text-embedding-3-small
Vector store: sqlite-vec (active) # ← active 확인
Indexed files: 15
Total chunks: 234
# 문제 출력 예시:
Agent: default
Provider: none # ← 임베딩 제공자 미설정
Vector store: disabled # ← 벡터 저장소 비활성화
Indexed files: 0 # ← 인덱싱 안됨
# Step 2: 인덱싱 강제 실행
$ openclaw memory index --verbose
# 또는 상태 확인과 동시에 재인덱싱 트리거
$ openclaw memory status --deep --index
# Step 3: 파일 시스템 직접 확인 (CLI가 실패할 경우)
# 인덱스 파일 존재 확인
ls -la ~/.openclaw/memory/
# 로컬 임베딩 모델 확인 (로컬 모드 사용 시)
ls -la ~/.openclaw/models/
# 또는 캐시 디렉토리 확인
ls -la ~/.cache/openclaw/embeddings/
# 검색 테스트
$ openclaw memory search "테스트 쿼리"
다음 설정을 변경하면 OpenClaw가 자동으로 전체 재인덱싱을 수행한다:
• provider 변경 (예: openai → local)
• model 변경 (예: text-embedding-3-small → text-embedding-3-large)
• remote.baseUrl 변경 (엔드포인트 변경)
9.3 Memory Flush가 작동하지 않음
# Step 1: Memory Flush 동작 기록 확인
# 세션 상태에서 memoryFlush 관련 필드 확인
cat ~/.openclaw/agents/default/sessions/sessions.json | jq '.memoryFlushAt, .memoryFlushCompactionCount'
# 정상 동작 시 출력 예시:
"2026-01-28T14:30:00Z" # ← 마지막 flush 시간
3 # ← flush가 발생한 compaction 횟수
# 미동작 시 출력:
null
null
# Step 2: 작업 공간 쓰기 권한 확인
touch ~/.openclaw/workspace/test_write.txt && rm ~/.openclaw/workspace/test_write.txt && echo "쓰기 권한 OK"
# 권한 에러 시:
chmod 700 ~/.openclaw/workspace
chmod 600 ~/.openclaw/workspace/MEMORY.md
# Step 3: 설정 확인
cat ~/.openclaw/openclaw.json | jq '.agents.defaults.compaction.memoryFlush'
# 예상 출력:
{
"enabled": true,
"softThresholdTokens": 4000
}
# 테스트용으로 낮은 임계값 설정 (빠르게 flush 트리거)
# "softThresholdTokens": 1000
- 읽기 전용 워크스페이스:
workspaceAccess: "ro"또는"none"설정 시 스킵됨 - 그룹 세션: Memory Flush는 개인(embedded Pi) 세션에서만 작동
- 임계값 미도달:
contextWindow - reserveTokensFloor - softThresholdTokens미도달
9.4 인덱스 손상 또는 동기화 문제
# Step 1: 현재 인덱스 상태 확인
$ openclaw memory status --deep
# 인덱스 파일 직접 확인
ls -la ~/.openclaw/memory/*.sqlite
# Step 2: 인덱스 완전 삭제 후 재구축
rm ~/.openclaw/memory/*.sqlite
# CLI로 재인덱싱 실행
$ openclaw memory index --verbose
# 또는 상태 확인과 동시에 재인덱싱
$ openclaw memory status --deep --index
# Step 3: Gateway 재시작이 필요한 경우
# macOS (데몬 서비스):
launchctl stop com.openclaw.gateway && launchctl start com.openclaw.gateway
# 수동 실행 중이면:
# 1. 기존 프로세스 종료
pkill -f "openclaw gateway"
# 2. Gateway 재시작
openclaw gateway --port 18789
# 3. 재인덱싱 확인
$ openclaw memory status --deep
• 파일 감시: 메모리 파일 변경 시 1.5초 후 자동 재인덱싱
• 세션 시작: 새 세션 시작 시 동기화 체크
• 검색 요청: 검색 시점에 동기화 상태 확인
• 임베딩 제공자/모델/엔드포인트 변경 시 전체 재인덱싱 트리거
마무리
이번 글에서는 OpenClaw의 Memory 시스템을 살펴봤다.
• 2레이어 구조: MEMORY.md (장기) + memory/YYYY-MM-DD.md (일일)
• 파일이 진실의 원천: 디스크에 저장되지 않으면 기억되지 않음
• 하이브리드 검색: Vector + BM25로 의미적/키워드 검색 결합
• Memory Flush: 컴팩션 전 자동으로 중요 정보 저장
• 그룹 보안: MEMORY.md는 개인 세션에서만 로드
• 고급 기능: extraPaths로 외부 문서 통합, 배치 임베딩/캐시로 비용 최적화
Memory 시스템을 잘 활용하면 OpenClaw는 단순한 챗봇이 아닌
나의 선호도, 프로젝트 맥락, 과거 결정사항을 모두 기억하는 개인 비서로 활용하는데 도움이 될 것 같다.
참고 자료
공식 문서:
커뮤니티:
- @steipete - OpenClaw 개발자 (Peter Steinberger)
- GitHub Repository
- OpenClaw Discord - 커뮤니티 지원
'AI > OpenClaw(구 Moltbotbot, Clawdbot)' 카테고리의 다른 글
당신이 좋아할만한 콘텐츠
-
OpenClaw (구 Moltbot, 구 Clawdbot) 리뷰(7) : OpenClaw 24시간 가동하기 - 잠들지 않는 나만의 자비스 만들기()홈랩부터 클라우드(VPS)까지 2026.02.02
-
OpenClaw (구 Moltbot, 구 Clawdbot) 리뷰(6) : Ollama 연동 가이드 - 로컬 LLM Ollama로 무료 AI 비서 만들기 2026.02.02
-
OpenClaw (구 Moltbot, 구 Clawdbot) 리뷰(4) : Moltbot 브라우저 자동화 - AI가 직접 웹을 서핑하는 방법 (Browser Automation 설정, 활용) 2026.02.01
-
OpenClaw (구 Moltbot, 구 Clawdbot) 리뷰(3) : OpenClaw Skills 설치 방법(opencode, ohmyopencode 등), 추천 스킬 & 워크플로우 알아보기 2026.01.30
소중한 공감 감사합니다