Skip to content

qmd 사용 가이드 (CMDS)

Key Insight

qmd는 Tobias Lütke(Shopify CEO)가 만든 로컬 마크다운 검색 엔진으로, Karpathy가 LLM Wiki 패턴의 공식 권장 도구로 지목한 바 있다. BM25 + 벡터 + LLM 재순위화를 완전 온디바이스로 제공하며, Ollama 없이 GGUF 모델을 자체 임베드한다.


1. 개요

1.1 qmd란?

  • 저장소: github.com/tobi/qmd (npm: @tobilu/qmd, 현재 설치 버전 2.1.0)
  • 용도: 로컬 마크다운 파일에 대한 하이브리드 검색 (키워드 + 시맨틱 + 리랭킹)
  • 런타임: Node.js ≥ 22 또는 Bun ≥ 1.0
  • 임베딩 백엔드: node-llama-cpp + GGUF 모델 (Ollama 불사용)
  • 저자: Tobias Lütke (Shopify CEO, tobi)

1.2 왜 qmd인가 — Karpathy 연결

Karpathy의 LLM Wiki 패턴 원문에서 직접 권장:

"qmd is a good option: it's a local search engine for markdown files with hybrid BM25/vector search and LLM re-ranking, all on-device. It has both a CLI (so the LLM can shell out to it) and an MCP server (so the LLM can use it as a native tool)."

LLM Wiki가 ~100 sources, ~수백 pages 규모로 성장할 때 index.md 한 파일만으로는 탐색이 어려워진다. qmd가 그 scale-up 경로를 제공한다.

1.3 CMDS 환경에서의 역할

  • 대상 볼트: CMDS_LLM_Wiki (satellite, Karpathy 3-Layer Architecture 구현체)
  • 인덱스 범위: Wiki(합성) + Raw Sources(원본) + Queries(합성 결과) — 총 3 collection
  • 접근 방식: Claude Code가 MCP 네이티브 툴로, 사용자는 CLI로 (hybrid usage)

2. 아키텍처

2.1 임베딩 스택 (Ollama와의 차이)

qmd는 Ollama를 지원하지 않는다. 대신 node-llama-cpp를 통해 GGUF 모델을 프로세스 내부에서 직접 로드한다.

계층구현
임베딩 모델embeddinggemma-300M-Q8_0 (Google Gemma 3 기반, 140+ 언어) ※ [[qmd 임베딩 모델 업그레이드 검토|상세 결정 로그]]
리랭커Qwen3-Reranker-0.6B (CJK 지원)
쿼리 확장qmd-query-expansion-1.7B (HyDE 스타일)
벡터 DBSQLite + vec0 확장
GPU 가속Apple Metal (M5 Max 기준 VRAM 107GB 활용)

qmd 2.1.0 CLI 버그 유의

QMD_EMBED_MODEL 환경변수 지정해도 qmd embed CLI는 하드코딩된 default(embeddinggemma-300M)를 사용한다. DB content_vectors.model 컬럼 조회로 실제 사용 모델 확인 가능. 실 운영상 Gemma-300M이 baseline이며, Qwen3로 전환하려면 upstream 수정 대기 또는 로컬 패치 필요.

장점 (Ollama 대비):

  • 별도 데몬 관리 불필요
  • Metal/CUDA 자동 감지
  • 프로세스 내부 호출 → 오버헤드 최소
  • 모델 파일 ~/.cache/qmd/models/에 자동 관리

단점:

  • 모델 공유 불가 (다른 도구가 Ollama를 쓰면 모델 중복 다운로드)
  • 한 시점에 하나의 임베딩 모델만 활성 (swap 시 재임베드 필요)

2.2 데이터 위치

경로용도
~/.config/qmd/index.yml사용자 전역 collection 설정
~/.cache/qmd/index.sqlite인덱스 DB (BM25 + 벡터)
~/.cache/qmd/models/GGUF 모델 파일 (자동 다운로드)
/tmp/qmd-reindex-cmds-llm-wiki.log자동 재인덱싱 로그

3. 설치 (이미 완료됨)

이 섹션은 참고용 기록. 이미 설치된 환경을 재구성할 때 사용.

3.1 사전 요구사항

bash
# Node.js 22+ (이미 설치, v22.22.1)
node --version

# Bun 1.0+ (이미 설치, 1.3.11)
bun --version

# Homebrew SQLite (이미 설치, 3.51.3)
brew install sqlite

3.2 qmd 설치

bash
bun install -g @tobilu/qmd

Postinstall 블록 경고

Bun이 node-llama-cpp postinstall을 자동 차단한다. 일반적으로 문제없지만, 네이티브 백엔드 문제 발생 시:

