PROTOCOL A

← Журнал

статья · 11.09.26 · 12 мин чтения

Сторож комментариев: машина читает комментарии под роликами за меня и будит, когда нужен человек

Скрипт без нейросети каждые две минуты читает комментарии под роликами, выдаёт подарок по кодовому слову и будит меня, когда нужен человек. Цифры и грабли.

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

Зачем сторож, если можно заглянуть в приложение

Механика воронки простая. В конце ролика я зову написать слово в комментарии: «Антиробот», «Проверки», «Ключи», «Смета». Под каждым словом лежит готовый текст: ссылка на пост в моём Telegram-канале с промптом, списком или разбором. Человек пишет слово, получает публичный ответ под комментарием и личное сообщение со ссылкой. Ссылка ведёт в канал, и это единственный перелив из роликов в канал, который у меня работает.

Сложность в том, что окно для личного сообщения закрывается: Instagram* пускает ответ в директ автору комментария только семь дней, дальше остаётся публичный ответ. На YouTube личных сообщений нет вовсе, там выдача всегда идёт публично в ветке. Слово, которое провисело, - это человек, который не получил обещанного, и я узнаю об этом, когда уже поздно.

До 13 августа комментарии читались руками из рабочей сессии. Это работало ровно так, как работает любая ручная проверка: пока я помнил, а помнил я не каждый день. Сторож заменил память расписанием.

Как устроен один проход

Сторож - это comments_watch.py на 933 строки, без единой нейросети внутри. Запускает его планировщик ноутбука каждые 120 секунд. Один проход выглядит так.

Сначала он берёт список опубликованных роликов из общего плана и идёт к площадкам за комментариями. Обход устроен двумя кругами. Быстрый круг идёт каждый проход и смотрит три самых свежих ролика. Глубокий круг раз в час обходит всё, что вышло за последние четырнадцать дней, и подбирает комментарии, пришедшие к старому ролику. У YouTube квота на запросы общая с заливкой видео и замерами, поэтому широкое окно каждые две минуты стоило бы слишком дорого, а раз в час - нормально.

Дальше найденное сверяется с журналом виденного. Новый комментарий попадает в журнал комментариев с полями: ролик, площадка, автор, текст, время комментария и время, когда его снял сторож. По этим двум временам и посчитана задержка, о которой ниже.

Если в новом комментарии есть кодовое слово и у машины есть готовый текст под него, она сама отвечает публично и пишет в директ. Если слова нет, но комментарий живой, он уходит задачей мне. Если слово есть, а текста под него нет, задача тоже уходит мне, с пометкой «собрать руками».

Задачи мне живут в общей очереди двух машин: сторож кладёт запись, коммитит и пушит её в приватный репозиторий, серверный агент подхватывает запись и пишет мне в Telegram. У ноутбука своего бота нет, и это осознанно: одна точка, откуда мне приходят сообщения, лучше двух.

В конце прохода сторож пишет отметку живости: время, круг, сколько комментариев видно, ответили ли площадки. Эту отметку читает отдельная проверка, и если отметка протухла, в очередь падает задача «сторож молчит». Так устроен весь конвейер, который я описывал в разборе контент-машины: журналы вместо памяти чата, файлы вместо договорённостей.

ЧастьЧто делаетКак часто
Быстрый кругкомментарии под тремя свежими роликамикаждые 2 минуты
Глубокий кругвсё, что вышло за 14 днейраз в час
Автовыдачапубличный ответ + директ по кодовому словусразу, если слову меньше 7 дней
Очередьзадача мне: живой комментарий или слово без текстасразу, пинг через серверного агента
Отметка живостивремя, круг, что видно, ответили ли площадкикаждый проход
Проверка живостичитает отметку, при тишине кладёт задачупо расписанию

Что машина делает сама, а что отдаёт мне

Автовыдача заработала 14 августа, когда у токена появились права отвечать под комментариями и писать в личку автору. С того дня слово с известным текстом закрывает машина: публичный ответ под комментарием и личное сообщение со ссылкой. Первая такая выдача случилась 17 августа под роликом про ровный ритм машинного текста, дальше 22 августа, 29 августа, три выдачи под роликом сорок семь в сентябре и одна 10 сентября.

