RL RanceLee Tutorials
← 튜토리얼로 돌아가기

Karpathy 스타일 위키를 재사용 가능한 스킬로 전환하기

지난 며칠 동안 이 스킬을 작동시키는 데 정말 고생했습니다.

Opus 4.6으로 시작했습니다. 20달러 이상을 썼는데도 작동하지 않았습니다. 2026년 4월 8일 아침에 출시된 새 모델이 모든 컴퓨팅 자원을 다 잡아먹은 건 아닌지 의심하기도 했습니다. 그렇지 않으면 한순간에 이해하다가도 다음 순간에 엉뚱한 방향으로 갈 리가 없으니까요.

나중에 Codex로 전환했고, 겨우 만들 수 있었습니다.

하지만 새로운 문제가 생겼습니다. 만든다고 해서 안정적으로 작동하는 건 아니라는 점이었습니다.

특히 진지하게 테스트하기 시작하면 가끔 지시를 무시하고 마음대로 변경하는 일이 발생했고, 정말 미칠 노릇이었습니다.

그래서 이 글에서는 단순히 “스킬을 만들었으니 다운로드하세요"라고 말하고 싶지 않습니다.

대신 다른 점을 분명히 하고 싶습니다. Karpathy가 제안한 LLM Wiki 방법을 Obsidian 볼트에서 실제로 구현하는 방법입니다.

이전 장에서는 방법을 다뤘습니다. 이번 장은 실전입니다.

현재 제 스킬의 민감 정보를 제거한 버전을 다운로드하고 싶다면 다음 링크를 이용하세요:

https://blog.discoverlabs.ac.cn/downloads/obsidian-wiki-skill/

API 키, 로컬 경로 등은 이미 제거했습니다. 하지만 미리 말씀드리자면, 그대로 복사하지 마세요.

이 방법에서 배울 수 있습니다. 이 스킬을 수정할 수도 있습니다. 하지만 그대로 바로 작동할 거라고 기대하지 마세요. 모든 사람의 노트 볼트는 너무 다릅니다.


내가 만든 것은 “AI가 노트를 정리하는 것"이 아니라 “AI가 장부 정리를 하는 것”

먼저 Karpathy의 Gist를 다시 살펴보겠습니다.

원본 링크:

https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f

핵심 아이디어는 사실 간단합니다.

현재 대부분의 사람들은 RAG를 통해 LLM으로 문서를 처리합니다. 파일을 한꺼번에 넣고, 질의할 때 검색해서 즉석에서 답변을 생성합니다.

물론 그렇게도 작동합니다.

하지만 문제는 모두 임시방편이라는 점입니다.

한 번 물어보면 한 번 조합합니다. 다시 물어보면 처음부터 다시 시작합니다. 축적이 없습니다.

그래서 그는 중간 계층을 제안했습니다. 매 질의마다 즉석에서 답변을 조합하지 말고, 지속적으로 Wiki를 유지 관리하라는 것입니다.

이 글을 읽었을 때 제 첫 반응은 “멋지다"가 아니었습니다.

이거야말로 Obsidian이 가장 잘하는 작업 아닌가? 였습니다.

Obsidian은 본질적으로 로컬 Markdown 파일 볼트이기 때문입니다.

Karpathy가 설명하는 Wiki는 기본적으로 Markdown 파일 모음입니다.

기본 형식이 거의 동일합니다.

차이점은 다음과 같습니다.

  • 예전에는 백링크, 주제 페이지, 구조 페이지를 수동으로 유지 관리했습니다.
  • 이제 AI가 이 “장부 정리” 작업을 도와줍니다.

참고: 장부 정리이지, 생각하는 것이 아닙니다.

점점 더 이 의견에 동의하게 됩니다.

글을 읽고, 판단하고, 자신의 의견을 쓰는 것은 여전히 여러분이 할 일입니다.

하지만 백링크 완성, 작성자 이름 정규화, 형식 확인, 파생 페이지 갱신 같은 작업은 본질적으로 잡일입니다. AI가 처리할 수 있습니다.


Obsidian에서 Karpathy의 3계층 구조를 구현한 방법

Karpathy 방법에서 가장 중요한 부분은 세 가지 계층입니다.

  • 원시 소스(Raw Sources)
  • 위키(The Wiki)
  • 스키마(The Schema)

obsidian-wiki 스킬도 이 세 가지 계층을 기반으로 구축되었습니다.

첫 번째 계층: 원시 소스

제 볼트에서 이 계층은 다음으로 구성됩니다.

  • 01-Notes/
  • 04-Output/