bash
cd ~/.bun/install/global/node_modules/node-llama-cpp
node ./dist/cli/cli.js postinstall

3.3 저장소 clone (참고용)

bash
cd /Users/yohankoo/DEV && git clone https://github.com/tobi/qmd

~/DEV/qmd/ — 소스 참조. 실제 실행은 ~/.bun/bin/qmd.


4. 한국어 임베딩 모델 설정

4.1 선택한 모델: Qwen3-Embedding-0.6B

  • HuggingFace URI: hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf
  • 크기: 639 MB (Q8_0 양자화)
  • 임베딩 차원: 1024
  • 언어 지원: 119개 언어, 명시적 CJK (Chinese-Japanese-Korean) 최적화
  • 선택 이유:
    • qmd 작성자가 공식 권장하는 multilingual 옵션
    • CJK 토크나이저가 한국어 어간 분리 처리
    • 영어 쿼리 ↔ 한국어 문서 cross-lingual 검색 지원
    • Q8_0 정확도 손실 ≤ 1%로 FP16 대비 절반 크기

4.2 환경변수 설정 (이미 완료됨)

~/.zshrc 끝에 추가:

bash
# === CMDS LLM Wiki — qmd (Karpathy Pattern) ===
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"

4.3 다른 모델로 교체할 때

모델 교체 시 전체 재임베드 필요:

bash
# 1. 환경변수 변경 후
export QMD_EMBED_MODEL="hf:<different-model>"

# 2. 강제 재임베드 (벡터 차원이 다를 경우 필수)
qmd embed -f

한국어 특화 대안 모델 (아직 GGUF 없음, 필요 시 직접 변환 필요):

  • nlpai-lab/KURE-v1 — Korean Universal Retrieval Embedding
  • dragonkue/bge-m3-ko — BGE-M3 Korean fine-tune
  • snunlp/KR-SBERT-V40K-klueNLI-augSTS — KLUE-NLI 기반

GGUF 변환: llama.cpp/convert_hf_to_gguf.py 참조.


5. Config 파일 (~/.config/qmd/index.yml)

5.1 현재 설정

yaml
global_context: |
  CMDS LLM Wiki — Karpathy 3-Layer Architecture.
  - Raw Sources (immutable, ingested originals)
  - Wiki (LLM-maintained pages: Concepts, Entities, Guides, MOCs)
  - Queries (synthesized answers filed back as compounding knowledge).

collections:
  wiki:
    path: /Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/20. Wiki
    pattern: "**/*.md"
    context:
      "/21. Concepts": "Abstract concepts, patterns, methodologies"
      "/22. Entities": "People, organizations, products"
      "/23. Guides": "How-to and practical implementation guides"
      "/24. Maps": "Map of Content (MOC) — topic-based indexes"

  raw_sources:
    path: /Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/10. Raw Sources
    pattern: "**/*.md"
    context:
      "/": "Immutable source documents — Wiki references via `source:` frontmatter"
      "/11. Articles": "Web articles, blog posts, gists"
      "/12. Papers": "Academic papers and technical reports"

  queries:
    path: /Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/30. Queries
    pattern: "**/*.md"

5.2 Context 어노테이션의 효과

context 필드는 LLM 재순위 단계에서 힌트로 사용된다. 예: "이 파일은 21. Concepts 아래 있음" → LLM이 "추상 개념 페이지"로 인지하고 관련성 판정에 반영.

5.3 볼트 내 백업본

CMDS_LLM_Wiki/90. Settings/qmd-config-template.yml — git-tracked 템플릿. 재설치 시:

bash
cp "90. Settings/qmd-config-template.yml" ~/.config/qmd/index.yml
qmd update && qmd embed

6. CLI 명령어 Cheat Sheet

6.1 기본 검색

bash
# Hybrid 검색 (BM25 + 벡터 + LLM 재순위, 권장)
qmd query "LLM Wiki 패턴의 핵심은?"

# 키워드만 (BM25, LLM 미사용)
qmd search "Karpathy"

# 벡터만 (시맨틱, 의미 검색)
qmd vsearch "지식 관리의 유지보수 문제"

# 결과 개수 제한
qmd query "Memex" -n 5

# 특정 collection만
qmd query "Memex" -c wiki
qmd vsearch "보안 취약점" -c raw_sources

6.2 출력 형식

bash
qmd query "..." --json        # JSON
qmd query "..." --md          # Markdown
qmd query "..." --files       # 파일 경로만
qmd query "..." --full        # 전체 내용
qmd query "..." --explain     # 스코어 상세
qmd query "..." --min-score 0.5

6.3 파일 조회

bash
# 단일 문서
qmd get "wiki/21-concepts/llm-wiki-pattern.md"

