LLM Wiki 구축기 - 문서 266개, 저장할 때마다 13종 검사를 통과해야 한다.

한라봉·2026년 10월 6일

LLM Wiki

목록 보기
2/2
post-thumbnail

이번 편은 LLM Wiki 가 왜 필요했고, 어떻게 구축했으며, 홈랩에 어떻게 올렸는지에 대한 이야기다. 원본 패턴과 다르게 간 부분이 꽤 있다.

LLM Wiki 에 대한 정보는 -> LLM Wiki 란 무엇인가?


비서에게 물어보려면, 내 기록부터 정리해야 했다

LFM2.5 글에서 서버에 상주하는 개인비서를 만든다고 작성했다. 시키고 싶은 일 네 가지를 적었는데, 그중 하나가 이거였다.

내 업무를 정리해 둔 RAG 에서 필요한 내용 찾아 주기

내 말을 알아듣는 것보다 중요한 게 있었다. 내가 뭘 해왔는지 비서가 알아야 한다.
예를 들어 공모전에서 뭘 정했는지, 왜 그렇게 결정을 했는지, 행사 예산이 얼마였는지. 이런 걸 모르면 내 일을 맡길 수가 없다.

그래서 내 기록을 정리해 두고 거기서 찾게 하려고 했다. 방식은 당연히 RAG 라고 생각했다.

그런데 질문할 때마다 조각을 새로 찾고, 찾아낸 것들이 서로 이어지지 않았다. 비서가 쓸 기억으로는 맞지 않았다. 내 기록은 몇십만 건이 아니라 수백 건이고, 찾는 내용은 정확해야 한다. 작년 행사 예산을 물었는데 비슷한 숫자를 가져오면 안 된다.

그리고 깨진 강의노트가 있었다

내 옵시디언 볼트는 세 벌이었다. 원본, 내가 조금 손댄 것, 그리고 분류를 다른 LLM 에 맡긴 것. 마지막 것이 문제였다. 정리를 맡겼더니 강의노트가 요약되면서 원문 문장이 사라졌다. 어떤 문서는 제목과 내용이 어긋났고, 서로 다른 자료가 한 파일에 섞여 있었다.

정리를 맡겼는데 자료가 줄었다.

원문을 건드리지 말라는 건 처음부터 정해 둔 규칙이었다. 문제는 그게 사람이 지키는 규칙이었다는 점이다. 맡겨 놓고 결과를 일일이 확인하지 않으면 그대로 깨진다.

원문은 보존한다. 요약이 원문을 대체하지 않는다.

이 한 줄이 지금 내 위키의 1순위 규칙이다. 달라진 건 규칙 자체가 아니라, 그 규칙을 검사한다는 점이다.

정리가 필요했던 이유는 더 있었다.

  • 기술노트, 프로젝트 문서, 활동 기록, 내 이력이 클라우드와 옵시디언에 흩어져 있었다.
  • 자료가 없어서가 아니라 쌓여만 있어서, 필요할 때 찾아 쓰기가 어려웠다.

원본 패턴과 다르게 간 세 가지

Karpathy 의 원문은 PC 한 대 안에서 도는 구조다. 옵시디언을 열어 두고, 그 옆에 에이전트를 띄워 놓고, 같은 폴더를 본다. 나는 세 군데를 바꿨다.

원본 패턴내 구조왜
위키가 있는 곳내 PC 폴더서버의 git 저장소PC 를 꺼도 살아 있어야 한다
접근 방법에이전트가 폴더를 직접 읽고 씀MCP 서버 하나휴대폰, PC, Agent 어디서든 같은 위키를 쓴다
품질 보증가끔 점검(lint)을 시킴저장할 때마다 자동 검사. 검사에서 걸리면 저장 자체를 거부원문이 깨진 경험이 있어서 검사는 자동으로 한다

세 번째가 가장 큰 차이다. 원본 패턴에서 점검은 가끔 돌리는 작업이지만, 내 구조에서는 저장 조건이다.


