0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

うろ覚えの一文でメモが一発ヒット。Shopify CEOが個人開発したローカルRAG「qmd」×Obsidian×Claude Codeをやってみた結果

0
Last updated at Posted at 2026-07-05

メモは書くほど見つからなくなる

Obsidian に YouTube の要約や技術メモを毎日溜めていたら、800 ファイルを超えたあたりで検索が破綻しました。

「人に教えるのが一番勉強になる、みたいな話をどこかでメモした気がする」——覚えているのはこの程度。キーワード検索で「教える」と打っても、ヒットが多すぎるか、言い回しが違って見つからないかのどちらかです。書いたときの単語を思い出せないと負け、というゲームになっていました。

これを qmd というローカル RAG 検索エンジンで解決したので、セットアップから Claude Code 連携までを共有します。埋め込みパイプラインの自前実装はゼロです。

うろ覚えの一文で、目的のノートが1位に出る

qmd を入れると、うろ覚えの一文をそのまま投げるだけで目的のノートが 1 位で返ってきます。

qmd-urooboe-search.png

クエリは「人に教えることが一番の勉強になるという話をどこかで見た」。ヒットしたのは t_wada さんのインタビュー動画の要約ノートで、該当箇所は「プロテージ効果(教えることが最深の学び)」という一節です。クエリと同じ単語がほぼ入っていないのに、意味で当ててくるのがポイントです。

さらに Claude Code と繋ぐと、検索という操作自体が消えて「聞くだけ」になります(後述)。

qmd とは — RAG を自分で実装しなくていい

qmd は Shopify CEO の Tobi Lütke が個人開発している OSS の Markdown 検索エンジンです。RAG 検索に必要な部品が全部入りで、こちらで実装するものは何もありません。

検索の流れは「クエリ拡張 → 3 層検索」の 4 段構成で、それぞれ担当が分かれています。

段階 技術 役割
クエリ拡張(前処理) qmd-query-expansion-1.7B うろ覚えの一文を複数の検索クエリに自動で言い換える
第1層: BM25 全文検索 SQLite FTS5 キーワードの完全一致に強い
第2層: ベクター検索 sqlite-vec + embeddinggemma-300M 意味の近さで探す
第3層: リランキング qwen3-reranker-0.6B 上位候補を LLM で並べ直す

lex: vec: hyde: の行がクエリ拡張の出力です。「教える → 教授するという経験」のような表記ゆれを機械側が吸収してくれるので、人間は正確なキーワードを思い出さなくてよくなります。前にもDifyで同じような構成のRAGの構築を紹介しましたが、今回はローカルでかなり手軽に導入できるのが魅力です。

モデルは 3 つ合計で約 2.1GB。すべて GGUF 形式のローカルモデルで、推論も含めて完全にローカルで完結します。個人メモを外部 API に投げたくない人にはこれが決定打だと思います。

セットアップ — 手を動かすのは10分、あとはダウンロード待ち

動作確認環境: macOS(Apple Silicon / M4 Pro)+ Bun 1.3.14 + qmd は 2026-07 時点の main ブランチです。

