В субботу была плохая погода, и я решил сделать то, что давно откладывал — создать свой контент-завод для http://onedaytours.ru/.
Тема контент-заводов очень популярна в определенных кругах маркетологов, но всегда проходила как-то мимо меня, как человека очень далекого от SMM и медиа. Тем не менее, для http://onedaytours.ru/ вопрос контента стоит довольно остро, потому что это по сути некоторое туристическое медиа и писать надо для всей России, а ресурсы у меня очень ограниченные, зато есть голова (одна штука) и руки (две штуки). 😑
Сама идея родилась еще месяц назад, когда мы с
https://t.me/tokenfriend общались после запуска http://onedaytours.ru/ и обсуждали, как туристические проекты можно развивать с помощью ИИ.
В чем суть идеи.
Достопримечательности — это на удивление статичные сущности. Петропавловская крепость была, есть и будет, иркутский 130-й квартал никуда не денется, дербентская Нарын-Кала простоит еще примерно вечность. В отличие от афиши, которую надо обновлять каждую неделю, база точек, собранная один раз, работает годами. Из нее можно делать сколько угодно контента — от карточек под поисковую оптимизацию до маршрутов под любой запрос туриста.
Конвейер получается довольно простым (хе-хе). На вход — город. Сначала идем в открытые картографические сервисы и вытаскиваем все достопримечательности, музеи, парки, смотровые — по Иркутску получилось 1766 точек. Каждую точку обогащаем Википедией, Викидатой и OSM — факты, фотографии с чистой лицензией, теги. Дальше языковая модель размечает точку по шести осям: тема, стиль, период, аудитория, опыт, атмосфера. Другой проход LLM выставляет оценку — насколько точка заслуживает быть в маршруте. Потом считаем семантические векторы — по два на точку, один для содержания, один для атмосферы (вайба). Потом формирую тематические подборки — «купеческий Иркутск», «советский модернизм», «природа и вода». И для топ-200 точек синтезирую авторские тексты голосом ODT. Всего на город — четыре-пять часов фоновой работы.
Главная инженерная задача — универсальность. Один и тот же код должен работать на Иркутске с декабристами, на Калининграде с ганзейским прошлым, на Дербенте с ширваншахами и горскими евреями. В итоге я разделил словарь на два слоя — универсальное ядро и локальный профиль города, где лежат региональные темы. Профили тоже генерятся автоматически — одна LLM пишет, другая проверяет покрытие эпох, третья сверяется с Википедией.
Отдельная задача — разделение данных на стабильное ядро и волатильный слой. Координаты, архитектор, век постройки, авторский текст меняются раз в никогда — одна таблица. Рейтинг, часы работы, временно закрыто или нет — постоянно, отдельная таблица, обновляется краулером по расписанию. Каждый слой живет своей жизнью и не тащит соседа за собой.
Еще пришлось повозиться с дедупликацией. Одна точка приходит из трех источников с разными названиями и смещенными на 30-50 метров координатами. Решается кластеризацией: если точки в радиусе 80 метров и названия похожи после нормализации — это один объект, берем самое полное описание, остальные имена складываем в алиасы для поиска.
На выходе по Иркутску — 1766 точек, 1604 размечены по всем осям, 24 подборки, 160 авторских текстов. Запустить это на оставшиеся 27 городов — одна пакетная команда и примерно 60 часов фоновой работы моделей. То есть всю Россию можно покрыть за пару суток, а дальше точечно докручивать редактурой.
Но сам контент — даже не самое интересное. За всем этим стоит граф точек города, где у каждой достопримечательности есть координаты, категория, шесть осей тегов, оценка, факты и векторы. А это уже не контентная база — это движок продукта. На нем можно строить алгоритмические маршруты под любой запрос, кросс-городские подборки, рекомендации «похожие точки в других городах», туры по следу конкретного архитектора.
То есть формально я в субботу пилил контент-завод для текстов, а по факту собрал инфраструктуру, на которой http://onedaytours.ru/ может стоять следующие лет пять. Как-то так.
До стабильного продакшн слоя еще далеко, но прототип у меня уже работает, так что после майских точно, коллеги! 🌝