Skip to main content
total-agent-memory — cover

Избранное

total-agent-memory totalmemory.dev

Постоянная память для AI-агентов разработки через MCP — локально или как аутентифицированный командный сервер с личной, командной и общей памятью (v14.9.0).

  • Python
  • SQLite
  • FastEmbed
  • ChromaDB
  • Ollama
  • MCP
  • Three.js

Проблема

Coding-агент без памяти переспрашивает одно и то же каждую сессию. И повторяет те же ошибки. Context window — не память, это working set. Векторный store — тоже не память, это Ctrl+F с эмбеддингами.

Хотелось ближе к тому, как работает senior-инженер: эпизодический recall (“это пробовали в прошлый вторник, не сработало”), семантический (“в компании логи пишутся в JSON”), decay, противоречия и право сказать “не знаю”.

Архитектура

  • Лексический путь: SQLite + FTS5 с ранжированием BM25 и fuzzy-поиск на опечатки.
  • Семантический путь: эмбеддинги FastEmbed (ONNX, без PyTorch в базовой установке). Источник истины для поиска — векторное хранилище в SQLite; ChromaDB — зеркало на запись.
  • Graph layer: сущности, связи и темпоральные факты, cognitive activation spreading.
  • Fusion: результаты объединяются через Reciprocal Rank Fusion, затем MMR для разнообразия.
  • Re-rank: опциональный CrossEncoder / BGE-реранкер, ставится отдельным extra и выключен в дефолтном fast-режиме.

Версия 14.9.0 (2026-10-13)

  • Память работает, даже если агент её не вызывает. Поиск, проверку правил и сохранение теперь делают хуки: каждый промпт получает подходящие правила и короткий блок релевантных записей (бюджет 400 токенов, лимит 1,5 с, промпт никогда не блокируется), новый PreToolUse-хук показывает правило прямо перед командой или правкой, к которой оно относится, а на Stop ход сверяется с правилами, показанными сессии. Промпт, которым пользователь поправляет агента («я же говорил»), становится черновиком инсайта и превращается в правило только после настоящих голосов. Приостановка правил теперь опирается только на явные оценки: раньше загрузка правил приостанавливала полезные после десяти стартов сессии.
  • Один тёплый сервер для всех клиентов. tam daemon держит один сервер на каталог памяти, клиенты подключаются через tam proxy: первый memory_recall сессии занимает 0,18 с вместо 1,51 с. Относительные даты («в прошлом месяце», «три недели назад») теперь дают поиску окно дат, вопросы «а что было раньше?» ставят первым старое значение (0/48 → 48/48), LongMemEval-S held-out — 88,0 на 400 вопросах. Результаты.
  • Импорт, экспорт, CI. tam import chatgpt|claude|mem0|markdown сохраняет исходные метки времени; tam export --encrypted переносит базу между машинами AES-256-GCM-бандлом. Инструментов стало 79 вместо 77, а каждый pull request прогоняет полный набор тестов на Ubuntu, macOS и Windows с Python 3.11–3.13.

Версия 14.8.0 (2026-10-08)

  • Каждый ярус поиска измерен, два из них починены. Веса, которыми сливаются ярусы поиска, стали настройкой, а новый харнесс измеряет вклад каждого яруса на LoCoMo, LongMemEval-S или копии установленной базы. На копии базы автора он нашёл ярус графа, который никогда не срабатывал (читал таблицу, в которую никто не пишет), и ярус представлений, который сравнивал запрос с произвольным подмножеством строк; оба исправлены. Те же 150 запросов: R@10 0,133 → 0,167, p50 поиска 336 мс → 128 мс. Результаты.
  • Вопросы, которые ранжирование упускало. Вопросы-советы дополнительно ищут конвенции проекта и поднимают реплики самого пользователя (preference-вопросы LongMemEval-S: MRR 0,460 → 0,509); session_end сохраняет итог сессии записью, которую находит поиск.
  • Эксплуатация. Цепочка резервных LLM-провайдеров, чтобы остановленная Ollama не оставляла очереди обогащения молча висеть, и часовая рефлексия теперь консолидирует простаивающие проекты на личных установках. Схемы 77 инструментов закреплены тестом; плагин, хуки и скилл не менялись.

