Перейти к основному содержанию
QMD — локальный поисковый сайдкар, который работает рядом с OpenClaw. Он объединяет BM25, векторный поиск и переранжирование в одном бинарном файле и может индексировать содержимое за пределами файлов памяти вашей рабочей области.

Что он добавляет по сравнению со встроенным движком

  • Переранжирование и расширение запросов для лучшей полноты поиска.
  • Индексирование дополнительных каталогов — документация проекта, заметки команды, любые файлы на диске.
  • Индексирование транскриптов сессий — поиск по прошлым разговорам.
  • Полностью локально — работает с официальным Plugin провайдера llama.cpp и автоматически загружает модели GGUF.
  • Автоматический резервный вариант — если QMD недоступен, OpenClaw прозрачно переключается на встроенный движок.

Начало работы

Предварительные требования

  • Установите QMD: npm install -g @tobilu/qmd или bun install -g @tobilu/qmd
  • Сборка SQLite, разрешающая расширения (brew install sqlite на macOS).
  • QMD должен быть в PATH Gateway.
  • macOS и Linux работают без дополнительной настройки. Windows лучше всего поддерживается через WSL2.

Включение

{
  memory: {
    backend: "qmd",
  },
}
OpenClaw создает самодостаточный домашний каталог QMD в ~/.openclaw/agents/<agentId>/qmd/ и автоматически управляет жизненным циклом сайдкара — коллекции, обновления и запуски embedding выполняются за вас. Он предпочитает текущие формы коллекций QMD и MCP-запросов, но при необходимости все еще переключается на альтернативные флаги шаблонов коллекций и старые имена MCP-инструментов. Согласование при запуске также пересоздает устаревшие управляемые коллекции по их каноническим шаблонам, когда более старая коллекция QMD с тем же именем все еще присутствует.

Как работает сайдкар

  • OpenClaw создает коллекции из файлов памяти вашей рабочей области и любых настроенных memory.qmd.paths, затем запускает qmd update, когда менеджер QMD открывается, и периодически после этого (по умолчанию каждые 5 минут). Эти обновления выполняются через подпроцессы QMD, а не через обход файловой системы внутри процесса. Семантические режимы также запускают qmd embed.
  • Коллекция рабочей области по умолчанию отслеживает MEMORY.md и дерево memory/. memory.md в нижнем регистре не индексируется как корневой файл памяти.
  • Собственный сканер QMD игнорирует скрытые пути и распространенные каталоги зависимостей/сборки, такие как .git, .cache, node_modules, vendor, dist и build. Запуск Gateway по умолчанию не инициализирует QMD, поэтому холодный старт не импортирует runtime памяти и не создает долгоживущий наблюдатель до первого использования памяти.
  • Если вы все же хотите инициализировать QMD при запуске Gateway, задайте memory.qmd.update.startup как idle или immediate. С memory.qmd.update.onBoot: true запуск выполняет начальное обновление. С onBoot: false запуск пропускает это немедленное обновление, но все равно открывает долгоживущий менеджер, когда настроены интервалы обновления или embedding, чтобы QMD мог владеть своим обычным наблюдателем и таймерами.
  • Поиски используют настроенный searchMode (по умолчанию: search; также поддерживаются vsearch и query). search использует только BM25, поэтому OpenClaw пропускает проверки готовности семантических векторов и обслуживание embedding в этом режиме. Если режим завершается ошибкой, OpenClaw повторяет попытку с qmd query.
  • Когда searchMode равен query, задайте memory.qmd.rerank как false, чтобы использовать гибридный путь запросов QMD без переранжировщика. OpenClaw передает --no-rerank в прямой CLI-путь QMD и rerank: false в MCP-инструмент запросов QMD. Для этой опции требуется QMD 2.1 или новее.
  • В выпусках QMD, которые объявляют фильтры по нескольким коллекциям, OpenClaw группирует коллекции из одного источника в один вызов поиска QMD. Более старые выпуски QMD сохраняют совместимый резервный путь с поиском по каждой коллекции.
  • Если QMD полностью отказывает, OpenClaw переключается на встроенный движок SQLite. Повторные попытки в ходе чат-ходов ненадолго откладываются после ошибки открытия, чтобы отсутствующий бинарный файл или сломанная зависимость сайдкара не создавали шквал повторов; openclaw memory status и одноразовые CLI-проверки все равно напрямую перепроверяют QMD.
Первый поиск может быть медленным — QMD автоматически загружает модели GGUF (~2 ГБ) для переранжирования и расширения запросов при первом запуске qmd query.

Производительность поиска и совместимость

OpenClaw поддерживает совместимость пути поиска QMD как с текущими, так и со старыми установками QMD. При запуске OpenClaw один раз на менеджер проверяет текст справки установленного QMD. Если бинарный файл объявляет поддержку нескольких фильтров коллекций, OpenClaw ищет по всем коллекциям из одного источника одной командой:
qmd search "router notes" --json -n 10 -c memory-root-main -c memory-dir-main
Это позволяет не запускать отдельный подпроцесс QMD для каждой коллекции долговременной памяти. Коллекции транскриптов сессий остаются в своей группе источников, поэтому смешанные поиски memory + sessions все равно дают диверсификатору результатов входные данные из обоих источников. Более старые сборки QMD принимают только один фильтр коллекции. Когда OpenClaw обнаруживает одну из таких сборок, он сохраняет путь совместимости и ищет по каждой коллекции отдельно, прежде чем объединять результаты и удалять дубликаты. Чтобы вручную проверить установленный контракт, выполните:
qmd --help | grep -i collection
Текущая справка QMD говорит, что фильтры коллекций могут нацеливаться на одну или несколько коллекций. Старая справка обычно описывает одну коллекцию.

