Skip to content
КОНЦЕПТЫ
6 мин. чтенияЧитать на английском

Конфигурация по инцидентам — правила агента, выросшие из прецедентов, а не из дизайна

Первый инстинкт при развёртывании автономного агента — спроектировать правила заранее. Команда садится с доской, перечисляет все ситуации, в которые агент может попасть, пишет исчерпывающий гайд, отгружает. К второй неделе агент сделал три вещи, которых команда не предвидела: отправил дубль сообщения из-за таймаута прокси, упомянул название проекта из удалённой памяти, перепутал UTC и МСК в расчёте дедлайна. Ни одна из этих ситуаций не была в исходном списке. Доска не провалилась из-за лени; она провалилась, потому что пространство возможных инцидентов больше, чем умеет покрыть upfront-дизайн.

***Паттерн, который я называю Конфигурация по инцидентам. Правила агента не проектируются — они накапливаются. Каждый инцидент — момент, когда поведение агента породило проблему, — логируется в выделенный каталог .learnings/. Оператор разбирает паттерн, потом промоутит жёсткое правило в основные конфигурационные файлы агента. Система растёт по прецедентам: каждый случай становится новой строкой правил. По форме — ближе к корпусу прецедентного права, чем к software-спецификации.

Механизм маленький, но дисциплинированный. Каталог .learnings/ из трёх файлов содержит рабочие заметки: LEARNINGS.md (корректировки поведения), ERRORS.md (технические отказы), FEATURE_REQUESTS.md (недостающие возможности). Когда случается инцидент, оператор (иногда сам агент) добавляет запись. Когда запись разобрана и урок обобщён, правило промоутится в один из основных конфигурационных файлов: поведение — в SOUL.md, процесс — в AGENTS.md, технический воркэраунд — в TOOLS.md. Перенос в конфиг — это момент, когда случай становится нормой.

Почему upfront-дизайн недопокрывает

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