# 특정 라인 범위
qmd get "wiki/21-concepts/llm-wiki-pattern.md:30 -l 20"

# 일괄 조회 (glob 또는 docid 목록)
qmd multi-get "wiki/22-entities/*.md"

6.4 인덱스 관리

bash
qmd status              # 전체 상태
qmd collection list     # collection 목록
qmd ls wiki             # 특정 collection 파일 목록
qmd ls wiki/24-maps     # 하위 경로만

qmd update              # 변경 파일 재인덱싱 (BM25)
qmd update --pull       # git pull 후 재인덱싱
qmd embed               # 벡터 임베딩 갱신
qmd embed -f            # 강제 전체 재임베드 (모델 교체 후)

qmd cleanup             # 캐시 정리, DB vacuum

6.5 Context 메타데이터 (수동 어노테이션)

특정 파일에 검색 힌트 추가:

bash
qmd context add "qmd://wiki/21-concepts/llm-wiki-pattern.md" "Core pattern — start here for Karpathy pattern questions"
qmd context list

7. MCP 서버 — Claude Code 네이티브 통합

7.1 등록 상태 (이미 완료)

bash
claude mcp list | grep qmd
# qmd: qmd-mcp-wiki  - ✓ Connected

7.2 등록 방식

환경변수를 stdio MCP에 전달하기 위해 래퍼 스크립트 사용:

파일: ~/.bun/bin/qmd-mcp-wiki

bash
#!/usr/bin/env bash
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
exec qmd mcp "$@"

Claude Code 등록 (user scope, 모든 프로젝트에서 접근 가능):

bash
claude mcp add -s user qmd qmd-mcp-wiki

7.3 LLM이 MCP로 할 수 있는 것

Claude Code 세션에서 다음 도구들이 자동 노출됨:

  • qmd__query — hybrid search
  • qmd__search — BM25 only
  • qmd__vsearch — vector only
  • qmd__get — 파일 내용 조회
  • qmd__multi_get — 일괄 조회
  • qmd__status — 인덱스 상태
  • qmd__ls — collection 탐색

즉, LLM이 Bash 없이도 네이티브로 위키 검색 가능.

7.4 재설정이 필요한 경우

bash
claude mcp remove qmd
claude mcp add -s user qmd qmd-mcp-wiki

8. 자동 재인덱싱 Hook

8.1 작동 방식

  • 트리거: PostToolUse (Write / Edit / MultiEdit)
  • 스코프: CMDS_LLM_Wiki 내부의 *.md 파일만
  • 제외: 00. Inbox/ (ingest 전 staging)
  • 디바운스: 8초 (burst 쓰기를 하나의 재인덱싱으로 병합)
  • 실행: 백그라운드, 메인 세션 논블로킹

8.2 Hook 파일

등록: CMDS_LLM_Wiki/.claude/settings.json

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/qmd-reindex.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

스크립트: CMDS_LLM_Wiki/.claude/hooks/qmd-reindex.sh (디바운스 + 백그라운드 실행)

8.3 수동 실행이 필요한 경우

  • Obsidian에서 직접 편집 (Claude Code 외부, hook 미발화)
  • 외부 도구로 대량 파일 변경
  • 임베딩 모델 교체 후
  • Hook 오류 발생 시
bash
# 수동 재인덱싱
qmd update && qmd embed

# 또는 Claude Code 세션 내에서
/reindex

8.4 로그 확인

bash
tail -f /tmp/qmd-reindex-cmds-llm-wiki.log

9. Workflow — 일상 사용

9.1 Ingest 후 자동 반영

새 자료 ingest → Claude Code가 Write 도구로 Wiki 페이지 생성 → PostToolUse hook 발화 → 8초 debounce 후 qmd update && qmd embed → 새 페이지 즉시 검색 가능.

사용자가 신경 쓸 것 없음.

9.2 Query 시 의사결정 트리

질문이 있다
├── 자연어 + 모호 → qmd query "..."  (권장, 재순위 포함)
├── 정확한 키워드 매치 → qmd search "..."  (빠름)
├── 시맨틱만, 속도 우선 → qmd vsearch "..."
└── 특정 파일 참조 → qmd get "path"

9.3 Obsidian 직접 편집 후

bash
/reindex     # 또는 터미널에서 qmd update && qmd embed

9.4 Lint 워크플로우와의 통합

/lint가 모순 · orphan · stale 검사 시 qmd를 활용 가능:

bash
# 모순 검사 예시
qmd search "contradiction" -c wiki
qmd query "이 페이지와 같은 주제를 다루는 다른 페이지는?"

# orphan 검사 (backlink 0인 페이지)
qmd ls wiki | while read page; do
  backlinks=$(qmd query "[[$page]]" --files | wc -l)
  [ "$backlinks" -eq 0 ] && echo "ORPHAN: $page"
