Sessions and memory

QMD メモリエンジン

QMD は、OpenClaw と並行して動作するローカルファーストの検索サイドカーです。BM25、ベクトル検索、再ランキングを単一のバイナリにまとめ、ワークスペースのメモリファイル以外のコンテンツもインデックス化できます。

組み込みより追加されること

  • 再ランキングとクエリ拡張により、より高い再現率を得られます。
  • 追加ディレクトリのインデックス化 -- プロジェクトドキュメント、チームノート、ディスク上の任意のもの。
  • セッション文字起こしのインデックス化 -- 以前の会話を思い出せます。
  • 完全ローカル -- 任意の node-llama-cpp ランタイムパッケージで動作し、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 マネージャーが開かれたときとその後の定期実行(デフォルトは 5 分ごと)で qmd update を実行します。これらの更新は QMD サブプロセス経由で実行され、プロセス内のファイルシステムクロールではありません。セマンティックモードでは qmd embed も実行されます。
  • デフォルトのワークスペースコレクションは MEMORY.mdmemory/ ツリーを追跡します。小文字の memory.md はルートメモリファイルとしてインデックス化されません。
  • QMD 独自のスキャナーは、隠しパスや .git.cachenode_modulesvendordistbuild などの一般的な依存関係/ビルドディレクトリを無視します。Gateway の起動ではデフォルトで QMD を初期化しないため、コールドブート時にはメモリが最初に使われるまでメモリランタイムのインポートや長寿命ウォッチャーの作成を避けられます。
  • それでも Gateway 起動時の更新が必要な場合は、memory.qmd.update.startupidle または immediate に設定します。オプトインの起動時更新は、完全な長寿命プロセス内ウォッチャーを作成する代わりに、ワンショットの QMD サブプロセスパスを使います。
  • 検索は設定済みの searchMode(デフォルト: searchvsearchquery もサポート)を使用します。search は BM25 のみなので、OpenClaw はそのモードではセマンティックベクトルの準備状況プローブと埋め込みメンテナンスをスキップします。モードが失敗した場合、OpenClaw は qmd query で再試行します。
  • 複数コレクションフィルターを通知する QMD リリースでは、OpenClaw は同一ソースのコレクションを 1 回の QMD 検索呼び出しにまとめます。古い QMD リリースでは、互換性のあるコレクション単位のフォールバックを維持します。
  • QMD が完全に失敗した場合、OpenClaw は組み込み SQLite エンジンへフォールバックします。バイナリ欠落や壊れたサイドカー依存関係で再試行の嵐が起きないよう、チャットターンでの繰り返し試行はオープン失敗後に短くバックオフします。openclaw memory status とワンショット CLI プローブは引き続き QMD を直接再確認します。

検索性能と互換性

OpenClaw は、QMD 検索パスを現在の 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 はこのプレフィックスを理解し、正しいコレクションルートから読み取ります。

セッション文字起こしのインデックス化

以前の会話を思い出すために、セッションのインデックス化を有効にします。

{
  memory: {
    backend: "qmd",
    qmd: {
      sessions: { enabled: true },
    },
  },
}

文字起こしは、サニタイズされた User/Assistant ターンとして ~/.openclaw/agents/<id>/qmd/sessions/ の下にある専用 QMD コレクションへエクスポートされます。

検索スコープ

デフォルトでは、QMD 検索結果はダイレクトセッションとチャンネルセッション(グループではない)に表示されます。これを変更するには memory.qmd.scope を設定します。

{
  memory: {
    qmd: {
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
    },
  },
}

スコープが検索を拒否した場合、OpenClaw は派生したチャンネルとチャット種別を含む警告をログに記録するため、空の結果をデバッグしやすくなります。

引用

memory.citationsauto または on の場合、検索スニペットには Source: <path#line> フッターが含まれます。フッターを省略しつつ、内部的にはパスをエージェントへ渡し続けるには、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.qmd.scope を確認してください -- デフォルトではダイレクトセッションとチャンネルセッションのみを許可します。

ルートメモリ検索が突然広すぎるようになりましたか? Gateway を再起動するか、次回の起動時照合を待ってください。OpenClaw は同名の競合を検出すると、古くなった管理対象コレクションを正規の MEMORY.mdmemory/ パターンに戻して再作成します。

ワークスペースから見える一時リポジトリが ENAMETOOLONG や壊れたインデックス化を引き起こしていますか? QMD のトラバーサルは現在、OpenClaw の組み込みシンボリックリンクルールではなく、基盤となる QMD スキャナーの挙動に従います。QMD がサイクル安全なトラバーサルまたは明示的な除外制御を公開するまでは、一時的なモノレポチェックアウトを .tmp/ のような隠しディレクトリ配下、またはインデックス化対象の QMD ルート外に置いてください。

設定

完全な設定範囲(memory.qmd.*)、検索モード、更新間隔、スコープルール、その他すべてのノブについては、メモリ設定リファレンス を参照してください。

関連