
Andrej Karpathy가 2026년 4월, LLM으로 개인 지식 베이스를 구축하는 방법을 공유했다. 논문과 아티클을 raw/에 쌓으면 LLM이 알아서 위키로 컴파일한다는 아이디어였다. 나는 그 아이디어를 Claude Code와 Python으로 직접 구현해봤다.
왜 만들었나
Karpathy의 워크플로우는 간단하다. 원본 자료를 raw/ 디렉토리에 넣으면 LLM이 읽고 마크다운 위키로 "컴파일"한다. RAG 없이, 벡터 DB 없이, 인덱스 파일과 문서 요약만으로 충분하다고 했다.
그런데 그가 "스크립트를 엮어 만든 임시방편적인 솔루션"이라 부른 그 파이프라인을 실제로 구현하면 어떻게 될까. 나는 Castle이라는 이름으로 직접 만들어봤다.
시스템 구조
├── CLAUDE.md # Claude Code 운영 지침 (5가지 작동 모드)
├── raw/ # 임시메모 — 사람이 수집한 원본
│ └── .processed # 처리 완료 목록 (incremental build)
├── wiki/ # 영구메모 — LLM이 컴파일한 결과
│ ├── _index.md # 마스터 인덱스 (토큰 절감 핵심)
│ ├── _log.md # 컴파일 로그
│ └── [클러스터]/ # 개념별 서브디렉토리
├── archive/ # 처리된 raw 보관 (삭제 금지)
├── output/ # Q&A 결과물, 린트 리포트
└── tools/
├── compile.py # raw/ → wiki/ 컴파일
├── search.py # 인덱스 기반 검색엔진
├── lint.py # 상태 점검
└── doku2obsidian.py # DokuWiki 자동 변환
핵심 원칙은 세 가지다.
summary 필드를 캐싱해두면 LLM이 전문을 읽지 않고 _index.md만 훑어도 전체 맥락을 파악할 수 있다.만든 도구들
① compile.py — 증분 컴파일러
raw/에 새 파일이 들어오면 .processed 목록과 대조해 미처리 파일만 골라낸다. 소스코드 빌드의 incremental build와 같은 구조다. LLM이 delta만 처리하므로 위키가 커져도 매번 전체를 재처리하지 않는다.
python tools/compile.py # 미처리 파일 전체 처리
python tools/compile.py --dry-run # 처리 대상만 미리보기
python tools/compile.py --file raw/파일.md # 특정 파일만
컴파일 결과 각 영구메모에는 아래 프론트매터가 자동으로 붙는다.
---
zettel: 0001a1
title: "제목"
summary: "한 줄 요약 — _index.md에 캐싱"
tags: [llm, zettelkasten]
links: []
backlinks: []
created: 2026-04-10
source: "raw/원본파일.md"
---
NNNN[a-z][0-9] 형식 (예: 0001a1, 0001b1). 순서번호(4자리) + 가지(알파벳) + 파생(숫자). 새 독립 개념은 새 번호, 기존 개념의 파생은 같은 번호에 가지를 늘린다. 루만의 제텔카스텐 인덱싱 방식을 그대로 따랐다.② search.py — 2단계 검색엔진
질문이 들어오면 먼저 _index.md의 요약과 태그로 1차 필터링한다. 그다음 필터링된 파일만 전문을 읽는다. LLM에 위키 전체를 던지는 대신, 관련 가능성이 있는 파일만 컨텍스트에 넣는 구조다.
python tools/search.py --query "RAG 인덱스" # 인덱스 기반 검색
python tools/search.py --query "드래곤" --full # 전문 검색 (폴백 포함)
python tools/search.py --tag "novel" # 태그 필터링
python tools/search.py --list # 전체 노트 목록
인덱스에서 매칭이 없으면 자동으로 전문 검색(full scan)으로 폴백한다. "RAG 없이 충분하다"가 아니라 "인덱스가 RAG를 경량으로 대체한다"는 것이 정확한 표현이다.
③ lint.py — 자가 치유 점검
위키가 커질수록 조용히 망가지는 것들이 생긴다. lint.py는 주기적으로 이를 잡아낸다.
| 점검 항목 | 설명 |
|---|---|
| 고립 노트 | 어디서도 링크되지 않는 노트 |
| 끊어진 링크 | [[링크]]가 실제 파일로 연결되지 않음 |
| 중복 zettel | 같은 코드가 두 개 이상 존재 |
| summary 누락 | 프론트매터에 요약 없는 노트 |
| archive 미완료 | .processed에 있지만 archive/로 이동 안 된 파일 |
python tools/lint.py # 전체 점검
python tools/lint.py --fix # 자동 수정 가능한 항목 처리
python tools/lint.py --report # output/에 리포트 저장
④ doku2obsidian.py — 포맷 자동 감지·변환
raw/에 DokuWiki로 작성된 문서를 넣으면 compile.py가 자동으로 감지해 Obsidian 마크다운으로 변환한 뒤 컴파일한다. 별도로 신경 쓸 필요가 없다.
감지 기준은 7가지 패턴의 점수 합산이다. 3점 이상이면 DokuWiki로 판정한다.
| 점수 | 패턴 | 예시 |
|---|---|---|
| 3점 | 헤딩 | ====== 제목 ====== |
| 3점 | 테이블 헤더 | ^ 항목 ^ 내용 ^ |
| 3점 | 이미지 | {{ :path:image.png?400|}} |
| 2점 | 코드블록 | <code>...</code> |
| 2점 | 고정폭 | ''텍스트'' |
| 1점 | 이탤릭 | //텍스트// |
| 1점 | 들여쓰기 목록 | * 항목 |
<code> 블록은 내용에 따라 다르게 변환된다. 대화문이면 > [!quote] 콜아웃, 아스키 다이어그램이면 코드블록, 짧은 개념어면 인용 블록으로.
python tools/doku2obsidian.py 파일.md --check # 감지만 (점수 출력)
python tools/doku2obsidian.py --scan # raw/ 전체 스캔
python tools/doku2obsidian.py --scan --convert # 스캔 + 일괄 변환
실제 사용 흐름
raw/에 넣는다. DokuWiki든 일반 마크다운이든 상관없다.python tools/compile.py 실행. DokuWiki 파일은 자동 변환 후 컴파일. 클러스터(폴더)도 키워드 기반으로 자동 분류된다. 소설 캐릭터는 novel/characters/, LLM 관련 노트는 ai-llm/으로.python tools/search.py --query "키워드"로 검색. 또는 Claude Code를 열고 /질문 궁금한 것을 입력하면 CLAUDE.md의 지침에 따라 _index.md부터 읽고 관련 노트를 찾아 답한다.python tools/lint.py로 상태 점검. 고립된 노트, 끊어진 링크를 잡아내고 output/에 리포트를 저장한다.Karpathy 방식과 뭐가 다른가
| Karpathy 원본 | Castle | |
|---|---|---|
| raw 보관 | 영구 보존 | archive/ 이동 (삭제 금지) |
| 인덱싱 | 중앙집중식 index.md | 각 노트 프론트매터 분산 캐싱 |
| 클러스터 | 수동 디렉토리 설계 | 키워드 기반 자동 분류 |
| 포맷 지원 | 마크다운 전용 | DokuWiki 자동 감지·변환 포함 |
| 상태 점검 | 수동 또는 LLM 요청 | lint.py 자동화 |
| 토큰 전략 | 인덱스 전체 독해 | summary 필드로 1차 필터링 |
Karpathy 본인이 "스크립트를 엮어 만든 임시방편적인 솔루션"이라 인정했다. Castle은 그 임시방편을 조금 더 체계적으로 만든 것에 가깝다. 핵심 아이디어는 그의 것이다.
CLAUDE.md — Claude Code를 IDE로 쓰는 방법
Castle 디렉토리에 CLAUDE.md를 두면 Claude Code가 매번 자동으로 읽는다. 여기에 5가지 작동 모드를 정의했다.
| 모드 | 명령 | 동작 |
|---|---|---|
| 컴파일 | /컴파일 |
raw/ delta 처리 → wiki/ 영구메모 생성 |
| 탐색 | /탐색 [노트제목] |
노트 분석 + wiki/ 연결 후보 5개 제안 |
| Q&A | /질문 [질문] |
_index.md 기반 질의응답 → output/ 저장 |
| 린트 | /린트 |
불일치·고립·누락 탐지 및 수정 |
| 아카이브 | /아카이브 |
처리 완료 raw 파일 archive/로 이동 |
Claude Code가 이 지침을 읽으면 "사람은 수집만, 나머지는 내가 한다"는 원칙대로 작동한다. Karpathy가 말한 LLM 주도 위키 관리가 실제로 돌아가는 방식이다.
'Programing & OS' 카테고리의 다른 글
| 맥북 2015 우분투 설치하기 - 오픈클로 설치를 위한 (0) | 2026.04.13 |
|---|---|
| N100 백업 시스템 설계 — HDD는 어떻게 선택하고 운영해야 하는가 (0) | 2026.04.12 |
| dokuwiki에서 obsidian까지 LLM wiki 만들기 (0) | 2026.04.11 |
| M1 pro 에서 M5 pro로 갈아타면서. (과스펙으로 간다.) (0) | 2026.03.28 |
| n100 기반 내부 서버 자동 라우팅 구조 (Cloudflare + nginx + www 디렉토리) (0) | 2026.03.26 |