Перейти к содержанию
Публикация AiManual

Долговременная память для Cursor: как LLM Wiki, QMD и Cursor CLI убирают «амнезию» между сессиями

Разбор рабочей схемы памяти для Cursor: неизменяемый raw/ и синтезируемый wiki/ по концепции LLM Wiki Карпати, гибридный поиск QMD через MCP, ingest через Curso

Коротко

Что будет в материале

  1. 01

    Почему Cursor «забывает» проект и что именно теряется между сессиями

  2. 02

    Концепция LLM Wiki Андрея Карпати: неизменяемый raw/ и синтезируемый wiki/

  3. 03

    QMD: гибридный поиск по накопленной базе

  4. 04

    Подключение QMD к Cursor через MCP

Чат в Cursor помнит проект, пока открыто окно. Закрыли, открыли новый - и агент снова не знает, почему показатель считается через инкрементальный слой, кто такой заказчик N и какой вариант SQL уже отбросили две недели назад.

Долговременная память упирается не в размер контекстного окна, а в отсутствие знаний вне чата и дешёвого способа в них заглядывать. В кейсе, разобранном на Habr, схема собрана из трёх частей: LLM Wiki по концепции Андрея Карпати (неизменяемый raw/ плюс синтезируемый wiki/), локальный поиск QMD с гибридом BM25 и векторов, ingest через Cursor Agent CLI, обёрнутый в четыре project skills. Модель отвечает за смысловое слияние фактов, скрипты держат порядок шагов, валидацию и переиндексацию.

Дальше разбор этой связки: что теряется между сессиями, как устроены слои и типы карточек, как работает двухэтапный поиск по docid, где проходит граница между LLM-инструкцией и детерминированной оркестрацией и какие компоненты в итоге оказались лишними. Часть деталей (полный состав карточек, набор skills, контрольные замеры) в опубликованном фрагменте кейса раскрыта не полностью, поэтому ниже они приведены в том виде, в каком их описывает автор (первоисточник).

Почему Cursor «забывает» проект и что именно теряется между сессиями

Большой контекст в Cursor спасает ровно до тех пор, пока проект живёт дольше одного чата: требования, SQL-гипотезы и причины отброшенных решений быстро расползаются по сессиям. Окно растягивает одну сессию, память проекта оно не создаёт.

Типичный сценарий из кейса выглядит так. На установочной встрече заказчик формулирует исходные требования, запись проходит через AudioToText и превращается в транскрипт. Дальше во время анализа модели данных появляются SQL-фрагменты, ограничения и гипотезы. Через неделю в новой сессии агент предлагает решение, которое уже отвергли, потому что нагрузка на витрину оказывалась недопустимой. Разработчик тратит время на повторное объяснение того, что было выяснено раньше.

Что теряется: требования, SQL-гипотезы и причины отброшенных решений

Практика показывает четыре категории знаний, которые утекают из проекта первыми:

  • Требования заказчика из транскрипта: формулировки, оговорки, приоритеты, сроки.
  • Промежуточные SQL-гипотезы: какие запросы проверяли, что показали, какие поля оказались ненадёжными.
  • Ограничения модели данных: где дубли, почему ключ составной, какие таблицы нельзя джойнить напрямую.
  • Аргументы против отброшенных вариантов: почему выбрали инкрементальный расчёт, а не полную перезагрузку витрины.

Без слоя памяти агент каждый раз начинает с нуля и повторно проходит те же развилки. Токены на это уходят реальные, а качество ответов падает: модель уверенно предлагает то, что уже проверено и отклонено.

Чем это отличается от обычного RAG и «ещё одного гайда по wiki»

Классический RAG ищет фрагменты: запрос, top-k чанков, ответ. Каждый следующий запрос снова собирает картину из кусков, а синтез между документами не сохраняется. LLM Wiki устроен иначе: производное знание накапливается в связанных карточках, где факты уже сведены и перепроверены, а первоисточник лежит рядом и доступен для сверки.

Задача статьи - не структура папок, а интеграция такого слоя в рабочий процесс Cursor: как материал попадает в базу, как агент его находит и как не дать индексу разъехаться с реальностью. Похожий класс задач решают и другие инструменты, например Later Bender с долговременным слоем состояния и MCP-подключением к разным моделям, но здесь акцент на связке редактора, локального поиска и CLI-обработки.

Концепция LLM Wiki Андрея Карпати: неизменяемый raw/ и синтезируемый wiki/

