Разработчик под ником, опубликовавший кейс на Habr, собрал сервис второй памяти, который каждую ночь около двух часов по московскому времени запускает конвейер обработки переписки в Telegram. Сначала Telethon скачивает новые сообщения из отмеченных пользователем чатов и папок, через час второй воркер превращает их в структурированную память: режет на куски, прогоняет через DeepSeek, раскладывает по таблицам и выгружает в markdown-файлы. К утру у человека появляется дополнительная информация в сервисе второй памяти.

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

МетрикаЗначение
Пользователей в базенесколько
Источников на пользователя7 (3 папки и 4 чата)
Чатов34
Сущностей281
Тем147
Человек108
Проектов26
Фактов1815
Задач184
Дневных заметок133
Токенов на входе3028 тысяч
Токенов на выходе7027 тысяч
Всего токенов10,05 млн
Стоимость обработкименьше 10 долларов
Среднее время задания205 секунд
Самое долгое заданиепочти 12 минут

Схема конвейера выглядит так. Telethon забирает сообщения по выбранным источникам. Каждое сырое сообщение получает запись в таблице состояния: ожидает, в процессе, обработано, ошибка. Планировщик в следующий прогон берёт только то, чего в этой таблице нет, — так автор не платит дважды за обработку одного и того же. Сообщения группируются по ключу «источник:чат», сортируются по дате и режутся на куски по 100 штук. Внутри куска только один чат, чтобы модель видела связный диалог. Из куска собирается транскрипт вида [дата] Отправитель: текст с обрезкой по 30 тысячам символов.

На каждый кусок идёт один вызов DeepSeek, который должен вернуть строгий JSON с полями daily_note, topics, people, projects и links. В промпт подкладывается список уже известных сущностей пользователя с просьбой переиспользовать имена. Без этого один и тот же проект каждый прогон называется по-новому, и база быстро превращается в мусорку. Когда все куски задания готовы, запускается merge. Сущности ищутся по ключу (пользователь, тип, каноническое имя), повторные упоминания не плодят дубликаты, а обновляют summary. Факты и задачи привязываются к сущностям, связи уходят в отдельную таблицу, а каждая запись ссылается на id исходных сообщений.

Последний шаг — выгрузка в обычные markdown-файлы Daily, Knowledge, People, Projects. Ссылки между заметками оформлены как [[wiki-links]], так что vault открывается в Obsidian. Экспорт идемпотентный: перед записью блока считается его sha256, и если такой блок уже выгружался, он пропускается. Готовая карточка выглядит примерно так: «Поездка в Анталью», собирались в сентябре, бюджет около 350 000 ₽ на двоих, [[Аня]] предложила даты, [[Саша]] уточнил расклад по отелю и перелёту. Связь в файл не пишется, она живёт в базе: у каждого факта и задачи есть ссылки на конкретные сообщения.

Цифры на момент публикации: в базе несколько пользователей, на одного в среднем по 7 источников (3 папки и 4 отдельных чата), но даже они за пару месяцев теста сгенерировали десятки тысяч сообщений в 34 чатах. Из этого получилось 281 сущность: 147 тем, 108 человек, 26 проектов. Плюс 1815 фактов, 184 задачи и 133 дневные заметки. По токенам вышло 10,05 млн: 3028 тысяч на входе и 7027 тысяч на выходе. Ответы дороже входа больше чем вдвое, потому что JSON со схемой занимает много места. По тарифам DeepSeek это меньше десяти долларов на все сообщения.

Одно задание — обработка всех новых сообщений одного пользователя за прогон — идёт в среднем 205 секунд. Самое долгое заняло почти 12 минут. Так как всё работает ночью, 12 минут вполне приемлемо. Что ломалось: часть заданий отменилась на середине, в базе остался текст cancelled — model changed to v4-flash. Автор менял модель на лету, а задание в этот момент выполнялось. Часть чанков посчитана одной моделью, часть другой. Данные не сломались, но такой подход требует аккуратности.

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