Я держу собственный сильно кастомизированный сетап Claude Code и за последний год построил под него две вещи, которые прямо относятся к тому, о чём пишет Арсений Зинченко в статье про отладочного агента для Kubernetes: навык для VictoriaMetrics поверх шести bash-скриптов, который я гонял по живому кластеру vm.ethinking.xyz, и многонедельный заход по rightsizing-у EKS (фазы A/B, охота на OOM, классы лимитов и JAVA_OPTS). Поэтому его текст я читал не как обзор технологии, а как описание развилки, на которой сам стоял.
Зинченко собирает read-only агента-отладчика подов, упаковывает его в плагин Claude Code с собственным маркетплейсом, подключает официальные навыки VictoriaMetrics для метрик, логов и алертов — и сознательно отказывается от MCP в пользу Skills. Цель он формулирует предельно честно: иметь агента, которому разработчик может задать вопрос «why the hell did that Kubernetes Pod crash». И сразу признаётся, что пока это PoC по части инструкций. Это правильная рамка, и спорить с ней я не собираюсь — я хочу разобрать одну инженерную ось, которую статья задевает, но не доводит до конца.
Моя позиция: обе схемы правильные, но в разных точках
Тезис простой. Зинченко даёт LLM шаблоны MetricsQL и LogsQL и позволяет агенту собирать конкретные запросы на лету. Я в своём VM-навыке сделал ровно наоборот: все HTTP-вызовы прогоняются через bash-скрипты, а агент видит только предагрегированный вывод и анализирует его. Это не «лучше» и «хуже» — это два конца одной оси: гибкость для ad-hoc-расследования против воспроизводимости и аудируемости.
Его подход выигрывает там, где запрос неизвестен заранее: ты сел дебажить «почему Grafana рестартует» (он, кстати, именно так и нашёл причину собственных рестартов), и тебе нужна свобода переформулировать MetricsQL пять раз за минуту. Мой подход выигрывает там, где прогон должен быть повторяемым и объяснимым постфактум: один и тот же скрипт даёт один и тот же агрегат, ревьюер видит ровно то, что видел агент, и через неделю можно воспроизвести цифру. Именно поэтому моя схема пережила фазы A/B rightsizing-а — там нельзя, чтобы агент каждый раз сочинял новый запрос: нужна была одна методология, дающая сравнимые числа по десяткам сервисов с базовой линией OOM=0.
Где он прав — и это не мелочь
Главный аргумент статьи я разделяю целиком. Зинченко точно ловит, что MCP не несёт того знания, ради которого городишь огород. Его формулировка бьёт в точку: «MCP only defines how to execute the query - not the query structure itself», и дальше — «the agent/LLM still decides on the query and the filters». Типизированный query(query: string) валидирует, что ты передал строку, но саму строку MetricsQL по-прежнему сочиняет модель. А вот навык может нести то, чего у MCP нет в принципе: какой именно stream-фильтр в нашем VictoriaLogs, какой обязательный label cluster в нашем VictoriaMetrics, какие корреляции для CrashLoopBackOff против OOMKilled. Это контекст среды, а не сигнатура функции.
С kubectl он тоже прав: оборачивать его в MCP смысла мало, потому что синтаксис kubectl любая модель знает наизусть, а специфику кластера достаточно положить в SKILL.md. И граница use-case он проводит честно — «we're building a read-only agent that debugs, not deploys», поэтому готовый deploy-навык ему не подходит. Резюме его выбора — «Bash + curl + our own skill with our context + official VictoriaMetrics skills» — для разведочной отладки полностью оправдано.
Где схема недотянута: read-only по чёрному списку — слабее, чем кажется
А вот тут начинается моя главная претензия, и она техническая. Гарантия read-only у Зинченко держится на deny-tools — glob-блэклисте: запрещены kubectl delete, *curl* -X *, пайпы в sh/bash, редиректы >/>>, rm/mv/cp. Список выглядит солидно, но блэклист по glob-паттернам — это игра, в которой защищающийся всегда отстаёт. Запись в файл без символа > делается через tee. POST без -X делается флагом --data в форме, которую паттерн не поймал, или через here-string и подстановку команд. xargs и env переносят запрещённую команду в обёртку, которую блэклист не разглядывает. Любой пропущенный вектор — это дыра, и закрывать их по одному можно бесконечно.
Я в своём сетапе доверяю обратной логике: allowlist (что явно разрешено — то и можно, остальное закрыто по умолчанию) плюс intent-level gate на продакшен-действия — любой kubectl exec/port-forward, SSH в прод или terraform apply требует явного именованного одобрения в текущей сессии. Allowlist не страдает от проблемы «забыли запретить ещё один вектор», потому что по умолчанию запрещено всё.
Но честно оговорю нюанс, который статья имеет право не педалировать: у нас разные модели угроз. Его агент — read-only debug на dev-кластере, где цена ошибки невелика и блэклист закрывает грубые промахи модели. Мой gate заточен под write/prod, где цена ошибки — инцидент. Так что это не разнос его дизайна, а указание на потолок: deny-tools хорош как defence-in-depth и плохо годится как единственная гарантия, если порог доверия к среде поднимается.
Что делать на практике
Выбор между двумя схемами я бы свёл к одному вопросу: прогон одноразовый или повторяемый. Для исследовательской отладки — «почему этот под упал прямо сейчас» — берите вариант Зинченко: шаблоны запросов плюс свобода модели их комбинировать, это быстрее и не требует писать скрипт под каждый новый разрез данных. Для всего, что нужно воспроизвести, заревьюить или защитить перед заказчиком — заворачивайте HTTP в скрипты и кормите агента готовым агрегатом; тогда вывод детерминирован, а аудит тривиален.
Опыт фаз A/B меня в этом убедил предметно: когда rightsizing идёт неделями, по десяткам сервисов, с классами лимитов и тюнингом JAVA_OPTS ради базовой линии без OOM, агент-сочинитель запросов превращается в источник несравнимых чисел. Скрипт — это и есть та самая дешёвая, скучная, надёжная часть, про которую я уже писал в «The Harness Is the Cheap Part»: дорого и интересно — рассуждение модели, а вот воспроизводимость берётся ровно с того, что вы зафиксировали обвязку.
А отказ от MCP ради Skills для kubectl — решение, под которым я подпишусь без оговорок. Там, где модель и так знает синтаксис, типизированная обёртка добавляет инсталляционную возню и не добавляет знания. Зинченко выбрал верный инструмент; я лишь дорисовываю вторую половину карты — точку, в которой к гибкости начинаешь предъявлять счёт за воспроизводимость.