즉, 원시 수집물, 원시 노트, 제가 쓴 글입니다.

이 계층을 매우 절제해서 유지합니다.

이 계층의 유일한 책임은 원본 콘텐츠를 보존하는 것입니다.

추가 기능을 부여하지 않습니다.

파생 콘텐츠를 섞지 않습니다.

원시 글이 반은 주제 페이지, 반은 색인 페이지가 되도록 두지 않습니다.

한번 섞이면 유지 관리가 어려워지기 때문입니다.

이 스킬을 만들면서 배운 가장 깊은 교훈 중 하나입니다. 원시 계층이 깨끗할수록 다른 모든 것이 쉬워집니다.

두 번째 계층: 위키

이 계층은 제 볼트에서 별도로 분리되어 있습니다.

01-Notes/wiki/

여기에는 AI가 파생한 구조 계층이 들어갑니다. 예를 들면:

  • 작성자 페이지
  • 주제 페이지
  • 색인
  • 로그
  • 백링크 디렉터리

즉, 원문은 원문 그대로입니다.

위키는 위키입니다.

두 계층은 분리되어 있습니다.

사소해 보이지만 실제로 매우 중요합니다.

계층을 분리하지 않으면 AI가 정리할 때마다 원문이 더 지저분해지는 경향이 있기 때문입니다.

오늘은 주제 블록을 추가합니다.

내일은 색인을 삽입합니다.

모레는 자동 생성된 요약을 추가합니다.

결국 볼트 전체가 계속 치우는데도 더 지저분해지는 방이 됩니다.

세 번째 계층: 스키마

많은 사람들이 이 계층을 간과합니다.

Karpathy는 원문에서 스키마를 언급합니다. 제 이해는 볼트가 어떻게 생겨야 하는지 AI에게 알려줘야 한다는 것입니다.

제 경우에는 다음이 포함됩니다.

  • SKILL.md
  • 여러 scripts/
  • 프론트매터 규칙
  • 작성자와 주제 작성 방식에 대한 제약
  • lint와 ingest에 대한 프로세스 제약

예를 들어, 현재 다음과 같은 규칙을 적용하고 있습니다.

  • 작성자는 백링크 형식이어야 함
  • 주제는 백링크 목록이어야 함
  • 작성자 페이지와 주제 페이지는 오직 01-Notes/wiki/에만 위치해야 함
  • 00-Inbox/는 처리용 인박스일 뿐, 위키에 직접 섞이지 않음
  • 원시 글에는 더 이상 파생 문단이 포함되지 않음

알게 되겠지만, 스킬이 작동하게 만드는 것은 프롬프트가 얼마나 아름답게 쓰였느냐가 아닙니다. 진짜 핵심은 이러한 제약이 먼저 확립되어 있다는 점입니다.


세 가지 작업을 실행 가능한 워크플로로 변환하기

Karpathy는 또한 세 가지 핵심 작업을 제시합니다.

  • Ingest
  • Query
  • Lint

저도 같은 방식을 따랐습니다.