Переопределение моделей

Переменные окружения моделей QMD передаются без изменений из процесса Gateway, поэтому вы можете настраивать QMD глобально без добавления новой конфигурации OpenClaw:
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"
После изменения модели embedding повторно выполните embeddings, чтобы индекс соответствовал новому векторному пространству.

Индексирование дополнительных путей

Укажите QMD дополнительные каталоги, чтобы сделать их доступными для поиска:
{
  memory: {
    backend: "qmd",
    qmd: {
      paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
    },
  },
}
Фрагменты из дополнительных путей появляются как qmd/<collection>/<relative-path> в результатах поиска. memory_get понимает этот префикс и читает из правильного корня коллекции.

Индексирование транскриптов сессий

Включите индексирование сессий, чтобы искать по прошлым разговорам. QMD нужны и общий источник сессий memorySearch, и экспортер транскриптов QMD:
{
  agents: {
    defaults: {
      memorySearch: {
        experimental: { sessionMemory: true },
        sources: ["memory", "sessions"],
      },
    },
  },
  memory: {
    backend: "qmd",
    qmd: {
      sessions: { enabled: true },
    },
  },
}
Транскрипты экспортируются как очищенные ходы User/Assistant в выделенную коллекцию QMD в ~/.openclaw/agents/<id>/qmd/sessions/. Установка только memorySearch.experimental.sessionMemory не экспортирует транскрипты в QMD. Попадания по сессиям по-прежнему фильтруются через tools.sessions.visibility. Видимость по умолчанию tree не раскрывает несвязанные сессии того же агента. Если сессия, диспетчеризованная Gateway, должна быть доступна для поиска из отдельной DM-сессии, задайте tools.sessions.visibility: "agent" намеренно.

Область поиска

По умолчанию результаты поиска QMD показываются в прямых и канальных сессиях (не в группах). Настройте memory.qmd.scope, чтобы изменить это:
{
  memory: {
    qmd: {
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
    },
  },
}
Когда область запрещает поиск, OpenClaw записывает предупреждение с вычисленным каналом и типом чата, чтобы пустые результаты было проще отлаживать.

Цитаты

Когда memory.citations равно auto или on, фрагменты поиска включают нижний колонтитул Source: <path#line>. Задайте memory.citations = "off", чтобы не добавлять этот колонтитул, при этом путь все равно будет передаваться агенту внутри системы.

Когда использовать

Выбирайте QMD, когда вам нужно:
  • Переранжирование для более качественных результатов.
  • Искать документацию проекта или заметки за пределами рабочей области.
  • Вспоминать прошлые разговоры сессий.
  • Полностью локальный поиск без API-ключей.
Для более простых настроек встроенный движок хорошо работает без дополнительных зависимостей.

Устранение неполадок

QMD не найден? Убедитесь, что бинарный файл находится в PATH Gateway. Если 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",
    },
  },
}
Используйте command -v qmd в окружении, где установлен QMD, затем повторно проверьте через openclaw memory status --deep. Первый поиск очень медленный? QMD загружает модели GGUF при первом использовании. Прогрейте с помощью qmd query "test", используя те же каталоги XDG, которые использует OpenClaw. Много подпроцессов QMD во время поиска? По возможности обновите QMD. OpenClaw использует один процесс для поисков по нескольким коллекциям из одного источника только тогда, когда установленный QMD объявляет поддержку нескольких фильтров -c; иначе он сохраняет старый резервный путь с поиском по каждой коллекции для корректности. QMD только с BM25 все еще пытается собрать llama.cpp? Задайте memory.qmd.searchMode = "search". OpenClaw считает этот режим только лексическим, не запускает проверки статуса векторов QMD или обслуживание embedding и оставляет семантические проверки готовности для настроек vsearch или query. Поиск завершается по тайм-ауту? Увеличьте memory.qmd.limits.timeoutMs (по умолчанию: 4000ms). Для более медленного оборудования задайте 120000. Пустые результаты в групповых чатах? Проверьте memory.qmd.scope — по умолчанию разрешены только прямые и канальные сессии. Поиск корневой памяти внезапно стал слишком широким? Перезапустите Gateway или дождитесь следующего согласования при запуске. OpenClaw пересоздает устаревшие управляемые коллекции по каноническим шаблонам MEMORY.md и memory/, когда обнаруживает конфликт с тем же именем. Временные репозитории, видимые из рабочей области, вызывают ENAMETOOLONG или ломают индексирование? Обход QMD сейчас следует поведению базового сканера QMD, а не встроенным правилам OpenClaw для символических ссылок. Держите временные checkout монорепозиториев в скрытых каталогах вроде .tmp/ или вне индексируемых корней QMD, пока QMD не предоставит безопасный к циклам обход или явные элементы управления исключениями.

Конфигурация

Полную поверхность конфигурации (memory.qmd.*), режимы поиска, интервалы обновления, правила области и все прочие настройки см. в справочнике по конфигурации памяти.

Связанные материалы