Перейти к содержимому
[ рис. automation ]

Автоматизация: дела, которые идут без тебя

Обложка в виде одних суток на сервере: линия времени от полуночи до полуночи, на ней закрашенные отметки для задач, которые включены и срабатывают в 02:30, 09:00, 09:05 и 11:00, пунктирные отметки для трёх выключенных дайджестов, бледные засечки для выключенной получасовой проверки здоровья и карточка над отметкой девяти утра с одной строкой из её лога.
[ рис. Одни сутки на сервере, нарисованные по настоящему расписанию: четыре запуска, четыре выключенные задачи и одна строка в логе, по которой видно, что задача в девять утра отработала. ]

Лестница этой серии состоит из пяти ступеней: спросить, дать себя узнать, дать посмотреть на свою работу, дать действовать и собрать свою собственную систему. Этот текст остаётся на пятой ступени, но смотрит на ту её часть, которая работает, пока ты спишь: не на ассистента, с которым ты разговариваешь, а на задачи, с которыми ты разговаривать давно перестал и которые срабатывают в девять утра независимо от того, смотрит на них кто-нибудь или нет.

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

Что заслуживает отдельной задачи

Фильтр у меня теперь один, и в нём три условия, которые должны выполняться одновременно: отдельную задачу по расписанию получает только то дело, которое повторяется, скучное и укладывается в правило, и больше ничего.

  • Схема из трёх карточек, где у каждого условия (повторяется, скучное, укладывается в правило) есть пример, который фильтр пропускает, и затенённый блок с тем, что это условие отсеивает.
    [ рис. Фильтр для того, что заслуживает задачи по расписанию: все три условия сразу, и большинство дел спотыкается на третьем. ]

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

Отсеивает такой фильтр больше, чем пропускает, и в этом весь смысл. Большинство того, что людям хочется автоматизировать, спотыкается на третьем условии: дело повторяется и скучное, но каждый раз требует маленького решения. А задача, которая принимает маленькие решения без тебя, это задача, чьи ошибки ты найдёшь сильно позже и сразу пачкой.

Три способа отдать дело

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

  • Схема из трёх карточек: нарисовать сценарий в n8n, Make или Zapier, написать скрипт и поставить его в cron или systemd, или отдать дело агенту в виде подсказки по расписанию, и каждая карточка заканчивается счётом, который этот способ оставляет.
    [ рис. Три способа отдать дело, сравнённые по тому, что каждый оставляет тебе в долг: подписку, вызов из оболочки или вызов модели вместе с привычкой проверять результат. ]

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

n8n. Для кого: тем, кому нужен холст, но машину, на которой он работает, хочется держать у себя, потому что n8n можно поставить на собственный сервер. Сколько стоит: версия Community Edition для своего сервера бесплатна, а облачные планы считаются в запусках сценариев за месяц, и на начальном их 2 500. Чего не умеет: избавить тебя от сервера, если ставишь его сам, ведь тогда его обновления, его данные и то, чтобы он не падал, становятся твоей заботой. Зачем мне это: на этом сервере ни для чего, а ручаться я могу только за то, что на нём стоит, так что этот абзац читай как обзор того, что есть вокруг, а не как мой опыт.

Make. Для кого: тем, кому нужен холст и компания, которая будет его крутить за тебя. Сколько стоит: бесплатный план даёт 1 000 кредитов в месяц и два активных сценария, а платные начинаются от $9 в месяц. Чего не умеет: запускаться на бесплатном плане чаще, чем раз в пятнадцать минут, причём счёт идёт в кредитах, так что сценарий, который гоняет цикл, заодно гоняет и деньги. Зачем мне это: ни для чего, и оговорка та же самая.

Zapier. Для кого: тем, кому нужно, чтобы два популярных приложения поговорили друг с другом, а заглядывать, что происходит между ними, не хочется никогда. Сколько стоит: бесплатно до 100 задач в месяц, где задачей считается успешно выполненный шаг (неудачные в счёт не идут), но только для сценариев из двух шагов, которые проверяются раз в пятнадцать минут. План Professional начинается от $19.99 в месяц при оплате за год. Чего не умеет: дёшево и в больших объёмах делать то, чего не покрывают его готовые коннекторы. Зачем мне это: ни для чего, по той же самой причине.

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

Отдать агенту. Вместо скрипта по расписанию ставится подсказка по расписанию: в одиннадцать разбудить ассистента, словами объяснить ему задачу и доставить то, что он напишет. Для кого: для дел, где на входе проза и на выходе тоже проза. Сколько стоит: вызов модели на каждом запуске, а сверх того привычка читать результат, и этот второй счёт выходит крупнее. Чего не умеет: дважды ответить абсолютно одинаково, поэтому для всего, с чем справилось бы правило, это неподходящий инструмент. Зачем мне это: мой ассистент Hermes ведёт собственный список задач по расписанию, и ежедневная задача с текстом у него единственная, к которой до сих пор подключена модель.

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

Два дела из этого дома

Первое дело это бот расходов, и полезнее него на моём сервере нет ничего.