done

10. 통합 구조 요약

┌─────────────────────────────────────────────────────────────┐
│  CMDS_LLM_Wiki (Obsidian Vault, Karpathy 3-Layer)           │
│                                                              │
│  10. Raw Sources/   ← immutable originals                    │
│  20. Wiki/          ← LLM-synthesized pages                  │
│  30. Queries/       ← filed-back query results               │
│         │                                                    │
│         │ Write/Edit                                         │
│         ▼                                                    │
│  .claude/hooks/qmd-reindex.sh  (PostToolUse, debounce 8s)    │
│         │                                                    │
│         ▼                                                    │
│  qmd update && qmd embed   ← background, Metal GPU           │
│         │                                                    │
│         ▼                                                    │
│  ~/.cache/qmd/index.sqlite                                   │
│         ▲                                                    │
│         │                                                    │
│  ┌──────┴──────────────────────────────────────────┐         │
│  │ Query access:                                    │         │
│  │ • Terminal: qmd query "..."                      │         │
│  │ • Claude Code: qmd__query MCP tool (native)      │         │
│  │ • /reindex (manual fallback)             │         │
│  └──────────────────────────────────────────────────┘         │
└─────────────────────────────────────────────────────────────┘

11. Troubleshooting

11.1 Dimension mismatch: Expected 1024 dimensions but received 768

원인: 인덱스 생성 시 모델과 쿼리 실행 시 모델의 임베딩 차원이 다름.

해결: env var이 새 셸에 상속되지 않았을 가능성. 다음 중 하나:

bash
# 현재 셸에 export
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"

# 또는 .zshrc 재로드
source ~/.zshrc

# 새 터미널 열기

11.2 ggml_metal_library_init_from_source: error compiling source

원인: Metal shader 런타임 컴파일 경고. 일반적으로 fallback으로 CPU/일부 기능 비활성화.

실제 영향: 대부분 무해. qmd status에서 "GPU: metal (offloading: yes)" 확인되면 Metal 활성.

11.3 첫 query 시 지연

원인: 쿼리 확장 모델 (1.28GB) 첫 다운로드.

해결: 기다리거나, vsearch(확장 불필요)로 우회:

bash
qmd vsearch "쿼리" -n 3

11.4 Hook이 발화하지 않음

점검:

bash
# Hook 실행 권한
ls -la "/Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/.claude/hooks/qmd-reindex.sh"

# settings.json 로드 확인
cat "/Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/.claude/settings.json"

# 수동 실행 테스트
echo '{"tool_input":{"file_path":"/Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/20. Wiki/test.md"}}' | \
  "/Users/yohankoo/Local Obsidian_MBP/CMDS_LLM_Wiki/.claude/hooks/qmd-reindex.sh"

11.5 MCP 연결 실패

bash
# 래퍼 직접 실행 테스트 (Ctrl+C로 종료)
qmd-mcp-wiki

# 재등록
claude mcp remove qmd
claude mcp add -s user qmd qmd-mcp-wiki
claude mcp list | grep qmd

12. Quick Reference

12.1 설치된 구성 파일

파일용도
~/.config/qmd/index.ymlCollection 설정 (3 collections)
~/.zshrc (line: QMD_EMBED_MODEL)Korean embedding env var
~/.bun/bin/qmdqmd CLI 바이너리
~/.bun/bin/qmd-mcp-wikiMCP 래퍼 스크립트
~/.claude.json (user scope)MCP 서버 등록
CMDS_LLM_Wiki/.claude/settings.jsonPostToolUse hook 등록
CMDS_LLM_Wiki/.claude/hooks/qmd-reindex.sh자동 재인덱싱 스크립트
CMDS_LLM_Wiki/.claude/commands/reindex.md/reindex 수동 명령
CMDS_LLM_Wiki/90. Settings/qmd-config-template.ymlConfig 백업/템플릿
/Users/yohankoo/DEV/qmd/qmd 저장소 clone (참고용)

12.2 자주 쓰는 명령

bash
# 기본 검색
qmd query "<자연어 질문>"

# 상태
qmd status

# 재인덱싱
qmd update && qmd embed

# Claude Code 세션 내
/reindex

12.3 관련 CMDS 가이드

  • [[Obsidian CLI 사용 가이드 (CMDS)]] — 자매 도구 (Obsidian 앱 제어)

12.4 외부 레퍼런스


Setup 완료일

2026-04-14 — CMDS_LLM_Wiki 기준 32 문서 (28 Wiki + 3 Raw Sources + 1 Query), 69 chunks, Qwen3-Embedding-0.6B (1024 dim) 벡터화 완료. Metal GPU 활용, embed 소요 15초.