Post

OpenClaw 스타일 메모리 시스템 구현하기 — AI 비서가 기억하는 법

OpenClaw의 파일 기반 메모리를 분석하고, Claude Code 텔레그램 봇에 적용했다. MEMORY.md + 일일 노트로 중요한 것만 기억한다.

OpenClaw 스타일 메모리 시스템 구현하기 — AI 비서가 기억하는 법

내 비서는 금붕어였다

지난 편에서 텔레그램 봇을 만들었다. 근데 이 녀석, 3초 전 대화도 기억을 못 한다.

“아까 그 코드 수정해줘” → “무슨 코드요?”

이건 비서가 아니다. 그냥 매번 처음 만나는 사이다.

솔직히 좀 화가 났다. 내가 만든 건데 왜 나를 모르냐고.

OpenClaw를 뜯어봤다

요즘 핫한 OpenClaw의 메모리 시스템을 분석해봤다. 핵심은 의외로 단순했다.

파일이 기억이다. 대화 전체가 아니라, 중요한 것만 마크다운 파일에 저장한다.

OpenClaw 메모리 구조

1
2
3
MEMORY.md              ← 장기 기억 (선호도, 결정사항)
memory/2026-02-06.md   ← 오늘 일일 노트
memory/2026-02-05.md   ← 어제 일일 노트

동작 원리는 이거다:

  1. 세션 시작 → MEMORY.md + 오늘/어제 노트만 읽음
  2. 대화 중 → AI가 “이건 기억할 만하다” 판단하면 기록
  3. 컨텍스트 다 찰 때 → 자동 저장
  4. 다음 세션 → 저장된 파일을 읽어서 맥락 유지

벡터 DB? RAG? 없다. 그냥 마크다운 파일이다. 사람이 직접 열어서 편집할 수도 있다. 이 단순함이 핵심이다.

나는 복잡한 걸 싫어하는 사람이다. 이걸 보고 바로 따라하기로 했다.

OpenClaw 메모리 구조

처음엔 대화 전체를 저장했다

v1: 무식한 방법

1
2
3
4
5
[
  {"role": "user", "content": "블로그 배포해줘", "timestamp": "..."},
  {"role": "assistant", "content": "배포 완료...", "timestamp": "..."},
  ...40 메시지 전부 저장
]

멍청했다. 토큰 낭비, 쓸데없는 대화도 다 포함, 파일은 점점 커지고. 20개만 유지해도 프롬프트가 엄청 길어졌다.

v2: OpenClaw 스타일 — 중요한 것만

1
2
3
4
5
data/
├── MEMORY.md         ← "사용자는 conda 선호", "ENFP 개발자"
└── daily/
    ├── 2026-02-07.md  ← 오늘 뭐 했는지
    └── 2026-02-06.md  ← 어제 뭐 했는지

프롬프트 길이가 1/5로 줄었다. 진작 이렇게 할 걸.

구현 — 생각보다 쉽다

1. [MEMO] 태그 — AI가 알아서 기억할 걸 고른다

시스템 프롬프트에 이렇게 넣었다:

1
2
중요: 대화 중 기억할 만한 정보가 있으면 답변 마지막에 아래 형식으로 알려줘:
[MEMO] 기억할 내용

Claude가 응답할 때 중요하다고 판단하면 [MEMO] 태그를 붙인다. 봇이 파싱해서 자동 저장. 사용자에겐 태그 없는 깨끗한 응답만 보여준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def extract_and_save_memos(response: str) -> str:
    lines = response.split("\n")
    clean_lines = []
    memos = []

    for line in lines:
        if line.strip().startswith("[MEMO]"):
            memo = line.strip()[6:].strip()
            memos.append(memo)
        else:
            clean_lines.append(line)

    for memo in memos:
        # "선호", "항상" 같은 키워드 → 장기 기억
        # 그 외 → 일일 노트
        if any(kw in memo for kw in ["선호", "항상", "기본", "설정"]):
            append_memory(memo)
        else:
            append_daily_note(memo)

    return "\n".join(clean_lines).strip()

2. 장기 기억 (MEMORY.md)

