Claude Code のセッション履歴をベクトル検索できる QMD を入れた

nanoclaw(Claude Code の fork)をアップデートしているとき、内部で QMD が使われているのを見かけた。調べてみたら「お、これ良さそう」となったので入れた。

QMD とは

QMD は、ローカルの Markdown ファイルを対象に検索エンジンを立てる CLI ツール兼 MCP サーバー。単純な grep と違うのは、BM25(キーワード検索)とベクトル検索を組み合わせて意味的に近いドキュメントを引けること。検索用の埋め込みモデルもローカルで動く(GPU がなくても動作する、が後ほど書くけど CPU だとクソ重い処理が一回だけある)。

インストール

本体は以下のように、npm でインストール。

npm install -g @tobilu/qmd

Claude Code はプラグインとして追加する。

claude plugin marketplace add tobi/qmd
claude plugin install qmd@qmd

今回やりたかったことと設定

自分は複数のリポジトリで Claude Code を使っていて、技術的な会話もリポジトリをまたいでいる。そこで、QMD のコレクションに全リポジトリのセッション Markdown を入れておけば、「あのリポジトリでやった話、なんだったっけ」を後から引ける。

同じようなことを実現できるものとして、claude-mem がある。

そもそもこれ入れればいいじゃんって話もあるけど、なんか分からんけど直感で QMD いいかもって思ってしまったので仕方ない。直感で突き進みます。

まずは、Claude のセッションをマークダウンに変換するスクリプト convert-sessions.js を用意して、~/.claude/hooks 配下に配置。

Claude Code 使い始めたのが割と最近なので、セッション数も100ほど。これをまず全部マークダウンへ変換して、~/.cache/qmd-sessions へ配置する。

そして、このディレクトリを QMD へ食わせる。

qmd collection add ~/.cache/qmd-sessions --name claude-sessions

これだけだと過去のセッションだけの登録になってしまうので、終わったセッションを片っ端から食わせるために、Stop hook に仕掛けを入れた。

Stop hook でセッション履歴を自動インデックス

Claude Code にはセッション終了時に発火する Stop hook があって、そこに以下を仕込んである:

  1. セッションの JSONL ファイルを Markdown に変換するスクリプト(convert-sessions.js)が走る
  2. qmd update で新規セッションをインデックスに追加する

これで Claude Code のセッションが終わるたびに、そのセッションの内容が QMD に取り込まれていく。

ひとつ工夫したことがあって、セッションの内容によっては、「うわ全然上手くいかないわ。別のセッションでもう一回やろう」ということがあり、いわゆる捨てるセッションになることがある。

こういう内容は登録したくないため、セッションの最後に、「上手くいかないから別セッションにするわ。#ng」みたいにハッシュをつけることで、これがついているセッションは記録対象外にするロジックにした。

qmd embed がクソ重い

インデックスに追加するだけではだめで、qmd embed でドキュメントのベクトル埋め込みを生成する必要がある。ML モデルを回す重い処理なんだけど、初回実行に限り、これがクソ重い。すげー時間がかかる。

自分の環境は専用の GPU がないので CPU 処理になったんだけど、同じ環境の人は時間かかると思って覚悟しといてください。ML モデルのダウンロードはまあ時間がかかるのはいいとして、100 ファイル程度で合計数十分かかった(1回で終わらず3回走らせた)。

qmd update でインデックスに追加したら qmd embed を実行する必要があるんだけど、初回以外の動作は軽いので、これも Stop hook に仕込んで、qmd update && qmd embed とした。

が、この記事を書いた後確認してみたら、qmd embed が積み重なってる状態になって CPU ファンがうるさくなったのでやっぱりやめた。

qmd embed についてはひとまず寝る前に手で実行でいいかな…

この記事も QMD 使って書いてみた

この記事を書くときも実際にやってみた。RTK と QMD のインストール作業は別リポジトリ(dotfiles、nanoclaw)でやっていたので、QMD でそのセッションを検索して内容を確認しながら記事にした。grep じゃなくてベクトル検索なので、「rtk hook install」みたいな正確なキーワードを知らなくても「RTK のインストール手順」という意図で引っかかる。

しばらく使ってみてから、claude-mem も検討しようかと思う。