---
title: "Markdown — это не память агента"
seoTitle: "Почему markdown-файлы ломаются как память AI-агента на масштабе"
description: "Часть лучших агентов в проде держат память в markdown-файлах, и для одного агента и одного пользователя это трудно побить. Паттерн ломается в предсказуемых местах: на масштабе, когда факты меняются, и при конкурентных агентах."
date: "2026-06-23"
author: "INITE Brain Team"
category: "Архитектура"
tags: ["память агента", "markdown", "граф знаний", "темпоральный граф", "источник факта", "AI-агенты"]
directAnswer: "Для одного агента, обслуживающего одного пользователя, при локальном источнике истины markdown-файлы — соразмерный выбор для памяти: бесплатно, прозрачно, без инфраструктуры. Их перестаёт хватать, когда хранилище перерастает выбор-по-файлам, когда факты меняются и нет истории и источника, чтобы поймать дрейф, когда несколько агентов пишут одновременно, или когда второй пользователь добавляет требования изоляции и хранения. Тогда память — это система: ранжированный retrieval, интервалы валидности, источник факта и сверка с источником, что даёт темпоральный граф знаний и чего плоский файл не может."
definitionSentence: "Память агента — это постоянное запрашиваемое хранилище, которое агент читает и пишет по ходу работы; markdown-файлы реализуют её хорошо на малом масштабе, но в них нет оси времени, источника, разрешения конфликтов и изоляции, которые нужны при нескольких агентах или пользователях."
faqs:
  - question: "Достаточно ли markdown-памяти для AI-агента?"
    answer: "Для одного агента, обслуживающего одного пользователя, при локальном источнике истины, из которого факты можно вывести заново, markdown-память часто и есть правильный выбор. Она бесплатна и прозрачна — поэтому её используют кодинг-ассистенты вроде Claude Code и фреймворки вроде Letta. Перестаёт хватать, когда появляется второй агент или пользователь, меняющиеся факты или требование к хранению."
  - question: "Масштабируется ли markdown-память?"
    answer: "Дальше, чем кажется по одному файлу, потому что хорошие реализации грузят описания файлов и выбирают пару нужных, а не вливают всё — подход progressive disclosure, который рекомендует Anthropic. Выбор всё равно деградирует, когда хранилище перерастает то, из чего модель может уверенно выбирать. Обычный следующий шаг — векторное хранилище, но оно ранжирует по похожести, а не по свежести или истинности, и не умеет заместить факт, когда тот меняется. Масштабировать память нужно ранжированным retrieval, который учитывает, насколько факт свежий и насколько верный."
  - question: "Что именно ломается, когда markdown-память растёт?"
    answer: "Ошибки накапливаются. Файл фиксирует, что записали, а не что это заместило и почему — поэтому неверный или замещённый факт лежит там, и поздние шаги строятся на нём. Git фиксирует, кто правил какую строку, а не валидность факта и откуда он взялся, и не мирит логические противоречия. В итоге память дрейфует от истины, и в формате нет ничего, чтобы это поймать."
  - question: "Могут ли несколько агентов делить один markdown-файл памяти?"
    answer: "Не безопасно. Без git у одновременных записей в один файл нет надёжного лока — файловые локи непоследовательны между платформами и ломаются на сетевых ФС, поэтому записи гонятся и затирают друг друга. С git текстовый merge разрешает один файл, но факты, записанные в разные связанные файлы, логически расходятся, и ничто не сверяет их с источником. Безопасные конкурентные записи требуют модели данных, которая разрешает их по источнику и таймлайну, а не общего файла."
  - question: "Может ли markdown-файл отслеживать, как факты меняются во времени?"
    answer: "Сам по себе — нет. Файл фиксирует, что записано, а не когда факт стал верен или ложен, поэтому рабочая практика — избегать волатильных фактов и выводить их заново из локального источника. Это работает для кода, где репозиторий и есть источник истины, и ломается для бизнес-фактов без локального источника. Отслеживать изменения нужно через интервалы валидности и запросы на момент времени, которые плоский файл выразить не может."
  - question: "Как проследить, откуда взялся факт в памяти агента?"
    answer: "У markdown-строки нет происхождения, а git скажет, кто её закоммитил и когда, а не из чего она выведена. Чтобы проследить, нужно, чтобы каждый факт ссылался на источник, из которого извлечён, — тогда агент может процитировать оригинал, а ты — проверить, почему система во что-то верит."