Версия 14.7.0 (2026-09-30)

  • Бюджет контекста заполняется целыми записями. memory_recall(mode="context", fill_budget=true) ищет до 100 результатов в глубину и кладёт целые записи по порядку ранга, пока не кончится бюджет символов, вместо того чтобы резать верхние результаты до отрывков. Контекст чаще содержит нужные доказательства: LoCoMo 0,815 → 0,890 при 8 000 символов, LongMemEval-S (все нужные реплики) 0,766 → 0,904 при 40 000. По умолчанию выключено. Результаты.
  • AMA-Bench, полный тестовый набор. В роли памяти агента на gpt-5-mini TAM набирает 0,658 по 24 ячейкам «домен × способность» на всех 208 эпизодах (судья gpt-5.2); GPT-5 mini, читающий траекторию целиком, на опубликованной доске набирает 0,656. Результат подан в рейтинг и считается заявленным самостоятельно, пока доска его не проверит. Метод и прогон.

Версия 14.6.0 (2026-09-28)

  • Сервер памяти для компании. tam setup спрашивает «Только я» или «Сервер компании». У командного сервера есть веб-дашборд:

    • приглашения по коду и роли (участник, руководитель отдела, наблюдатель компании, суперадмин);
    • журнал аудита и настройки провайдеров с зашифрованными ключами.

    Добавлены онбординг отделов с тестами, отчёты об активности (memory_report) и offboarding. Все данные можно хранить в PostgreSQL: на тесте паритета оба бэкенда возвращают одинаковый топ-10.

  • Настройки и приватность в личной установке. В локальном дашборде появилась страница настроек. API-ключи хранятся зашифрованными и больше не пишутся в конфиги клиентов. Секреты маскируются на всех путях записи. tam redact-existing чистит то, что сохранили старые версии, а memory_delete(hard=true) стирает запись со всеми копиями.

  • Плагин для Hermes Agent. hermes-tam-memory делает TAM встроенным провайдером памяти для Hermes Agent от Nous Research. Плагин сохраняет каждый ход и перед следующим поднимает нужные воспоминания. Он добавляет tam_recall и tam_save и работает локально или с командным сервером.

Версия 14.5.1 (2026-09-24)

  • Запись больше не оказывается выше собственного обновления. Cross-encoder из 14.5.0 знал «настоящее» значение и мог поднять его над записанным обновлением («Windows Vista» → Microsoft выше более позднего «Raytheon»). После переранжирования значения одного утверждения теперь идут от нового к старому. На MemoryAgentBench FactConsolidation самое новое значение стоит первым в 98 вопросах из 100 вместо 45; LoCoMo и LongMemEval не меняются. Результаты.

Версия 14.5.0 (2026-09-23)

  • Без значимой разницы с Mem0 Platform. Mem0 публикует ответы, по которым посчитаны его цифры на LoCoMo и LongMemEval. Если оценить их вместе с ответами total-agent-memory на тех же отложенных вопросах, причём в каждой конфигурации оценки обе системы проверяет одна и та же модель с одним промптом: LongMemEval-S 92,25 против 91,00, LoCoMo 88,02 против 88,46. Ни одна разница не значима на этих вопросах, но это не доказанная эквивалентность. При этом поиск работает локально и не вызывает LLM ни при записи, ни при поиске. Отчёт и как его воспроизвести.
  • Контекст для модели стал полнее. Кросс-энкодер читает каждого кандидата вместе с соседними репликами, относительные даты («в прошлый четверг») получают дату, которую означают, а бюджет контекста распределяется по рангу, и длинная верхняя запись больше не обрезается до отрывка.