Failure-режим upfront-дизайна выглядит так: тридцатистрочный конфиг, предвосхищающий очевидные случаи, неточно специфицирующий три из них в незаметных местах и совершенно молчащий о тех случаях, которые на самом деле произошли. Команда либо чинит конфиг реактивно (в каком случае она и занимается incident-driven-config'ом, просто без названия) — либо убеждает себя, что агент «работает», пока он накапливает мелкие промахи.

Incident-driven-путь инвертирует работу. Начни с намеренно минимального конфига — те несколько правил, которые очевидны достаточно, чтобы на них ставить, — и дай остальному накопиться. У каждого правила есть провенанс: файл говорит почему правило существует и какой инцидент его породил. Это позволяет конфигу расти без баласта: когда старое правило больше не применимо, оператор читает его провенанс и решает отбросить.

Шкаф из трёх файлов learnings

Промежуточная стадия между инцидентом и правилом — каталог .learnings/. Три файла, каждый — длинный лог:

  • LEARNINGS.md — поведенческие корректировки. Агент делал X, и это вызывало проблему; правило — делать Y вместо. Примеры из кейса: Перед любой отправкой дамп контекста разговора (последние 20–30 сообщений). После каждой отправки проверить, что ушло ровно одно сообщение.
  • ERRORS.md — технические отказы. Инструмент, скрипт или среда сломались; что случилось, как диагностировано. Пример: Таймауты Telethon, когда HTTP-прокси сбрасывается каждые 3–4 запроса; решение — переподключение каждые 2–3 операции.
  • FEATURE_REQUESTS.md — недостающие возможности агента. Вещи, замеченные оператором в эксплуатации, полезные, но не необходимые сейчас. Пример: Telethon-демон → webhook для реалтайм-мониторинга; Gmail-интеграция через OpenClaw hooks.

Шкаф — staging-зона. Не каждая запись становится правилом — какие-то наблюдения оказываются одноразовыми, какие-то feature-request'ы откладываются в roadmap. Промоушен в основной конфиг — дисциплина.

Шаг промоушена

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

  • Поведенческая корректировка (тон, что говорить, чего никогда не говорить) уходит в SOUL.md как жёсткий запрет. Никогда восклицательного знака. Женский род всегда. См. persona-through-prohibitions.
  • Процессная корректировка (когда действовать, в каком порядке, с какой последовательностью) уходит в AGENTS.md. Перед отправкой в форум-чат проверить, что topic-id соответствует теме. После каждой отправки проверить, что ушло ровно одно сообщение.
  • Технический воркэраунд (как использовать инструмент, как обработать отказ) уходит в TOOLS.md. Сбросить http_proxy env vars в пустое; передавать прокси прямо в конструктор Telethon.
  • Расписание уходит в HEARTBEAT.md. Кроны работают ежедневно, включая выходные — промоутировано после того, как агент пропустил субботние напоминания.

Промоушен маленький — одна-две строки. Новое правило включает свой провенанс, часто как комментарий: (после инцидента 22.03 с тройным дублем сообщения в чате X). Провенанс — это то, что позволяет оператору сделать аудит правил через несколько месяцев и убрать те, чья исходная причина больше не действует.

Проработанный пример — месяц прецедентов

Конфиг агента кейса вырос на эти правила за первый месяц эксплуатации, каждое привязано к конкретному инциденту:

| Инцидент | Промоутированное правило | Назначение | |---|---|---| | Тройная отправка сообщения после таймаута прокси | После каждой отправки проверить, что ушло одно сообщение. При дубле удалить немедленно. | HEARTBEAT.md | | Утечка названия удалённого проекта | Удалённые проекты убраны отовсюду: файлы, память, инструменты, персона. Никогда не упоминать. | SOUL.md | | Путаница UTC vs МСК в дедлайнах | Всегда считать и показывать в МСК. Никогда не путать с UTC. | SOUL.md | | Пропущенные субботние напоминания | Кроны работают ежедневно, включая выходные. | HEARTBEAT.md | | 18 шаблонных ответов без чтения истории чата | Перед любой отправкой дамп последних 20–30 сообщений чата. | HEARTBEAT.md | | Несовпадение topic-id в форуме | Перед отправкой в форум-чат проверить, что topic-id соответствует теме. | AGENTS.md | | Wrong-context-статус клиенту | Статусные ответы клиенту требуют одобрения оператора. | AGENTS.md |

Каждое правило — одна строка в конфиге. Вместе они — накопленный опыт развёртывания, закодированный в форме, которую агент читает на каждом крон-вызове. Конфиг короткий — двадцать-сорок строк — потому что правила специфичны. Корпус «вещей, которым агент научился» живёт в .learnings/ и остаётся там, пока паттерн не достаточно общий для промоушена.

Аналог из прецедентного права

Ближайший аналог паттерна вне computing — common-law-юриспруденция. Каждое дело даёт постановление; постановление становится прецедентом; со временем корпус прецедентов формирует поведение суда без upfront-кодификации. Сила аналогии — в том, как правила накапливаются: случай за случаем, с провенансом, — и в том, что они узкие: каждое правило покрывает конкретную ситуацию, которая его породила, а не гипотетический более широкий класс.

Слабость аналогии — в том, что у case law есть доктрина stare decisis: суды следуют прошлым постановлениям. Агентским конфигам нужно активное обслуживание: когда среда меняется, правила, привязанные к старой среде, нужно убирать, а не следовать им. У конфига кейса есть примеры убранных правил — «мониторить только будни» было убрано в тот же день, когда оно было промоутировано в «мониторить ежедневно, включая выходные».

Где паттерн подходит

  • Долгие развёртывания агентов, где операционная среда слишком сложна для upfront-дизайна.
  • High-trust-контексты, где оператор может быть в петле на каждом инциденте и сам разбирает и промоутит правила.
  • Системы с чётким разделением конфигурации и кода — файлы, которые агент читает при старте, отделимые от логики агента.

Слабее всего в полностью unattended-системах, где нет оператора для шага промоушена. Там либо нужен другой механизм (LLM-самореф­лексия, автоматическая генерация правил), либо upfront-дизайн с принятием его недопокрытия.

Два режима отказа

  • Промоушен без провенанса. Правило садится в конфиг без записи инцидента, который его породил. Через месяцы оператор не может понять, актуально ли оно. Решение: каждое промоутированное правило включает однострочный комментарий с названием инцидента.
  • Шкаф без промоушена. Инциденты копятся в .learnings/, но не доходят до основного конфига. Агент продолжает повторять ошибки. Решение: работа оператора — шаг промоушена; ревью шкафа с известной частотой (оператор кейса делает это еженедельно).

См. также