!Astro.props.image &&
← Назад к блогу

Строим RCA-агента на Amazon Bedrock AgentCore

По материалам моего доклада на AWS Community Day Central Asia: как один вопрос «почему под перезапускается?» вырастает из одного вызова модели в ограниченный цикл расследования, что нужно, чтобы такого агента эксплуатировать, и какую роль играют Strands и AgentCore.

Виктор Ведмич · 13 мин чтения

ai agents aws bedrock kubernetes mcp

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

Что будет дальше, вы знаете, потому что сами это делали. Открываете алерт. Делаете kubectl describe по поду. Идёте в CloudWatch за логами, в Prometheus за графиком памяти, в вики за ранбуком, который кто-то написал в прошлом году. Один инцидент, несколько систем, а настоящая работа происходит у вас в голове: связать улики между собой.

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

Как раз сбор и сопоставление улик машина может взять на себя первой. Только не чат-ассистент, который объясняет вставленный в чат лог: это копилот, и он отвечает на вопросы. В 2 часа ночи мне нужен агент. Агент сам выбирает следующую проверку, сам обращается к системам и приносит отчёт с уликами. Копилот отвечает. Агент расследует.

Это текстовая версия моего доклада про агента для анализа первопричин инцидентов (root cause analysis, RCA), с которым я выступил на AWS Community Day Central Asia 2026 в Ташкенте. План тот же:

  1. Какие возможности нужны агенту?
  2. Что нужно, чтобы его эксплуатировать?
  3. Чем помогают Strands и AgentCore?
  4. Как собрать своего RCA-агента?

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

Виктор Ведмич на сцене CAEx на фоне экрана с анонсом доклада Building an RCA Agent with Amazon Bedrock AgentCore, 25 сентября
AWS Community Day Central Asia 2026, CAEx, Ташкент.

Один вопрос, пять слоёв

Самый понятный способ объяснить агента, который я знаю: взять один вопрос и отвечать на него снова и снова, каждый раз добавляя одну возможность. На каждом шаге смотрим, что ответ может, а чего не может. (Ответы и значения ниже иллюстративные и синтетические, как и на слайдах.)

Только модель: правдоподобно и в общем

Спросите генеративную модель «почему под перезапускается?», и вы получите хороший ответ на другой вопрос. Частые причины: контейнеру не хватило памяти (OOMKilled), процесс падает на старте, не проходит liveness- или startup-probe, плохой конфиг или образ. Сделайте kubectl describe pod и посмотрите последнюю причину завершения.

Это полезный общий совет, но в 2 часа ночи он ничего не объясняет. Такой ответ подходит любому поду где угодно. Причина простая. Модель предсказывает следующий токен по тому, что лежит в промпте. Её знания заканчиваются на дате обучения, памяти между вызовами у неё нет, доступа к вашему кластеру тоже. Контекст: единственный канал в модель. Всё дальнейшее сводится к тому, чтобы передавать через этот канал данные получше.

Добавляем наши знания через RAG

Retrieval-augmented generation (RAG) добавляет в промпт наши собственные документы. Вопрос служит запросом к индексу ранбуков, и самые подходящие фрагменты вместе со ссылкой на источник попадают в контекст.

Ответ меняется: «В вашем ранбуке лимиты памяти match-api указаны как известный риск. Проверьте последнюю причину завершения и сравните потребление памяти с настроенным лимитом за период инцидента».

Теперь ответ опирается на наши знания. Но посмотрите, чего всё ещё нет: на сам под никто не взглянул. Поиск возвращает текст ранбука, а не текущие данные из кластера.

Добавляем живые инструменты через MCP

Здесь картина меняется. С инструментами модель может запросить наблюдение. Через Model Context Protocol (MCP) приложение предлагает модели список инструментов, например eks_describe_pod. Модель предлагает вызов, а выполняет его приложение.

Теперь в контексте результат инструмента (синтетический, как и все значения здесь): последнее завершение OOMKilled, exit code 137, лимит памяти 512Mi. И ответ наконец про этот под: «Предыдущий контейнер завершился по OOM (exit 137) при лимите 512Mi. Следующая проверка: working set памяти за последний час и история деплоев. Пока не установлено, почему выросло потребление памяти».

Модель предлагает eks_describe_pod(pod). Приложение проверяет политику и вызывает EKS tool server через MCP. Наблюдение (OOMKilled, exit 137) возвращается в промпт.