Версия 14.4.0 (2026-09-22, вошла в 14.5.0)

  • Запись может погасить значение, которое она заменяет. memory_save(supersede=true) помечает устаревшими прежние записи того же проекта и типа, которые начинаются теми же словами и заканчиваются другим значением («гражданство — Аргентина» → «… Армения»). Включается явно, потому что правило погасило бы и «любит рок», когда приходит «любит джаз». На MemoryAgentBench FactConsolidation (одношаговые вопросы) gpt-4o-mini поднимается с 82 до 99 (6k) и с 85 до 93 (262k).
  • Запись дешевле на миллионе записей. Сохранение больше не заставляет кэш векторов перечитывать всё: следующий поиск без фильтра по проекту занимает 0,37 с вместо 4,2 с. Обновление словаря понятий, которое раз в минуту задерживало сохранение, теперь занимает 2,6 мс: 99-й перцентиль сохранения упал с 1,4 с до 0,14 с.

Версия 14.3.1 (2026-09-21)

  • Обновления фактов больше не теряются. 14.3.0 считала почти одинаковые записи повтором, поэтому после «гражданство Месси — Аргентина» и «… — Армения» оставалась Аргентина; на MemoryAgentBench FactConsolidation терялось 36 фактов из 455. Теперь повтор — только дословно то же утверждение, и он заменяет старую запись, так что после «A, B, снова A» текущим остаётся A.
  • Быстро на миллионе записей. Поиск в пределах проекта больше не замедляется с ростом всей базы: 25 мс вместо 781 мс на 100 тыс. записей, 105 мс вместо 6–64 с на миллионе (200 клиентов, одна машина). MCP_HTTP_WORKERS запускает несколько процессов HTTP-сервера на одном порту для сервисов с многими клиентами.

Версия 14.3.0 (2026-09-21)

  • Jev проверяет противоречия. memory_answer может проверять найденные факты на противоречия моделью Jev от TypeSafe. Она не генерирует текст, а отвечает на типизированные вопросы вероятностями: каждая пара фактов — один вопрос, все в одном запросе. По сравнению с проверкой на Claude Haiku 4.5 на тех же вопросах точность та же (35 из 78 против 36 на LongMemEval knowledge-update), проверка ускоряется с 3,1 до 1,9 с, а Jev выставил счёт на $0,04 за все 78 вопросов. Включается переменной MEMORY_CONTRADICTION_SCORER=jev.
  • Аккуратнее с API-ключом. Пустой ключ или ключ с управляющими символами отклоняется до отправки запроса, и в тексте ошибки ключа нет. Ту же проблему в официальных SDK TypeSafe я отправил им как issue.

Версия 14.2.0 (2026-09-21)

  • Факты, которые меняются со временем. memory_answer теперь отвечает последним значением: «Маша любит красный», сохранённое в мае, и «Маше больше не нравится красный — она полюбила зелёный», сохранённое в августе, дают ответ зелёный, раньше красный. Ридер видит, когда сохранена каждая запись, и значение считается актуальным, пока его не изменит более поздняя запись. На LongMemEval knowledge-update верных ответов стало 35 из 78 вместо 12 (Claude Haiku 4.5).
  • Противоречие разрешается, а не приводит к отказу. Обе записи уходят ридеру вместе с датами; MEMORY_CONTRADICTION_POLICY=abstain возвращает отказ из 14.1.0. Противоречие про другого человека больше не блокирует ответ.
  • Русские словоформы и единый формат времени. «Маша» в вопросе находит «Маше» в записи. Время хранится в одном формате UTC, старые записи переводятся при обновлении.

Версия 14.1.0 (2026-09-21)

  • Поиск опровержения в memory_answer. Перед ответом второй поиск ищет факты, которые опровергают вероятный ответ: небольшая модель переворачивает вопрос, а каждая пара «за — против» (не больше 5 × 5) оценивается одним пакетным вызовом. При оценке 0,60 и выше ответ — «Not enough information», сторона не выбирается; от 0,30 до 0,60 — ответ с оговоркой.
  • memory_answer на Anthropic и Ollama: оба провайдера теперь отдают вывод строго по схеме, и grounded reader больше не падает на JSON в markdown-обёртке.

