Тихие отказы в ИИ-пайплайнах: почему зелёный статус контейнера врёт и как мы срезали 90% расхода на LLM
Запасная ветка в блоке catch без отдельного счётчика и алерта маскирует полный отказ системы: новый агентный конвейер из трёх моделей не отработал в продакшне ни разу за несколько месяцев, пока CLI зависал на пустых OAuth-конфигах MCP-серверов. Постановка детерминированного предфильтра заголовков и триграммного дедупликатора перед вызовом LLM и генерацией медиа отсекла 76,5% информационного шума и сократила ежедневные расходы на API примерно на 90% (со 100+ до 22 вызовов за прогон). Использование DEFAULT 0 вместо DEFAULT NULL при миграции колонки рейтинга молча выкинуло из выдачи 678 качественных статей, а цикл сна перед первым запуском фоновой задачи обнулял обновление курсов валют при каждом деплое.

Самый дорогой класс багов в автономных ИИ-системах — это не падение с красным трейсбеком, а тихий отказ (silent failure). Контейнер в docker ps светится статусом Up, крон завершается с кодом 0, статьи выходят в ленту — а новый код, на который ты потратил неделю, в реальности не выполнился ни одного раза.
Именно это произошло в моём новостном ИИ-конвейере после переезда со связки n8n + Airtable на собственный серверный стек (40 часов миграции, MIGRATION.md на 600+ строк для сохранения контекста между сессиями). Я собрал цепочку из трёх агентов (EditorAgent, WriterAgent, QAAgent) и обернул её в аккуратный try / catch с переключением на старый AIProcessor.
Почему блок catch с запасной веткой маскирует пятиярусный отказ месяцами?
Поскольку запасная ветка исправно выпускала материалы, внешне система выглядела здоровой. Лишь спустя несколько месяцев я заметил в логах регулярную строку Agent pipeline failed. Falling back to AIProcessor. Когда мы начали снимать слои этого отказа (сессия потребовала 1 320 сообщений и 517 запусков субагентов), под капотом обнаружилась матрёшка из пяти причин:
- Короткоживущий токен авторизации CLI протухал каждые несколько часов.
- Настройка
timeoutпринималась конструктором базового агента, но не пробрасывалась в дочерний вызов. - Тяжёлая модель на этапе кураторства не укладывалась в лимит времени на больших пачках (перевод на более быструю модель ускорил шаг в 3–4 раза).
- Обновлённый бинарник CLI перестал принимать устаревший флаг
--max-tokens. - Внутри контейнера CLI намертво зависал на строке
Fetched 4 servers, пытаясь инициализировать облачные MCP-коннекторы (Notion, Figma, Linear, Sentry) с пустыми OAuth-конфигами.
Урок железный: любой fallback без отдельного счётчика и алерта — это не отказоустойчивость, а маскировка аварии. Точно так же статус Up у контейнера не ловит внутренний Python-скрипт в краш-лупе по SyntaxError на 98% CPU: настоящая проверка — стабильный PID старше 60 секунд и прогон python3 -m py_compile.
Как перестановка фаз пайплайна и триграммный дедуп экономят 90% бюджета на модели?
Вторая ревизия вскрыла финансовую дыру: из 3 235 обработанных новостей в публикацию шло 340, но дорогие вызовы LLM, обложки и озвучка (TTS) выполнялись до финального отсева (88% бюджета сгорало впустую, а дублирующийся crontab дёргал сборщик 288 раз в сутки вместо 48). Мы поставили перед моделью бесплатный предфильтр на регулярках и весах источников (100+ паттернов на EN/RU/ZH, где для иероглифов без пробелов используется includes() вместо \b):
``javascript function scoreArticle(title, sourceName) { let score = 0; const t = (title || '').toLowerCase(); const s = (sourceName || '').toLowerCase(); if (SOURCE_TIERS.tier1.some(x => s.includes(x))) score += 4; else if (SOURCE_TIERS.tier2.some(x => s.includes(x))) score += 3; let kw = 0; for (const rx of AI_KEYWORDS) { if (rx.test(title)) kw++; } score += Math.min(kw, 4); if (AI_COMPANIES.some(c => t.includes(c))) score += 2; if (title && title.length > 20) score += 1; if (/\d/.test(title)) score += 1; return score; } ``
Этот фильтр отсекает 76,5% входящего шума за ноль токенов. Поиск дублей мы перевели с LLM на гибрид коэффициента Жаккара по триграммам и расстояния Левенштейна (снизив порог Жаккара для русской морфологии с 0,65 до 0,40 со сверкой сущностей). Расход на API упал на 90% (со 100+ до 22 вызовов за прогон), а чистка сиротских медиа освободила 4,9 ГБ (1 764 картинки и 1 398 аудио).
Почему DEFAULT 0 в миграции базы и sleep перед первым прогоном прячут данные?
Третий тихий отказ стоил месяца поисков: при добавлении колонки ALTER TABLE ... ADD COLUMN hot_score INTEGER DEFAULT 0 все 678 старых статей получили оценку 0, и SQL перестал отличать «ещё не считали» от «получили ноль». Переход на DEFAULT NULL и бэкфилл вернули в выдачу 581 статью, утроив одобренную базу с 341 до 943. Рядом нашлись забытый LIMIT 5 в выборке оркестратора и пропущенное поле audio_path в SELECT, прятавшее 2 244 готовых аудиофайла на 6 ГБ (69% базы). Наконец, фоновая задача курсов валют начиналась с await asyncio.sleep(86400) до первого запуска и при ежедневных деплоях не сработала ни разу (вылечено FIRST_RUN_DELAY_S = 90 и last_success_at), а проверка статики через curl по коду 200 на SPA-конфиге nginx получала index.html вместо пропавших PDF.
Эти инварианты наблюдаемости встроены в платформу Nomad AI и облачный рантайм agent.nomadnet.ai. Практикум по отладке автономных пайплайнов доступен в Hamidun Academy (72-часовой триал), а аудит-скрипты лежат в Vibe Club.
- 8 июл. 2026 г.ИИ-агенты молчат об ошибках: 6 паттернов отказов в автоматизации
- 8 нояб. 2026 г.GPT-6 Astra тихо саботировал safety-задачи: на 40% хуже при той же сложности
- 22 апр. 2026 г.Wired: редакции тайно внедряют AI-помощников для написания статей — и молчат о последствиях
- 5 июл. 2026 г.AI-персонализация в ритейле: как данные меняют опыт покупателя в реальном времени
Вопросы и ответы по материалу
Почему блок catch с запасной веткой маскирует пятиярусный отказ месяцами?
Поскольку запасная ветка исправно выпускала материалы, внешне система выглядела здоровой. Лишь спустя несколько месяцев я заметил в логах регулярную строку Agent pipeline failed. Falling back to AIProcessor. Когда мы начали снимать слои этого отказа (сессия потребовала 1 320 сообщений и 517 запусков субагентов), под капотом обнаружилась матрёшка из пяти причин: Короткоживущий токен авторизации CLI протухал каждые несколько часов.
Как перестановка фаз пайплайна и триграммный дедуп экономят 90% бюджета на модели?
Вторая ревизия вскрыла финансовую дыру: из 3 235 обработанных новостей в публикацию шло 340, но дорогие вызовы LLM, обложки и озвучка (TTS) выполнялись до финального отсева (88% бюджета сгорало впустую, а дублирующийся crontab дёргал сборщик 288 раз в сутки вместо 48).
Почему DEFAULT 0 в миграции базы и sleep перед первым прогоном прячут данные?
Третий тихий отказ стоил месяца поисков: при добавлении колонки ALTER TABLE ... ADD COLUMN hot_score INTEGER DEFAULT 0 все 678 старых статей получили оценку 0, и SQL перестал отличать «ещё не считали» от «получили ноль». Переход на DEFAULT NULL и бэкфилл вернули в выдачу 581 статью, утроив одобренную базу с 341 до 943. Рядом нашлись забытый LIMIT 5 в выборке оркестратора и пропущенное поле audio_path в SELECT, прятавшее 2 244 готовых аудиофайла на 6 ГБ (69% базы).
Соберите рабочего ИИ-агента или сервис своими руками без ручного кода
В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.
Главное из мира ИИ — раз в неделю
7 ключевых событий недели, отобранных вручную. Без шума, репостов и пресс-релизов.
Готово! Проверьте почту — мы отправили подтверждение.