О себе Портфолио Кейсы Услуги Блог Контакт 🎙 Поговорить с AI
EN DE RU
🎙 Поговорить с AI
October 19, 2026 · 5 min read

MCP-зоопарк уже ломает команды: как выбрать один runtime для агентов вместо 10 несовместимых тулов

Я Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production-grade агентные системы на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Последние месяцы я вижу один и тот же сбойный паттерн: команда уже подключила MCP-серверы, локальные tools, workflow-автоматизацию и кастомные wrappers, а потом выясняется, что агент проходит demo, но ломается на правах доступа, таймаутах и несовместимых схемах вызова в реальной среде. Пр

Denis Shokhirev
Denis Shokhirev
Agentic AI Systems Architect
Telegram LinkedIn

Я Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production-grade агентные системы на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Последние месяцы я вижу один и тот же сбойный паттерн: команда уже подключила MCP-серверы, локальные tools, workflow-автоматизацию и кастомные wrappers, а потом выясняется, что агент проходит demo, но ломается на правах доступа, таймаутах и несовместимых схемах вызова в реальной среде.

Проблема не в том, что MCP плох сам по себе. Проблема в том, что команды превращают runtime в зоопарк: один инструмент для orchestration, другой для tool calling, третий для secrets, четвертый для observability, пятый для human review, и все это живет без единого контракта выполнения. В regulated среде это особенно быстро всплывает: кто имеет доступ к данным, где логируется вызов, как ограничивается действие агента, и кто вообще отвечает за отказоустойчивость.

Почему MCP-sprawl ломает команды раньше, чем модель начинает ошибаться

Когда у вас 10 несовместимых тулов, вы платите не только временем на интеграцию. Вы создаете 10 разных моделей отказа. Один сервер возвращает JSON-схему, другой — свободный текст, третий требует отдельной аутентификации, четвертый не умеет идемпотентность. В итоге вы дебажите не поведение агента, а поведение glue-code между тулзами.

Anthropic в документации по tool use и Model Context Protocol прямо показывает, что ценность появляется там, где есть стандартный интерфейс вызова инструмента и предсказуемый обмен контекстом, а не просто длинный список подключений. Источник: Anthropic Docs, 2025, https://docs.anthropic.com/. Я с этим согласен по практическим причинам: на 3 недавних внедрениях самые дорогие инциденты были не в модели, а в слое исполнения между моделью и инфраструктурой.

Типичные симптомы tool sprawl

СимптомКак выглядитЧто ломается
Дублирование tool registryОдни и те же функции описаны в Claude Code, n8n и локальном сервисеРазъезжаются схемы и права
Разные контракты ошибокГде-то 500, где-то text error, где-то timeout без телаАгент не умеет восстанавливаться
Секреты разбросаныDoppler, env, ручные токены в n8nАудит и ротация становятся ручными
Нет единого state layerЧасть состояния в памяти агента, часть в Supabase, часть в workflowНельзя воспроизвести решение

Что считать runtime для агентов на практике

Я называю runtime не библиотеку и не protocol-spec. Runtime — это слой, который принимает решение о вызове tools, исполняет их по единому контракту, логирует действия, контролирует state, retries, timeouts и доступ к данным. Если этого слоя нет, у вас не runtime, а набор интеграций.

В моем стеке чаще всего работает такой принцип: Claude или Anthropic SDK принимает решение, Postgres или Supabase хранит state и audit trail, n8n исполняет внешние бизнес-процессы там, где важна интеграционная наглядность, а секреты живут в Doppler. Ключевой момент: для агента все это должно выглядеть как один исполнимый слой, а не как 5 независимых миров.

Минимальный контракт tool execution

from anthropic import Anthropic
import os, json

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

tools = [{
    "name": "create_invoice",
    "description": "Create invoice in ERP",
    "input_schema": {
        "type": "object",
        "properties": {
            "customer_id": {"type": "string"},
            "amount": {"type": "number"}
        },
        "required": ["customer_id", "amount"]
    }
}]

msg = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=800,
    tools=tools,
    messages=[{"role": "user", "content": "Create invoice for C-102 with 1200 EUR"}]
)

print(json.dumps(msg.model_dump(), indent=2, ensure_ascii=False))

Этот код не решает orchestration целиком, но показывает главное: инструмент описан схемой, вызов модели предсказуем, а не завязан на случайные парсеры текста. Дальше вы уже оборачиваете исполнение в retries, policy checks и persistent state.

Как выбрать один runtime вместо 10 тулов

Я смотрю не на количество интеграций в каталоге, а на 5 жестких критериев.

1. Единый контракт вызова tools

Если tools в одной системе описаны JSON schema, а в другой — prompt-конвенцией, команда быстро теряет контроль. Нужен один формат определения входов, выходов и ошибок.

2. Наблюдаемость на уровне действия