Отправная точка решения: между сырыми источниками и ответами модели появляется отдельный слой, связанная Markdown-wiki, которую агент дополняет по мере поступления новых материалов. Сырые документы остаются неизменными, производное знание постепенно накапливается в тематических страницах, индексе и журнале изменений (описание концепции в кейсе).

Слой raw/: первоисточники, которые нельзя менять

В raw/ попадают транскрипты AudioToText, фрагменты SQL, документы заказчика, выгрузки и заметки встреч. Правило одно и жёсткое: папка только пополняется, файлы не редактируются. Правки и уточнения живут в wiki/, а не в источнике.

Такая дисциплина даёт три вещи. Воспроизводимость: любой факт из карточки можно поднять до исходного файла. Аудит: видно, когда и откуда пришло знание. Пересборку: при смене схемы карточек wiki/ синтезируется заново из того же raw/, без потери основы.

Слой wiki/: карточки sources, entities, concepts, analyses

Синтезированный слой разложен по типам карточек, чтобы агент понимал, что перед ним: описание источника, сущность проекта, правило или разбор гипотезы.

Тип карточкиЧто фиксируетПример из проекта
sourcesИсточник, дата, что из него извлеклиТранскрипт установочной встречи со ссылкой на файл в raw/
entitiesСущности проекта и их связиЗаказчик, система-источник, таблица фактов, витрина
conceptsПонятия, правила расчёта, ограниченияФормула показателя и запрет на джойн двух таблиц напрямую
analysesРазборы гипотез и принятых решенийПочему выбран инкрементальный расчёт вместо полной перезагрузки

Точка входа - index.md: с него агент начинает навигацию по базе. Журнал изменений фиксирует, что и когда добавили, чтобы правки не растворялись в массе файлов.

SCHEMA.md и AGENTS.md: правила, по которым агент собирает wiki/

SCHEMA.md описывает структуру карточек, обязательные поля и правила именования. AGENTS.md задаёт поведение агента при ingest и поиске: что читать, в каком порядке, что писать в карточку, чего не делать.

Ключевой момент: эти файлы лежат в репозитории и версионируются. Правило из промпта чата исчезает вместе с сессией, правило из SCHEMA.md подхватывается в любом вызове, включая фоновый запуск через CLI.

QMD: гибридный поиск по накопленной базе

Когда в wiki/ набираются сотни карточек, читать их подряд бессмысленно. QMD работает как локальный поисковый движок: гибрид BM25 и векторного поиска, query expansion и reranking поверх собранной базы.

Зачем BM25 рядом с векторами: точные термины против смысла

BM25 ловит точное совпадение терминов. Имя таблицы, название сущности, аббревиатура из требований, номер тикета - всё это векторная модель может «размыть» синонимами. Векторный поиск закрывает другую половину задач: вопрос перефразирован, терминология в карточке и в запросе разная, а смысл тот же.

Query expansion расширяет запрос синонимами и связанными терминами, reranking пересортировывает выдачу, поднимая действительно релевантные карточки наверх. Так компенсируются слабые места каждого метода по отдельности: точность BM25 и гибкость эмбеддингов.

Двухэтапный поиск: кандидаты, затем чтение по docid

Поиск идёт в два шага. Сначала движок возвращает ранжированный список кандидатов с идентификаторами docid: короткие записи, по которым видно, о чём карточка. Потом агент читает одну-две нужные карточки целиком, по конкретному docid.

Для Cursor это критично. Агент не затягивает всю wiki/ в контекст, а берёт минимум: список кандидатов плюс два файла. Контекстное окно остаётся под саму задачу, а не под библиотеку знаний.

Подключение QMD к Cursor через MCP

QMD подключается к Cursor как MCP-сервер поиска, и агент вызывает его как обычный инструмент: «найди в базе, что известно про расчёт показателя». Ответ приходит в структурированном виде, с docid для последующего чтения.

Что отдавать через MCP, а что оставить скриптам

Через MCP имеет смысл отдавать только интерактивные операции: поиск кандидатов и чтение карточки по docid. Ingest, валидацию и переиндексацию лучше держать в CLI и bash-скриптах. Причина прагматичная: отладка поиска идёт в диалоге, а обработка источников должна быть воспроизводимой и запускаться одной командой.

В эволюции подхода был отдельный MCP-контур для обработки, от него отказались в пользу более простой схемы. MCP для поиска при этом остался: именно он даёт агенту дешёвый доступ к базе во время работы.