구조

  지금:  휴대폰 앱, PC, Agent, Claude.ai
  예정:  서버의 Hermes Agent
         │
         │  https://wiki-mcp.example.com/mcp   (Google OAuth, 허용 계정 1개)
         ▼
  Cloudflare ──▶ 라우터(ER7206) ──▶ Nginx Proxy Manager
                                           │
                                           ▼
  라즈베리파이 4             MCP 서버 (읽기 9, 편집 미리보기 11, 저장 1)
                         위키 사본을 RAM(tmpfs)에 올려 둠. 5분마다 받아옴
                                           │ git push (검사를 통과한 변경만)
                                           ▼
  메인 서버                git 저장소(원본), 읽기 전용 사본, 보관소, 매일 백업

들어오는 길을 하나로 뒀다. 어디서 접속하든 같은 주소로 같은 위키를 본다. 각자 복사본을 들고 있지 않는다. 지금은 Claude 에 MCP 로 연결하여 사용하고 있다.

라즈베리파이 4 에는 SSD 가 장착되어 있지 않다. SD카드 수명 때문에 위키 사본은 RAM 에 둔다. 재부팅하면 비워지고 다시 받아온다.


폴더 둘, 파일 하나를 내 구조로 옮기면

LLM Wiki 란 무엇인가?에서 정리한 구조가 내 구조에서는 이렇게 대응된다.

원본 패턴내 구조
raw/ (원본 자료)옵시디언 볼트 3벌. 서버 보관소에 읽기 전용으로 잠금
wiki/ (LLM 이 쓴 위키)git 저장소의 Markdown 266개
CLAUDE.md (스키마)_meta/분류_및_분할_기준.md(기준), _meta/위키_편집_가이드.md(절차), _meta/규칙.json(스크립트가 읽는 값)

스키마를 셋으로 나눈 이유가 있다. 사람이 판단하는 기준, 세션이 따르는 절차, 스크립트가 읽는 값은 바뀌는 속도가 다르다. 한 파일에 섞으면 값 하나 고치려다 기준 문장을 건드리게 된다.


문서 한 장은 이렇게 생겼다

---
title: CAKE 프로젝트 개요
summary: "영상 속 얼굴이 AI 로 조작되었는지 공간, 시간, 주파수 세 관점의 딥러닝 모델로 …"   <- 검색과 판단에 가장 큰 영향
keywords: ["CAKE", "Catch Fake", "딥페이크 탐지", "졸업작품"]
id: CAKE_프로젝트_개요
type: 기획        # 강의노트|공지|회의록|기획|규정|명단|회고|메모|MOC
tier: 정리        # 원문|정리|색인
status: active
date: 2025-06-10
tags: ["프로젝트_및_공모전"]
hub_fix: ["CAKE 딥페이크 탐지"]        <- 사람이 정한 허브
hubs: [...]                            <- 스크립트가 다시 씀
role: [...]  people: [...]             <- 스크립트가 다시 씀
derived_from: "5_프로필_및_인프라/통합프로필_원문.md"   <- 무엇을 근거로 썼는지
---

(본문)

---
## 연결                      <- 스크립트가 만드는 자동 푸터
- **허브**: [[CAKE 딥페이크 탐지]]  - **인물**: [[AAA]] · [[BBB]]

규칙은 하나다. 사람이 정하는 항목과 스크립트가 만드는 항목을 갈라 둔다.

hub_fix 와 role_fix 는 내가 정한다. hubs, role, 아래 연결 푸터, 허브 문서, 색인은 저장할 때마다 다시 만들어진다. 자동 생성이 틀려도 내가 정한 값은 살아남는다.

위는 tier: 정리 문서라 derived_from 이 붙는다. tier: 원문 문서에는 대신 source 가 붙고, 원본 볼트에서의 경로가 그대로 들어간다. 이 값은 저장할 때 바뀌지 않는다.

role 자동 추출이 사람이 아닌 이름을 집어올 때가 있다. 그럴 때만 role_fix 를 적어서 고정한다.

tier — 이 문서가 원문인가, 내가 정리한 것인가

tier뜻규칙개수
원문원본에서 옮긴 문서줄을 그대로 둔다. 고치려면 사유가 필요하다204
정리원문을 바탕으로 새로 쓴 해설자유롭게 쓰되 근거 문서를 적는다54
색인목차링크 목록만7

