Ну или бесконечная борьба с ИИ-Альцгеймером
Я искал рабочее решение для памяти ИИ-агента с момента как поставил первый OpenClaw Перепробовал наверное почти всё и вот рассказываю, что и зачем искал, и к чему пришёл и как вообще до такой жизни докатился 🙂
С чего начал (почти)
Про OpenClaw не буду, слишком грустная история которая меня убедила что я тупой инженегр и мой удел писать в DeepSeek «А как какать? Объясни простыми словами»
Поставил Hermes Agent, (пошел прогрев на рекламу очень нужного всем ТГ канала :)) )
сказал «запомни» агент запомнил. Красота. Нет. Через неделю понял: красота, пока агент сам догадывается вызвать memory(). А если забыл всё по новой. А он забыл, он вообще вам ничего не обязан, тем более помнить и думать за вас, дежурно так сказать напоминаю.
Хотелось тяночку: после каждого ответа чтобы факты сохранялись сами. И чтобы анализы (Prism, ADR) не пропадали, а шли в базу знаний. Денег
MemPalace
Первое, что я попробовал MemPalace. Звучало как архитектура да еще и от Милы Йовович, у меня не было шанса не попробовать: комнаты, коридоры, туннели между концептами. Поставил, запустил индексацию. Получил 58 тысяч чанков на 1.1 гигабайта. 96% из них — дубликаты того, что уже лежало в state.db.
MemPalace оказался тяжёлым, невстроенным и, главное, ненужным в моем случае. Я даже написал статью «Память: 80 строк и один cron» — про то, как отказался от многослойной архитектуры в пользу простоты. Я оставил MemPalace как артефакт и перестал думать, что память ИИ-агента это сложно. (Вру — это сложно)
Четыре компонента
После MemPalace у меня было четыре компонента памяти, каждый со своей задачей:
-
MEMORY.md + USER.md — файлы с фактами, которые агент читает при старте
-
state.db (SQLite FTS5) — поиск по истории сессий
-
HippoRAG — граф знаний с ассоциативным поиском
-
wiki-файлы — структурированные анализы
Четыре сервиса, четыре точки отказа, четыре способа сказать «я не помню».
Я сократил до двух: MEMORY.md для быстрых фактов (инжектятся в промпт) и state.db для поиска (session_search, assoc_search). HippoRAG оставил как опциональную надстройку. Wiki — отдельно, по необходимости.
Первая попытка: findings_to_wiki
Написал MemoryProvider, который в sync_turn() сохраняет факт в MEMORY.md. Триста строк Python. Назвал findings_to_wiki.
Код https://gist.github.com/NikolayGusev-astra/446bff15a8bd76e4151a1c72d05c5ffe
Если в ответе есть структурированный анализ — детектится по заголовкам (## Findings, ## Decision, ## Conservation Law).
Примечание : паттерны детекции настраиваются через config.yaml, можете подставить свои.
Сырые файлы сохраняются в ~/wiki/raw/auto-findings/. Потом built-in skill research/llm-wiki превращает их в полноценные wiki-страницы: frontmatter, cross-links, index.
Zero зависимостей. Файлы открываются блокнотом. Ничего не падает, потому что ломаться нечему.
Масштабирование
Видел вчера пост от FlowWow
В лоб вижу что им агент нужен но у них своя специфика, ну и пошел думать как туда hermes agent бы встал, спойлер в идеале допилить немного напильником и как родной, Проблема только в мультитенантности памяти.
-
MEMORY.md — один файл на всех. Контаминация диалогов: факты одного пользователя подмешиваются в контекст другого
-
wiki-файлы — общая куча. Анализы по проекту A видны при обсуждении проекта Б
-
Нет per-user изоляции — данные одного пользователя видит агент другого
-
Нет поиска по содержимому, кроме линейного сканирования
Чем заменить подумал ну и логичный вопрос а «а какой бизнес кейс решаем, какие метрики успеха?» А где еще такие задачи? И логичный ответ — Логиже!!!
ClickHouse
ClickHouse я знаю, я на нём логи агрегировал. ИИшники даже не смотрят в сторону observability-инструментов. У них нет привычки работать с log DB. ClickHouse для них «база для аналитики» максимум и вообще что-то на старперском 🙂 «Мы такие вещи с клодом за неделю пишем нафиг нам твое вонючее старперское легаси» А для меня это очевидный кандидат: log DB уже умеет всё, что нужно. Если что у меня и павербанков штук пять и набор проводов для зарядников есть и фильмы я качаю а не онлайн смотрю :))
В 24.x появилось то, что делает ClickHouse полноценным memory backend:
-
cosineDistance()— векторный поиск для RAG -
tokenbf_v1(илиtextindex в 26.2+) — текстовый поиск по словам -
MATERIALIZED VIEW— агрегация без внешних воркеров -
TTL— забывание старых данных по расписанию -
PARTITION BY user_id— нативная изоляция пользователей
Одна таблица agent_memory(user_id, timestamp, content, embedding, metadata) заменяет в принципе все
Итого:
Solo
user -> agent -> findings_to_wiki -> MEMORY.md (авто-факты) -> wiki/raw/auto-findings/ | research/llm-wiki -> wiki/concepts/
-
300 строк Python, stdlib
-
Файлы открываются блокнотом
-
Один пользователь, один агент
-
Сложность: установил и забыл
Enterprise
user -> agent -> ClickHouse Memory Provider -> agent_memory | cosineDistance / tokenbf / TTL
-
ClickHouse 24.x, отдельный сервер
-
100+ пользователей, PARTITION BY user_id
-
TTL по расписанию
-
Одна таблица вместо пяти компонентов
|
Параметр |
Solo |
Enterprise |
|---|---|---|
|
Пользователей |
1 |
100+ |
|
Хранение |
Файлы |
ClickHouse |
|
Поиск |
session_search (FTS5) |
cosineDistance + tokenbf |
|
Забывание |
LRU по limit |
TTL по расписанию |
|
Изоляция |
Файловая |
PARTITION BY user_id |
|
Ресурсы |
0 |
8+ ГБ |
|
Зависимости |
stdlib |
ClickHouse 24.x |
Сразу отвечаю на ответы
«ClickHouse для памяти — избыточно.»
Для одного пользователя да. Для ста нет. Solo-архитектура существует именно для этого случая.
«А ClickHouse Memory Provider существует?»
В разработке. Надо его где-то развернуть и поэмулировать. Статья про направление, не про готовый продукт.
«ClickHouse жрёт 8 ГБ, зачем?»
ClickHouse — сервис. Если он уже стоит для логов одна таблица не требует нового инстанса.
«А как же Qdrant / ChromaDB / Pinecone?»
Они решают задачу поиска по миллионам векторов. ClickHouse покрывает и текст, и векторы, и TTL, и партишены всё в одном.
до сюда никто все равно не дочитает так что реклама канала
Код findings_to_wiki — gist + PR #21139 в репозиторий Hermes Agent
ClickHouse Memory Provider — в разработке
ссылка на оригинал статьи https://habr.com/ru/articles/1032630/