Избранное
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 и поиск.