Версия 14.0.0 (2026-09-15)

  • Один аутентифицированный сервер для личной, командной и общей памяти. У каждой области своя база, граф и индекс; поиск идёт по всем областям, доступным токену.
  • Авторство и история ревизий. Автор и клиент берутся из личного токена; правка создаёт ревизию, а проверка ревизии не даёт затереть чужое изменение.
  • Командный веб-интерфейс: поиск, просмотр, сохранение, редактирование и история.
  • Удалённый MCP-мост с восемью базовыми инструментами; в локальном каталоге 76 инструментов.
  • Настраиваемые внутренние LLM-провайдеры: Ollama, OpenAI-совместимые endpoint’ы или Anthropic.
  • Scoped retrieval и векторный поиск с учётом модели: каждое пространство эмбеддингов опрашивается своей моделью и размерностью; несовместимые сохранённые векторы исключаются, а не сравниваются молча.
  • Приватные write intents: приватные секции вырезаются до записи в durable outbox.
  • Опциональный grounded reader (memory_answer), отклоняющий противоречивые утверждения. Обычный поиск (recall) его не использует.

Проверки: CI-матрица релиза прошла — нативные установки на Ubuntu 24.04, Windows 2022, macOS 15 Intel и macOS 15 arm64 с Python 3.11, 3.12 и 3.13, а также Docker Compose, браузерные тесты в Chromium / Firefox / WebKit, сборка пакета и полный набор тестов из исходного архива, где проходят 2 145 тестов.

Ключевое в реализации

  • Multi-representation хранилище — запись может быть проэмбежена как исходный текст, summary, ключевые слова, вопросы и сжатая форма; поиск идёт по всем представлениям.
  • Self-extracting knowledge graph — сущности и связи извлекаются автоматически, fact merger разруливает противоречия.
  • Темпоральные факты — у фактов есть valid_from / valid_to, kg_at показывает, что было верно на заданный момент.
  • Локальный дашборд — включает 3D WebGL-вид (Three.js) графа знаний.

Замеры retrieval

Измерены на 13.x и приведены в README v14. Это recall поиска — попадает ли нужное свидетельство в топ-5, — а не точность ответов:

  • LongMemEval (публичный, longmemeval_s, 470 вопросов, v13.0.0, дефолтный fast-профиль): recall@5 (any) = 95.1 %.
  • LoCoMo (1 536 вопросов): R@5 = 0.607.
  • BEAM в масштабе 1M (625 проб): R@5 = 0.448.

Никакого рейтинга относительно других продуктов памяти не заявляется.

Результаты

MIT, Python 3.11+, MCP-native. Работает как локальный stdio-сервер для одного человека или как командный сервер за HTTPS reverse proxy. Подключается к Claude Code, Codex CLI, Cursor и другим MCP-клиентам, а к Hermes Agent — через плагин провайдера памяти. Версия 14.6.0 опубликована как GitHub Release с wheel и исходным архивом, на PyPI, через npm-обёртку 1.9.0, как образ в ghcr.io для linux/amd64 и linux/arm64, в официальном MCP Registry и в Homebrew tap. Сайт продукта: totalmemory.dev.

Уроки

  • Recall — это стек, а не сервис. Лексический, семантический и графовый поиск промахиваются по-разному; выигрыш даёт их fusion.
  • Забывание — это фича. Без decay store заполняется устаревшими фактами, которые вытесняют актуальные.
  • Бенчмарки требуют той же проверки, что и код. В 13.0.0 я отозвал прежнюю, более высокую цифру LongMemEval: оказалось, что раннер мерил собственное автономное ранжирование, а не путь, которым ходит агент. Цифры выше получены через реальные store и поиск.