Когда агенту нужен веб-поиск, 5 MCP-серверов — это уже операционный риск: как выбрать один стек без зоопарка интеграций
Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я запускаю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самый неприятный момент в таких системах обычно не в модели, а в дне, когда агенту “просто добавили веб-поиск”, а через 2 недели у вас уже 5 MCP-серверов, разный auth, разные логи и ни одного ясного ответа, почему ночью выросли таймауты.
Снаружи это выглядит как нормальная эволюция стека. На практике это часто начало операционного долга: больше сетевых hop’ов, больше секретов, больше точек отказа, сложнее аудит, сложнее воспроизводимость ответов. Если вы работаете в логистике, fintech или industrial automation, проблема не в том, что у агента много инструментов. Проблема в том, что веб-поиск начинает жить по другим правилам, чем остальная система.
Почему 5 MCP-серверов — это не гибкость, а новый класс отказов
MCP сам по себе не проблема. Проблема начинается, когда каждая новая capability приезжает как отдельный сервер: один для поиска, другой для crawl, третий для документов, четвертый для браузера, пятый для внутренней базы знаний. Архитектурно вы получаете не набор tools, а распределенную систему без общей модели отказов.
Что ломается первым
По моему опыту, первыми ломаются 4 вещи:
| Слой | Что кажется удобным | Что реально болит в prod |
|---|---|---|
| Auth | Каждый сервер со своим token | Ротация секретов и drift прав доступа |
| Observability | Отдельные логи по сервисам | Нет единого trace для одного ответа агента |
| Latency | Можно подключать по мере роста | P95 расползается из-за каскада сетевых вызовов |
| Governance | Команды автономны | Нельзя быстро объяснить, какие внешние данные видел агент |
Если агент отвечает клиенту, а потом вы разбираете инцидент, вас мало интересует красота интерфейса tools. Вас интересует цепочка: какой запрос ушел наружу, какие документы вернулись, какой prompt был собран, какой policy его пропустил и что сохранилось в Postgres.
Как выбирать стек: не “лучший поиск”, а минимальный operational surface area
Я выбираю стек не по числу фич в демо, а по 5 критериям:
1. Единая модель аутентификации
Если поиск, внутренние данные и orchestration используют разные схемы секретов, вы уже платите налог на эксплуатацию. У меня секреты живут централизованно в Doppler, а сервисы получают только то, что им нужно.
2. Наблюдаемость на уровне одного задания агента
Один запрос агента должен иметь один correlation id, проходящий через n8n, backend, Postgres и внешний поиск. Иначе root cause analysis превращается в ручную археологию.
3. Контроль выхода наружу
В regulated среде нельзя позволять агенту искать “весь интернет” без ограничений. Нужны allowlist доменов, лимиты по времени, лимиты по числу fetch и понятный журнал доступа.
4. Деградация без каскадного падения
Если веб-поиск недоступен, агент должен перейти в режим “answer from internal sources only”, а не зависнуть на 3 ретраях и убить очередь.
5. Один стек данных для аудита
Я предпочитаю хранить execution metadata, tool calls и policy decisions в Postgres или Supabase, а не размазывать их по 6 SaaS-панелям. Для аудита это проще и дешевле.
Практический паттерн: один gateway инструментов вместо россыпи MCP endpoint’ов
Если агенту нужен веб-поиск, browsing и retrieval, я стараюсь дать ему один контролируемый вход, а не 5 прямых подключений. Это может быть один backend-сервис, который сам уже решает: сходить в поиск, сходить в Postgres, применить policy, нормализовать ответ и записать trace. Для модели это один tool interface. Для эксплуатации это один контракт.
import os
import requests
from urllib.parse import urlparse
ALLOWED_HOSTS = {"example.com", "docs.python.org"}
def fetch_url(url: str, timeout: int = 8) -> str:
host = urlparse(url).netloc
if host not in ALLOWED_HOSTS:
raise ValueError(f"host not allowed: {host}")
response = requests.get(
url,
timeout=timeout,
headers={"User-Agent": "agent-gateway/1.0"}
)
response.raise_for_status()
return response.text[:20000]Важен не сам Python-код, а идея: policy стоит перед сетевым вызовом, а не после него. Это дешевле, безопаснее и лучше объясняется аудитору.
Почему не давать модели прямой доступ ко всему
Anthropic в документации по tool use и model context protocol описывает MCP как способ стандартизировать доступ к инструментам, но стандарт не снимает с вас архитектурные решения по границам доступа и контролю исполнения. Источник: Anthropic Documentation, 2025, https://docs.anthropic.com/. Стандартный протокол не заменяет policy layer.
Минимальный production stack для веб-поиска в агенте
Для большинства B2B-сценариев мне хватает такого контура:
| Задача | Инструмент | Зачем |
|---|---|---|
| Orchestration | n8n | Управление workflow, retries, branching |
| App backend | Python + Anthropic SDK | Tool calling, policy enforcement |
| State / audit | Postgres или Supabase | Trace, execution logs, approval state |
| Secrets | Doppler | Централизованная выдача секретов |
| Static checks | semgrep, bandit, gitleaks | Проверка кода и секретов до релиза |
export DATABASE_URL="postgresql://app:pass@db/app"
export ANTHROPIC_API_KEY="***"
export SEARCH_TIMEOUT_SECONDS="8"
semgrep --config auto .
bandit -r app/
gitleaks detect --source . --no-banner
python -m app.workersemgrep, bandit и gitleaks — это не “про AI”, а про дисциплину поставки. Когда агентный контур быстро растет, обычные ошибки остаются обычными ошибками: секреты в репозитории, небезопасные subprocess, SQL без параметризации. OWASP регулярно напоминает, что сложность интеграций сама по себе увеличивает площадь риска; хороший ориентир — OWASP Top 10, 2021, https://owasp.org/www-project-top-ten/.
Как понять, что у вас уже integration sprawl
Я использую простой чек-лист. Если на 3 и более пункта ответ “да”, стек уже пора упрощать:
- У каждого инструмента агента отдельные credentials и отдельный owner
- Вы не можете за 10 минут восстановить полный trace одного ответа
- Поиск в интернете и поиск по внутренним данным логируются в разных местах
- При падении внешнего поиска агент не умеет деградировать предсказуемо
- Никто не может быстро перечислить, какие домены агенту вообще разрешены
Если это про вас, не добавляйте 6-й MCP-сервер. Сначала сведите поверхность системы к одному gateway и одной модели наблюдаемости.
FAQ
MCP — плохая идея?
Нет. Плохая идея — бесконтрольное размножение MCP-серверов без общей policy layer, трассировки и владельца эксплуатации. Протокол полезен, когда он встроен в управляемую архитектуру.
Когда отдельные MCP-серверы все-таки оправданы?
Когда у вас разные trust boundary, разные команды и разные требования по изоляции. Но даже тогда нужен единый audit trail и общий контракт наблюдаемости.
Можно ли обойтись без веб-поиска?
Во многих B2B-процессах — да, если достаточно RAG по внутренним данным. Веб-поиск нужен там, где данные быстро меняются или решение зависит от внешнего контекста.
Почему не отдать все в один SaaS?
Иногда это разумно для старта. Но в regulated среде вы быстро упираетесь в вопросы residency, auditability и контроля доступа, поэтому единый управляемый стек часто лучше, чем случайный набор удобных сервисов.
Что важнее: latency или auditability?
В production нужны оба. Но если выбирать, в regulated рынках я сначала обеспечиваю объяснимость и контроль, а потом оптимизирую P95.
Где у вас сегодня ломается агентный контур сильнее всего: в трассировке tool calls, в деградации внешнего поиска или в управлении секретами между MCP-серверами? Я правда хочу это понять на реальных production-кейсах.
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.