Как я научил нейросеть искать велопокатушки за меня

Анонсы любительских велозаездов в России живут в сотнях телеграм-чатов: «в субботу катим от метро, темп бодрый, кто с нами — плюсуйте». Найти, куда поехать в выходные, — значит вручную листать десятки чатов. Я собрал конвейер, который сам находит эти чаты, читает анонсы через LLM и складывает их в единый календарь — dodofo.ru. Рассказываю, как это устроено и что получилось: 192 источника, сотни заездов Москвы и Питера, и всё это крутится на двух дешёвых VPS.

dodofo.ru - главная
dodofo.ru - главная

Боль

Я велосипедист. Каждую пятницу у меня один и тот же ритуал: открыть десяток телеграм-чатов и понять, куда можно выехать в выходные. Проблема в том, что велодвижуха в России почти целиком живёт в Telegram, и у неё нет ни одной точки входа:

  • у каждого клуба и района свой чат — «Вело-ЮЗАО», «Строгино», рандоннёры, шоссеры, гравийщики;
  • анонс — это простыня текста в свободном формате: где-то есть дата и точка старта, где-то «как обычно, от той же беседки»;
  • маршрут — отдельной ссылкой на сторонний сервис: чтобы просто взглянуть на трек, надо куда-то переходить, и так по каждому заезду;
  • главный вопрос — «а мне туда вообще можно?» — решается вручную: сидишь, тыкаешь по анонсам и трекам и прикидываешь, где покатаешься комфортно, а где либо не вывезешь, либо будешь абузой для группы;
  • и это ещё не всё: надо понять, как добраться до старта, и есть ли вообще заезд поближе к дому;
  • а через два дня анонс тонет под сотней сообщений «а какая резина у тебя?».

Агрегаторы типа афиш существуют для гранфондо и больших марафонов, но 90% реальной жизни — это клубные покатушки на 20–100 человек, которые нигде, кроме своего чата, не анонсируются. В Telegram есть и каналы-агрегаторы покатушек, но у них та же беда, только с другой стороны: чтобы туда попасть, организатор должен специально написать админу канала. Большинство оргов этого просто не делает — им и в своём чате хорошо.

Максимально полное описание заезда в телеграм
Максимально полное описание заезда в телеграм

Идея: пусть анонсы читает машина

Руками это не собрать: source-база — сотни чатов, формат — произвольный текст. Но это идеальная задача для LLM: «вот пост из чата, скажи, это анонс заезда? Если да — вытащи дату, время, точку старта, дистанцию, темп, дисциплину».

Так появился dodofo.ru — календарь велозаездов, который наполняется автоматически. Человек в конвейере остался только один — я, в роли модератора.

Шаг 1. Найти чаты — тоже через Telegram

Первая проблема: откуда взять список источников? Гуглить «велочат Бутово» бесполезно — половина чатов нигде, кроме самого Telegram, не засвечена.

Решение: у Telegram есть внутренний поиск по публичным чатам и каналам (метод contacts.search в MTProto API). Я написал утилиту, которая гоняет по нему матрицу запросов «велотермины × география»: вело/шоссе/гравел/МТБ/бревет × города Подмосковья и Ленобласти, потом вторым заходом — × районы Москвы и Питера. Получилось порядка тысячи запросов (с паузами — Telegram строго следит за флудом).

Дальше ручная курация: выкинуть мото и самокаты, магазины, прокаты и веломастерские, чаты других регионов. После фильтра в базе осталось 192 живых источника — от многотысячных каналов до районного чата на полсотни человек.

Шаг 2. Конвейер: прочитать, понять, опубликовать

