PunchEbonyi PDP gov candidate pledges to end child hawking, house-help cultureRTP DesportoMédio do Benfica Enzo Barrenechea operado ao joelho esquerdoThe Jerusalem PostConverse removes ad campaign criticized over KKK-esque imagery, issues apologyCNN بالعربيةرياضيون وأثرياء ينامون على هذا السرير الذكي.. ما فائدته؟عالم التقنيةهونر تستعد لإطلاق سلسلة WIN 2 و WIN Pad للألعاب في أكتوبر7sur7Macron remet la Légion d’honneur à Martin Scorsese et Robert De NiroGMA News4 katao, kabilang ang 3 menor de edad, sugatan matapos saktan umano ng ilang barangay officialsVilaWeb“L’espardenya o l’esvàstica, tu tries”: protesta antifeixista de Junts, ERC, Comuns i la CUP al parlamentChannel News AsiaCOE premiums all close lower in latest bidding exerciseIl Fatto QuotidianoLionel Richie per la terza volta ricoverato in ospedale: il cuore del “re della disco” cede ancora, il tour viene cancellatoThe Sydney Morning HeraldNRL Tips - Finals Week 3BBC NewsMigrants taken to Dover after more than 30 hours at sea
The Daily Newsstand · Free, Always
Wednesday, September 23, 2026

5 технических граблей на пути к AI‑агрегатору Telegram‑каналов

Translate

Делаю в одиночку приложение, которое собирает публикации из подобранных Telegram‑каналов по темам, убирает дубли и шум с помощью AI‑классификации и превращает результат в короткий аудио‑дайджест. Ниже — не обзор архитектуры целиком, а разбор конкретных мест, где план и реальность разошлись, и что пришлось чинить.

Грабля 1. RSS — не от Telegram, а через чужой мост со своим невидимым лимитом

Прямого доступа к Telegram API для чтения произвольных публичных каналов нет — это API для ботов, а не для мониторинга чужих каналов. Решение — бесплатный сторонний сервис, который превращает публичный канал в RSS‑ленту по URL. У него неофициальный лимит — по опыту, около 13–15 запросов подряд в течение нескольких минут, дальше сервис отвечает 429 и восстанавливается дольше, чем указано в официальной документации (заявлено 15 запросов/мин, фактическое время простоя больше).

Это не разовая проблема, а параметр архитектуры: именно этот лимит определяет паузу между темами внутри пайплайна (75 секунд) и, соответственно, нижнюю границу частоты полного цикла сбора по всем темам (около 40–45 минут на 12 тем). Внешняя зависимость без SLA и без официальной документации стала жёстким ограничением скорости всего продукта.

Грабля 2. Экономика количества запусков, а не только денег

У сервиса автоматизации, который использую, на базовом тарифе — лимит запусков в месяц (2500) и лимит одновременных запусков (5). Раньше у каждой из 12 тем было собственное расписание — 12 независимых точек входа. При учащении расписания (например, до ежечасного) это моментально умножает число засчитываемых запусков в 12 раз и выбивает тариф.

Решение — единая точка входа («Оркестратор»), которая по расписанию вызывает все 12 тем последовательно изнутри себя: внутренние вызовы в лимит не засчитываются, считается только сам факт срабатывания Оркестратора. Это не архитектурная эстетика, а прямое следствие тарифной модели — при другой схеме оплаты решение, вероятно, было бы другим.

Грабля 3. Дедуп, который не дедуплицировал вообще

В пайплайне были два разных идентификатора для одной и той же новости:

— external_id — детерминированный хэш от ссылки на пост и даты. Работает корректно: одна и та же статья из разных источников даёт одинаковый external_id, и бэкенд по нему корректно схлопывает дубли на приёме.

— cluster_id — хэш от точного текста описания (первые 200 символов), задуманный для кросс‑канальной кластеризации «разные каналы написали об одном и том же своими словами».

