지난 글에서 가장 야심찬 설계를 봤다. 여섯 번째이자 개별 리뷰의 마지막은 정반대로 가장 작고 단순한 GenWiki(yvonshong)다.
스타 1개, 6월 이후 멈춘 프로젝트
GitHub API로 확인하니 1스타·0포크, 마지막 push가 6월 6일 — 석 달 가까이 업데이트가 없다. 이 시리즈에서 사실상 가장 작은 규모였다.
main.ts 하나에 전부 들어있다
export default class GenWikiPlugin extends Plugin이 main.ts
1099줄 전체를 차지한다. onload, loadSettings, initFolders,
loadDatabase, rebuildEmbeddings, runIngest, executeQuery,
runLint, 심지어 QueryModal과 GenWikiSettingTab 클래스까지
전부 이 한 파일 안에 있다. 다른 다섯 개(특히 karpathywiki의
믹스인, AI Wiki의 컨트롤러 분리)와 비교하면, 이게 왜 파일을
나누는지 거꾸로 이해가 됐다 — 1099줄 안에서 “인제스트 로직이
어디서 끝나고 쿼리 로직이 어디서 시작하는지”를 찾는 것 자체가
일이었다.
흥미롭게도 rebuildEmbeddings라는 메서드가 있는 걸 보면, README
요약에서는 안 드러났던 임베딩 기반 검색을 실제로 쓰고 있었다 —
검색 요약만 봤으면 몰랐을 부분이다.
런타임 의존성이 0개
package.json의 dependencies가 비어 있다. LLM 호출도, JSON
파싱도, 전부 표준 라이브러리와 직접 짠 fetch 호출로 처리하는
것으로 보인다. 이 시리즈에서 가장 무게가 가벼운 선택이었다 —
번들 크기도 작고 의존성 취약점 걱정도 적지만, provider가 늘어날
때마다 그만큼 코드를 손으로 더 써야 한다.
배운 점
여섯 개 중 가장 작고 멈춘 프로젝트를 마지막에 보니, 나머지 다섯 개가 각자 왜 그렇게 구조를 잡았는지가 오히려 더 선명해졌다. 파일을 나누는 것, 컨트롤러를 분리하는 것, provider SDK를 쓰는 것 — 전부 “이렇게 안 하면 어떻게 되는가”를 GenWiki가 그대로 보여주고 있었다. 작게 시작하는 것 자체는 문제가 아니지만, 한 파일에 다 몰아넣은 채로 기능이 계속 늘어나면 결국 이 지점에 도달한다는 것도 확인한 셈이다.