Дальше работает конвейер из четырёх стадий:

  1. Скрейп. Коллектор по MTProto-сессии читает новые посты из всех источников.
  2. Пре-фильтр. Дешёвый локальный классификатор отсеивает очевидный мусор — обсуждения, мемы, продажу колёс. Это важно для экономики: LLM-вызовы стоят денег, и жечь их на сообщение «кто-нибудь едет завтра?» жалко. До нейросети доходит только малая часть потока.
  3. LLM-разбор. Кандидатов читает Claude и возвращает структуру: дата, время, точка старта, маршрут, дистанция, темп, дисциплина, требования. Параллельность ограничена, очередь переживает и флуд-вейты Telegram, и лимиты API.
  4. Дедупликация. Самое неожиданно сложное место. Один и тот же заезд анонсируют в пяти чатах, с разными формулировками и опечатками. Дедуп детерминированный: окно по дате, сигналы «ссылка на один маршрут» и «совпадение гео+времени», название — только вспомогательный модификатор. Слить два разных заезда страшнее, чем показать дубль, поэтому явно разное время старта — жёсткий блокер слияния.

И одно принципиальное правило: уважение желания кататься своей компашкой. Если в анонсе написано «только для своих», «не для репоста», «инфа для чата» — такой заезд в календарь не попадает. Публичный календарь — для тех, кто рад новым людям, а не способ притащить толпу туда, где её не ждут.

Результат — карточка заезда с нормальной структурой вместо простыни текста.

dodofo.ru vs пост в телеге
dodofo.ru vs пост в телеге

Шаг 3. Архитектура: два сервиса в двух странах

Техническая деталь, которая может пригодиться другим: система разрезана на два сервиса.

  • Коллектор (скрейп + LLM-разбор) живёт на VPS в Европе — оттуда без танцев доступны и Telegram API, и API нейросетей.
  • Сайт и основная база живут на хостинге в России — быстрый отклик для аудитории и задел под 152-ФЗ (впереди пользовательские аккаунты).

Между ними — узкий внутренний контракт: коллектор копит результаты в буферной базе и пушит готовые структуры по HTTP с идемпотентностью (повторная доставка не создаёт дублей). Если один сервис лежит — второй продолжает работать.

Стек скучный и дешёвый: Go на бэке, Vue 3 на фронте, PostgreSQL + PostGIS, nginx, Docker, GitLab CI. Два маленьких VPS суммарно дешевле подписки на пару SaaS-сервисов.

Что получилось

  • 192 источника — чаты и каналы Москвы, Подмосковья, Питера и Ленобласти;
  • сотни заездов в календаре с начала года — от вечерних покатушек до бреветов на 200 км (зимой, как выяснилось, велочаты массово катаются на лыжах — конвейер честно тащит и это);
  • у каждого заезда — своя страница с ЧПУ вида /velozaezdy/moskva/2026-07-19/nazvanie, страницы городов, дисциплин и организаторов — календарь заодно работает как SEO-каталог;
  • фильтры: город, дисциплина (шоссе/гравел/МТБ/бревет), дата.
dodofo.ru - шоссейные заезды в Москве
dodofo.ru - шоссейные заезды в Москве
dodofo.ru - заезды организатора
dodofo.ru - заезды организатора

Грабли, на которые я уже наступил

  • «Как обычно, от беседки». Часть анонсов понятна только своим: без даты, без точки. LLM тут честно пасует — такие посты уходят в скип. Лечится только контекстом источника (домашний город чата, история прошлых заездов).
  • Афиши-картинки. Многие организаторы постят красивую афишу, а в тексте — пусто. Учу конвейер разбирать картинки через vision-модель: гейт срабатывает, когда текст поста ни о чём не говорит.
  • Экономика LLM. Наивный вариант «шли всё в нейросеть» умножает счёт на порядок. Пре-фильтр до LLM + дешёвая модель для рутины + кэширование промптов — и разбор поста стоит копейки.
  • Дедуп без жалости. Сначала я боялся агрессивного слияния дублей. Потом посмотрел на выдачу с тремя копиями одного заезда и перестал бояться: лучше одно слитое событие с несколькими источниками, чем три карточки-близнеца.

Что дальше

Календарь — это первая, «read-only» часть продукта. Дальше много различных планов по развитию сервиса, но пока не готов с ними делиться на широкую аудиторию.

Сейчас мне важнее другое: полезен ли такой календарь вам?

Если вы катаете в Москве, Подмосковье, Питере или Ленобласти — загляните на dodofo.ru и скажите, чего не хватает. Если знаете живой велочат, которого нет в выдаче, — напишите в комментариях, добавлю в источники. И отдельно интересно: какой город добавлять следующим?

2