Публичных ответов у машины семь вариантов. До 7 сентября была одна фраза на все случаи, и лента ответов выглядела машинной: пять одинаковых «Отправил в личку» подряд под разными людьми. Теперь вариант выбирается по номеру комментария, устойчиво и без случайности: повторный проход даст тот же текст, а не новый.

С 9 сентября часть слов выдаётся через ворота подписки: человек получает приветствие с кнопкой, жмёт «Проверить», и материал уходит после проверки подписки на канал. Это отдельный механизм, о нём будет свой разбор.

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

Вывод из того дня я записал правилом: проектируя сторожа, спрашивать не «что он умеет обработать», а «что он увидит и не передаст дальше». Эта разница и есть дыра. Теперь любой живой комментарий уходит задачей с пометкой «нужен ответ по существу».

Задержка: от полутора суток до нуля

Главная цифра сторожа - время от комментария до момента, когда машина его увидела. Я посчитал её по журналу для всех комментариев за месяц.

Задержка от комментария до обнаружения сторожем по каждому из 61 комментария. Комментарии, написанные до появления сторожа, он подобрал только глубоким кругом 19 августа, спустя 2-11 дней; у пришедших при живом стороже до 19 августа медиана 1.1 часа и хвост до 108 часов; после 19 августа у большинства задержка нулевая, максимум 5 часов. Данные журнала comments-log.json
Задержка от комментария до обнаружения сторожем по каждому из 61 комментария. Комментарии, написанные до появления сторожа, он подобрал только глубоким кругом 19 августа, спустя 2-11 дней; у пришедших при живом стороже до 19 августа медиана 1.1 часа и хвост до 108 часов; после 19 августа у большинства задержка нулевая, максимум 5 часов. Данные журнала comments-log.json

У комментариев, пришедших при живом стороже до 19 августа, медиана задержки была 1.1 часа, худший случай 108 часов. А 9 комментариев, написанных до его появления, он подобрал только глубоким кругом 19 августа, спустя 2-11 дней: это точки в левом верхнем углу графика. Причина - окно наблюдения: сторож смотрел три последних ролика, а выпускал я по ролику в день, то есть видел он трое суток. Комментарий, пришедший к ролику на четвёртый день, не видел никто. Проверка 19 августа прямым запросом к площадке показала: из 17 комментариев в Instagram* сторож видел четыре. Потерь тогда не случилось, слова и вопросы закрывал я руками, но с 14 августа выдача машинная, и то же окно означало бы прямую потерю.

После 19 августа, когда появились два круга, у 42 комментариев медиана задержки ноль минут: комментарий снимается тем же двухминутным проходом, в который он пришёл. Максимум 5 часов, и это комментарии, пришедшие, пока ноутбук спал.

Про сон ноутбука отдельно. Сторож живёт на моём компьютере, и он спит вместе с ним. За 26 дней в логе 11 774 прохода при потолке 720 в сутки: были дни с 681 проходом и дни со 130.

Проходов сторожа по дням с 17 августа по 11 сентября: от 130 до 681 при потолке 720 в сутки, провалы - дни, когда ноутбук спал. Данные лога планировщика
Проходов сторожа по дням с 17 августа по 11 сентября: от 130 до 681 при потолке 720 в сутки, провалы - дни, когда ноутбук спал. Данные лога планировщика

Эту дыру закрыл второй путь. С 17 августа на сервере стоит приёмник вебхука: Instagram* сам стучится в него в момент комментария, и выдача уходит за секунды. Сторож на ноутбуке остался подстраховкой. А 10 сентября выяснилось, что подстраховка мешает. Сервер отвечал за секунды, ноутбук через две минуты лез в тот же комментарий и получал отказ: личный ответ на комментарий площадка разрешает ровно один. В логе это выглядело как «приветствие не ушло», хотя человек уже всё получил. Теперь Instagram* ведёт одна машина, сервер, а ноутбук остался на YouTube, где вебхуков нет и опрос - единственный путь.

