- Опубликовано
Самая сложная часть долгоживущих агентов — не модель
- Авторы

- Имя
- Михаил Люблин
- https://x.com/mlcka3i
Самая сложная часть долгоживущих агентов — не модель
Последние несколько месяцев я строил NoodleTomato — агентную систему для генерации видео с помощью ИИ. Она получает бриф и работает над ним часами: планирует видео, делегирует задачи worker-ам, запускает код, генерирует сцены и другие медиа, тратит реальные деньги почти на каждом шаге и в конце выдает результат, которым человек должен пользоваться без доработок.
Я начинал с убеждением, что ограничивающим фактором станет модель. Но нет. С моделью все было нормально. Постоянно ломалось все, что находилось вокруг нее.
Например, типичная задача NoodleTomato может выглядеть так: создать десятиминутный документальный фильм о новой технологии — превратить письменный бриф в сценарий, записать или синтезировать дикторский текст, сгенерировать сорок или пятьдесят визуальных сцен, подобрать музыку, сделать субтитры, собрать таймлайн и экспортировать финальный мастер. Другая задача — рекламный ролик продукта: девяностосекундное launch-видео, несколько коротких версий, закадровый текст на разных языках и форматы для YouTube, TikTok и Instagram.
Это не единичный запрос «сгенерируй видео». Это полноценное производство из сотен зависимых решений: какая сцена иллюстрирует каждое предложение, где начинается и заканчивается дикторский текст, достаточно ли длинный получился клип, нужно ли приглушить музыку под голос и действительно ли финальный рендер содержит все одобренные материалы.
Проблема
Чат-ассистент отвечает на один вопрос, и человек читает ответ. Если ответ неверен, человек это замечает и задает новый вопрос. Цикл замыкается за секунды и почти ничего не стоит.
Долгоживущий агент разрывает этот цикл. Он принимает сотни решений до того, как кто-то посмотрит на результат. Каждое решение зависит от предыдущих. Каждое может потратить деньги, записать состояние или запустить задачу, которая завершится через час. А сам запуск переживает все остальное: контекстное окно модели, процесс worker-а, деплой, действовавший в момент старта, и внимание человека.
Поэтому меняется и смысл слова «ошибка». В чате ошибка — плохой ответ. В долгом запуске ошибка — правдоподобный результат, построенный на неверной картине мира: worker уверенно завершает работу с половиной входных данных, бюджет незаметно заканчивается и сообщается как недоступная функция, или проверка проходит, потому что объект, который она проверяет, никогда не был записан.
Ничто из этого не выглядит как ошибка модели. Скорее кажется, что модель точно выполнила инструкцию, используя доступную ей информацию.
Почему это сложно
Модель не видит весь запуск. Ее контекст — окно в задачу, которая намного больше этого окна. Все, что вы ей показываете, становится ее реальностью. Если снимок состояния не содержит ожидающие задачи, модель не может знать, что чего-то не хватает, и будет правильно рассуждать, приходя к неправильному выводу.
Ошибки не проявляются сразу, а накапливаются. Маленькое значение по умолчанию на третьем шаге становится предпосылкой тридцатого. К моменту, когда человек видит результат, неверный поворот уже скрыт под часами последовательной работы. Исправить его стоит дороже, чем стоил исходный запуск.
Агент также сам оценивает собственную работу. Если оставить систему без ограничений, она будет и создавать результат, и проверять его, выбирая наиболее удобную трактовку любой проверки. Не из злого умысла — просто ее стимулом становится завершение.
Деньги и побочные эффекты реальны. Каждый шаг может потратить деньги, а каждая повторная попытка — потратить их снова. Система, которая «обычно права», иногда платит дважды или оплачивает работу, которую потом выбросит.
Длинные запуски пересекают границы, которых короткие не касаются. Worker-ы достигают лимитов и заменяются. Сервисы деплоятся посреди работы. У баз данных бывают плохие часы. Восстановление нельзя оставлять на потом.
Почему это важно
Ценность агента пропорциональна тому, как долго его можно оставить без присмотра. Инструмент, которому нужен человек каждые десять минут, — это автодополнение. Инструмент, которому можно выдать бриф вечером и доверить результат утром, — уже коллега.
Все самое интересное в агентах начинается по ту сторону этой границы. Ее не закрывает более умная модель. Ее закрывает harness — система вокруг модели, которая делает ошибки ограниченными, видимыми и дешевыми.
Что сработало
Хранилище должно быть источником истины, а не диалог
Все, что знает система, живет в версионируемых артефактах. Агенты — расходуемые worker-ы: они читают хранилище, выполняют шаг и записывают результат обратно. Погибшего worker-а заменяет новый, который читает то же состояние. Диалог нужен для управления, но не является журналом.
Состояние должно честно сообщать, чего в нем нет
Ожидающая работа, ожидаемое количество результатов и незавершенные партии должны быть видны в данных, которые читает модель. Если состояние неполное, оно должно это обозначать. Любой fallback или обрезание должны проявляться громко, потому что следующий шаг примет оставшийся результат за полный.
Разделяйте предложение и решение
Модель формулирует намерение в виде данных. Детерминированный код превращает намерение в последствия: рендеры, расходы и побочные эффекты. Модель не работает с деньгами напрямую, не выдает себе возможности и не объявляет собственную работу одобренной.
Критические проверки должны быть там, где агент их не пропустит
Любая проверка, которую агент сам решил запустить, — лишь рекомендация. Важные проверки выполняются на стороне хоста, на пути к выдаче результата, и различают «структурно корректно» и «хорошо».
Ограничивайте каждого worker-а
У каждого worker-а должен быть фиксированный набор инструментов, бюджет и набор возможностей. Все три параметра нужно считать на уровне всей задачи, а не отдельного worker-а: worker-ы приходят и уходят. Если worker отказывается, причина должна называться точно, чтобы модель не превратила потраченный бюджет в «недоступную функцию».
Не ждите. Просыпайтесь по событию
Координатор завершает свой ход и просыпается, когда долгие задачи заканчиваются. Один ход длится секунды. Именно это превращает деплой или падение посреди многочасового запуска из инцидента в мелкую помеху.
Изолируйте ненадежное выполнение
Код, который пишет модель, должен выполняться в sandbox без секретов и с доступом лишь к короткому списку ограниченных действий. Ничто внутри sandbox не является истиной; фиксация данных в хранилище должна быть явной.
Перед каждым долларом должна стоять граница в коде
Сначала резервируйте средства, затем списывайте фактическую стоимость, возвращайте остаток и используйте ключ для каждого платного вызова, чтобы повторная попытка не списала деньги дважды. Все числа, которые видит человек, должен вычислять код — в той единице, в которой человек платит.
Запрашивайте согласие там, где его можно дать
Если агент отклоняется от исходного запроса, простой отказ может заблокировать запуск: агент не способен сам получить разрешение. Но если показать отклонение на карточке согласования, где человек и так принимает решение, запуск не окажется в тупике.
Должна быть возможность воспроизведения
Самым полезным инструментом отладки стала возможность восстановить хранилище на любой ревизии и запустить проверки офлайн. Когда запуск стоит денег, replay позволяет не платить дважды только для того, чтобы подтвердить диагноз.
Общий принцип
Все эти практики — разные проявления одной идеи: модель предлагает, а код и люди распоряжаются последствиями. Ничто сказанное моделью не должно становиться реальным действием, пока не пройдет через границу, находящуюся за пределами модели.
Когда в системе что-то ломалось, причина никогда не заключалась в недостаточной способности модели. Причина была в том, что я позволил предложению превратиться в последствие, не поставив между ними никакой границы.