Разработчик собрал автономный анализатор новостей на Google Таблицах и Gemini без выделенного сервера
Разработчик из потока «Разработка» описал, как собрал автономную систему отбора и перевода новостей об ИИ в энергосбережении на базе Google Apps Script, Google Таблиц и Gemini API. Решение обходится без постоянно работающего сервера и использует параллельные запросы к модели, чтобы укладываться в шестиминутный лимит выполнения скриптов Google.
Задача, которую поставил перед собой автор, выглядит прикладной и узкой: получать в Telegram только те материалы о применении искусственного интеллекта в энергосбережении и энергобезопасности, где действительно описан результат внедрения, а не рекламные обещания. Обычные RSS-агрегаторы такую фильтрацию не обеспечивают, поскольку даже тонкая настройка ключевых слов пропускает маркетинговые тексты без технических деталей и подтверждённых KPI. Поэтому ставка была сделана на языковую модель, которая оценивает смысл анонса, а не совпадение строк. Работа над инструментом велась около двух месяцев в связке с ChatGPT и Gemini, а один из приёмов — параллельная отправка независимых запросов — вынесен в отдельный разбор.
Архитектурно система не является сервером в привычном смысле, хотя в заголовке и фигурирует это слово: речь идёт о классическом serverless-сценарии на Google Apps Script, где скрипт просыпается по триггеру, обрабатывает порцию данных, при необходимости ставит себе дополнительные «будильники» и засыпает. Основа решения — четыре листа Google Таблицы: RSS со списком примерно ста источников, NewsInbox с анонсами до отбора, NewsQueue с отобранными статьями и черновиками постов, а также Log с уже обработанными ссылками. Модели разделены по задачам: Gemini 3.5 Flash-Lite с лимитами 15 запросов в минуту и 500 в сутки решает, подходит ли анонс, а Gemini 3.8 Flash с лимитами 5 и 20 соответственно получает тексты отобранных статей и готовит итоговые посты. Очереди нужны, чтобы переживать сбои API и окончание времени запуска: анонс сохраняется до отбора, готовый пост — до отправки в Telegram, поэтому при неудачной отправке не приходится заново просить модель написать тот же текст.
Ключевое узкое место обнаружилось на этапе фильтрации анонсов. В одной из версий бот успевал обработать за запуск лишь одну пачку новостей, о чём свидетельствует фрагмент реального отчёта: оценено Lite — 10, ожидают Lite — 22, подготовка заняла 3 секунды, сбор RSS — 126 секунд, работа Lite — 92 секунды, после чего сработало ограничение по времени. Google Apps Script жёстко лимитирует выполнение шестью минутами на запуск, поэтому экономия даже 80 секунд напрямую влияет на то, сколько работы вообще поместится в один цикл. При последовательном вызове каждая следующая пачка ждёт ответа по предыдущей, хотя между ними нет логической зависимости: чтобы оценить новости с одиннадцатой по двадцатую, модели не нужен результат по первой десятке. Именно эти ожидания и было решено перекрыть.
Технически применены два разных приёма, которые автор намеренно разделяет. Первый — группировка внутри запроса: модели передаётся сразу десять анонсов с просьбой вернуть десять решений, что сокращает число обращений к API, но не уменьшает суммарный объём обрабатываемого текста. Второй — параллельные запросы: несколько таких пачек отправляются, не дожидаясь ответа по каждой из них, и количество API-запросов от этого не снижается. В скрипте это выражено двумя константами — BATCH_SIZE, равной десяти, и LITE_PARALLEL_BATCHES, равной пяти, что при достаточном числе новостей и свободной квоте даёт группу до 50 анонсов в пяти независимых запросах. Каждый запрос получает собственный контекст, поэтому модель, обрабатывающая первую пачку, не видит остальные четыре, а критерии отбора остаются едиными.
Отдельного внимания заслуживает дисциплина работы с квотами и ошибками. Автор подчёркивает, что одна строка fetchAll() не заменяет учёт лимитов и обработку сбоев: чтение таблиц, резервирование квот и планирование повторов вынесены за рамки демонстрации, но именно они обеспечивают устойчивость. Контроль свежести реализован отдельно — статьи с распознанной датой старше семи суток пропускаются, в том числе при повторной обработке очереди, а для материалов без даты ограничено время ожидания. Накопленная очередь при этом не блокирует очередной сбор RSS, что позволяет системе продолжать накапливать анонсы, пока предыдущие ещё ждут обработки. Финальное решение остаётся за человеком: бот присылает черновик с кнопками «Опубликовать» и «Отклонить», а первая копирует сообщение в рабочий чат вместе со ссылкой и форматированием.
В более широком контексте описанный подход показателен для текущего этапа развития инструментов на базе больших языковых моделей. Разработчики всё чаще отказываются от выделенной инфраструктуры в пользу serverless-сценариев, где вычисления запускаются по событию, а роль базы данных и панели управления берёт на себя обычная таблица. На этом фоне жёсткие лимиты бесплатных тарифов и ограничения времени выполнения становятся не досадной помехой, а архитектурным фактором, определяющим размер пачки, число параллельных запросов и логику повторов. Параллелизм в таких системах перестаёт быть оптимизацией ради скорости и превращается в способ уложиться в отведённое окно, а разделение моделей по задачам — в инструмент экономии квоты: дешёвая и быстрая модель фильтрует, более capable и редкая готовит финальный текст.
Для российских разработчиков и небольших команд подобные схемы интересны прежде всего доступностью: Google Таблицы, Apps Script и Telegram Bot API не требуют собственных серверов и затрат на хостинг, а обработка иноязычных источников с выдачей результата на русском закрывает типовую потребность медиа- и аналитических проектов. Ограничения при этом остаются существенными — зависимость от внешних API, их квот и доступности, а также необходимость самостоятельно выстраивать обработку ошибок и повторов. Открытым вопросом остаётся масштабирование: при росте числа источников и ужесточении лимитов бесплатных тарифов придётся либо переходить на платные уровни, либо усложнять логику приоритизации и отложенной обработки. Пока же автор демонстрирует, что аккуратно спроектированный скрипт способен автономно принимать внешние данные, обрабатывать их и выдавать результат, не требуя ни выделенного сервера, ни постоянного вмешательства человека.