Чек-лист подключения без привязки к конкретным командам:

  1. QMD индексирует wiki/ и отдаёт поиск как вызываемую функцию.
  2. В Cursor регистрируется MCP-сервер поиска в конфигурации MCP.
  3. Проверка: агент вызывает инструмент и получает список кандидатов с docid.
  4. Проверка второго шага: агент читает карточку по docid и цитирует её содержимое.
  5. Права сервера ограничены чтением: поиск не должен уметь править wiki/.

Ingest через Cursor CLI и четыре project skills

Ручной ingest в основном чате работает, пока материалов мало. Дальше он превращается в серию однотипных действий, где модель легко пропускает шаг или переписывает карточку не по схеме. Финальная схема кейса: четыре project skills (save-raw, ingest-cli, context-cli, qmd) и детерминированные bash-обёртки вокруг Cursor Agent CLI.

SkillЗадачаКто исполняет
save-rawПоложить первоисточник в raw/ без измененийСкрипт
ingest-cliЗапустить изолированный вызов Cursor CLI для синтеза карточекОбёртка плюс модель
context-cliСобрать контекст для вызоваСкрипт
qmdПереиндексировать wiki/ после измененийСкрипт

save-raw и ingest-cli: от источника до карточки

save-raw отвечает за первый шаг: источник попадает в raw/ с понятным именем и метаданными, без правок содержимого. ingest-cli вызывает Cursor CLI с инструкцией из AGENTS.md и SCHEMA.md: модель получает материал и задачу синтеза, а не весь текущий чат с его историей.

Изолированный вызов важен именно этим. Обработка идёт в чистом контексте: на входе конкретные файлы и правила, на выходе карточки. Чат разработчика при этом остаётся рабочим местом и не превращается в свалку промежуточных шагов.

context-cli и qmd: сборка контекста и переиндексация

context-cli собирает то, что нужно передать в вызов: новые файлы из raw/, связанные карточки, актуальные фрагменты index.md. qmd переиндексирует базу после изменений.

Переиндексация - обязательный шаг, а не приятное дополнение. Без неё поиск продолжает отдавать старые версии карточек, и агент уверенно цитирует то, что уже переписано. Симптом неприятный: в wiki/ текст правильный, а в ответах всплывают прошлые формулировки.

validate-wiki.py: валидация до переиндексации

Валидатор стоит между ingest и индексацией. Он проверяет структуру карточек и обязательные поля, ловит битые ссылки между страницами и расхождения со SCHEMA.md. Порядок жёсткий: ingest, затем validate-wiki.py, затем переиндексация QMD. Если валидация падает, индекс не обновляется, и база не получает мусор.

Валидатор не заменяет ревью. Он отсекает формальный брак: пропущенное поле, несуществующую ссылку, карточку не того типа. Смысловые ошибки синтеза ловит человек, читая analyses и concepts.

Граница между LLM-инструкцией и детерминированной оркестрацией

Главный вывод кейса формулируется коротко: модель делает смысловое слияние фактов, скрипты гарантируют порядок шагов, валидацию и переиндексацию. Всё, что можно проверить детерминированно, не должно зависеть от настроения модели.

Что оставить в skill, а что вынести в скрипт

В skill остаются правила синтеза, формат карточек, ссылки на SCHEMA.md и AGENTS.md, указание, какие связи протягивать. Во внешний скрипт уходят вызовы CLI, последовательность шагов, запуск validate-wiki.py и переиндексация qmd.

Критерий разделения простой. Если шаг проверяется автоматически (файл существует, поле заполнено, ссылка ведёт на реальную карточку), он уходит в скрипт. Если шаг требует суждения (слить два факта в один, увидеть противоречие между транскриптом и SQL-гипотезой), он остаётся за моделью.

Когда отдельный agent harness становится лишним

Эволюция подхода шла через настройку QMD, попытку вынести ingest в DeepSeek Harness, запуск локальной модели, отдельный MCP-контур и возврат к схеме с Cursor, project skills и вызовом Cursor CLI для фоновой обработки.

Harness добавляет слой, который нужно поддерживать: своя конфигурация, свои ошибки, свой способ передавать контекст. Cursor CLI уже даёт изолированный вызов с нужной моделью и правилами из репозитория. Если оркестрацию забирают на себя bash-обёртки, отдельный harness перестаёт решать задачу, которую не решает CLI. Похожие границы контроля над агентами разбираются в материале о том, как Cursor выстраивает доверие к ИИ-агентам через верификацию, skills и жёсткие CI-проверки.