선호도, 프로필, 결정사항. 세션마다 항상 로드된다.

1
2
3
4
5
# WonderX 장기 기억

- [2026-02-06 17:30] 사용자는 conda 환경을 선호한다
- [2026-02-06 17:45] 블로그 프레임워크: Astro + GitHub Pages
- [2026-02-06 18:00] 댓글 시스템: Disqus (게스트 댓글 가능)

수동으로도 넣을 수 있다:

1
/remember conda 환경 이름은 wonderx-bot

3. 일일 노트 (daily/YYYY-MM-DD.md)

오늘 뭘 했는지. 오늘 + 어제 노트만 자동으로 로드된다.

1
2
3
4
5
6
# 2026-02-06 일일 노트

- [17:00] 사용자: 텔레그램 봇 만들어줘
- [17:15] 블로그 SEO 최적화 작업 시작
- [17:30] 카테고리 사이드바 추가
- [18:00] OpenClaw 스타일 메모리 시스템 구현

4. 프롬프트 조합

Claude에게 보내는 구조는 이렇다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[시스템 지시]
너는 WonderX AI 비서야. 게으른 개발자의 비서...

---

[장기 기억]
# WonderX 장기 기억
- conda 선호, Astro 블로그, Disqus 댓글...

[최근 노트]
# 2026-02-06 일일 노트
- 텔레그램 봇 구현, 메모리 시스템 구현...

---

[현재 요청]
아까 만든 메모리 시스템에 검색 기능 추가해줘

이렇게 하면 Claude가 오늘 뭘 했는지 아는 상태에서 답변한다. “아까 그 코드”가 뭔지 안다. 금붕어 탈출이다.

메모리 시스템 동작 화면

OpenClaw vs 내 봇 비교

 OpenClawWonderX Bot
메모리 방식마크다운 파일마크다운 파일 (동일)
자동 저장memory flush + AI 판단[MEMO] 태그 + AI 판단
수동 저장“이거 기억해” 자연어/remember 명령어
비용API 토큰 과금 (Heartbeat에 하룻밤 $20)Max 플랜 포함 ($0)
검색SQLite + 벡터 + BM25 하이브리드오늘/어제만 로드 (심플)
복잡도TypeScript 39개 파일Python 1개 파일 (memory.py)

OpenClaw은 시맨틱 검색, 임베딩, SQLite 인덱스까지 있다. 대단하다. 근데 솔직히 개인 비서 수준에서는 과하다.

오늘/어제 노트 + 장기 기억이면 충분하다. 나중에 필요하면 그때 검색 기능을 붙이면 된다. 오버엔지니어링은 게으름의 적이다.

새 명령어

명령기능
/memory현재 기억 상태 조회
/remember 내용장기 기억에 수동 저장
/clear장기 기억 초기화

삽질 포인트

“기억해야 할 것을 저장해줘”라고 모호하게 쓰면 망한다

처음에 시스템 프롬프트를 대충 썼다. Claude가 뭘 저장해야 할지 몰라서 아무것도 안 저장하거나, 쓸데없는 걸 저장했다.

[MEMO]라는 명확한 포맷을 정해주고, 예시를 주니까 바로 잘 됐다. AI한테 모호하게 시키면 모호한 결과가 나온다. 당연한 건데 매번 잊는다.

장기 vs 일일 분류를 잘해야 한다

“사용자는 conda를 선호한다” → 장기 기억 “오늘 블로그 배포했다” → 일일 노트

이걸 잘못 분류하면 장기 기억이 쓸데없는 정보로 오염된다. 키워드 기반 분류가 완벽하진 않지만, 80%는 맞는다. 나머지 20%는 수동으로 고친다.

다음 편 예고

  • 스케줄링 & Heartbeat: 매일 아침 상태 알림, 블로그 빌드 체크 자동화
  • OpenClaw에서 제일 인기 있는 기능이다. 이게 되면 진짜 “자동 비서”가 된다

기억 없는 AI는 도구다. 기억하는 AI는 동료가 된다.


전체 코드는 비공개 레포에 있다. 궁금한 건 x@wonderx.co.kr로.

This post is licensed under CC BY 4.0 by the author.