Счёт заметили во вторник утром. Двести тридцать евро за одну ночь у поставщика модели при обычных семи евро в сутки. Это была не самая неприятная часть.
Неприятная часть лежала в базе. Сто сорок две новые карточки контрагентов, созданные между двумя и шестью часами ночи. Почти все дубликаты уже существующих компаний, часть с перепутанными реквизитами, и понять, какие именно карточки испорчены, с первого взгляда невозможно. Плюс одиннадцать тысяч обращений к чужому сервису проверки компаний, после которых этот сервис перестал отвечать на запросы фирмы до конца суток. Вместе с ним встала проверка новых клиентов, которую делают живые менеджеры.
Агент не сломался. Он всю ночь честно работал.
Ночь, когда никто не смотрел на систему
Задача у него была простая. Берём новые компании из формы на сайте, дополняем данными из внешнего реестра, создаём карточку. Днём это работало больше месяца и экономило менеджеру около часа в день.
В районе двух ночи реестр ответил на один запрос в неожиданном формате. Шаг не смог разобрать ответ и завершился ошибкой.
Дальше агент сделал то, для чего его и построили. Он попробовал ещё раз. Снова ошибка. Он решил, что план был неудачный, и составил новый: поискать компанию по другому полю. Тоже ошибка. Составил ещё один план: создать карточку без данных реестра, а дополнить её следующим шагом. Карточку создал. Дополнение опять не прошло. Составил новый план.
Ошибка, повтор, новый план, снова ошибка. Круг замкнулся около двух ночи и разомкнулся в шесть, когда у поставщика модели закончился суточный лимит расходов.
Стоит обратить внимание на то, что именно остановило агента. Не проверка количества созданных записей. Не ограничение частоты обращений к чужому сервису. Не предел числа шагов в задаче. Остановили деньги, и то случайно, потому что кто-то полгода назад поставил суточный потолок в дашборде поставщика и забыл про него.
Это был единственный предел, который в системе вообще существовал.
Ограничили счёт у поставщика модели и решили, что защитились
Такую конфигурацию я вижу чаще всего. В панели поставщика модели стоит месячный или суточный потолок расходов, и на этом разговор про ограничения заканчивается.
Понятно, почему так получается. Это единственный предел, который приходит готовым. У него есть свой экран, своё число и своё уведомление на почту. Его не надо проектировать, обсуждать с разработчиками и закладывать в сроки. Его просто включают.
Но счёт у поставщика модели измеряет размышления, а не действия. Между размышлением и действием лежит всё, что касается внешнего мира: ваша база, чужие сервисы, почта клиентов, деньги на счетах, документы.
Сто сорок две испорченные карточки в той истории стоили примерно сорок центов модельных вызовов. Вычищали их два человека полтора дня, и ещё неделю всплывали последствия, потому что часть карточек успела уйти в бухгалтерскую выгрузку. Заблокированный ключ доступа не стоил вообще ничего в деньгах и остановил проверку новых клиентов до конца рабочего дня.
Про то, как ошибка одного шага расходится дальше по автоматизации и превращается в происшествие, я разбирал отдельно в статье одна ошибка ИИ и пять систем, которые уже успели её повторить. Здесь речь о другом. О границах, которые не дают повторяющейся ошибке стать массовой, даже когда она уже началась.
Поэтому первую мысль стоит сформулировать прямо. Стоимость задачи это одна ось, и не главная. Две другие важнее: сколько объектов агент успел затронуть и как быстро он воздействует на внешний мир.
Что именно стоит ограничивать
Речь не о бухгалтерии. Речь о границах системы, то есть о том, какого размера вред эта система способна нанести за единицу времени.
- Шаги в одной задаче. Сколько действий агент может сделать, прежде чем задача считается неудачной. Это то, что превратило бы ночь из примера в короткую утреннюю строку в журнале.
- Обращения к инструментам. Инструмент это любое место, куда агент ходит: ваша база, чужой сервис, почта, файловое хранилище. Считать их надо отдельно от шагов, потому что один шаг может сделать десять обращений.
- Количество объектов за одну операцию. Самый важный и самый редко существующий предел. Агент, который может изменить пять записей, это помощник. Агент, который может изменить пять тысяч записей одной операцией, это риск другого класса. В одном продукте агента попросили поправить статус у конкретного заказа, ошибка в условии отбора дала ему все заказы месяца, и операция спокойно дошла до конца, потому что ничто в системе не сказало «это слишком много».
- Частота обращений к чужим системам. Не общее количество, а скорость. Чужой сервис почти всегда считает вас по скорости, и именно она приводит к блокировке ключа.
- Объём выгружаемых данных. Агент, который умеет выгрузить всю базу клиентов ради сводки, это канал утечки даже без злого умысла. Достаточно одной ошибки в условии отбора и одного письма не тому адресату.
- Деньги на задачу и на период. Две разные величины, обе нужны.
- Число одновременных задач. Десять параллельных агентов, каждый в рамках своих пределов, вместе кладут чужой сервис не хуже одного зациклившегося.
| Что ограничиваем | Что это останавливает |
|---|---|
| Шаги в одной задаче | Бесконечный круг рассуждений |
| Обращения к инструментам | Долгую возню вокруг одной ошибки |
| Объекты в одной операции | Массовую правку не тех записей |
| Частоту обращений наружу | Блокировку вашего ключа доступа |
| Объём выгружаемых данных | Вынос базы целиком |
| Деньги на задачу | Один дорогой сбой |
| Деньги на период | Тот же сбой, повторённый сто раз |
| Одновременные задачи | Общий перегруз и лавину |
Десять безобидных задач подряд
Предел на задачу и предел на сутки отвечают на разные вопросы, и один не заменяет другой.
Разберём случай, который выглядит здоровее ночной истории. В компании стоял предел в пятьдесят обращений на задачу, и он честно работал. Задача упиралась в потолок, помечалась неудачной и попадала обратно в очередь на повторную обработку. Очередь запускала её снова. За ночь одна и та же задача прошла этот путь тридцать раз.
Каждый запуск был в рамках предела. Ночь в рамки не уложилась.
Предел на задачу отвечает на вопрос, сколько вреда принесёт одна поломка. Предел на период отвечает на другой вопрос: сколько раз эта поломка успеет повториться, пока её не заметит человек. Второй вопрос обычно дороже.
То же самое верно для объектов. Правило «агент меняет не больше двадцати записей за операцию» выглядит достаточным ровно до того момента, когда операций за ночь оказывается сто. А правило «агент создаёт не больше тридцати карточек за сутки» остановило бы ночь из первой истории на тридцатой карточке вместо сто сорок второй, и чистка заняла бы у людей пару часов вместо полутора дней.
Поэтому пределы ставятся парами. На задачу и на сутки. На операцию и на период. Для денег точно так же: потолок на одну задачу и потолок на месяц, потому что десять безобидных задач подряд дают совсем не безобидный итог.
Предел, который агент может поднять сам, это не предел
Это место, где формальная защита чаще всего оказывается декорацией. Я встречал три вида ненастоящих пределов.
- Предел, написанный в тексте задания для модели. «Не делай больше пятидесяти обращений к реестру». Модель может это выполнить, а может увлечься и не выполнить, и никто в системе этого не заметит. Инструкция в задании это просьба, а не ограничитель. Просьба хороша тем, что помогает агенту работать разумно. Границей системы она не является.
- Предел, до которого агент дотягивается своими же инструментами. Агенту дали широкие права на настройки, чтобы он мог сам чинить мелочи и не дёргать людей. В настройках лежит и потолок шагов. Формально он есть. Фактически агент, упёршийся в него, вполне способен поднять число и продолжить, и это будет выглядеть как успешно решённая задача.
- Предел, который спрашивает разрешения у модели. Самый коварный вид. На потолке система спрашивает у модели, продолжать ли работу, и модель отвечает, что продолжать. Так предел превращается в вопрос, заданный тому, кого он должен останавливать.
Правило здесь простое. Предел обязан жить там, куда агент не дотягивается, и проверять его обязан тот, кто выполняет действие, а не тот, кто его придумывает. Счётчик живёт в коде, который ходит в чужой сервис. Ограничение на количество записей живёт в правах доступа к базе. Потолок расходов живёт у поставщика и в вашем собственном учёте. Ни одно из этих мест агенту менять не положено.
У владельца продукта есть короткий способ это проверить, не разбираясь в коде. Задайте команде один вопрос: что физически произойдёт, если агент решит, что предел мешает делу? Если ответ звучит как «он его не нарушит, мы же его попросили», предела нет.
С каких чисел начинать и как их пересматривать
Универсальных чисел не существует. Значения, которые подходят сервису на сто клиентов с ручной проверкой, убьют работу маркетплейса и наоборот. Но способ посчитать свои числа одинаковый.
Возьмите десять обычных успешных запусков задачи. Не показательных, а рядовых. Померьте по каждому четыре величины.
- Сколько шагов.
- Сколько обращений к инструментам.
- Сколько объектов затронуто.
- Сколько потрачено денег.
Возьмите не среднее, а максимум из десяти, и удвойте его. Это ваш стартовый потолок. Среднее не годится, потому что нормальная работа неровная, и потолок по среднему будет ломать половину честных запусков.
Для объектов и денег добавьте второй вопрос, и он важнее первого. Какую сумму вы готовы списать без совещания? Сколько неправильных записей ваши люди в состоянии вычистить за один рабочий день? Из двух чисел, посчитанного и допустимого, берётся меньшее. Обычно меньшим оказывается второе, и это очень полезное открытие.
Новая задача начинается с узкого коридора намеренно. В первую неделю она будет упираться в потолок, и это не беда, а смысл упражнения. Каждое упирание это разговор о том, была ли работа настоящей. Расширять пределы стоит на основании доказательств: «за неделю упёрлись семь раз, в шести случаях работа была нужной, поднимаем с пятидесяти до восьмидесяти».
Здесь же лежит компромисс, которого не обойти. Слишком узкий предел останавливает полезную работу, и хуже того, он учит людей обходить автоматизацию стороной, вручную. Слишком широкий предел гарантирует, что рано или поздно вы получите крупный счёт и крупный ущерб одновременно. Ошибиться в узкую сторону дешевле: она стоит ожидания и раздражения, а вторая стоит чистки базы и разговоров с клиентами. Начните узко и расширяйте по фактам.
Пересматривать значения имеет смысл раз в месяц в начале жизни автоматизации, потом при любом изменении условий: новая интеграция, новый объём, новая роль у агента. И каждый инцидент обязан менять хотя бы одно число, иначе он ничему не научил.
Сигнал о приближении к пределу как ранний признак поломки
Сработавший предел это авария. Приближение к пределу это диагноз, и он гораздо интереснее.
В одном сервисе задача обычно укладывалась в двенадцать обращений к инструментам при потолке в шестьдесят. За две недели она незаметно доросла до сорока обращений. Задача при этом успешно завершалась, ничего не падало, жалоб не было, в отчётах всё зелёное. Причина была в том, что внешний сервис начал отвечать медленнее и чаще срываться, а агент это компенсировал повторами. Ещё через неделю это превратилось в ночной инцидент.
Числа предупреждали об этом две недели. Просто никто не смотрел на расстояние до потолка, потому что потолок не был пробит.
Поэтому предупреждение стоит ставить примерно на семидесяти процентах от предела, и не на единичную задачу, а на долю задач. «Каждая пятая задача за сутки подошла к потолку шагов ближе чем на треть» это ранний признак того, что либо работа изменилась, либо инструкции агента устарели, либо чужая система деградирует.
Сигнал должен приходить человеку по имени и содержать число. Какой предел, какое значение, какая задача, за какой период. Уведомление «агент близок к пределу» без числа люди читают один раз, второй раз они его уже не открывают.
Пределы, записанные там, где их найдут
Третья ошибка, которая встречается не реже двух предыдущих, выглядит безобидно. Пределы есть, но о них никто не знает.
В одной команде их настраивал разработчик, который потом ушёл. Остальные помнили, что какое-то ограничение существует, но не помнили ни значения, ни места. Когда агент остановился, дежурный сделал единственное, что мог сделать за пять минут: перезапустил задачу. Потом ещё раз. Предел при этом никто не отменял, он просто перестал что-либо значить, потому что его не с чем было соотнести.
Лечится это одной страницей. Таблица из пяти колонок.
- Что ограничено.
- Какое значение.
- Где оно проверяется.
- Кто имеет право его менять.
- Когда его последний раз пересматривали.
Страница, а не только код, и уж точно не чья-то память.
Вот с чего стоит начать на этой неделе. Возьмите один работающий у вас агент и попросите команду заполнить по нему такую страницу. Не проектировать новую защиту, не оценивать сроки, просто записать то, что есть сейчас.
Самое ценное в этом упражнении обычно не то, что заполнено. Ценно то, что в двух или трёх строках окажется прочерк и слово «не ограничено», и до этого момента никто в команде не произносил этого вслух.
А когда страница будет готова, посмотрите на одну строку. Сколько объектов ваш агент может изменить за одну операцию? Если ответ звучит как «сколько понадобится», вы уже знаете, какое число нужно поставить первым.
Разберём вашу ситуацию
Опишите свою ситуацию. Обсудим подход, необходимый объём участия и следующий шаг.
Разобрать мой проект