이 구분이 없으면 내가 정리한 문장과 원본 문장이 섞인다. 섞이면 나중에 원문을 복원할 수 없다. 그래서 원문 문서에는 해설을 덧붙이지 못하게 막아 두었다. 보탤 말이 있으면 tier: 정리 문서를 새로 만들고 연결한다.


겪은 사고와 그때 만든 장치

지금 구조는 설계해서 나온 게 아니다. 터진 걸 막으면서 하나씩 생겼다.

겪은 일만든 장치
요약하다 원문이 잘림tier 구분. 원문 수정에 사유 필수
본문 키워드로 허브를 추측하다 보니, 섞여 든 다른 내용 때문에 엉뚱한 허브가 배정됨본문 매칭 폐지. hub_fix 다음 폴더 경로 순서로만 배정
이름이 나왔다는 이유로 무관한 사람이 태그됨관여(role)와 언급(people) 분리. 이름 근처에 직책이 있어야 관여로 본다
"차기학" 처럼 잘린 단어가 인물 허브가 됨제외어 목록(78개)
폴더 이름만 보고 분류해서, 남이 담당한 업무가 엉뚱한 조직에 들어감명의(누가 낸 글인가) 우선 원칙과 명의 검사
파일명 일괄 치환이 원본 경로(source) 13건까지 바꿔 버림source 는 어떤 도구로도 못 바꾸게 막고, 추적성 검사 추가
쪼개다가 문장이 바뀜분할은 줄 범위만 지정. 서버가 원래 줄을 그대로 옮긴다
검사를 내가 기억해서 돌림저장할 때마다 자동 검사

마지막 줄이 이 글에서 제일 하고 싶은 말이다. 사람이 기억해서 지키는 규칙은 결국 안 지켜진다. 그래서 규칙을 저장 경로에 넣어 두었다.


저장 한 번에 일어나는 일

이 부분이 내 구조에서 제일 중요하다. 어떤 도구로 고치든 실제 저장은 한 곳을 지난다.

미리보기 도구 -> (내가 승인) -> 저장
   1. 잠금          5분 동기화와 같은 잠금을 쓴다
   2. 최신본 받기
   3. 해시 대조      미리보기 이후 파일이 바뀌었으면 거부
   4. 적용
   5. 갱신 스크립트  허브, 인물, 색인, 연결 푸터 다시 생성
   6. 13종 검사      저장 전보다 지적이 늘면 전부 되돌리고 거부
   7. 커밋 -> push   사유와 변경 파일을 커밋 메시지에 남김

13종은 이렇다.

필수 항목, tier와 type 값, 허브 배정, 위키링크, 고아 첨부(파일 단독), 파일명 중복, id 일치, 원본 줄 누락, 분할 관계, 인물 타당성, 고립 문서, 출처 추적성, 명의와 폴더 일치

이 중 하나가 특히 중요하다. 원본 줄 누락 검사다.

원본 볼트에서 내용이 있는 줄을 전부 추려 해시로 만들어 두었다. 15,413줄이다. 위키 어딘가에 그 해시가 있어야 한다. 사유 없이 하나라도 사라지면 저장이 거부된다. 원문이 깨졌던 경험 때문에 만든 장치이고, 덕분에 원본 볼트를 PC 에서 치우고도 검사가 돈다.

한 번 저장에 약 10초 걸린다. 느리지만, 이 10초가 내가 실수로 원문을 지우는 일을 막는다.

실제로 거부되면 이렇게 나온다. 원문 문서의 본문 한 줄을 사유 없이 지우려고 한 결과다.


쓰는 방법

읽을 때는 그냥 물어본다.

  • "TTS Overlay 에 대한 정보를 띄워줘"

작성할 때는 이렇게 간다.

"이 내용 위키에 올려줘"
  -> 세션이 기준서와 가이드를 먼저 읽는다
  -> 명의, 폴더, tier, 허브, 관여자를 정한다
  -> 기준에 없는 판단이면 나한테 묻는다
  -> 미리보기(diff)를 보여준다
  -> 내가 승인해야 저장된다