Одна деталь на этом слайде важнее всего остального в первой половине: модель предлагает вызов, а делает его приложение. Модель никогда не трогает ваш кластер. Ваше приложение проверяет политику, вызывает MCP-сервер и возвращает наблюдение. Права живут в коде и конфигурации, а не в добрых намерениях модели. (Если MCP вам в новинку, начните с MCP-серверов простыми словами.)

Цикл сам выбирает следующую проверку

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

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

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

Не всё должно быть агентом

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

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

В дизайне RCA агентным сделано только само расследование. Приём алертов идёт фиксированным workflow с заданной схемой вебхука. Инструменты работают только на чтение. Решение об исправлении принимает человек. Оставьте агента там, где последовательность проверок нельзя задать заранее, а всё вокруг держите детерминированным.

Skills и subagents, когда они нужны

Картину дополняют ещё две возможности.

Skill задаёт переиспользуемую процедуру для повторяющейся работы. «Расследование рестарта» описывает, когда её применять (перезапуск контейнера, а не любой вопрос про Kubernetes), и как действовать: посмотреть предыдущее состояние завершения, сопоставить метрики со временем рестарта, сравнить правдоподобные причины, привести улики и перечислить недостающие проверки. Skill подгружается в промпт, когда задача подходит под условия его применения. Skills дают инструкции. Инструменты дают возможности.

Subagent получает ограниченную задачу в свежем контексте. Контекст основного расследователя заполняется быстро: вопрос, состояние пода, фрагменты ранбуков, десять экранов логов и метрик. Если отдать «посмотри на память вокруг рестарта» специалисту по телеметрии, весь этот шум останется у него. Специалист возвращает сжатые выводы, а не свою переписку. Цена: задержка, ещё одна передача и в разы больше токенов, чем у одного агента. Делегировать стоит ради бюджета контекста, а не ради оргструктуры.

Модель, знания (RAG), инструменты (MCP), skills, subagents. Это карта возможностей, а не обязательный стек: добавляйте возможность, когда она нужна задаче.

Это карта возможностей, а не обязательный стек. Добавляйте возможность, когда она нужна задаче. Прототип, который я показывал, использует модель, RAG и MCP-инструменты в цикле. Skills и subagents можно добавить по мере роста, начинать с них не нужно.

Эксплуатация: самое сложное

Всё, что было до сих пор, помещается на доске. А потом вы пытаетесь запустить это для настоящего on-call и выясняете, что цикл составляет лишь часть приложения. Рабочему агенту нужно окружение: где он работает, кто какой инструмент может вызывать, что нужно блокировать, что переживает отдельный запуск, какая версия промпта сейчас в работе и что произошло и почему.

Четыре пункта стоит разобрать подробнее.

Три решения о доступе, а не одно

Caller: кто может вызвать агента. Tools: какие действия над какими ресурсами. Content: логи служат уликами, а не указаниями. Здесь есть все три фактора риска: приватные данные, недоверенный контент и канал наружу.

Логин отвечает только на первый вопрос: кто может вызвать агента? Второй: что агенту можно делать своими инструментами. Посмотреть один workload можно. Изменить алерт нельзя. Третий вопрос все пропускают: контент. Логи нельзя считать доверенным вводом. Любой, кто может записать строку в лог, может записать текст, который окажется в контексте вашей модели. Относитесь к контенту как к уликам, а не как к указаниям.

У этого RCA-агента есть все три ингредиента, которые делают агента рискованным: приватные данные (кластер), недоверенный контент (логи) и канал наружу (отчёт). Поэтому каждая граница должна быть явной, в конфигурации, которую можно протестировать. Фраза «будь осторожен» в промпте не заменяет ни одно из этих решений.

У памяти три срока жизни

«Память» означает три разные вещи. Разговор живёт до конца расследования. Запись о расследовании (что запускалось, статус, где лежит отчёт) должна пережить сессию, потому что завтра её кто-то будет искать. А проверенное знание об инциденте, после того как человек подтвердил итог, может стать зацепкой для следующего инцидента. Зацепкой, которую надо проверить, а не причиной, которой надо верить. Канонические логи и ранбуки остаются в своих хранилищах, чтобы переиспользованный контекст всегда можно было сверить с источником.

Правка промпта считается релизом

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

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

Три вида записей отвечают на три вопроса

Алерт, вызов инструмента, вызов модели, отчёт. Аудит API: кто что вызвал. Трейсы выполнения: какие шаги прошли. Сохранённые запросы и ответы: что модель получила и вернула.