---

Часть самых способных агентов в проде держат память в обычных markdown-файлах, и для одного агента и одного пользователя это трудно побить. Паттерн ломается в предсказуемых местах: на масштабе, когда факты меняются и ошибки накапливаются, и при конкурентных агентах.

## Что markdown-память делает хорошо

Директория markdown-файлов — правильный инструмент, когда область узкая. Кодинг-ассистенты — самый ясный случай. Файлы вроде `CLAUDE.md` или кросс-инструментальная конвенция `AGENTS.md` фиксируют правила проекта, которые агент грузит каждую сессию, а авто-память даёт ему вести свои заметки между запусками. Хранилище бесплатно, и сервис держать не надо.

Лучшие реализации дисциплинированнее одного растущего файла. Anthropic называет принцип *progressive disclosure*: считать окно контекста конечным и подтягивать только тот контекст, что нужен шагу. MemFS у Letta держит директорию `system/` всегда в контексте, а остальное отдаёт как имена файлов с описаниями и грузит содержимое по требованию. Manus держит состояние восстановимым, а не резидентным — выкидывает содержимое страницы из контекста, пока хранит URL. Файловая система — это диск к оперативке окна контекста, и агент подгружает то, что нужно.

Одно преимущество перехвалено. Хранилище — это текст, поэтому продают так: человек его смотрит и курирует. На практике пишет агент, а человек редко аудитит результат — значит markdown-память должна оставаться корректной *без* куратора. Для односубъектного ассистента на одной машине тянуться к базе — это затраты без выгоды. Дальше пост о том, что происходит, когда нагрузка расширяется.

## Retrieval и масштаб

Выбор файлов — это сам по себе слой retrieval, и он держит, пока хранилище не перерастёт то, с чем выбор справляется. Модели, выбирающей из списка описаний файлов, есть на что опереться всё меньше по мере удлинения списка — поэтому задокументированные схемы толкают к консолидации памяти, а не к накоплению.

Когда хранилище это перерастает, очевидный шаг — векторное хранилище. Для памяти он неверный. Векторное хранилище — это индекс похожести, а похожесть — не релевантность. Оно ранжирует по расстоянию эмбеддингов, поэтому факт полугодовой давности набирает столько же, сколько вчерашний, если текст совпадает, и у него нет механизма заместить факт, когда тот меняется: пользователь, перешедший с Python на Rust, оставляет оба утверждения в хранилище как независимые векторы. Оно не умеет пройти по связи двух фактов и считает непроверенную реплику равной проверенной записи. Векторный индекс делает хранилище больше, не делая его памятью. Эту нить мы тянули в [Почему AI-агентам нужна память за пределами векторного поиска](/ru/blog/memory-beyond-vector-search).

Масштабировать память на деле нужно ранжированным retrieval, который остаётся быстрым по мере роста данных и всё ещё взвешивает, насколько свежий и насколько верный каждый факт. У плоского файла и векторного индекса нет ни того, ни другого.

## История и источник

Markdown-файл фиксирует, что записано, а не что это заместило и почему. Когда факт меняется, агент либо перезаписывает старую строку — уничтожая историю, — либо дописывает новую, оставляя файл с обеими. Ни один путь не фиксирует, что один факт заместил другой, или откуда взялся каждый. Поздний агент считает уцелевшую строку или противоречие решённым делом и действует по нему. Ошибка накапливается, пока каждый шаг строится на прошлом.

Git этот разрыв не закрывает, хоть и похож на историю версий. Он отслеживает, кто менял какую строку и когда, а не из чего факт выведен и когда был верен. Он мирит текст, а не смысл, поэтому два коммита, каждый из которых сливается чисто, могут оставить память логически противоречивой.

Перепроверка по источнику истины — практика, что держит файловую память честной, и у неё есть предусловие. Совет Anthropic по progressive disclosure — доставать текущее состояние в рантайме, а не кешировать его: агент может сделать `grep` по репозиторию, чтобы убедиться, что функция всё ещё существует, прежде чем полагаться на строку, которая её называет. Это работает, потому что источник локален и его дёшево перепроверить. У бизнес-фактов такой страховки нет. Почему аккаунт пометили или что пользователь предпочитал в прошлом квартале — этого нет в локальном файле, чтобы вывести заново, поэтому неверная строка остаётся неверной.

