Перейти к содержанию

Глава 12. SLO для агентных систем

1. Начнем с вопроса: как понять, что агент поддержки действительно здоров

Продолжим тот же сценарий поддержки.

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

Но после первых разборов возникает следующий вопрос:

Как понять не задним числом, а каждый день, здорова ли система на самом деле?

Вот здесь и появляются SLO.

Обычный uptime отвечает только на вопрос: “Компонент был доступен или нет?”

Для агента поддержки этого мало. Даже если все сервисы формально работают, система уже может быть нездорова:

  • пользователь ждет слишком долго;
  • агент создает слишком много лишних тикетов;
  • доля эскалаций медленно ползет вверх;
  • стоимость типового запроса растет;
  • безопасный путь слишком часто ломает нормальные сценарии;
  • шлюз политики не пускает нужное действие или, наоборот, пропускает лишнее;
  • слой verifier или grading дрейфует и начинает считать небезопасные или низкокачественные запуски здоровыми.

SLO нужны именно для этого: переводить разговор о “здоровье” из ощущения в измеримые цели.

В этой главе это означает прежде всего язык бюджетов. SLO — это еще не процесс реагирования. Они задают, какой уровень деградации, небезопасного поведения, нагрузки на операторов или эрозии качества verifier система может потреблять до того, как другой слой должен будет реагировать.

Роль SLO в этой книге тоже вполне конкретна. Трассы захватывают сырую историю. Оценки производят суждения. Наблюдаемость сохраняет доказательства на масштабе системы. Assurance отвечает на findings. SLO задают бюджет здоровья и бюджет риска, которые платформа имеет право тратить в рабочем режиме.

Нужны схемы и артефакты?

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

2. SLO должны описывать поведение запуска, а не здоровье отдельных деталей

Очень частая ошибка выглядит так:

  • модель отвечает быстро;
  • векторное хранилище доступно;
  • API тикетной системы жив;
  • адаптер почти не падает.

Все это полезно, но ни одна из этих метрик сама по себе не отвечает на главный вопрос:

Получает ли пользователь правильный, безопасный и своевременный результат?

Для агента поддержки важен не uptime отдельной библиотеки, а исход всего запуска:

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

Поэтому SLO для агентных систем лучше строить вокруг поведения на уровне запуска.

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

3. Для этого агента поддержки реально важны пять групп SLO

На практике для агентной системы эксплуатационного уровня почти всегда достаточно начать с небольшого набора:

  • SLO успешности;
  • SLO задержки;
  • SLO безопасности;
  • SLO стоимости;
  • SLO эскалаций.

Этого уже хватает, чтобы видеть не только “система жива”, но и:

  • полезна ли она;
  • не стала ли она слишком медленной;
  • не размывается ли граница безопасности;
  • не дорожает ли типовой сценарий;
  • не перегружает ли она людей.

Не нужно пытаться измерить все сразу. Нужен компактный набор метрик, который действительно влияет на пользовательский результат и операционную стабильность.

4. Success SLO должно быть ближе к задаче, чем к HTTP 200

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

Но для агента поддержки запуск может быть формально “успешным” и при этом плохим:

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

Поэтому SLO успешности стоит привязывать к вещам вроде:

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

У агента поддержки успех должен описывать не “не было исключения”, а “задача реально решена”.

Сквозной кейс: SLO для дублей

В кейсе сортировки обращений поддержки SLO успешности должен считать дубль тикета не “успешным созданием”, а ошибкой исхода. Хорошая цель звучит ближе к задаче: застрявшие запросы получают ровно один корректный тикет с нужным контекстом, а side_effect_unknown не заканчивается слепым повтором. Тогда SLO защищает пользователя и оператора, а не просто зеленый HTTP-статус.

5. Latency SLO должно раскладывать задержку по этапам

Если ты видишь только общий p95 по запуску, ты знаешь, что система стала медленнее, но не понимаешь почему.

Для того же агента поддержки задержка может уехать в разные места:

  • извлечение стало дольше возвращать историю запроса;
  • модель начала думать больше из-за раздутого prompt;
  • адаптер инструмента долго ждет внешнюю тикетную систему;
  • путь подтверждения зависает на человеке;
  • очередь фоновых задач начала давить на свежие запуски.