Проверка на 1003 записях за 14 дней показала 1002 уникальных cluster_id — то есть механизм не «работал слабо», а не работал практически никогда: разные каналы почти всегда описывают одно событие разными словами, и хэш от точного текста этого не ловит в принципе. Позже (после стоп‑листа служебных слов и добавления стемминга — «Россия»/«России», «дроны»/«беспилотники» и тому подобное) отдельный экспериментальный механизм на сравнении заголовков (а не заголовка с резюме, как было изначально по ошибке) дал точность около 89% на выборке — но это уже другой механизм, работающий параллельно и пока не подключённый к реальной ленте.

Грабля 4. Платишь за озвучку дважды — и не сразу это видно

Многие каналы относятся сразу к нескольким темам (например, один канал деловых изданий — сразу к «Банкам» и «Финансам»). Каждая тема — при старой архитектуре — отдельный прогон пайплайна с собственным вызовом синтеза речи. Дедупликация по external_id происходит на бэкенде после того, как аудио уже сгенерировано и оплачено — то есть бэкенд корректно схлопывает дубль на экране пользователя, но деньги на повторную озвучку уже потрачены.

Прямой подсчёт по 14 дням: 2275 фактических вызовов синтеза речи на 1003 уникальных атома — множитель ×2.27, то есть около 56% озвучки было избыточным. В деньгах, по тарифу на тот момент, это ориентировочно 1300 ₽/мес экономии при устранении дубля (оценка снизу — реальный текст для озвучки длиннее текста для отображения, потому что числа проговариваются словами).

Фикс — кэш «этот атом уже озвучен в другой теме за последние 48 часов» перед вызовом синтеза. Не сработал бы без побочного эффекта от другого исправления: пока темы стартовали по независимым расписаниям с разбросом в минуту, соседние прогоны почти всегда работали параллельно (замеры показывали пересечение по времени в 1.5–2.3 минуты), и кэш систематически промахивался — тема, стартовавшая на минуту позже, читала кэш раньше, чем предыдущая успевала туда записать. Когда для починки другого инцидента прогоны сделали строго последовательными через единый Оркестратор, кэш начал работать как задумано — без единой правки самого кэша.

Грабля 5. Ложно‑зелёный статус: расписание чаще — конвейер встал почти полностью

Учащение цикла сбора с 4 раз в сутки до раза в час привело не к постепенному росту расходов, как ожидалось, а к почти полной остановке сбора материалов с первого же часа новой частоты. Причина — бесплатная дневная квота классификатора (лимит 500 запросов/сутки на модель) была исчерпана в первый же час: при 4 прогонах в сутки квоты хватало неделями, при 24 — она кончилась почти сразу.

Хуже другое: сам Оркестратор при этом продолжал отчитываться «success» на всех прогонах. Ошибка ловится на уровне отдельной темы (осознанное решение — чтобы сбой одной темы не останавливал остальные), и должна была уйти в отдельный лог с email‑алертом, но алерт оказался выключен ещё с более раннего инцидента и не был включён обратно. Без ручной проверки данных полный отказ сбора остался бы незамеченным.

Что это меняет в архитектуре дальше

Классификатор был заменён с одной LLM на другую по стоимости (перешли на более дешёвую модель при выросшем объёме материала — прежняя осталась в графе отключённым резервом на случай сбоя новой). Готовится следующий шаг: не по одному вызову модели на материал, а батчами (около 15 материалов за вызов), с гейтами (по дате, по уже виденному external_id, по кросс‑канальному совпадению) до обращения к модели, а не после — потому что при текущей схеме до 19 вызовов из 20 уходят либо на «это не подходящий материал», либо на повторную обработку того, что уже разбирали час назад.

Честно о масштабе

Проект в ранней бете, соло‑разработка. По данным прямых запросов к базе за август: 4733 открытий приложения, 1037 прослушиваний, ежедневное число уникальных слушателей почти всегда 1–6 (максимум 11 за день). Подтверждённых внешних регистраций с реальной активностью на начало сентября — 0 (8 из 9 учётных записей в базе — сам фаундер, технический соавтор и один сотрудник платформы автоматизации, тестировавший продукт). При этом среди тех немногих внешних слушателей, что были, доля дослушивания стабильно держится в диапазоне 60–80% по неделям — то есть там, где до контента реально доходят, он не производит впечатление низкого качества. Узкое место — не контент и не техника, а количество людей, которые вообще узнали о продукте.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.