Грабли за месяц, с датами

  • 17 августа: 384 запуска впустую. В расписании стоял системный питон, которому macOS не даёт читать папку с проектом. Скрипт запускался каждые пятнадцать минут и умирал на первой строке. Со стороны это выглядело как «комментариев нет», а в отчётах я писал «выдача уходит сама», потому что по коду так и было. Проверить надо было один раз, открыв лог. После этого появилась отметка живости и проверка, которая её читает: автоматика считается рабочей только по результату последнего прохода, а не по строчке в расписании.
  • 19 августа: конфликт в шине. Два компьютера пишут в один репозиторий, и сторож умер на битом файле журнала, пойманном на полуслове. Молчал 69 минут. Теперь битый файл не роняет проход: список виденного без него пропускать нельзя, иначе люди получат выдачу второй раз, а всё остальное переживается значением по умолчанию.
  • 19 августа: задача, которая висела пять дней. В очереди лежала выдача под роликом 023, хотя ответ стоял там же с 14-го. Задачу ставила машина, а снимать должен был человек, и он не снимал. Пока в очереди висит сделанное, я перестаю верить очереди целиком. Теперь сторож сам чистит очередь: спрашивает у площадки, стоит ли под комментарием наш ответ.
  • 20 августа: «сметана» вместо «сметы». Кодовое слово искалось подстрокой, и «проверки» ловилось внутри «перепроверки», а падежи не ловились вовсе. Теперь слово ищется от начала слова с границами, и у каждого частого слова свой корень с исключениями: «смет», но не «сметан»; «ключи», но не «ключик».
  • 28 августа: свой журнал ответов. Чистка очереди узнавала наш ответ только по дежурной фразе выдачи. На живой комментарий я отвечаю по-человечески, и такой ответ проверка не видела, задача висела бы вечно. Площадка при этом автора ответа не отдаёт, поэтому появился свой журнал: ответил - записал.
  • 30 августа: слова, которые бывают обычными. «Госуслуги» под роликом про журнал входов зритель пишет и просто так: «зашёл в госуслуги, всё чисто». Такое слово считается заявкой только капсом, как и просит ролик. А 10 сентября живой тест показал вторую половину: на телефоне первая буква заглавная сама, и «Эффект» с большой буквы правило капса не пустило. Одиночное слово теперь заявка при любом регистре.
  • 7 сентября: машина ответила мне самому. Свой первый комментарий под роликом содержит кодовое слово: «напиши в ответ, пришлю». Своё до этого дня определялось списком фраз, а формулировка под роликом 047 с ними не совпала ни одной буквой. Машина увидела слово, сочла комментарий зрительским и отработала полный цикл: ответила «Отправил в личку» под моим же комментарием и написала мне в директ. Теперь своё определяется по автору, а не по тексту: спрашиваем у площадки имя своего аккаунта и сравниваем.
  • 8 сентября: слепота ручки. Счётчик у ролика показывал три комментария, а список приходил пустым. Два живых вопроса висели три часа на пике раздачи. Появилась запасная ветка через старый токен, которая отдаёт всё, хоть и без автора.

Каждая из этих граблей записана правилом в папке, которую машина читает перед работой. Правил про сторожа четыре, и все они про одно: «работает» и «видит» - разные вопросы, проверять надо оба.

Что это стоит и что осталось мне

Стоит сторож ноль рублей сверх того, что уже есть: ноутбук, сервер и токены площадок. Ни одного запроса к языковой модели он не делает, и это принципиально. Я много пишу про нейросотрудников, и самый частый вопрос под теми текстами - «сколько это ест токенов». Этот пример показывает, что большая часть рутины закрывается вообще без модели: расписанием, журналами и одним вопросом «дошёл ли проход до конца». Модель нужна там, где надо понять текст. Найти слово в комментарии и отправить готовую ссылку - работа по правилам.

Мне осталось три вещи. Первая - отвечать по существу: живые вопросы под роликами машина только поднимает, текст ответа пишу я. Вторая - выбирать кодовые слова и следить за риском частых. Если в выдачах пойдут комментарии без явной просьбы, слово меняется на редкое, и решать это по журналу, а не по ощущению. Третья - читать грабли: каждый сбой сторожа за месяц был не в коде обхода, а в вопросе, который никто не задал. «Достаточно ли он видит?», «Что он увидит и не передаст?», «Чей это комментарий?».

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

*Instagram принадлежит компании Meta, которая признана экстремистской организацией и запрещена на территории России.

Журнал - про системы, которые работают у меня каждый день. Что похожее можно собрать под ваш бизнес - на странице услуг.

Что можно внедрить у себя

Сторож комментариев: машина читает комментарии под роликами за меня и будит, когда нужен человек - Протокол А