Поэтому полезно смотреть не только на задержку end-to-end, но и на этапы:

  • p95 / p99 запуска;
  • задержку извлечения;
  • задержку span модели;
  • задержку выполнения инструмента;
  • ожидание подтверждения;
  • время ожидания в очереди.

Тогда SLO задержки перестает быть красивой цифрой и становится инструментом диагностики.

Но это все еще бюджетный инструмент, а не контур реагирования. Latency SLO говорит команде, сколько замедления можно терпеть до того, как потребуется действие. Более поздняя глава про assurance уже отвечает за сдерживание, владение и реагирование, когда этот допуск нарушен.

5.1. Бюджет задержки начинается не со скорости модели, а с терпения пользователя

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

Если пользователи начинают уходить через 8-10 секунд, то агент с 25-секундным средним временем ответа спроектирован плохо, даже если его метрики качества выглядят высоко.

Именно поэтому полезно думать не только в терминах "ускорить все", а в терминах маршрутизируемого пайплайна:

  • быстрый путь для частых и простых случаев;
  • более медленный путь рассуждения только для неоднозначных, высокорисковых или необычно сложных запусков.

Практически это часто означает:

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

Тогда SLO задержки перестает быть чисто платформенной метрикой и начинает работать как часть соответствия продукту.

6. Safety SLO должно жить рядом с надежностью, а не отдельно от нее

В агентной системе безопасность нельзя держать как отдельное “приложение по безопасности”, которое живет само по себе. Для эксплуатации это часть системного здоровья.

Для агента поддержки полезно измерять как минимум:

  • долю запусков без policy violations;
  • долю запусков без cross-tenant retrieval;
  • долю операций записи без неизвестного побочного эффекта;
  • покрытие подтверждениями для высокорисковых действий;
  • долю запусков без инцидентов с чувствительным исходящим трафиком.

Это особенно важно после инцидентов вроде дубля тикета или небезопасной записи памяти: если безопасность не попадает в SLO, команда очень быстро снова начинает оптимизировать систему только по скорости и удобству.

По мере того как слои оценки и verifier становятся частью дисциплины релизов, полезно отслеживать и их качество как отдельное измерение здоровья. Система не вполне здорова, если поведение рантайма кажется приемлемым только потому, что verifier стал шумным или слишком доверчивым.

У агентной системы здоровье почти всегда многомерно

flowchart LR
    A["Здоровье агента поддержки"] --> B["Успешность"]
    A --> C["Задержка"]
    A --> D["Безопасность"]
    A --> E["Стоимость"]
    A --> F["Эскалация"]

7. SLO стоимости помогает поймать тихую деградацию раньше инцидента

У агентных систем есть неприятная особенность: они могут оставаться “рабочими”, пока экономика уже тихо разрушается.

В этом сценарии поддержки это часто выглядит так:

  • извлечение тянет в prompt слишком много контекста;
  • модель чаще ходит в инструменты без пользы;
  • планировщик делает лишние шаги;
  • повторы раздувают запуск;
  • сводки памяти начинают занимать лишний бюджет.

Поэтому SLO стоимости полезно считать хотя бы по:

  • стоимости на успешный запуск;
  • токенам на запуск;
  • вызовам инструментов на запуск;
  • доле использования дорогой модели.

Если этого нет, команда заметит деградацию слишком поздно: когда агент еще “помогает”, но уже стоит заметно дороже.

8. Escalation SLO защищает не систему, а людей вокруг нее

Human-in-the-loop не является бесплатной страховкой.

Если агент поддержки:

  • слишком часто запрашивает подтверждение;
  • слишком часто уходит в ручную сверку;
  • слишком часто перекидывает решение человеку;

он может выглядеть безопасным, но в реальности просто перекладывает хаос на операторов.

Поэтому полезно отслеживать:

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

Для агента поддержки это критично: слишком высокая доля эскалаций быстро делает автоматизацию декоративной.

9. Практические правила для дизайна SLO