Если оркестрацию отдать модели, типовые сбои предсказуемы: пропущенный шаг переиндексации, карточка не по схеме, ingest, который «на всякий случай» переписал источник в raw/. Каждый такой сбой дешевле предотвратить скриптом, чем искать причину устаревших ответов через неделю.

Замеры и эволюция подхода: что сработало, а что оказалось избыточным

Контрольные замеры времени ingest в кейсе выглядят так: около 4,5 минуты через Cursor CLI с флагом --model auto против примерно 15 минут на локальной 27B-модели на Mac Studio M4 Max.

Cursor CLI с --model auto против локальной 27B на Mac Studio M4 Max

СценарийВремя ingestУсловия
Cursor CLI, --model autoоколо 4,5 минутыИзолированный вызов с правилами из SCHEMA.md и AGENTS.md
Локальная 27B-модель через oMLXоколо 15 минутMac Studio M4 Max

Это контрольные замеры автора на конкретном железе и конфигурации, а не бенчмарк. Время зависит от объёма источника, числа связанных карточек и загрузки машины, поэтому цифры стоит читать как порядок величин.

Локальная модель при этом не списана со счетов. Она оправдана, когда материал нельзя отправлять во внешний сервис, когда нет стабильной сети или когда счёт за API упирается в бюджет. Для регулярного ingest больших транскриптов разница в три раза по времени заметна: четыре с половиной минуты и пятнадцать минут дают разную пропускную способность за рабочий день.

Какие компоненты оказались избыточными и почему

Список тупиков полезнее списка удачных решений, потому что его можно не повторять:

  • DeepSeek Harness: лишний слой оркестрации, который пришлось бы поддерживать параллельно с CLI.
  • Локальная модель через oMLX: медленнее и без выигрыша в качестве для задачи синтеза карточек.
  • Отдельный MCP-контур: усложнение без практической пользы, пока поиск и обработка живут в разных подсистемах.

Остались QMD, MCP для поиска, project skills, Cursor CLI и validate-wiki.py. Схема из этого набора объясняется целиком: где лежат знания, как их найти, кто их обновляет и что мешает индексу устареть. Полный разбор эволюции и цифры приводит автор кейса (Habr, 18 октября 2026).

Кому подходит схема и какие у неё ограничения

Схема окупается на долгоживущих проектах, где контекст накапливается месяцами: аналитика данных, консалтинг, продуктовые команды с длинным циклом согласований. Для задачи на один вечер сборка raw/, wiki/, QMD и skills обойдётся дороже, чем несколько повторных объяснений агенту.

Если задача близка по природе, но проект другой, полезно посмотреть, как автоматизируют handover между сессиями при работе с большой кодовой базой: там состояние переносит отдельный harness, а здесь его хранит wiki/.

Чек-лист внедрения: от raw/ до project skills

  1. Завести raw/ и договориться, что файлы там не редактируются.
  2. Описать SCHEMA.md: типы карточек, обязательные поля, правила именования.
  3. Описать AGENTS.md: как агент читает источник, что пишет в карточку, как ищет.
  4. Собрать wiki/ с index.md и журналом изменений, начать с ручного ingest на 5-10 источниках.
  5. Настроить QMD и проверить гибридный поиск на реальных вопросах по проекту.
  6. Подключить MCP-сервер поиска к Cursor и убедиться, что агент читает карточку по docid.
  7. Собрать четыре skill: save-raw, ingest-cli, context-cli, qmd.
  8. Добавить validate-wiki.py и зашить порядок ingest, валидация, переиндексация в bash-обёртку.

Ограничения стоит держать в голове с самого начала. Правила в SCHEMA.md и AGENTS.md требуют дисциплины: расхождение между схемой и реальными карточками ломает и навигацию, и поиск. Валидатор ловит формальный брак, смысловые ошибки остаются на ревью. Качество синтеза зависит от модели: слабая модель уверенно сведёт два противоречащих факта в один. Переиндексация добавляет шаг к каждому обновлению, и пропуск этого шага проявляется не сразу, а через устаревшие ответы.

Начинать проще с ручного ingest и двух-трёх карточек на источник. Автоматизация через Cursor CLI и project skills нужна тогда, когда база выросла настолько, что ручная обработка стала узким местом. Граница между LLM-инструкцией и скриптами проводится по одному вопросу: можно ли результат шага проверить автоматически. Если да, шаг уходит в код, и память проекта перестаёт зависеть от того, помнит ли модель прошлый чат.

Подписаться на канал