前提は 2 つ。Bun(未導入なら curl -fsSL https://bun.sh/install | bash)と、macOS の場合は Homebrew 版 SQLite です。

brew install sqlite

Homebrew 版が要るのは、macOS 標準の SQLite は拡張機能のロードが無効化されていて、ベクター検索(sqlite-vec)が動かないためです。入れておけば qmd が自動で見つけて使ってくれます(後述の qmd doctor で SQLite runtime のバージョンが Homebrew 版になっていれば OK)。

本体は GitHub からインストールします。

bun install -g https://github.com/tobi/qmd

注意: npm レジストリにも qmd という名前のパッケージがありますが、無関係の別物(v0.0.0 のプレースホルダ)です。GitHub からのインストール一択です(2026-07 時点で確認)。

Bun はセキュリティのため、インストール時に postinstall スクリプトを勝手に実行しません。qmd はソース配布なので、スクリプト実行を許可したうえで手動ビルドまで済ませます。

bun pm -g trust --all
cd ~/.bun/install/global/node_modules/@tobilu/qmd
bun install && bun run build
qmd doctor   # セットアップ検証

--all はブロック中の全パッケージのスクリプトを許可します。気になる場合は bun pm -g untrusted で対象一覧(node-llama-cpp と tree-sitter 系)を確認してから、bun pm -g trust <パッケージ名> で個別に許可してください。

なお、この時点の qmd doctor は「モデルが無い」と警告を出しますが、次の qmd pull で消えます。ここでは SQLite runtime のバージョンが確認できれば OK です。

次にモデル 3 つ(約 2.1GB)をダウンロードします。

qmd pull

あとは vault を「コレクション」として登録し、説明文(コンテキスト)を付け、埋め込みを生成するだけです。

qmd collection add ~/vault/private --name private
qmd context add qmd://private "個人ノート。動画の要約、Webクリップ、技術メモなど"
qmd embed

コンテキストは検索時に LLM へ渡され、精度に効いてきます。

埋め込み生成の実測は、約 850 ファイル → 6,187 チャンクで 4分41秒(M4 Pro)でした。インデックスは ~/.cache/qmd/index.sqlite の 1 ファイルで、この規模なら 54MB です。

検索は「速いBM25」と「賢いハイブリッド」を使い分ける

コマンドは 3 つあります。

コマンド 何が動くか 速度 使いどころ
qmd search BM25 のみ 一瞬 単語を覚えているとき
qmd vsearch ベクターのみ 数秒 意味で探したいとき
qmd query 全部入り(言い換え+検索+リランク) 20秒前後 うろ覚え・本気の検索

キーワードを覚えているなら BM25 で十分です。LLM を使わないので一瞬で返ります。

qmd-bm25-search.png

覚えていないときが qmd query の出番です。リランキングが重いので 20 秒ほどかかりますが、「見つからなくて 10 分 grep し続ける」よりずっと安い、という感覚です。

ちなみに差分検知はコンテンツハッシュベースです。エディタやプラグインがファイルを触っただけ(内容は不変)では再インデックス・再埋め込みは走りません。

Claude Code から使うと「検索」という操作が消える

qmd は MCP サーバーを内蔵しているので、Claude Code への登録は 1 行です。

claude mcp add qmd -- qmd mcp          # このプロジェクトだけ
claude mcp add --scope user qmd -- qmd mcp  # 全プロジェクトで使う場合

登録すると query get multi_get status の 4 ツールが生えて、Claude が質問の内容から勝手に検索してくれます。

実際にヘッドレスで聞いてみた結果がこれです。検索コマンドを 1 文字も打っていません。

qmd-claude-demo.png

動画名・要点 3 行・出典ファイルパスまで返ってきています。「探す → 開く → 読む → 要約する」が全部 1 回の質問に畳み込まれるので、体験としては検索というよりナレッジベースとの対話です。

レイテンシについて正直に書いておくと、MCP 経由でも検索 1 回あたり 10〜20 秒程度かかります(リランキングが支配的なため)。ただし待つのは Claude であって自分ではないので、体感は「質問を投げて、答えを読む」だけです。

インデックスは夜間バッチで勝手に最新になる

メモは毎日増えるので、インデックス更新は cron / launchd に任せます。差分だけ処理されるので、日々の実行は数十秒で終わります。

qmd update   # ファイルの追加・変更を再インデックス
qmd embed    # 新規チャンクだけ埋め込み生成

1 つだけ罠があって、launchd / cron の PATH には ~/.bun/bin が入っていません。スクリプト側で足しておきます。

export PATH="$HOME/.bun/bin:$PATH"
qmd update && qmd embed

うちでは毎晩 0 時に走っている既存の launchd ジョブの最後にこの 2 行を足しました。インデックスが 1 日古くても実害はないので、失敗しても通知を出すだけにして、同居している他の夜間処理は止めない扱いにしています。

ハマりどころ3つ — 偽npmパッケージ・未ビルド・PATH

実際に踏んだ順に、要点だけ再掲します(詳細は各節)。

  1. npm の qmd は別物。インストールは GitHub から bun install -g https://github.com/tobi/qmd 一択(セットアップ節参照)
  2. 入れただけでは動かないqmd --version が「not built」と言ってきたら、trust + 手動ビルドが必要。qmd doctor が SQLite・モデル・GPU をまとめて診断してくれるので便利
  3. 夜間バッチで command not found: qmd。launchd / cron の PATH に ~/.bun/bin を足す

まとめ

  • qmd を使うと、BM25 + ベクター + リランキングの 3 層 RAG 検索が 自前実装ゼロ・完全ローカル で手に入る
  • うろ覚えの一文で目的のノートが 1 位に出る。書いたときの単語を思い出すゲームからの解放
  • Claude Code に MCP 登録すると「検索する」が「聞くだけ」になる
  • 埋め込み生成は 850 ファイルで 5 分弱、夜間バッチに qmd update && qmd embed を足せば運用は放置

Obsidian にメモを溜めていて Claude Code を使っている人なら、1~2時間でできます。おすすめです。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?