Мне нужен не просто application log, а запись: какой агент, с каким prompt/context, какой tool вызвал, с каким аргументом, к какому результату это привело, и можно ли это воспроизвести. Без этого root cause analysis превращается в догадки.

3. Состояние вне модели

Если критическое состояние живет только в контекстном окне, вы потеряете повторяемость. State должен быть в Postgres или Supabase, с версионированием и понятной моделью блокировок.

4. Policy enforcement до вызова side effects

Агент не должен сам решать, можно ли отправлять письмо, менять лимит или трогать PII. Эти проверки должны жить вне модели.

type ToolCall = { name: string; input: Record<string, unknown> };

export function allowTool(call: ToolCall, role: string): boolean {
  const restricted = ["send_email", "update_payout", "delete_record"];
  if (restricted.includes(call.name) && role !== "approved_operator") {
    return false;
  }
  if (call.name === "update_payout" && typeof call.input["amount"] === "number") {
    return Number(call.input["amount"]) <= 1000;
  }
  return true;
}

5. Сканирование кода и workflow до релиза

Если вы генерируете код, SQL или automation, проверяйте это до выхода в prod. OWASP публикует LLM Top 10 как список типовых рисков для приложений с LLM, включая excessive agency и insecure output handling. Источник: OWASP GenAI Security Project, 2025, https://genai.owasp.org/. Для Python и инфраструктуры я обычно ставлю semgrep, bandit и gitleaks в CI.

semgrep --config=p/owasp-top-ten .
bandit -r app/ -f json -o bandit-report.json
gitleaks detect --source . --report-format json --report-path gitleaks.json

Когда n8n, Supabase и Postgres помогают, а когда мешают

n8n полезен там, где у вас много внешних систем и нужно быстро, прозрачно собирать бизнес-процессы. Но n8n не должен становиться hidden runtime, в котором живет половина агентной логики без версионирования и тестов. Supabase удобен как managed слой для state, auth и быстрых внутренних интерфейсов, но для чувствительных сценариев я часто оставляю self-hosted Postgres как source of truth.

Хороший признак архитектуры: если завтра вы меняете модель или добавляете еще один tool provider, state model, policy layer и audit trail не меняются радикально. Плохой признак: смена одного инструмента тянет переписывание всех workflow.

Практическая схема для regulated рынка

Если вы работаете с B2B-клиентами в Европе, мой базовый шаблон простой. Модель принимает решение, но не исполняет side effects напрямую. Все tool calls проходят через policy layer. Все состояния и решения пишутся в Postgres. Секреты управляются централизованно. Внешние процессы, которым нужна визуальная orchestration, уходят в n8n. Все generated artifacts проходят статический анализ и ручной review там, где есть риск денег, персональных данных или внешних сообщений.

Такой подход не делает систему идеальной. Но он убирает главный источник хаоса: когда команда думает, что строит агентов, а по факту строит набор несовместимых переходников.

FAQ

MCP достаточно, чтобы стандартизировать весь стек?

Нет. MCP помогает стандартизировать способ описания и вызова инструментов, но не заменяет policy layer, state management, audit trail и контроль side effects.

Стоит ли держать orchestration внутри n8n?

Только для части процессов. Если основная логика принятия решений и recovery живет в n8n без тестируемого кода и явного state layer, поддержка быстро становится дорогой.

Можно ли выбрать runtime без self-hosted Postgres?

Да, если managed среда закрывает ваши требования к журналированию, резервированию и доступу. Но source of truth должен быть один, а не размазан по памяти агента и workflow-нодам.

Что важнее: выбор модели или выбор runtime?

Для production почти всегда важнее runtime. Модель можно заменить за неделю, а плохой execution layer ломает доступы, наблюдаемость и воспроизводимость месяцами.

С чего начать аудит tool sprawl?

С карты всех tool calls, секретов, state stores и точек side effects. Если вы не можете за 30 минут объяснить, где агент принимает решение и где оно исполняется, sprawl уже начался.

Где у вас сегодня больше всего отказов в агентной системе: в model reasoning, в policy checks, в tool execution или в state recovery после ошибки? Мне правда интересно сравнить это с тем, что я вижу в проде у B2B-команд в Европе.

I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.

Читать дальше
AI-ассистент для Blender: как интеграция мультиагентных рабочих процессов экономит недели ручной 3D-работы
Почему ваши AI-агенты падают в проде: как Trigger.dev решает проблему надёжности и оркестрации
Контекстное окно для AI-агентов: как сократить расходы на память и ускорить цепочки задач
Anthropic заменяет Git: как AI-агенты ломают привычную инфраструктуру разработки
Все статьи →
Где это применяется
Услуги — что мы делаем
Поговорить с голосовым агентом
Кейсы
Готовы к следующему шагу?

Превратить процесс в систему, которая работает

Продакшн-качество, а не демо.

Обсудить проект → ← Все статьи