에이전트 메모리 엔진 (8/10) — Karpathy의 LLM Wiki를 실전에 적용하기
Andrej Karpathy가 제안한 18개 기능 중 17개를 구현하고, 6개를 추가한 구현 기록
핵심 요약
- Karpathy가 공유한 LLM Wiki 아이디어를 OpenClaw 에이전트 플랫폼에 전면 적용했다
- 원문 18개 기능 중 17개를 구현하고, 실전 운영에서 발견한 필요를 해결한 독자 기능 6개를 추가했다
- RAG처럼 매번 검색하는 대신, LLM이 영구적인 위키를 점진적으로 구축하고 유지하는 패러다임
LLM Wiki란 무엇인가
Andrej Karpathy가 공개한 LLM Wiki 개념의 핵심은 간단하다. RAG처럼 매번 외부 문서를 검색하는 대신, LLM 스스로 구조화된 마크다운 위키를 점진적으로 구축하고 유지한다.
위키는 세 가지 동작으로 운영된다.
- Ingest: 원본 자료(raw sources)를 받아 위키 페이지에 반영. 연관 페이지를 연쇄 업데이트.
- Query: 위키를 기반으로 질의응답. 답변 중 발견한 지식 공백을 위키에 승격.
- Lint: 위키 전체를 검사. 모순·공백·오래된 정보를 탐지하고 정리.
이 세 동작이 루프를 이루면, 지식 베이스는 사람 개입 없이 스스로 정제된다.
본문
1. Karpathy 원문 18개 기능 vs OpenClaw 구현
| # | Karpathy 기능 | OpenClaw 구현 | 상태 |
|---|---|---|---|
| 1 | Raw Sources (불변 원본) | memory/ + docs/manuals/ | ✅ |
| 2 | Wiki (LLM 유지 마크다운) | bank/ 다수 파일 Context Tree | ✅ |
| 3 | Schema (설정 공진화) | tree-index.json + AGENTS.md | ✅ |
| 4 | Ingest 연쇄 업데이트 | retain-merge cascade_update | ✅ |
| 5 | Ingest 인터랙티브 | source-ingest.py --interactive | ✅ |
| 6 | 외부 소스 자동 Ingest | source-ingest.py --url/--file | ✅ |
| 7 | Query (위키 기반 답변) | recall-tree.py BM25 하이브리드 | ✅ |
| 8 | Query→Wiki 승격 | recall-tree.py --promote | ✅ |
| 9 | LLM 리랭킹 | recall-tree.py --rerank (oMLX gemma-4) | ✅ |
| 10 | Lint 기본 | bank-lint + memory-warning-report | ✅ |
| 11 | Lint 탐색 제안 | exploration.page_gap_suggestions | ✅ |
| 12 | Lint 미해결 모순 추적 | exploration.unresolved_contradictions | ✅ |
| 13 | index.md (카탈로그) | tree-index.json (전체 파일 색인) | ✅ |
| 14 | log.md (시간순 기록) | _meta/changelog.md | ✅ |
| 15 | Git 버전 관리 | git tracked | ✅ |
| 16 | Schema 공진화 | self-review 크론 자동 갱신 | ✅ |
| 17 | 배치 vs 인터랙티브 토글 | 기본=1건, Reflect=배치 | ✅ |
| 18 | Obsidian 그래프 뷰 | N/A (CLI 환경) | — |
17/18 구현. 유일하게 구현하지 않은 것은 Obsidian 그래프 뷰인데, CLI 환경이라 해당 사항이 없다.
2. Ingest / Query / Lint 동작의 실제 구현
세 동작 각각을 어떻게 구현했는지 구체적으로 설명한다.
Ingest
def ingest(source, interactive=False):
content = fetch(source)
tags = TAG_ROUTING.classify(content) # 결정론적 정규표현식 분류
target_files = resolve_targets(tags) # W/B/O/S → 대상 파일 결정
for f in target_files:
cascade_update(f, content) # 연쇄 업데이트
changelog.append(source, tags)
TAG_ROUTING은 W(세계 사실) / B(활동) / O(의견) / S(상태) 4가지 태그를 정규표현식 키워드로 분류한다. LLM 판단 대신 결정론적 규칙을 택한 이유는 아래 시행착오 섹션에서 설명한다.
Query
def query(q, rerank=False, promote=False):
candidates = bm25_hybrid_search(q) # BM25 + 키워드 하이브리드
if rerank:
candidates = llm_rerank(candidates, model="oMLX/gemma-4")
answer = generate_answer(q, candidates)
if promote and has_knowledge_gap(answer):
wiki.create_stub(q) # 공백 → 위키 신규 페이지 생성
return answer
한국어 교착어 처리가 핵심이다. "가치관이" → "가치관" 형태소 처리를 BM25 색인 단계에서 적용한다. 영어 중심 검색 라이브러리에서는 기본 제공하지 않는다.
Lint
lint_checks = [
check_contradictions, # 미해결 모순 탐지
check_page_gaps, # 링크는 있으나 페이지 없는 공백 탐지
check_stale_entries, # confidence-decay 임계값 이하 항목
check_orphan_pages, # 어디서도 참조되지 않는 페이지
check_data_gaps, # 수치 있으나 출처 없는 항목
]
Lint는 수동 실행과 자동 실행 두 가지로 운영한다. Reflect 크론(03:00)이 전체 Lint를 배치로 수행하고, micro-cycle(30분)이 경량 버전을 실행한다.
3. Karpathy에 없는 OpenClaw 독자 기능 6가지
실전 운영에서 원문이 다루지 않는 문제를 발견하고 추가한 기능들이다.
1. confidence-decay (의견 신뢰도 감쇠)
의견(opinions) 파일에 신뢰도 점수를 부여하고 자동 감쇠한다. 하루에 -0.02씩 감소하고, 0.30 미만이면 자동 삭제된다. Karpathy는 "모순 감지"만 언급했지만, 의견의 시간적 가치를 수치화하는 것은 별개 문제다. 오래된 의견과 최신 의견은 같은 무게를 가져서는 안 된다.
2. fuzzy dedup (유사 중복 방지)
80% 키워드 오버랩 기준으로 중복 축적을 방지한다. "Flutter 상태 관리가 좋다"와 "Flutter의 state management가 좋다"는 표현만 다른 동일 내용이지만, exact match로는 중복을 잡을 수 없다.
3. TAG_ROUTING (결정론적 태그 라우팅)
W/B/O/S 태그를 정규표현식 키워드로 자동 분류해 대상 파일을 결정한다. "도구 변경" → world/tools.md, "프로젝트" → world/projects.md. LLM 판단 대신 결정론적 규칙을 쓰는 이유는 분류 안정성 때문이다.
4. proactive briefing (자율 브리핑)
다수 모드의 proactive briefing으로 위키 내용을 기반으로 능동적으로 정보를 제공하는 시스템이다. 대화 컨텍스트 기반 모드를 포함한다. 위키는 수동으로 검색되는 것만이 아니라, 능동적으로 정보를 제공할 수 있어야 한다.
5. 3계층 자동 증류 파이프라인
memory/(일일 로그) → bank/(큐레이션 지식) → recall/(검색 버퍼) 3단계가 자동 운영된다. Reflect(매일 03:00 전체 증류)와 micro-cycle(30분 경량 증류)이 사람 개입 없이 지식을 정제한다.
6. 한국어 교착어 BM25 부분 매칭
"가치관이" → "가치관" 형태소 처리. 영어 중심 검색 시스템에서는 기본 제공하지 않는 기능이다.
4. RAG vs Wiki 패러다임의 차이
RAG 방식: 질문 → 벡터 검색 → 상위 N개 chunk 반환 → LLM 답변 - 장점: 구축이 간단 - 단점: 검색 실패 시 답변 품질 급락. 지식이 축적되지 않음
Wiki 방식: LLM이 지식을 구조화된 마크다운에 직접 기록 → 검색 시 구조화된 파일에서 탐색 - 장점: 지식이 점진적으로 정제됨. 구조가 있어서 검색 정밀도 높음 - 단점: 초기 구축에 시간 필요. 유지보수 파이프라인 필요
Wiki 방식이 장기 운영에서 압도적으로 유리한 이유는 지식의 누적 정제다. RAG는 매 쿼리마다 원시 청크를 탐색하지만, Wiki는 이전 Ingest·Query·Lint가 쌓아 올린 정제된 구조를 탐색한다. 동일한 질문에 대한 답변 품질이 운영이 길어질수록 개선된다.
5. 실측 수치
| 항목 | 수치 |
|---|---|
| 검색 정밀도 | 10/10 자연어 쿼리 |
| 파일 크기 | 최대 46KB → 10.6KB (75% 감소) |
| 중복 축적 | fuzzy dedup 후 0건 |
| 토픽 커버리지 | 주요 토픽 전반 100% |
| memory-warning | 다수 → 소수 |
| LLM 정확도 (Gemma 4) | 16/16 (100%) |
시행착오
처음부터 Wiki를 설계하지 않았다: 단일 파일에 지식을 축적하다 46KB까지 비대해진 후에야 구조화의 필요성을 인식했다. Karpathy의 프레임워크를 참고해 schema를 먼저 설계하고, 기존 파일을 역방향으로 분해·재분류하는 작업이 필요했다.
LLM 의존도 과신: 초기에는 태그 분류도 LLM에 맡겼지만, 비결정론적 결과로 인해 같은 입력이 다른 파일에 라우팅되는 문제가 있었다. TAG_ROUTING으로 결정론적 규칙을 도입한 후 안정화되었다.
OpenClaw → Hermes 마이그레이션 과정의 교훈: OpenClaw가 안정 운영 중일 때 Hermes로 마이그레이션을 시도했으나 토큰 폭주가 발생했다. OpenClaw로 복귀 후 현재 Hermes 재설계를 검증 중이다. Wiki 시스템은 이 과정에서 플랫폼 독립적으로 유지되어야 한다는 점을 확인했다.
마무리
Karpathy의 LLM Wiki는 Ingest / Query / Lint 세 동작의 루프로 작동한다. 이 구조를 실전에 적용하면 RAG 방식으로는 도달할 수 없는 수준의 지식 정제와 검색 정밀도를 달성할 수 있다. 핵심은 아이디어를 그대로 복사하는 것이 아니라, 자신의 환경(언어, 운영 방식, 데이터 특성)에 맞게 재설계하는 것이다.
시리즈 전체 안내: 시리즈 목차
댓글
댓글 쓰기