14명의 AI 전문가가 리뷰한 학습 위키 빌더: v1.0까지의 여정
전공책은 안 읽히는데 나무위키는 하루종일 읽을 수 있잖아
전공 교과서를 펼치면 10분 만에 잠이 옵니다. 그런데 나무위키에서 ‘양자역학’ 문서를 열면 두 시간이 순삭됩니다. 같은 내용인데 왜 이렇게 다를까?
위키는 링크를 타고 탐색하는 재미가 있습니다. 하나의 개념에서 다른 개념으로 자연스럽게 이동하며, 취소선 드립과 (괄호 안 부연설명)이 딱딱한 내용을 소화하기 쉽게 만들어줍니다. 그러면 교과서를 나무위키로 만들면 되지 않을까?
2026년 3월 17일 오후 1시 55분, Claude Code에게 이 아이디어를 던졌습니다.
13:55 Initial commit — Python CLI (1,145줄)14:24 29분 후 — TypeScript/Bun 전면 리라이트19:04 v0.3.0 — LLM 파이프라인 + 웹 UI + 다중 프로바이더19:46 v0.4.0 — 나무위키 페르소나 시스템 탑재20:13 v0.4.1 — 나무위키 CSS 테마하루 만에 아이디어에서 배포까지. 이것이 AI 코딩 에이전트 시대의 속도입니다.
하지만 “동작하는 것”과 “좋은 것”은 다릅니다. v0.4.2는 기능은 됐지만 보안은 구멍투성이, 테스트는 0개, 코드 품질은 4.0/10이었습니다.
여기서 14명의 AI 전문가가 등장합니다. kiwimu를 11 라운드에 걸쳐 리뷰하고, 발견된 이슈를 즉시 수정하는 사이클을 반복했습니다. 보안 A 등급, 품질 8.5/10을 달성한 뒤, Dynamic Q&A, SM-2 간격 반복, 웹 편집, 마크다운 인제스트까지 구현하고 실제 교과서로 데모를 만들어 내부 배포까지 완료한 12일간의 기록입니다.
왜 14명인가
1인 개발 프로젝트의 가장 큰 약점은 시야의 편향입니다. 코드를 짠 사람이 리뷰도 하면, 자기가 놓친 걸 자기가 발견할 수 없습니다.
이걸 해결하기 위해 전혀 다른 관점을 가진 14명의 페르소나를 설계했습니다. 한 번에 14명을 투입한 것이 아니라, 점진적으로 확장했습니다.
| 단계 | 라운드 | 페르소나 | 핵심 질문 |
|---|---|---|---|
| 기술 기초 | R01 | 🛡️ Security / ⚡ Performance / 🔧 Quality / 📊 PM / 🎨 UX / 🏗️ Architecture | ”이 코드가 안전하고 빠르고 유지보수 가능한가?” |
| 사용자 관점 | R09 | 🎓 Student User / 🌐 OSS Contributor / 📚 EdTech Specialist / 🖥️ DX Engineer | ”실제로 쓸 만한가?” |
| 전문 영역 | R11 | 🗄️ DB Architect / 🌈 Frontend / 📢 Marketing / 🏆 Hackathon Judge | ”깊이 파면 뭐가 나오나?” |
처음부터 14명을 돌리면 안 됩니다. 보안 구멍이 뚫린 상태에서 마케팅 피드백을 받으면 우선순위가 꼬입니다. 기술 → 사용자 → 전문 영역 순서로 확장하는 것이 핵심이었습니다.
리뷰 → 수정 사이클
이 프로세스에서 가장 중요한 설계 결정은 “리뷰만 하는 게 아니라 즉시 고친다”는 것입니다.
리뷰 라운드 N (병렬 에이전트 3~6명) ↓통합 리포트 → 이슈 분류 (CRITICAL / HIGH / MEDIUM / LOW) ↓수정 에이전트 팀 (병렬, 파일 영역별 분리) ↓커밋 + 푸시 → 리뷰 라운드 N+1 (수정 검증)리뷰 에이전트와 수정 에이전트가 동일한 대화 세션 안에서 실행됩니다. 리뷰 결과가 바로 수정 에이전트의 프롬프트가 됩니다. Jira 티켓 등록도, 스프린트 계획도 없습니다. 컨텍스트가 살아있는 상태에서 바로 고칩니다.
R01: 첫 리뷰 — 58건의 충격
6명의 페르소나가 병렬로 전체 코드베이스를 리뷰했습니다.
CRITICAL 9건, HIGH 12건, MEDIUM 17건, LOW 20건. 총 58건.
가장 충격적이었던 발견 세 가지:
인증이 없다 (4명 합의)
// 누구나 API key를 변경할 수 있었다POST /api/settings{ "api_key": "attacker-controlled-key" }Security, Code Quality, Architecture, PM 4명이 독립적으로 같은 문제를 지적했습니다. 4명이 합의한 이슈는 신뢰도가 다릅니다. 이후 “합의 수”가 우선순위를 정하는 핵심 기준이 되었습니다.
LLM 호출이 완전 직렬
for (let i = 0; i < chunks.length; i++) { const raw = await chatComplete(system, prompt, 16384); // 10개 = 50초+}Performance 엔지니어의 계산: Promise.allSettled + concurrency=3으로 60% 시간 단축 가능. API 비용은 동일하고 wall-clock time만 줄어든다.
PM의 한 줄 진단
“kiwimu는 ‘위키를 만드는 도구’에 머물러 있다. 위키로 학습하는 도구로 진화해야 리텐션을 확보할 수 있다.”
이 한 줄이 이후 퀴즈 시스템, 간격 반복 등 모든 학습 과학 기능 개발의 방향을 결정했습니다.
수정 팀: 병렬 에이전트의 힘
R01 발견 후, 3개 에이전트 팀을 병렬로 투입했습니다:
| 에이전트 | 담당 | 파일 영역 |
|---|---|---|
| security-fixes | 인증, SSRF, Path Traversal | index.ts, web.ts |
| perf-fixes | 인덱스, N+1, RegExp | store.ts, renderer.ts |
| quality-fixes | slugify, dead code, 폰트 | chunker.ts, style.css |
서로 다른 파일을 담당하므로 충돌 없이 병렬 실행됩니다. 3개 에이전트가 동시에 코드를 수정하고, 모두 완료되면 한 번에 커밋. 이 패턴이 전체 프로세스의 처리량을 3배로 올렸습니다.
v0.5.0 → v0.6.0: 보안, 성능, 아키텍처
R01~R04를 거치며 기술적 기반을 확립했습니다.
보안: Bearer 토큰 인증, SSRF 방지(프라이빗 IP 차단 + 리다이렉트 재검증), sanitize-html + CSP 헤더, Path Traversal 방어.
성능: LLM Phase 1 병렬화(외부 의존성 없이 인라인 parallelMap 구현, concurrency=3), SQLite 인덱스 4개, N+1 백링크를 벌크 쿼리로 교체.
아키텍처: 735줄 God File을 3개로 분리:
index.ts (308줄) — CLI만server.ts (327줄) — 웹 서버services/ingest.ts (100줄) — 공유 로직동시에 any 타입 19건 → 0건, 테스트 0개 → 33개, LLM 클라이언트를 클래스 기반으로 전환.
R04 시점에서 code quality 점수가 4.0에서 8.0/10으로 올랐고, R05에서 첫 SHIP IT 판정을 받았습니다.
R09: 새로운 눈 — “이걸 진짜 쓸 사람은 뭐라고 할까?”
SHIP IT을 받았지만, 뭔가 빠져있다는 느낌이 있었습니다. 기존 리뷰어들은 모두 만드는 사람의 관점이었습니다. 쓰는 사람은 아직 한 번도 물어보지 않았습니다.
완전히 새로운 4개 페르소나를 만들었습니다.
대학생 사용자 (6/10)
“시험 벼락치기에는 쓸만한데, 매일 쓸 이유가 없다. Anki 대체? SRS도 없는데?”
EdTech 전문가의 진단표
| 항목 | 등급 |
|---|---|
| 능동적 회상 (Active Recall) | C+ |
| 간격 반복 (Spaced Repetition) | F |
| 피드백 품질 | D |
| 메타인지 | F |
“퀴즈는 있지만 간격 반복이 없고, 학습 이력 추적이 전무하며, 피드백이 이모지뿐이다. 이 상태로는 ‘학습 도구’라 부를 수 없다.”
기존 8라운드의 보안/성능/품질 리뷰에서 한 번도 발견하지 못한 관점이었습니다. 같은 코드를 봐도 렌즈가 다르면 완전히 다른 문제가 보입니다.
v0.8.0: 학습 과학 기반 재설계
EdTech 리뷰의 F 등급을 받고, 학습 과학 기능을 구현했습니다.
스마트 퀴즈 선택: 미풀이 → 오답 → 오래된 정답 순으로 출제하는 기초적인 간격 반복. Anki의 SM-2까지는 아니지만, ORDER BY RANDOM()에서 크게 진화했습니다.
해설: 퀴즈 생성 시 LLM에게 “왜 이 답이 맞는지” 설명을 함께 요청. R10에서 학생 사용자가 “해설이 가장 큰 변화”라고 평가했습니다.
학습 이력: quiz_attempts 테이블로 시도 기록을 저장하고, 약한 개념을 식별.
R11: 마지막 렌즈
마지막으로, 한 번도 사용하지 않은 4개 관점을 투입했습니다. 여기서 가장 인상적인 발견이 나왔습니다.
Database Architect — 10개 라운드가 놓친 버그
// INSERT OR REPLACE는 내부적으로 DELETE + INSERT로 동작한다.// 기존 row의 ID가 바뀌면서 자식 행(quizzes, links)이 고아가 된다!INSERT OR REPLACE INTO pages ...
// 수정: UPSERT — ID를 유지하므로 자식 행이 안전하다INSERT INTO pages (...) ON CONFLICT(slug) DO UPDATE SET ...보안 리뷰어도, 성능 리뷰어도, 품질 리뷰어도 찾지 못한 데이터 무결성 버그를 DBA가 첫 리뷰에서 찾았습니다. 관점의 다양성이 곧 품질입니다.
Marketing Manager — 성장의 실종
“가치 제안이 없다. ‘나만의 학습 위키를 만드세요’는 기능 설명이지 가치 제안이 아니다.”
“생성된 위키에 ‘Built with Kiwi Mu’ 배지가 없다. 바이럴 루프가 완전히 차단되어 있다.”
Hackathon Judge — 8.075/10
| 카테고리 | 점수 |
|---|---|
| Demo Impact | 8.5 |
| Technical Depth | 8.0 |
| Completeness | 8.5 |
| Innovation | 7.0 |
| Polish | 8.0 |
상위 10-15%, 입상권이라는 평가. 우승을 위해서는 Innovation 점수를 올릴 킬러 피처가 필요하다는 조언이었습니다.
리뷰 이후: v0.9.0 → v1.0.0+
R11이 끝나고 “SHIP IT”을 받았지만, 해커톤 심사관의 조언이 귓가에 맴돌았습니다. Innovation 7.0. 킬러 피처가 필요했습니다.
v0.9.0 — Dynamic Q&A
위키 페이지를 읽다가 모르는 부분이 나오면? 기존에는 별도로 검색하거나, 새 문서를 수동으로 추가해야 했습니다.
Dynamic Q&A는 이 흐름을 완전히 바꿨습니다. 텍스트를 드래그하면 팝오버가 나타나고, LLM에게 바로 질문할 수 있습니다. 답변은 새로운 개념 페이지로 자동 생성되고, 드래그한 텍스트는 그 페이지로의 하이라이트 링크가 됩니다. 학습 중 궁금증이 생기는 순간, 위키가 유기적으로 확장됩니다.
services/dynamic-qa.ts(서버)와 build/static/dynamic-qa.js(클라이언트)로 구현했습니다. serve 모드에서 실시간 동작합니다.
v1.0.0 — SM-2 + 웹 편집 + tech debt 정리
SM-2 간격 반복: R09에서 EdTech 전문가가 준 F 등급을 드디어 해결했습니다. Anki의 SM-2 알고리즘을 구현하여, 퀴즈 결과에 따라 복습 일정이 자동으로 조정됩니다. 학습 대시보드에서 숙달도, 약한 개념, 복습 일정을 한눈에 볼 수 있습니다.
웹 페이지 편집: serve 모드에서 각 페이지의 마크다운을 직접 편집할 수 있는 모달을 추가했습니다. LLM이 생성한 내용이 마음에 들지 않을 때, 브라우저에서 바로 수정 가능합니다.
tech debt 정리: 누적된 기술 부채를 정리하고, 코드 구조를 안정화했습니다.
마크다운 인제스트 + LaTeX 수정
kiwimu add <directory>로 디렉토리 내 모든 .md 파일을 일괄 인제스트할 수 있게 했습니다. 이것이 진짜 데모를 만드는 열쇠였습니다.
OpenStax 교과서(University Physics, Astronomy 등)의 마크다운 버전을 다운로드하여, 실제 대학 교과서 수준의 위키를 자동 생성했습니다. LaTeX 수식 렌더링도 KaTeX로 완전히 지원하면서, 물리학 교과서의 복잡한 수식이 깨지지 않고 표시됩니다.
내부 배포
마지막 단계는 실제 서비스로 올리는 것이었습니다. Docker 컨테이너로 패키징하고, Traefik 리버스 프록시 + CoreDNS + Let’s Encrypt 자동 인증서로 kiwimu.internal.jiun.dev에 배포했습니다. 실제 사용자가 접속하여 체험할 수 있는 라이브 데모가 완성되었습니다.
숫자로 보는 여정
| 영역 | v0.4.2 | v1.0.0+ |
|---|---|---|
| Security | CRITICAL | A |
| Performance | CRITICAL | B+ |
| Code Quality | 4.0/10 | 8.5/10 |
| Product | — | 8.0/10 |
| CRITICAL 이슈 | 9 | 0 |
| HIGH 이슈 | 12 | 0 |
| 테스트 | 0 | 33 |
any 타입 | 19 | 0 |
| LLM 프로바이더 | 2 | 4 |
| 커밋 | — | 15+ |
주요 신규 기능: Bearer 토큰 인증, SSRF/XSS/Path Traversal 방지, LLM 병렬화(60% 단축), OpenAI+Anthropic, --demo 모드, 학습 퀴즈+SM-2 간격 반복, Dynamic Q&A, 웹 페이지 편집, 학습 대시보드, MD 디렉토리 일괄 인제스트, LaTeX/Mermaid 렌더링, 다크 모드, 모바일 메뉴, 검색 키보드 네비게이션, ARIA 접근성, “Built with Kiwi Mu” 배지, OG 태그, CONTRIBUTING/CHANGELOG/CI.
이 과정에서 배운 것들
페르소나 확장에는 순서가 있다
기술(보안, 성능) → 사용자(학생, DX) → 전문 영역(DB, 마케팅). 보안 구멍이 뚫린 상태에서 마케팅 피드백을 받으면 우선순위만 꼬입니다.
합의 수가 우선순위다
4명이 독립적으로 같은 문제를 지적하면, 그건 진짜 문제입니다. 1명만 지적한 이슈는 전문적 관점일 수도, 과잉 반응일 수도 있습니다.
같은 코드, 다른 렌즈, 다른 버그
10라운드의 리뷰가 놓친 INSERT OR REPLACE 버그를 DBA가 첫 리뷰에서 찾았습니다. 같은 렌즈로 더 깊이 파는 것보다 다른 렌즈를 추가하는 것이 ROI가 높습니다.
리뷰와 수정 사이에 간격이 없어야 한다
리뷰 에이전트가 끝나면 바로 수정 에이전트를 투입합니다. 컨텍스트가 살아있는 상태에서 수정하면 효율이 완전히 다릅니다. Jira 티켓이 필요 없습니다.
수확 체감 지점을 인식해야 한다
R05에서 SHIP IT을 받은 후 R06-R08에서는 찾는 이슈가 줄었습니다. 이때가 새로운 페르소나를 추가할 타이밍입니다.
12일의 타임라인
| 날짜 | 마일스톤 |
|---|---|
| Day 1 (3/17) | Python 프로토타입 → 29분 후 TS 리라이트 → 나무위키 페르소나 → 배포 |
| Day 2 (3/18) | 페르소나 외부화, npm 호환성 → v0.4.2 |
| Day 3 (3/19) | R01 |
| Day 4 (3/20) | npm publish, 학습 과학 구현 → v0.8.0~v0.8.1 |
| Day 6-7 (3/22-23) | DB 무결성, 성장 기능, 접근성 → v0.8.2 |
| Day 8-10 (3/25-27) | Dynamic Q&A, SM-2 간격 반복, 웹 편집, 대시보드 → v0.9.0~v1.0.0 |
| Day 11-12 (3/28-29) | 마크다운 인제스트, LaTeX 수정, OpenStax 데모 생성, 내부 배포 (Docker + Traefik + CoreDNS + Let’s Encrypt) |
11 라운드, 14 페르소나, 15+ 커밋, 12일.
“전공책은 안 읽히는데 나무위키는 하루종일 읽을 수 있잖아”에서 시작하여, 보안 A 등급의 학습 위키 빌더를 거쳐, Dynamic Q&A와 SM-2 간격 반복을 갖춘 v1.0으로. 그리고 실제 대학 교과서로 만든 데모를 내부 서버에 배포하는 것까지.
아이디어 한 줄에서 실서비스까지, AI 코딩 에이전트와 함께한 12일간의 전체 기록입니다.
kiwimu는 npm에서 설치할 수 있고, bunx @open330/kiwimu init --demo로 30초 만에 체험할 수 있습니다. GitHub에서 소스를 확인하고, 라이브 데모에서 직접 체험해 보세요.
Comments
Loading comments...