이 스킬의 실제 워크플로는 다음과 같습니다.

  • Ingest: wiki_lint.py --preflight + ob_shuanglian.py suggest/apply + wiki_ingest.py
  • Query: 먼저 wiki/index.md, authors/*.md, topics/*.md를 읽고, 필요하면 원문으로 돌아가 세부 내용 확인
  • Lint: wiki_lint.py, wiki_migrate.py, wiki_build_skeleton.py

Ingest: 새 콘텐츠를 볼트에 추가하기 전에 검사

AI가 “글을 보고 즉흥적으로 처리"하도록 두지 않습니다.

현재 워크플로는 사전 점검(preflight)으로 시작합니다.

먼저 프론트매터가 올바른지 확인합니다.

그다음 과거 오염(historical contamination)이 있는지 확인합니다.

그다음 백링크 제안을 만듭니다.

사용자가 확인한 후에야 실제로 적용합니다.

마지막으로 위키 파생 계층을 갱신합니다.

왜 이렇게 번거롭게 할까요?

모델이 여러 번 가르쳐줬기 때문입니다.

이런 가드레일을 추가하지 않으면, 모델이 열심히 “결정"을 내릴 것입니다.

문제는 그 결정이 여러분이 원하는 것이 아닐 수 있다는 점입니다.

그래서 강력한 확인 게이트를 추가했습니다.

주제를 마음대로 쓰지 못하게 합니다.

백링크를 바로 적용하지 못하게 합니다.

작성자 별칭을 스스로 결정하지 못하게 합니다.

제안을 하고, 제가 확인한 후에 씁니다.

덜 효율적으로 보일 수 있습니다.

하지만 지식 베이스에서 가장 두려운 것은 느린 것이 아니라 조용히 잘못된 것을 쓰는 것입니다.

Query: 원문의 바다에서 낚시하는 것이 아니라 먼저 위키 계층을 읽기

쿼리의 경우, 제 접근 방식은 “볼트 전체를 검색해서 AI에게 요약하라고 넘기는 것"이 아닙니다.

대신 먼저 다음을 거칩니다.

  • wiki/index.md
  • authors/*.md
  • topics/*.md

AI가 먼저 구조화된 계층을 보게 합니다.

필요할 때만 특정 글로 돌아가 세부 내용을 확인합니다.

장점은 분명합니다.

매번 흩어진 원문에서 다시 조합할 필요가 없습니다.

대신 이미 정리된 계층에서 답변합니다.

이는 Karpathy가 말하는 “축적"에 더 가깝습니다.

Lint: 가장 중요하면서도 가장 과소평가된 단계

많은 사람들이 LLM Wiki를 보면 Query에 집중합니다.

하지만 작업을 하면 할수록 Lint가 진정한 가치가 있는 곳이라는 생각이 듭니다.

지식 베이스가 커지면 가장 큰 골칫거리는 “답을 얻을 수 없다"가 아니라 다음과 같은 것들입니다.

  • 프론트매터가 엉망
  • 작성자 이름이 일관되지 않음
  • 주제가 분산됨
  • 원문에 역사적 구조가 남아 있음
  • 파생 페이지가 점점 왜곡됨
  • 같은 개념이 여러 다른 이름으로 나타남

이런 것들을 수동으로 유지 관리하려고 하면 정말 미칠 노릇입니다.

계속할 수도 없습니다.

바로 이것이 AI가 가장 잘하는 일입니다.

여러분을 대신해 세상을 이해하는 것이 아닙니다.

하지만 볼트를 순찰하고, 대조하고, 더티 데이터를 찾고, 상호 참조를 채워 넣는 것입니다.

그래서 Karpathy의 용어가 매우 적절합니다. 장부 정리(bookkeeping).


진짜 함정은 모델이 아니라, 내 오래된 노트 볼트

이것이 제가 가장 강조하고 싶은 점입니다.

많은 사람들이 이런 글을 읽고 본능적으로 생각합니다.

“아, 스킬을 다운로드해서 설치하면 AI가 내 지식 베이스를 관리해 주겠구나.”

그렇지 않습니다.

이 스킬의 가장 큰 도전 과제는 프롬프트, 스크립트, 심지어 모델도 아닙니다.

바로 오래된 노트가 너무 많고, 그 형식이 일관되지 않다는 점입니다.

지금 lint를 실행하면 다음과 같은 규모가 보입니다.

  • 글 유형 원시 소스: 457개
  • 전체 원시 파일: 833개
  • 대기열: 249개
  • 백링크 디렉터리에는 이미 471개의 주제가 있음

그 규모를 생각해 보세요.

이제는 “몇 개 노트를 정리하는” 수준이 아닙니다.

오히려 오랜 역사를 가졌지만 일관된 기준이 없는 낡은 시스템을 인수하는 것과 비슷합니다.

어떤 글은 전체 작성자 이름이 있습니다.

어떤 글은 별칭이 있습니다.

어떤 주제는 매우 상세합니다.

어떤 주제는 매우 분산되어 있습니다.

일부 오래된 파일에는 이전 구조의 잔재가 여전히 남아 있습니다.

그래서 점점 한 가지가 확실해졌습니다.

LLM Wiki를 구축하려면 첫 단계는 AI가 인수하도록 두는 것이 아닙니다. 첫 단계는 볼트를 “인수할 가치가 있는” 상태로 청소하는 것입니다.

그렇지 않으면 AI가 부지런할수록 엉망을 더 퍼뜨리게 됩니다.


그렇다면 이 스킬이 실제로 추가로 하는 일은 무엇인가?

Karpathy의 원문만 읽으면 매우 우아한 방법론이라고 생각할 것입니다.

하지만 실제로 구축하면서 채워야 할 많은 엔지니어링 세부 사항을 발견했습니다.

예를 들어:

  • 프론트매터 표준화
  • 작성자 별칭 정규화
  • 주제에 백링크 형식 강제
  • 원시 계층과 파생 계층 완전 분리
  • 00-Inbox/를 처리용 인박스로 사용
  • 주요 단계에 사용자 확인 게이트 추가
  • lint, migrate, ingest 같은 스크립트로 워크플로 분할

Karpathy가 이런 점을 생각하지 못한 것은 아닙니다.

그의 Gist는 패턴을 설명하는 것이지, 여러분의 볼트에 맞는 구체적인 구현을 설명하는 것이 아닙니다.

실제로 구현할 때는 이 계층을 직접 채워야 합니다.

현재 제 obsidian-wiki 스킬이 본질적으로 하는 일은 이것입니다.

추상적인 패턴을 제 Obsidian 볼트에서 실행되는 워크플로로 변환하는 것.

따라서 다운로드한다면 가장 중요한 것은 “내 디렉터리 구조를 복사하는 것"이 아닙니다.

왜 이렇게 계층을 나눴는지, 왜 여기서 확인이 필요한지, 왜 여기서 lint를 하는지, 왜 여기서 자동 적용을 사용하지 않는지를 이해하는 것입니다.


직접 해보고 싶다면, 먼저 이것들을 수정하세요

민감 정보를 제거한 버전을 제 블로그 다운로드 페이지에 올렸습니다.

https://blog.discoverlabs.ac.cn/downloads/obsidian-wiki-skill/

하지만 다운로드 후 가장 먼저 할 일은 실행하는 것이 아닙니다.

수정하는 것입니다.

적어도 다음 사항을 확인하세요.

  1. 볼트 경로가 제 경로와 동일한가?
  2. 01-Notes/, 04-Output/, 00-Inbox/ 구조가 동일한가?
  3. 프론트매터 필드가 제 것과 일관된가?
  4. 작성자 이름과 주제 이름이 이미 상당히 일관된가?
  5. “제안, 확인, 기록” 워크플로를 유지하고 싶은가?
  6. 스크립트에 API가 관련되어 있다면 자신의 키로 교체했는가?

제가 공개한 버전은 API 키와 로컬 경로를 이미 제거했습니다.

받은 후에는 자신의 환경에 맞게 조정해야 합니다.

그리고 여전히 권장합니다. 제 방법을 템플릿으로 취급하지 말고 참고 자료로만 사용하세요.

볼트가 주로 독서 노트라면 규칙이 제 것과 다를 수 있습니다.

볼트가 주로 프로젝트 노트라면 주제의 세분화 수준이 다를 것입니다.

볼트가 아직 “일단 모으고 나중에 정리” 단계라면 Query보다는 Lint와 Ingest를 먼저 안정적으로 만드는 데 집중해야 할 것입니다.

그러니 그대로 복사하지 마세요.

접근 방식을 바탕으로 수정하는 것이 더 안정적입니다.


요약

이 글을 마무리하면서 제 자신의 느낌이 더 분명해졌습니다.

Karpathy의 제안은 단순히 “AI가 지식 베이스를 정리하는 데 도움을 줄 수 있다"는 아이디어가 아닙니다.

그 진정한 가치는 지식 관리에서 인간과 AI의 역할 분담을 재정의했다는 점입니다.

인간은 판단을 담당합니다.

AI는 장부 정리를 담당합니다.

이 작업을 하면 할수록 그 말이 더 믿어집니다.

오늘 배운 점:

  1. Karpathy의 LLM Wiki 핵심은 세 가지 계층 구조와 세 가지 작업이지, 단일 프롬프트가 아니다
  2. obsidian-wiki 같은 스킬의 핵심은 “요약을 잘하느냐"가 아니라 Raw Sources, Wiki, Schema를 분리할 수 있느냐이다
  3. 실제로는 Lint가 Query보다 더 중요한 경우가 많다. 역사적 데이터 정리가 작업의 대부분이기 때문이다
  4. 오래된 노트가 많고 형식이 엉망일수록 다른 사람의 스킬을 그대로 복사해서는 안 된다
  5. 스킬을 다운로드하는 것은 쉽다. 진짜 도전은 자신의 지식 베이스에 맞게 조정하는 것이다

핵심 정리:

  • AI는 생각을 대신하는 것이 아니라 장부 정리에 가장 적합하다
  • 원시 계층과 파생 계층은 반드시 분리해야 한다. 그렇지 않으면 정리할수록 지식 베이스가 더 엉망이 된다
  • 사용자 확인 게이트는 추가 단계가 아니라 AI가 마음대로 행동하지 못하게 하는 필수 가드레일이다
  • 형식을 먼저 표준화한 후에 자동화를 논하라. 순서를 바꾸면 나중에 고생한다
  • 이 스킬은 수정할 수 있지만, 그대로 복사하는 것은 권장하지 않는다