네 번째 줄이 중요하다. 명의를 못 찾겠거나, 맞는 폴더나 허브가 없거나, 등장인물의 소속을 모르면 멈추고 물어본다. 추측해서 채우면 그 추측이 그대로 기록이 된다.

도구는 21개다. 읽기 9개(검색, 개요, 전문, 목록, 최근 변경, 허브 타임라인, 첨부, 검증, 이력), 편집 미리보기 11개(새 문서, 덧붙이기, 속성 수정, 본문 수정, 이동, 분할, 삭제, 첨부, 기준 수정, 대분류 신설, 되돌리기), 그리고 저장 1개다.


숫자로 보면

항목값
문서266개
주제 허브 / 인물 허브36 / 35
첨부파일161개 (104MB)
원본 줄 색인15,413줄
13종 검사지적 0건
저장 한 번약 10초
라즈베리파이 RAM 사용512MB 중 213MB

보안은 이렇게 했다

방식만 적는다. 주소, IP, 계정명, 포트 같은 값은 쓰지 않는다.

  • 외부에서 오는 길은 하나다. 도메인 하나, 리버스 프록시 하나, 서버 하나
  • 로그인은 Google OAuth 를 쓴다. 자체 비밀번호를 만들지 않았고, 허용한 계정 하나만 통과한다
  • MCP 서버가 실행된 포트는 방화벽에서 프록시 장비 한 대만 허용한다
  • 서비스에 시스템 격리를 걸어 두어 위키 폴더 외에는 쓰기가 막혀 있다
  • 저장소 전용 계정은 셸이 git-shell 이라 git 명령 외에는 실행되지 않는다
  • 비밀키는 권한 600 파일 하나에만 둔다. 위키, git, 채팅에 적지 않는다
  • 매일 백업하고 날짜별 스냅샷 7개를 유지한다

해 보니 어땠나

좋았던 것. 휴대폰에서 "그때 뭐했지" 하고 물으면 바로 나온다. 문서를 찾아 열 필요가 없다. 질문을 할수록 위키에 페이지가 늘어난다.

대신 치르는 것. 저장 한 번에 10초가 걸린다. 그리고 자료 하나를 넣을 때마다 문서 여러 개를 읽고 고치니 소비되는 토큰이 많다.
원본 패턴에서 LLM 은 갱신하는 것을 지겨워하지 않는다고 했는데, 지겨워하지 않는 대신 토큰을 쓴다. LFM2.5 글에서 비서의 모델을 로컬로 바꾸려는 이유와 같은 문제다.

가장 효과가 컸던 것. 기준을 위키 안에 넣은 것. 기준서와 가이드가 위키 문서라서, 어느 세션에서 시작하든 같은 규칙을 읽고 시작한다. 기준이 바뀌면 그것도 같은 승인 절차로 바뀐다. 규칙 자체가 버전으로 관리된다.


한계

규모. 원문이 말하는 기준은 자료 100개 정도이고, 이 방식을 소개한 기사들은 1만 개 수준까지 본다. 내 위키는 266개라 색인 파일 하나로 충분하다. 더 늘면 검색을 따로 추가해야 한다.

비용. 사람이 손으로 쓰지 않을 뿐, 자료를 넣을 때마다 토큰이 소비된다. 자료 하나가 문서 열 몇 개를 건드리면 그만큼 읽고 쓴다.

용도. 개인용 도구로 보는 게 맞다. 파일 기반이라 권한 분리도, 동시 수정 제어도 없다. 여러 사람이 같이 쓰는 환경이라면 다른 선택이 필요하다.


앞으로 할 것

  • 로컬 모델 연결. LFM2.5 글에서 다루었던 모델을 사용한다면 전기세 말고는 비용이 들지 않는다. 토큰을 걱정할 필요가 없다. 다만, LLM Wiki 란 무엇인가? 글에서 다룬 LLM 품질에 대한 검토가 필요하다.
  • 검색 보강. 지금은 제목, 키워드, 요약, 본문에 점수를 매기는 방식이다. 문서가 더 늘면 단어 검색과 의미 검색을 같이 쓰는 쪽으로 가야 한다