Когда что-то пойдёт не так, вы зададите три разных вопроса, и на каждый нужна своя запись. Кто вызвал какой API и когда? Это аудит. Какие шаги выполнились, упали или заняли время, и был ли вообще диагностический шаг? Это трейсинг выполнения. Что модель на самом деле получила и вернула? Это сохранённые запросы и ответы модели. Ни одна запись не отвечает на все вопросы, а для каждой заранее нужно решить, кому дать доступ, какие чувствительные данные маскировать и сколько хранить.

Где тут Strands и AgentCore

Теперь сопоставим эти требования с AWS. Работу делают две части: Strands Agents, open-source SDK от AWS (Python и TypeScript), который крутит цикл агента в коде вашего приложения, и Amazon Bedrock AgentCore, набор сервисов для эксплуатации агентов в проде.

Strands приятно скучный. Агент в нём состоит из модели, списка инструментов и системного промпта:

return Agent(
    model=self._model,
    tools=tools,
    system_prompt=system_prompt,
)

Окружение для эксплуатации даёт AgentCore:

On-call приложение, затем Runtime с RCA-агентом, моделью Bedrock и Memory, затем Gateway (с Identity и Policy) к tool servers EKS, CloudWatch, Prometheus и Knowledge Base. Рядом Observability и Evaluations.
  • Runtime хостит агента: среда выполнения и жизненный цикл сессии. Ваш entrypoint принимает запрос, крутит цикл Strands и возвращает отчёт.
  • Gateway отдаёт агенту tool servers как MCP-инструменты: одно место для обнаружения и вызова инструментов.
  • Identity отвечает на вопрос «чьими полномочиями?»: кто вызывающий на входе и какие учётные данные уходят к инструментам на выходе.
  • Policy проверяет вызовы инструментов на пути через Gateway. Политики пишутся на Cedar и работают по принципу default-deny, так что «смотреть можно, менять нельзя» становится конфигурацией, которую можно протестировать, включая вызовы, которые должны быть запрещены.
  • Memory может хранить проверенное знание об инцидентах для опционального поиска.
  • Observability и Evaluations дают трейсы по каждому расследованию и способ оценить поведение до релиза.

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

Три заметки из практики.

Сессия не заменяет запись о задаче. Runtime управляет сессиями, но запись о расследовании (статус и отчёт, которые можно найти после конца сессии) должна лежать в хранилище, которым владеет ваше приложение. Повторы и дубли алертов тоже ваши решения. Сессия их за вас не примет.

Memory хранит зацепки, а не истину. Сейчас прототип ищет по ранбукам. Поиск по прошлым инцидентам пока только запланирован. В этой схеме проверенный итог инцидента будет попадать в долговременную память через IngestData, API прямой загрузки, который появился у AgentCore Memory в сентябре 2026. Настроенные стратегии извлечения будут обрабатывать его асинхронно, а следующее расследование сможет искать получившиеся записи в пределах своей области. Если загрузка упала, сначала разберитесь с причиной, а потом запускайте повторно.

Observability: три переключателя, и включать их придётся вам. Три вида записей соответствуют трём возможностям AWS. AWS CloudTrail пишет аудит вызовов API, но по умолчанию не всё. Вызовы моделей Bedrock вроде InvokeModel и Converse приходят как management events. А вызовы AgentCore Runtime, Gateway и Memory, как и поиск по Knowledge Base, относятся к data events, и их нужно включать явно.

Второй переключатель в вашем коде: инструментируйте приложение, чтобы оно отправляло трейсы OpenTelemetry, и AgentCore Observability сохранит трейсы, спаны и метрики в Amazon CloudWatch.

Третий: логирование вызовов моделей Amazon Bedrock, которое сохраняет запросы и ответы модели в CloudWatch Logs, Amazon S3 или в оба места. По умолчанию оно выключено. Три записи, три переключателя. И диагноз всё равно нужно сверять с реальным наблюдением.

Собираем RCA-агента

Время для рабочего примера. Первая задача намеренно маленькая: тот самый под в 2 часа ночи.

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

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

Собственный RCA-агент выбирает инструменты через MCP gateway, за которым четыре tool servers (EKS, CloudWatch, Prometheus, Knowledge Base), и выдаёт диагноз с планом исправления. Схема показывает структуру исходного кода и не доказывает, как система ведёт себя в работе.

В основе один агент-расследователь за gateway с четырьмя MCP tool servers:

СерверНа какой вопрос помогает ответить
EKSЧто случилось с подом?
CloudWatchЧто показывают логи, алармы и метрики?
PrometheusКак менялся нужный ряд метрик?
Knowledge BaseКакой ранбук подходит?

Вокруг него обычное приложение. Алерт из CloudWatch, Alertmanager или ручной запуск попадает в бэкенд, который его нормализует, сохраняет расследование и вызывает Runtime. Расследователь опрашивает инструменты и генерирует отчёт. Приложение сохраняет результат, а UI периодически его запрашивает.

