Skip to content
게으른 엔지니어의 기술 블로그
Go back

obsidian-llm-wiki(karpathywiki)를 파보니 — 임베딩 없이 그래프로 검색하는 이유

비슷한 옵시디안 플러그인 여섯 개를 파보니 · 1/7편

옵시디안 플러그인 이름을 고민하다가, 같은 컨셉(Andrej Karpathy의 LLM Wiki)을 구현한 플러그인이 이미 여럿 있다는 걸 알게 됐다. 검색 요약만 보고 넘어가는 대신, 여섯 개를 전부 GitHub에서 직접 클론해서 소스 코드를 읽었다. 첫 번째는 그중 가장 크고 활발한 obsidian-llm-wiki (green-dalii, 플러그인 id는 karpathywiki)다.

GitHub 지표 — 551스타, 활발히 유지보수 중

9월 2일, GitHub API로 직접 확인하니 551스타·68포크, 전날에도 커밋될 만큼 활발했다. 릴리스 30개, 최신 버전은 1.27.0. ko-fi 후원 링크가 있는 걸 보면 진지하게 이어가는 1인 프로젝트로 보인다.

임베딩·벡터DB가 없다 — 대신 그래프 위 PPR

가장 큰 차이는 검색 방식이다. 이 플러그인은 RAG(임베딩+벡터 검색)를 아예 안 쓴다. 대신 노트에서 엔티티·개념을 추출해서 [[wiki-link]] 그래프를 만들고, 그 그래프 위에서 Personalized PageRank(PPR)로 검색한다 — 렉시컬 매칭 → 키워드 생성 → 로컬 스캔 → 시맨틱 폴백 → PPR 확장까지 5단계 캐스케이드로 답을 찾아간다. 자체 벤치마크로는 순수 kNN(임베딩 유사도만 쓰는 방식) 대비 27.1% vs 24.1%로 우위라고 주장하고 있었다.

지금 만들고 있는 플러그인은 정반대로 RAG(임베딩) 기반이다. 우열의 문제라기보다는 서로 다른 트레이드오프다 — RAG는 구현이 단순하고 벡터 검색 라이브러리만 있으면 되지만, 이론적으로 “의미적으로 비슷해 보이는데 실제로는 무관하다”는 위험이 있다. 그래프+PPR은 관계가 명시적으로 링크로 존재해야 잡히니까 그런 위험은 구조적으로 줄어들지만, 링크가 안 걸린 진짜 관련 정보는 놓칠 수 있다.

main.ts를 쪼개는 방식 — 믹스인 패턴

main.ts가 453줄인데, 실제 로직은 대부분 main-commands/ 폴더 아래 파일(ingest-commands.ts, schema-commands.ts, connection- commands.ts 등)로 나뉘어 있다. 그리고 이걸 Object.assign (LLMWikiPlugin.prototype, ingestCommands, schemaCommands, ...)로 플러그인 클래스 프로토타입에 갖다 붙이는 믹스인 패턴을 쓴다. TypeScript interface LLMWikiPlugin extends IngestMethods, SchemaCommandsMethods {} 같은 선언 병합도 같이 써서, 파일은 여러 개로 나뉘어 있는데 코드에서는 this.ingestSomething()처럼 한 클래스의 메서드인 것처럼 접근할 수 있게 만들어뒀다. 파일을 잘게 쪼개고 싶은데 매번 컨트롤러 객체를 거쳐 호출하는 번거로움은 피하고 싶을 때 쓸 만한 패턴이다.

API 키를 OS 키체인에 저장한다

Obsidian의 app.secretStorage API를 써서 API 키를 OS 키체인에 저장한다. 예전 버전에서 평문으로 data.json에 저장하던 사용자를 위한 마이그레이션 코드도 있는데, 이게 꽤 신중하게 짜여 있다 — 평문 키를 임시 필드에 스테이징해두고, 실제로 키체인 쓰기가 성공한 뒤에야 원본 평문 필드를 지운다. 쓰기가 실패하면 평문이 그대로 남아있어서 다음 로드 때 마이그레이션이 다시 시도된다. 마이그레이션 도중 뭔가 실패해도 키를 아예 잃어버리는 경우가 없게 만든 설계다.

배운 점

가장 크고 활발한 프로젝트답게, 검색 방식(그래프+PPR)부터 코드 구조(믹스인)까지 나름의 이유가 있는 선택들이었다. 특히 API 키 마이그레이션을 2단계로 쪼갠 부분은, “설정 스키마가 바뀔 때 사용자 데이터를 잃지 않는다”는 문제를 실제로 진지하게 다뤄본 사람의 코드라는 인상을 줬다.


Share this post:

비슷한 옵시디안 플러그인 여섯 개를 파보니

  1. 1. obsidian-llm-wiki(karpathywiki)를 파보니 — 임베딩 없이 그래프로 검색하는 이유
  2. 2. AI Wiki(ikeniborn)를 파보니 — API 키를 data.json에서 뺀 이유
  3. 3. AI RAG + LLM Wiki를 파보니 — 서비스 파일 30개짜리 설계가 하루 만에 버려졌다
  4. 4. Auto LLM Wiki를 파보니 — 바꾸기 전에 미리 보여주는 게 핵심이었다
  5. 5. Ziran LLM Wiki를 파보니 — 말로 설명하면 평가해주는 파인만 학습법
  6. 6. GenWiki를 파보니 — 1099줄짜리 파일 하나가 전부였다
  7. 7. 여섯 개를 다 보고 나서 — 지금 만드는 것과 비교해보니