Если нужен короткий набор правил, который реально помогает, он обычно такой:

  1. Начинай с исхода на уровне запуска, а не с метрик отдельных компонентов.
  2. Success должен описывать решенную задачу, а не просто отсутствие исключения.
  3. Safety, стоимость и эскалации должны считаться частью здоровья системы, а не отдельными приложениями к надежности.
  4. Latency полезно раскладывать по этапам, иначе она плохо диагностируется.
  5. SLO имеют смысл только тогда, когда влияют на решения о раскатке и изменениях.
  6. Если контроль релиза зависит от вывода verifier, качество verifier тоже должно входить в модель здоровья.

10. Пример политики SLO для агента поддержки

Ниже не “канонические” числа, а пример дисциплины:

slo:
  success:
    successful_run_rate: ">= 97%"
  latency:
    run_p95_ms: "<= 12000"
    tool_span_p95_ms: "<= 2500"
  safety:
    policy_violation_rate: "< 0.2%"
    unknown_side_effect_rate: "< 0.05%"
  cost:
    avg_tokens_per_run: "<= 18000"
    avg_cost_per_successful_run_usd: "<= 0.12"
  escalation:
    manual_intervention_rate: "< 8%"
  verifier:
    false_positive_rate_high_risk: "< 1%"
    failure_attribution_agreement_rate: ">= 95%"

Главное здесь не точные проценты. Главное, что команда заранее договорилась, как выглядит нормальное состояние системы.

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

И это же чистая граница с assurance. SLO говорят, сколько боли, дрейфа, стоимости, небезопасного поведения или нагрузки на людей платформа может терпеть. Assurance решает, что делать, когда эти бюджеты уже перестали соблюдаться.

Теперь эта договоренность может включать и слой verifier, особенно если раскатка, assurance или классификация после инцидента зависят от его суждений.

11. Простой кодовый пример классификации здоровья

Ниже каркас, который показывает идею: один и тот же запуск оценивается не по одной метрике, а по нескольким измерениям сразу.

from dataclasses import dataclass


@dataclass
class RunHealth:
    successful: bool
    latency_ms: int
    policy_violated: bool
    cost_usd: float


def classify_run_health(run: RunHealth) -> str:
    if run.policy_violated:
        return "safety_failure"
    if not run.successful:
        return "task_failure"
    if run.latency_ms > 12_000:
        return "slow_success"
    if run.cost_usd > 0.12:
        return "expensive_success"
    return "healthy"

Это простая модель, но она полезна именно тем, что не прячет операционное качество за формальным “успехом”.

12. Что чаще всего ломается в культуре SLO

Проблемы здесь очень повторяемы:

  • success считают через HTTP-статус;
  • latency видят только по вызову модели;
  • safety живет отдельно от надежности;
  • стоимость вообще не попадает в модель здоровья;
  • человеческая эскалация не считается частью здоровья системы;
  • качество verifier предполагается, а не измеряется;
  • SLO существуют только на дашборде и не влияют на раскатку.

Если так происходит, SLO становятся декорацией. Команда смотрит на цифры, но не управляет платформой через них.

В этот момент у платформы уже могут быть дашборды, но реального слоя здоровья и бюджетов у нее все еще нет.

13. Быстрый тест зрелости для дисциплины SLO

Команде не стоит думать, что у нее уже здоровое управление сервисом, только потому, что она смотрит на uptime, p95 задержки и несколько dashboard-алертов.

Более сильная планка такая:

  • здоровье определяется на уровне запуска, а не только на уровне компонентов;
  • безопасность, стоимость и эскалации считаются полноправными измерениями здоровья системы;
  • успех означает решенную задачу, а не просто отсутствие исключения;
  • SLO влияют на решения о раскатке, откате и изменениях;
  • люди защищены от тихого переноса нагрузки на них.

Если большинство этих условий не выполняется, у команды уже могут быть метрики, но реальной дисциплины SLO для агентных систем пока нет.

14. Что делать сразу после этой главы

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

  1. Есть ли у тебя определение успеха на уровне запуска?
  2. Видишь ли ты задержку по этапам, а не только общую?
  3. Есть ли SLO безопасности, а не только uptime?
  4. Считаешь ли ты стоимость на полезный исход?
  5. Видно ли, сколько реальной нагрузки уходит на людей?
  6. Влияют ли SLO на решения о раскатке?

Если на несколько вопросов подряд ответ “нет”, значит наблюдаемость у тебя уже появилась, но здоровье системы все еще не управляется через цели качества.

15. Что читать дальше

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

16. Полезные справочные страницы