はじめに
QMD メモリエンジン
QMD は、OpenClaw と並行して動作するローカルファーストの検索サイドカーです。 BM25、ベクトル検索、リランキングを単一のバイナリに統合し、ワークスペースのメモリファイル以外のコンテンツもインデックス化できます。
組み込み機能に加えて提供されるもの
- リランキングとクエリ拡張により再現率を向上。
- 追加ディレクトリをインデックス化 - プロジェクトドキュメント、チームノート、ディスク上のあらゆるもの。
- セッショントランスクリプトをインデックス化 - 以前の会話を呼び出せます。
- 完全ローカル - 公式の llama.cpp プロバイダー Plugin で動作し、 GGUF モデルを自動ダウンロードします。
- 自動フォールバック - QMD が利用できない場合、OpenClaw はシームレスに 組み込みエンジンへフォールバックします。
はじめに
前提条件
- QMD をインストールします:
npm install -g @tobilu/qmdまたはbun install -g @tobilu/qmd - 拡張機能を許可する SQLite ビルド(macOS では
brew install sqlite)。 - QMD が Gateway の
PATHに含まれている必要があります。 - macOS と Linux では、そのまま動作します。Windows では WSL2 の使用が最も適切にサポートされています。
有効化
{ memory: { backend: "qmd", },}OpenClaw は ~/.openclaw/agents/<agentId>/qmd/ の下に自己完結型の QMD ホームを作成し、
サイドカーのライフサイクルを自動的に管理します。コレクション、更新、埋め込みの実行は自動で処理されます。
現在の QMD コレクション形式と MCP クエリ形式を優先しますが、必要に応じて
代替のコレクションパターンフラグや古い MCP ツール名へフォールバックします。
また、同名の古い QMD コレクションが残っている場合、起動時の調整によって、
古くなった管理対象コレクションが正規パターンで再作成されます。
サイドカーの仕組み
- OpenClaw は、ワークスペースのメモリファイルと設定済みの
memory.qmd.pathsからコレクションを作成します。QMD アダプターが更新、埋め込み、デバウンス、 タイムアウトのヒューリスティクスを管理し、これらはユーザー設定ではありません。 - QMD は引き続き、エージェントごとの QMD ホーム内にある
index.sqlite、YAML コレクション設定、 モデルのダウンロードを管理します。これらは外部ツールのアーティファクトであり、 OpenClaw の状態テーブルではありません。OpenClaw が所有する調整情報は SQLite のみに存在します。 1 つの共有リースがエージェント間の埋め込み処理を制限し、各エージェントデータベース内の 1 つのリースが、そのエージェントのコレクション、更新、埋め込みの書き込みを直列化します。 ランタイムは QMD のファイルロックサイドカーを作成しなくなりました。openclaw doctor --fixは、 以前のプロセス所有者が古くなっていることを確認した後にのみ、廃止されたサイドカーを削除します。 アップグレードは完全な切り替えです。新しいバージョンを使用する前に、 状態ディレクトリを共有するすべての OpenClaw プロセスを停止して再起動してください。 新旧の QMD ライターの混在はサポートされておらず、ランタイムは意図的に、 廃止されたサイドカーとの二重ロックを行いません。 - デフォルトのワークスペースコレクションは、
MEMORY.mdとmemory/ツリーを追跡します。小文字のmemory.mdは、ルートメモリファイルとしてインデックス化されません。 - QMD 独自のスキャナーは、非表示パスと、
.git、.cache、node_modules、vendor、dist、buildなどの一般的な依存関係/ビルドディレクトリを無視します。Gateway の起動時には QMD は遅延初期化され、 メモリが最初に使用されたときにマネージャーが初期化されます。 - 検索では、設定済みの
searchMode(デフォルト:search、vsearchとqueryにも対応)を使用します。searchは BM25 専用なので、そのモードでは OpenClaw は セマンティックベクトルの準備状況プローブと埋め込みメンテナンスを省略します。モードが 失敗した場合、OpenClaw はqmd queryで再試行します。 searchModeがqueryの場合、memory.qmd.rerankをfalseに設定すると、 リランカーを使用せずに QMD のハイブリッドクエリパスを利用できます(QMD 2.1 以降が必要)。 OpenClaw は、直接 QMD CLI パスには--no-rerankを、 QMD の MCP クエリツールにはrerank: falseを渡します。- 複数コレクションフィルターへの対応を通知する QMD リリースでは、OpenClaw は 同じソースのコレクションを 1 回の QMD 検索呼び出しにまとめます。古い QMD リリースでは、 互換性のあるコレクションごとのフォールバックを維持します。
- QMD が完全に失敗した場合、OpenClaw は組み込みの SQLite エンジンへフォールバックします。
バイナリの欠落やサイドカー依存関係の破損によって再試行ストームが発生しないよう、
オープン失敗後はチャットターンでの再試行を短時間バックオフします。
openclaw memory statusと 1 回限りの CLI プローブでは、引き続き QMD を 直接再確認します。
検索パフォーマンスと互換性
OpenClaw は、現在および古い QMD インストールの両方と互換性のある QMD 検索パスを維持します。
起動時に、OpenClaw はマネージャーごとにインストール済み QMD のヘルプテキストを 1 回確認します。 バイナリが複数のコレクションフィルターへの対応を通知している場合、OpenClaw は 同じソースのすべてのコレクションを 1 つのコマンドで検索します。
qmd search "router notes" --json -n 10 -c memory-root-main -c memory-dir-mainこれにより、永続メモリコレクションごとに QMD サブプロセスを 1 つ起動することを回避できます。
セッショントランスクリプトのコレクションは独自のソースグループに残るため、
memory + sessions の混合検索でも、両方のソースからの入力を
結果ダイバーシファイアーに渡せます。
古い QMD ビルドでは、コレクションフィルターを 1 つしか受け付けません。OpenClaw が そのようなビルドを検出すると、互換性パスを維持し、結果をマージして重複排除する前に 各コレクションを個別に検索します。
インストール済みの契約を手動で確認するには、次を実行します。
qmd --help | grep -i collection現在の QMD ヘルプには、1 つ以上のコレクションを対象にできることが記載されています。 古いヘルプでは通常、単一のコレクションについて説明されています。
モデルのオーバーライド
QMD モデルの環境変数は Gateway プロセスから変更されずに渡されるため、新しい OpenClaw 設定を追加せずに QMD をグローバルに調整できます。
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"export QMD_RERANK_MODEL="/absolute/path/to/reranker.gguf"export QMD_GENERATE_MODEL="/absolute/path/to/generator.gguf"埋め込みモデルを変更した後は、インデックスが新しいベクトル空間と一致するように 埋め込みを再実行してください。
追加パスのインデックス化
追加ディレクトリを QMD に指定して、検索可能にします。
{ memory: { backend: "qmd", qmd: { paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }], }, },}追加パスからのスニペットは、検索結果に qmd/<collection>/<relative-path> として
表示されます。memory_get はこのプレフィックスを認識し、
正しいコレクションルートから読み取ります。
セッショントランスクリプトのインデックス化
以前の会話を呼び出せるようにするには、セッションのインデックス化を有効にします。QMD には、
一般的な memory.search セッションソースと QMD トランスクリプトエクスポーターの両方が必要です。
{ memory: { backend: "qmd", search: { experimental: { sessionMemory: true }, sources: ["memory", "sessions"], }, qmd: { sessions: { enabled: true }, }, },}トランスクリプトは、サニタイズされたユーザー/アシスタントのターンとして、
~/.openclaw/agents/<id>/qmd/sessions/ 配下の専用 QMD コレクションにエクスポートされます。
sources: ["sessions"] のみを設定しても、トランスクリプトは QMD にエクスポートされません。
rememberAcrossConversations または明示的な QMD セッションエクスポートも有効にしてください。
セッションのヒットは、引き続き
tools.sessions.visibility によってフィルタリングされます。
デフォルトの tree 可視性には、現在のセッション、そのセッションから生成されたセッション、
および周囲のグループ認識を通じて監視される同一エージェントのグループセッションが含まれます。
session.dmScope: "main" の場合、マルチユーザー DM 構成のユーザーはメインセッションを共有し、
その監視対象グループのコンテンツを呼び出せます。DM を分離するにはピアごとの
dmScope を使用するか、可視性を "self" に設定して、周囲の監視対象セッションの
読み取りを無効にします。その他の無関係な同一エージェントのセッションには、引き続き
"agent" 可視性が必要です。
検索範囲
デフォルトでは、QMD の検索結果はダイレクトセッションにのみ表示され、
グループチャットやチャンネルチャットには表示されません。これを変更するには memory.qmd.scope を設定します。
{ memory: { qmd: { scope: { default: "deny", rules: [{ action: "allow", match: { chatType: "direct" } }], }, }, },}上記のスニペットが実際のデフォルトルールです。スコープによって検索が拒否されると、 OpenClaw は導出されたチャンネルとチャットタイプを含む警告を記録するため、 空の結果をデバッグしやすくなります。
引用
memory.citations が auto または on の場合、検索スニペットには
Source: <path>#L<line>(または #L<start>-L<end>)フッターが追加されます。auto
モードでは、フッターはダイレクトチャットセッションにのみ追加されます。
エージェントには内部的にパスを渡しつつフッターを省略するには、
memory.citations = "off" を設定します。
使用する場面
次のものが必要な場合は QMD を選択します。
- リランキングによる、より高品質な結果。
- ワークスペース外のプロジェクトドキュメントやノートの検索。
- 過去のセッション会話の呼び出し。
- API キーを使用しない完全ローカル検索。
より単純な構成では、追加の依存関係なしで 組み込みエンジンが適切に動作します。
トラブルシューティング
QMD が見つかりませんか? バイナリが Gateway の PATH に含まれていることを確認してください。
OpenClaw をサービスとして実行している場合は、シンボリックリンク
sudo ln -s ~/.bun/bin/qmd /usr/local/bin/qmd を作成します。
シェルでは qmd --version が動作するのに OpenClaw が
spawn qmd ENOENT を報告する場合、Gateway プロセスの PATH が
対話型シェルとは異なっている可能性があります。バイナリを明示的に固定してください。
{ memory: { backend: "qmd", qmd: { command: "/absolute/path/to/qmd", }, },}QMD がインストールされている環境で command -v qmd を使用し、その後
openclaw memory status --deep で再確認します。
最初の検索が非常に遅いですか? QMD は初回使用時に GGUF モデルをダウンロードします。
OpenClaw が使用するものと同じ XDG ディレクトリを使用して、qmd query "test" で事前ウォームアップしてください。
検索中に多数の QMD サブプロセスが発生しますか? 可能であれば QMD を更新してください。
OpenClaw は、インストール済み QMD が複数の -c フィルターへの対応を
通知している場合にのみ、同じソースの複数コレクション検索に 1 つのプロセスを使用します。
それ以外の場合、正確性を維持するため、古いコレクションごとのフォールバックを使用します。
BM25 専用の QMD が引き続き llama.cpp をビルドしようとしますか?
memory.qmd.searchMode = "search" を設定してください。OpenClaw はそのモードを
字句検索専用として扱い、QMD のベクトル状態プローブと埋め込みメンテナンスを省略し、
セマンティック準備状況の確認を vsearch または query の構成に委ねます。
検索がタイムアウトしますか? memory.qmd.limits.timeoutMs(デフォルト: 4000ms)を増やしてください。
低速なハードウェアでは、たとえば 120000 のように高い値に設定します。この制限は、
エージェントの memory_search 呼び出し中に実行される QMD 独自の検索コマンドに適用されます。
セットアップ、同期、組み込みフォールバック、補助コーパス処理には、それぞれ独自の短い期限が維持されます。
グループチャットやチャンネルチャットで結果が空になりますか? ダイレクトセッションのみを許可する
デフォルトの memory.qmd.scope では、これは想定された動作です。そこで QMD の結果を使用する場合は、
group または channel のチャットタイプに対する
allow ルールを追加してください。
ルートメモリ検索の範囲が突然広くなりすぎましたか? Gateway を再起動するか、
次回の起動時調整を待ってください。OpenClaw は、同名の競合を検出すると、
古くなった管理対象コレクションを正規の MEMORY.md および memory/
パターンで再作成します。
ワークスペースから見える一時リポジトリが ENAMETOOLONG やインデックス化の破損を引き起こしていますか?
QMD の走査では、OpenClaw の組み込みシンボリックリンクルールではなく、
基盤となる QMD スキャナーに従います。QMD が循環を安全に処理する走査または
明示的な除外制御を提供するまでは、一時的なモノレポのチェックアウトを
.tmp/ のような非表示ディレクトリ内、またはインデックス対象の QMD ルート外に配置してください。
設定
完全な設定項目(memory.qmd.*)、検索モード、更新間隔、
スコープルール、その他すべての調整項目については、
メモリ設定リファレンスを参照してください。