Sessions and memory
Движок памяти QMD
QMD — это ориентированный на локальную работу вспомогательный сервис поиска, который работает вместе с OpenClaw. Он объединяет BM25, векторный поиск и переранжирование в одном исполняемом файле и может индексировать содержимое за пределами файлов памяти рабочего пространства.
Преимущества по сравнению со встроенным механизмом
- Переранжирование и расширение запросов для повышения полноты поиска.
- Индексирование дополнительных каталогов — проектной документации, заметок команды и любых данных на диске.
- Индексирование расшифровок сеансов — для обращения к предыдущим беседам.
- Полностью локальная работа — используется официальный плагин провайдера 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/ и автоматически управляет жизненным циклом
вспомогательного сервиса: коллекциями, обновлениями и запусками построения эмбеддингов.
Предпочтение отдаётся актуальным форматам коллекций QMD и запросов MCP, но при
необходимости используются альтернативные флаги шаблонов коллекций и старые имена инструментов MCP.
Сверка при запуске также пересоздаёт устаревшие управляемые коллекции с их
каноническими шаблонами, если старая коллекция QMD с тем же именем всё ещё
существует.
Как работает вспомогательный сервис
- OpenClaw создаёт коллекции из файлов памяти рабочего пространства и всех
настроенных
memory.qmd.paths, затем запускаетqmd updateпри открытии диспетчера QMD и периодически после этого (memory.qmd.update.interval, по умолчанию5m). Обновление выполняется через подпроцессы QMD, а не посредством обхода файловой системы внутри процесса. В режимах семантического поиска также выполняетсяqmd embed(memory.qmd.update.embedInterval, по умолчанию60m). - Стандартная коллекция рабочего пространства отслеживает
MEMORY.mdи деревоmemory/.memory.mdв нижнем регистре не индексируется как корневой файл памяти. - Собственный сканер QMD игнорирует скрытые пути и распространённые каталоги зависимостей и сборки,
такие как
.git,.cache,node_modules,vendor,distиbuild. По умолчанию при запуске Gateway QMD не инициализируется (memory.qmd.update.startupпо умолчанию имеет значениеoff), поэтому при холодном запуске среда памяти не импортируется, а долгоживущий наблюдатель не создаётся до первого обращения к памяти. - Установите
memory.qmd.update.startupвidleилиimmediate, чтобы всё же инициализировать QMD при запуске Gateway.memory.qmd.update.onBootпо умолчанию имеет значениеtrueи запускает первоначальное обновление при старте; установите значениеfalse, чтобы пропустить немедленное обновление (долгоживущий диспетчер всё равно открывается, если настроены интервалы обновления или построения эмбеддингов, поэтому QMD продолжает управлять своими обычными наблюдателями и таймерами). - Для поиска используется настроенный
searchMode(по умолчанию:search; также поддерживаютсяvsearchиquery).searchиспользует только BM25, поэтому в этом режиме OpenClaw пропускает проверки готовности семантических векторов и обслуживание эмбеддингов. Если режим завершается с ошибкой, OpenClaw повторяет попытку сqmd query. - Если
searchModeимеет значениеquery, установитеmemory.qmd.rerankвfalse, чтобы использовать гибридный путь запросов QMD без переранжировщика (требуется QMD 2.1 или новее). OpenClaw передаёт--no-rerankв прямой путь CLI QMD иrerank: falseв инструмент запросов MCP QMD. - В выпусках QMD, заявляющих поддержку фильтров по нескольким коллекциям, OpenClaw объединяет коллекции из одного источника в один вызов поиска QMD. Для старых выпусков QMD сохраняется совместимый резервный путь с отдельным вызовом для каждой коллекции.
- Если QMD полностью отказывает, OpenClaw переходит на встроенный механизм SQLite.
После ошибки открытия повторные попытки в последовательных циклах чата ненадолго откладываются, чтобы
отсутствие исполняемого файла или неисправная зависимость вспомогательного сервиса не вызывали лавину повторных попыток;
openclaw memory statusи однократные проверки CLI по-прежнему проверяют QMD напрямую.
Производительность и совместимость поиска
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"После изменения модели эмбеддингов повторно постройте эмбеддинги, чтобы индекс соответствовал новому векторному пространству.
Индексирование дополнительных путей
Укажите 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 }, }, },}Расшифровки экспортируются в виде очищенных реплик пользователя и ассистента в выделенную коллекцию QMD
в ~/.openclaw/agents/<id>/qmd/sessions/. Установка только
memorySearch.experimental.sessionMemory не экспортирует расшифровки в
QMD.
Результаты из сеансов по-прежнему фильтруются параметром
tools.sessions.visibility. Стандартная
видимость tree не предоставляет доступ к несвязанным сеансам того же агента. Если
сеанс, запущенный через Gateway, должен быть доступен из отдельного сеанса личных сообщений,
явно установите 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>#L<line> (или #L<start>-L<end>). В режиме auto
нижний колонтитул добавляется только для сеансов прямого чата. Установите
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 и обслуживание эмбеддингов,
а проверки семантической готовности оставляет конфигурациям vsearch или query.
Истекает время ожидания поиска? Увеличьте memory.qmd.limits.timeoutMs (по умолчанию: 4000ms).
Для более медленного оборудования установите большее значение, например 120000. Это ограничение применяется к
собственным командам поиска QMD во время вызовов агентом memory_search; настройка, синхронизация,
встроенный резервный механизм и работа с дополнительным корпусом используют собственные, более короткие сроки ожидания.
Пустые результаты в групповых чатах или каналах? Это ожидаемое поведение при
стандартном memory.qmd.scope, который разрешает только прямые сеансы. Добавьте правило
allow для типов чата group или channel, если хотите получать там результаты QMD.
Поиск по корневой памяти внезапно стал слишком широким? Перезапустите Gateway или дождитесь
следующей сверки при запуске. При обнаружении конфликта одинаковых имён OpenClaw пересоздаёт устаревшие управляемые
коллекции с каноническими шаблонами MEMORY.md и memory/.
Временные репозитории, видимые из рабочего пространства, вызывают ENAMETOOLONG или нарушают индексирование?
Обход QMD следует правилам собственного сканера QMD, а не встроенным правилам OpenClaw
для символических ссылок. Храните временные рабочие копии монорепозитория в скрытых
каталогах, например .tmp/, или за пределами индексируемых корней QMD, пока QMD не предоставит
безопасный при циклах обход или явные средства исключения.
Конфигурация
Полное описание параметров конфигурации (memory.qmd.*), режимов поиска, интервалов обновления,
правил области и всех остальных настроек см. в
справочнике по конфигурации памяти.