Проект не публичный, но вот два фрагмента, которые я показывал со сцены. Расследователь собирается по стандартному паттерну Strands, а инструменты приходят из gateway:

with gateway_client as mcp:
    agent = Agent(
        model=bedrock_model,
        tools=mcp.list_tools_sync(),
        system_prompt=instructions,
    )
    result = agent(alert_text)

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

А инструмент представляет собой обычную функцию с понятным контрактом. Эта отдаёт состояние пода и работает только на чтение:

@mcp.tool()
@log_tool_execution
def eks_describe_pod(
    pod_name: str, namespace: str = "rca-demo"
) -> dict[str, Any]:
    cmd = ["kubectl", "get", "pod", pod_name,
           "-n", namespace, "-o", "json"]
    result = subprocess.run(
        cmd, capture_output=True, text=True, timeout=30
    )
    ...

Она возвращает ресурсы и текущее и предыдущее состояние контейнера. За ранбуки отвечает один инструмент поиска, bedrock_kb_retrieve(query, top_k=3), тонкая обёртка над API Retrieve в Amazon Bedrock Knowledge Bases, который возвращает каждый фрагмент вместе с источником и оценкой релевантности. Запрос по типу сбоя, фрагменты подходящего ранбука, и дальше сверка этих рекомендаций с текущими уликами.

Что должен показывать полезный отчёт

Виктор Ведмич на фоне слайда What a useful RCA report must show: диагноз, улики, исправление
Слайд, который я оставил бы, если бы можно было оставить только один.

У полезного RCA-отчёта три части:

  • Диагноз: объяснение, которое подтверждается наблюдениями.
  • Улики: что вернули инструменты и чего не хватает.
  • Исправление: рекомендуемые действия и шаг проверки.

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

Демо

Виктор Ведмич на главной сцене рассказывает слайд Demo Flow, рядом баннер спикера и логотип ICT Week Uzbekistan 2026
Ход демо: запуск, наблюдение, проверка.

В демо было три шага. Заранее подготовленный сбой в EKS запускает расследование. Смотрим на реальные результаты инструментов и на найденный ранбук. Потом сверяем диагноз и предложенное исправление с уликами. Вот запись, которую я показывал в зале (2:49):

Записанное демо (2:49): RCA-агент расследует отрепетированный сбой в EKS.

Строить или взять готовое?

Строить самому не обязательно. AWS DevOps Agent даёт управляемое расследование инцидентов и планы устранения. Действия, которые меняют ресурсы (directed actions), по умолчанию выключены, и каждое требует одобрения оператора в момент выполнения. AgentCore Harness даёт настроенного агента с управляемым циклом, которого потом можно экспортировать в код Strands. Свой цикл на Strands позволяет задать собственные контракты инструментов, ранбуки, формат отчёта и границы того, что агенту разрешено делать.

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

Что я вынес

Стройте вокруг задачи. Улики, которые можно проверить. Эксплуатируйте как софт.

Три вывода, которые я принёс бы своей команде:

  1. Стройте вокруг задачи. Полезный первый агент маленький. В докладе: один расследователь, четыре tool servers, один повторяющийся вопрос.
  2. Делайте улики проверяемыми. Отчёт показывает свои улики: причину завершения и лимит, процитированный фрагмент ранбука и то, что проверить не удалось.
  3. Эксплуатируйте как софт. Версионируйте, наблюдайте, оценивайте: версия в каждом отчёте, трейсы по каждому расследованию, прогон прошлых инцидентов перед релизом.

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

День в Ташкенте

Общий план сцены Main Hall в CAEx во время доклада: баннер спикера и слайд Demo Flow
Main Hall в CAEx во время демо.

AWS Community Day Central Asia 2026 прошёл в пятницу, 25 сентября, в CAEx в Ташкенте, в последний день ICT Week Uzbekistan. Его провела AWS User Group Tashkent при поддержке юзер-групп Казахстана и Кыргызстана, а открылся он кейноутом Jeff Barr «Adapting to Change». Мой доклад был в 10:15. Спасибо Шахзоду Ходжаеву, Тарасу Терещенко и всей команде организаторов за отличный день.

Доклад я закончил вопросом, и задам его вам: что первым делом расследовал бы ваш агент?

Ссылки

Источники

Утверждения про AWS, Strands и MCP сверены с этими официальными источниками 2026-10-03.

Открыть поиск

Esc
↑ ↓ навигация ↵ открыть