На каждую оплату картой банк присылает мне SMS, а iOS Shortcuts на телефоне это сообщение подхватывает и пересылает его текст вместе с токеном в заголовке маленькому серверу на Python, который стоит у меня на машине. Скрипт `expense_bot.py` вытаскивает из текста сумму, дату и продавца, по продавцу определяет категорию и пишет одну строку в Notion, где эта строка связывается с нужной статьёй в базе Budget и с месяцем, к которому относится трата. Запускает его systemd как `expense-bot.service` с `Restart=always`, слушает он порт 8080, и с начала августа в его логе записано 155 созданных строк.

  • Схема из четырёх карточек (SMS от банка, iOS Shortcuts, expense_bot.py на порту 8080 и новая строка в Notion), под которой идёт полоса с шестью полями этой строки, где Budget и Month Classification отмечены как связи.
    [ рис. Это схема, а не снимок экрана: настоящее устройство бота расходов от оплаты картой на телефоне до одной строки в Notion и шесть полей, которые он записывает. ]

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

Второе дело это дайджесты, и они стоят в списке, который Hermes держит для своих задач по расписанию. Задач там девять, и вот этот список, снятый прямо на машине, пока я писал этот текст.

  • Сеанс в терминале на сервере: таблица из девяти задач по расписанию с флагом включения, расписанием и названием, где три дайджеста и сторожевая проверка стоят в false, а под ней systemctl показывает, что expense-bot.service загружен, включён и работает.
    [ рис. Настоящий сеанс, снятый на сервере, пока писался этот текст: девять задач в том виде, в каком они стоят сейчас, и бот расходов, который работает двенадцать дней без перезапуска. ]

Три из девяти были дайджестами (новости Ближнего Востока, новости про AI и новости про игры), каждый писала модель и доставляла в чат, и все три сейчас выключены. Одна задача пишет текст в одиннадцать и модель при этом запускает, а другая в девять проверяет обновления ассистента и подтягивает их, причём это обычная команда, к которой никакая модель не подключена. Ещё одна через пять минут после неё обновляет шлюз, следующая в половине третьего ночи пересобирает граф навыков, а сторожевая проверка здоровья, которая раньше запускалась каждые тридцать минут, тоже выключена. К девятой я ещё вернусь.

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

Когда хватает правила, а когда без модели не обойтись

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

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

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

Как заметить через три недели

Ради этого раздела весь текст и затевался. Задача по расписанию ломается совсем не так, как ломается программа, которой ты сейчас пользуешься: она ломается молча, и тишина при этом выглядит в точности как спокойный день.

  • Схема из трёх слоёв наблюдения (строка, которая приходит, служба, которая перезапускает себя сама, и взгляд раз в неделю), где у каждого указан файл или настройка, на которых он держится, и поломка, которую он ловит.
    [ рис. Три слоя наблюдения и поломка, которую ловит каждый из них, причём задачу, которая ни разу не запустилась, замечает только взгляд раз в неделю. ]

Слежу я в три слоя, и каждый ловит свою поломку.

Строка, которая приходит. Задача обновления в девять утра складывает всё, что сделала, в `/tmp/hermes-update.log`, а в чат отправляет одно короткое сообщение о том, что изменилось и что шлюз перезапустится через пять минут, так что подробности лежат в файле, который я открываю, только когда что-то не так, а чат получает одну строку, которую я прочитаю за секунду. Слабость у этого способа честная: в день, когда ничего нового нет, задача молчит нарочно, и тишина тогда означает либо «делать было нечего», либо «даже не запускалась». Я с этим мирюсь, потому что ассистент ещё и записывает последний статус каждой задачи, и как раз там второе значение и становится видно.

Служба, которая перезапускает себя сама. У бота расходов стоит `Restart=always`, а его главный цикл нарочно завершается, если умер поток сервера, так что тихое зависание превращается в падение, которое systemd видит и исправляет. Этот слой ловит поломку, которую с телефона не заметишь никогда, ведь телефону в любом случае ответили «обрабатываю».

Взгляд раз в неделю. Раз в неделю я смотрю на список и на лог, и это единственный слой, который ловит то, чего не ловят первые два: две записи в Notion, которые не прошли 21 сентября и не дошли никуда, кроме лога, и ту самую девятую задачу. Девятая задача была разовым перезапуском шлюза, который однажды вечером в июне поставили на время, уже прошедшее днём того же дня, и она не запускалась ни разу. Её статус через три месяца всё ещё говорит, что она запланирована, и ничто мне об этом так и не сообщило.

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

Сколько это стоит и во что обходится поддержка

Деньги тут самая простая часть. Бот расходов не стоит ничего сверх сервера, который и так был включён, задача обновления обходится одним вызовом из оболочки, а дайджест стоит вызова модели в день, что на одном запуске немного, но и не ноль, и это единственная строка в счёте, которая растёт с каждой новой задачей.

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

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

Начни с одного дела, которое проходит все три проверки, напиши для него скрипт и дай ему строку, которая приходит, а потом оставь его в покое на три недели и посмотри, знаешь ли ты до сих пор, что оно работает. Всё в этой серии лежит под тегом The AI ladder. Дальше, и уже последним: то, за что из всего этого действительно имеет смысл платить.