[2026-10-08 추가] 검사를 하나 더 넣었다

질문을 받았다.

인용한 문장이 원문과 같은지 비교하는 검사도 들어 있는지 궁금합니다.

없었다. 확인해 보니 빠뜨린 게 아니라, 검사 방식 자체가 못 잡는 종류였다.

원본 줄 누락 검사는 원본 -> 위키 한 방향만 향한다. 원본 줄 15,413개가 위키 어딘가에 남아 있는지만 확인한다. 출석부와 같다. 명단에 적힌 사람이 다 왔는지는 알 수 있지만, 명단에 없는 사람이 들어온 건 알 수 없다.

LLM이 요약해 놓고 원문이라고 적어 두면 줄이 사라지는 게 아니라 늘어난다. 명단에 없는 사람이 들어온 것이다. 이 경우 검사는 그냥 통과시킨다.

더 들여다보니 비교할 원문 자체가 없었다. 내 줄 색인은 옵시디언 볼트로만 만들었다. 웹 문서는 색인에 한 줄도 없다. 원본 패턴의 raw/ 가 의심스러울 때 돌아와 대조하는 자리인데, 나는 내 볼트만 잠가 두고 웹 자료는 읽고 버렸다. 그 자리가 비어 있었다.

그래서 두 가지를 만들었다. 인용할 웹 원문은 받을 때 떠서 보관하고 줄마다 해시를 남긴다. 그리고 14번째인 인용 대조 검사를 만들었다. 인용은 이렇게 표시한다.

> [!인용] web_20261008_llm-wiki
> This is the key difference: the wiki is a persistent, compounding artifact.

이 블록의 각 줄을 해시로 바꿔, 보관할 때 만들어 둔 그 출처의 해시 목록에 있는지 확인한다. 글자가 하나라도 다르면 값이 달라지니 요약해 놓은 문장은 걸린다. 없으면 저장이 거부된다. 원본 줄 누락 검사와는 방향이 반대다.

Karpathy Gist 원문을 보관하고, 같은 출처에 가짜 문장을 넣어 저장해 봤다.

{"ok": false,
 "error": "검증 지적이 늘어 저장하지 않음 (기준 위반)",
 "new_errors": ["[14 인용이 원문과 다름] 3_프로젝트_및_공모전/LLM위키_구축_계획.md <- web_20261008_llm-wiki
                 > Vector databases are strictly unnecessary at any scale."],
 "저장": "취소됨 (위키는 그대로)"}

다만, 표시한 인용만 검사한다. 마커([!인용] 표시) 없이 본문에 섞어 쓰면 여전히 못 잡는다.

검사를 열세 개 만들어 놓고도 그게 한 방향만 본다는 걸 질문이 들어와서 알게 되었다.

검사는 13가지에서 14가지로, 도구는 21개에서 23개가 됐다. 웹 원문을 보관하는 것과, 보관한 원문을 꺼내 보는 것이 늘었다.


[LLM Wiki 란 무엇인가?] : https://velog.io/@kyeong9743/LLM-Wiki-1
참고 : Karpathy의 llm-wiki Gist · LFM2.5 1편 · LFM2.5 2편

profile
논리를 따라가는 걸 좋아하고, 왜 그렇게 되는지 이해하고 넘어가야 직성이 풀리는 사람으로, 이곳에 직접 만들고 운영하면서 막혔던 지점과 그걸 풀어낸 과정을 기록합니다.

2개의 댓글

comment-user-thumbnail
2026년 10월 7일

점검을 가끔 돌리는 작업이 아니라 저장 조건으로 바꿨다는 세 번째 차이가 핵심으로 읽혔습니다. 저도 같은 위키 방식을 쓰는데 원문 폴더와 정리본 폴더를 나누고 정리본에는 직접 쓰지 않게 해 뒀습니다. 그런데도 자료를 모으던 AI 가 웹 문서 요약을 원문 그대로라며 인용으로 적어 둔 것을 나중에 원문과 대조하다 세 군데나 찾은 적이 있어요. 13종 검사 가운데 인용한 문장이 원문과 같은지 비교하는 검사도 들어 있는지 궁금합니다.

1개의 답글