Расскажу историю длиной в полгода, на которой я ясно ощутил все плюсы и ограничения современных инструментов работы с LLM.
Простая идея с глубокими последствиями
В августе 2025 года мой отец предложил создать поисковик-анализатор новостей: задаёшь список источников и запрос — система присылает сводку с ответами и ссылками. Казалось, это классическая задача для RAG: собрал, показал, получил аплодисменты. Я за 1–2 месяца в свободное время собрал рабочий прототип. Он умел искать по смыслу, генерировать ответы на основе найденных постов и даже помогал открывать статьи. В мыслях — салюты, шампанское, AI-единороги.
Но реальность
При тестировании выявились две серьёзные проблемы. Во-первых, сложные запросы вроде «причины шатдауна правительства США» давали мимо: либо находили только упоминания Трампа, либо вообще ничего. Во-вторых, система плохо понимала сущности: ЦБ РФ мог трактоваться как два отдельных слова или вообще как неизвестная абстракция. Обе проблемы указали на один фундаментальный изъян — чрезмерная зависимость от семантической близости. Это ведёт к размытию смысла на длинных запросах, непредсказуемому поведению имён собственных и поиску по частоте, а не по смыслу.
Особенно остро встал вопрос связей. Например, связь «Израиль — нефть — рубль» очевидна для любого, кто живёт в 2026 году, но её не найти через семантический поиск, как бы вы ни переформулировали запрос. Я начал искать альтернативы.
Ищем связи
Семантический поиск хорош, но он не видит связей между событиями и объектами. Обычный RAG — плоская система: он находит схожие тексты, но не понимает, как они связаны. Есть Graph RAG и Event-based RAG. Первый строит связи на основе совместного упоминания в документах. Это работает для статичных источников, вроде Кодекса, но не для динамичных новостей, где связи меняются, а сущности устаревают или приобретают новые значения.
Graph RAG слишком неповоротлив: он строит жёсткие связи, а в мире новостей сложно определить, что будет узлом — новость, событие или объект. А если появится сверхузел вроде «экономика», граф станет неуправляемым. Поэтому я выбрал Event-based RAG — подход, заточенный под динамические события и их связи. Подробнее — в статье arxiv.org/abs/2507.13396. Я рассмотрел готовые фреймворки, но в итоге решил написать свою реализацию — база уже была, а graphiti не подходил под мои задачи.
Дао мягких и жёстких связей
Я понял: ключевое — понять, что и как связывать. Цель — построить граф, который:
- легко обновлять (минимум усилий на изменение весов или рёбер);
- расширяет знания, а не дублирует частотную связанность;
- учитывает временной контекст;
- избегает сверхузлов.
Такой граф можно поддерживать в актуальном состоянии и использовать для расширенного контекста. Но как его построить?
Новость — это состояние объектов в момент времени. Проще: новость = событие = отношения объектов. Так родилась формула, которая до сих пор лежит в основе проекта: ARTICLE - EVENT - ENTITY.
Теперь нужно было разместить это в графе. Если хранить всё вместе, получится перепутанный клубок. Например, текст про катки и OpenAI окажутся в одной плоскости, а Трамп — центральным узлом с тысячами связей. Это неработаемо.
Решение — разделить данные на изолированные плоскости: статьи, события, объекты. Связи между плоскостями — жёсткие (неизменные): статья содержит событие, событие включает объекты. Внутри плоскостей — мягкие связи, которые рассчитываются динамически.
Например, статья:
Иран открывает Ормузский пролив для судоходства, сообщил глава МИД страны Аббас Арагчи. «В соответствии с прекращением огня в Ливане, проход для всех коммерческих судов через Ормузский пролив объявляется полностью открытым на оставшийся период прекращения огня», — написал министр в X. (источник).
В системе: статья попадает в плоскость постов, два события — в плоскость событий (с жёсткой связью к статье), объекты (Иран, Ормузский пролив, Аббас Арагчи, Ливан) — в плоскость объектов (с жёсткой связью к событиям). При поиске по «Ливан» алгоритм может найти «Ормузский пролив» через общее событие — именно это и нужно от «умного» поиска.
Как работала система и чего ей не хватало
К тому моменту система напоминала франкенштейна с двумя пайплайнами:
Сохранение: по расписанию собираются посты из открытых Telegram-каналов. Они нормализуются, фильтруются и обрабатываются: из них LLM выделяет события и объекты, строятся эмбеддинги. Тексты идут в векторную БД, связи — в SQL.
Поиск: запрос перефразируется, выделяется временной интервал. Формируется несколько подзапросов, идёт семантический поиск, фильтрация, добавление слабо связанных событий, затем LLM суммирует найденные статьи и отвечает на вопрос.
Были и оптимизации: извлечение тегов, якорей, разные стратегии под типы запросов. В целом — почти готовое решение. Но изначальные цели — качество и удобство — не были достигнуты полностью.
Заказчик (опять же, папа) выдвигал требования, о которых я не подумал:
- если в посте есть «читайте дальше на сайте», система должна парсить внешнюю ссылку;
- нужно задавать тему и получать оповещения по расписанию;
- события надо проверять в зарубежных источниках и сравнивать интерпретации.
Я понял: впихивать всё в один проект — путь к неподдерживаемому швейцарскому ножу. Либо всё в одном промпте, либо в куче мелких инструментов — и везде потеря контроля.
Агенты (самая важная часть)
Я несколько недель использовал агента на OpenClaw: он вёл учёт трат, искал товары, напоминал о событиях. Был впечатлён простотой и «дружелюбностью» интерфейса. Решил внедрить агента в свой проект. Решение пришло быстро:
- гиперперсонализация — зона ответственности агента пользователя;
- надёжность — задача модели данных и поисковых алгоритмов;
- сервис перестаёт быть точкой входа и становится инструментом в руках агента;
- следовательно, сервис должен быть источником знаний, хранилищем и набором инструментов.
Я разбил проект на минимальные функции и открыл к ним доступ через авторизацию. Результат:
Сервис стал понятным источником знаний с контролируемыми инструментами. Агент сам решает, какой запрос задать, с какими фильтрами, когда отправить, может вести локальный кэш, искать и добавлять статьи. На него легли две ключевые задачи: персонализация и парсинг источников.
Смена парадигмы — с push на pull. Это принципиально: ответственность разделена, пользователь получает свободу. С точки зрения бизнеса: зачем продавать доступ к API, следить за тарифами, бороться с ботами? Лучше продавать доступ к платформе — хранилищу и MCP-серверу для агентов. Агенты пользователь настраивает сам: из шаблонов или покупает отдельно. Для меня это — новый взгляд на мир.
Ограничения и открытые вопросы
Статья упрощает некоторые проблемы. Например, безопасность источников: если разрешить внешним пользователям добавлять данные, злоумышленник может заспамить систему. Для «семейного» проекта это не критично, но в продакшене нужна защита.
Вторая проблема — память. Она не решена. Входная точка поиска — всё ещё семантический поиск. Я исследую ассоциативную память, но пока без значимых результатов.
Эта статья — рассказ о попытке уйти от плоского поиска в конкретной задаче. Искренне благодарю за внимание и за то, что дочитали до конца.