Чтобы это ловить, нужны две вещи, которых файл не фиксирует: *когда* каждый факт был верен и *откуда* он взялся. С интервалами валидности агент может спросить, что держалось на заданную дату; со ссылкой от каждого факта к источнику — проверить, почему он во что-то верит. Строка прозы не несёт ни того, ни другого. Оси времени целиком посвящён пост [Что такое битемпоральный граф знаний](/ru/blog/bitemporal-knowledge-graph).

## Конкурентные агенты

Несколько агентов, делящих одну память, упираются в две проблемы. Без git у двух агентов, пишущих один файл одновременно, нет надёжного лока — файловые локи непоследовательны между платформами и ломаются на сетевых ФС, поэтому записи гонятся и затирают друг друга.

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

Мирить конкурентные записи — это разрешать их по источнику и таймлайну, а не сливать текст. Это свойство модели данных, и у директории файлов его нет.

## Доступ и хранение

Второй пользователь меняет задачу. Права файлов решают, кто может открыть файл, но не могут выразить, что агент, действующий за одного пользователя, видит факты этого пользователя и больше ничьи, когда все факты лежат в одной директории. Как только входят команды или границы комплаенса, память становится задачей управления доступом. Удаление в файле — это ручная правка без записи, что оно случилось: ни политики хранения, ни аудита того, что и когда убрали — разрыв за [правом на забвение по GDPR в RAG-системе](/ru/blog/gdpr-forget-rag).

Эти контроли должны сидеть *ниже* слоя памяти и применяться на каждое чтение и запись, с журналом аудита, который формат файла вести не может. Как только в зону попадают данные больше чем одного человека, это не опционально.

## Где markdown-память не дотягивает

| Проблема | Markdown-память | Что нужно для решения |
| --- | --- | --- |
| Retrieval на масштабе | Выбор по целым файлам; деградирует с ростом | Ранжированный retrieval, остающийся быстрым |
| Меняющиеся факты | Перезапись или накопление; нет истории | Интервалы валидности; запросы на момент времени |
| Источник факта | Нет; git логирует коммиты, не факты | Каждый факт связан со своим источником |
| Конкурентные агенты | Гонка без git; расхождение с ним | Сверка по источнику и таймлайну |
| Управление доступом | Права файлов; ручные удаления | Изоляция, хранение и аудит ниже слоя |

## Что меняет темпоральный граф

У этих проблем общий корень: файл хранит текст, а памяти нужна структура. Темпоральный граф знаний её даёт. Факты становятся рёбрами с интервалами валидности, поэтому изменение *продлевает* историю, а не перезаписывает её, и каждый факт ссылается на источник, из которого извлечён. Новые записи сверяются с графом и таймлайном, а не сливаются как текст — когда два утверждения конкурируют, спорные случаи помечаются, а не затираются молча.

Именно так и построен INITE Brain. У каждого факта двое часов — когда он был верен и когда граф о нём узнал, — поэтому можно запросить настоящее или переиграть любую прошлую дату. Конфликтующие записи проходят по скоринговой лестнице и приземляются как `COMPETING`, а не как тихая победа последней записи. Каждый факт ссылается на сообщение, из которого взялся. Forget — это синхронный жёсткий каскад по фактам, рёбрам и эмбеддингам, оставляющий HMAC-надгробие как доказательство. Тенанты изолированы на уровне базы, а PII закрыт по scope на каждое чтение. Retrieval — ранжированный конвейер: гибридное слияние векторов и keyword, расширение по рёбрам графа, personalized PageRank, cross-encoder и listwise-reranker — он берёт recall@1 0.962 на эвал-сьюте, потому что точность даёт структура вокруг эмбеддингов, а не эмбеддинги сами по себе.

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

## Как выбирать

Решение крутится вокруг четырёх вопросов. Сколько агентов и пользователей делят память? Меняются ли факты, так что память должна держать их сверенными? Берутся ли факты из источников, которые агент не может вывести заново локально? Подпадают ли данные под режим хранения или комплаенса?

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

Держи markdown, пока он подходит. Тянись к темпоральному графу в тот момент, когда агенту нужно помнить, *что было верно, когда и откуда взялось*.
