Дисклеймер: в статье упоминается Meta — организация, признанная экстремистской и запрещённая на территории РФ. Статья — не прогрев и не реклама курсов/самопиар и пр.. Все логи, цифры и скрины — из реальных прогонов тестового аккаунта.
Всем привет! В финале прошлой статьи я обещал разбор Reasoning Lock — того самого бага, где рассуждающая модель тратит токены и отвечает пустотой. Разбор готов, правки в воркфлоу заказчика встают в бой, и я хочу выпустить его с живой метрикой, после нескольких дней наблюдений в проде за тем, как изменения работают. А пока счётчик тикает, публикую из бэклога мини — историю, которая созрела ещё в двадцатых числах августа — в разгар фурора вокруг загадочной stealth‑модели. Фурор уже стих, но эксперимент от этого хуже не стал: за три дня стелс‑модель «навайбкодила» воркфлоу на 127 нод, который реально ходит по API, генерирует медиа и публикует Reels. Ниже я покажу архитектуру, код, честный список косяков модели и моих собственных, и экономика эксперимента. Постараюсь вкратце и по существу.)
Цель, так сказать, эксперимента — нагрузочное тестирование свежей LLM в роли кодера на сложном распределённом пайплайне: пять внешних API, бинарные потоки, три десятка условий ветвления, асинхронные поллинги — и всё в одном воркфлоу! Сейчас на западном рынке бум автономных связок в духе «скрапинг‑генерация фото/видео‑автопостинг». Я сам контентом не занимаюсь — мне интересны пайплайны и отказоустойчивость. Но задача подходит как идеальное ТЗ!)
И тут совпало: с 20 по 25 августа на OpenRouter открылся бесплатный доступ к загадочной модели stealth/ox‑alpha. Позже она деанонизировалась — FAQ OpenRouter это официально подтверждает: это Z.ai, GLM 5.3 Flash (z‑ai/glm-5.3-flash в селекторе Cline). Расклад по ней такой: контекст 1М токенов, нативная мультимодальность (текст, картинки, видео на вход), заявка от Z.ai “efficient coding and long‑horizon agent tasks” — всё вы про это читали и знаете). Релиз состоялся 26 августа, то есть стелс‑окно дало неделю игры до официального анонса. Большой контекст, нулевая цена. Я открыл VS Code, запустил Cline и закинул ТЗ на полноценный медиа‑конвейер в n8n.
За три дня (с 21 по 23 августа) ушло 60,9 млн токенов — 85,3% из них кеш‑хиты, итоговый счёт по blended‑цене $0,07/1M составил около $4. Суть что на выходе — воркфлоу на 127 нод (изначально 156, потом рефакторил), который реально ходит по API, генерит медиа и публикует Reels. Ниже — архитектура, код, честный список косяков модели и моих собственных, и экономика эксперимента.
ТЗ: не «сделай мне хайповые и залётные рилсы», а «ты — senior n8n solutions architect»
Все тут понимают что LLM — это не волшебник/экстрасенс. Банальное правило: чем точнее вход — тем меньше галлюцинаций на выходе. Поэтому в Cline я прописал не «придумай автопостинг с алертами в телеграм», а максимально (вроде как)) структурированный бриф с итерациями. Сокращённая версия реального промпта стала такой:
ROLE You are a senior n8n solutions architect. You produce production-ready, importable n8n workflow JSON. You never invent API parameters or node fields; when unsure, you say so explicitly. PROJECT CONTEXT БЭКЛОГ: «AutoContent-Factory v1.0» — автономный конвейер ИИ-аналитики трендов, генерации мультимедиа и автопостинга в Instagram на базе self-hosted n8n. КОНТУРЫ: 1 — парсинг конкурентов (ScrapeCreators API), формула виральности 1.5 — семантический фильтр (LLM-reranker, порог релевантности) 2 — AI-диспетчер (строгий JSON: сценарий/промпт видео/caption) 3 — мультимодальная генерация (видео/голос/обложка через OpenRouter) 5 — автопостинг (Instagram Graph API) API FACTS (from official docs) - 1 credit = 1 request; cache hits = 0 credits - GET /v1/instagram/user/reels — метрики БЕЗ caption - GET /v2/instagram/media/transcript — 10–30 s, timeout >= 60 s - HTTP 402 = out of credits; 5xx = transient RULES One contour per message. No secrets. Defensive JS (try/catch, null-checks). If ambiguous — ask ONE clarifying question.
Оглашу ключевыеприёмы, которые сэкономили мне нервы:
Роль вместо просьбы. «Senior‑архитектор» меняет тон генерации: модель пишет defensively, а не разговорно — упрощенно.
Явно запрещено выдумывать параметры. Нет уверенности — скажи и добавь в список «VERIFY MANUALLY».
Итерации по контурам. По одному контуру за сообщение — модель не путается в зависимостях.
Output Contract = Один JSON‑блок + инструкции по импорту + список сомнительных параметров.
Единственное что забыл дать модели по задачам, в самом конце сборки готового воркфлоу — так это детальную техническую документацию. Так бы и статью написал более детальнее и проще!:‑)

Архитектура воркфлоу: 5 контуров, 127 нод

Честная арифметика воркфлоу, чтобы никто не пересчитывал за меня: 127 = 113 нод в пяти контурах (23 + 17 + 17 + 37 + 19) + 2 входных триггера (Schedule и Manual) + 4 disabled‑заглушки под будущие итерации + 8 стикеров‑документации. Рабочих нод, соответственно, 115: 113 контурных + 2 триггера. Подробнее поясню каждый контур:
1 ‑й контур: назовём «Разведка» (23 ноды)
Схема такая: Schedule (24ч) — список конкурентов — Reels через ScrapeCreators — математика виральности: views > avg × 2.5 — тег TRENDING — для трендовых дотягиваются caption (/v1/НЕЛЬЗЯgram/post) и транскрипт (/v2/instagram/media/transcript, таймаут 60с; null — caption‑only). Пока список конкурентов — статические тестовые хендлы: для реального внедрения подставляются желаемые ниши.
Контур 1.5: назовём «Семантический фильтр» (17 нод)
LLM-reranker оценивает релевантность в выбранной нише (я выбрал по автоматизации на n8n) по шкале 0–1. На роль реранкера я выбрал Qwen3 Reranker 8B через chat/completions. В его промпт зашит рубрикатор с живыми примерами: «Строим LLM‑агента в n8n для обработки заявок» = 0.95 (core ниша), «Как настроить ChatGPT» = 0.75 (AI productivity), ИИ в целом = 0.5–0.69, смежное (саас бизнес) = 0.2–0.49, личные влоги = 0.0–0.19. Всё ниже порога улетает в тупик Drop: Below Threshold. Без этого контура данная «фабрика» генерировала бы контент по случайно залетевшему личному влогу автора контента.
2 ‑й контур: AI‑диспетчер (17 нод)
Модель не копирует чужой пост! Зачем штамповать однотипный контент. Она «выжимает ДНК виральности» (хук, триггер, формат, призыв) и собирает оригинальную идею. Выход — строгая JSON‑схема: angle, hooks, voice_script (120–160 символов), video_prompt, НЕЛЬЗЯgram_caption. Валидный черновик падает в Google Sheets со статусом DRAFT.
3- й контур: медиа‑цех (37 нод)
Видео:seedance-2.0-mini с фулбэком на veo-3.1-lite, асинхронный поллинг (Wait 10s × 20 попыток). Голос: TTS отдаёт сырой PCM, который конвертится в WAV на лету. Конфиг в «Clean Voice Script» рассказывает о себе ещё одну вещь: флаги ARCHIVE_TO_DRIVE=false и MUSIC_ENABLED=false — это эконом‑конфиг: seedance-2.0-mini/ 480p/ 5s с фолбэком на veo-3.1-lite. Обложка: image‑generation с неоновым тех‑вайбом. Всё с ретраями, варнингами и статусами MEDIA_READY / MEDIA_FAILED.
Последний контур: дистрибуция (19 нод)
Внутри — ещё один сюрприз: склейка видео с голосом через ffmpeg (Write -Exec -Read в /tmp). Голос опционален: нет голоса = видео уходит как есть под ключом final_mp4. Плюс у контейнера Instagram свой поллинг FINISHED - Wait 5s * 12.
Google Drive (upload + share publicly) — Instagram Graph API (контейнер REELS — publish) — permalink — обновление Sheets — отчёт в Telegram.
Диспетчер статусов на Google Sheets
Чтобы 127 нод не запутались, на каком этапе находится каждый ролик, я не стал городить сложную базу данных, а сделал простой диспетчер статусов прямо в Google Таблицах.

Рефакторинг ради стабильности: было 156 — стало 127
Первая версия собиралась по принципу «если соберёт воркфлоу — то лишь бы работало» и раздулась до 156 нод. Минус 29 за пару вечеров:
дублирующиеся error‑ветки сведены в единый паттерн
Failed? → 402? → alert / fail-open;Честности ради: в списке
disabled - reserve-нода Search google, которую стелс‑модель напланировала «на будущее» и которую я не стал удалять. Пусть лежит.)все медиа‑конфиги и модели вынесены в одну
Code-ноду (Clean Voice Script)вместо россыпиSet-нод;убраны промежуточные хэндоф‑заглушки от старых версий архитектуры.
Раскладка по типам нод:
Тип | Количество | Зачем |
IF (условия) | 30 | ошибки, 402, статусы, наличие бинарников |
Code (JS) | 28 | парсинг, нормализация, PCM в WAV, конфиги |
Telegram | 12 | алерты на каждый критический сбой |
HTTP Request | 11 | все внешние вызовы |
NoOp | 11 | точки передачи между контурами + тупики дропов |
Sticky Note | 8 | документация прямо на канвасе |
LangChain | 6 | 2 агента + 2 модели + 2 structured‑парсера |
Google Sheets | 4 | статистика: append + 3 update |
StopAndError | 4 | жёсткий стоп при 402 |
Триггеры | 3 | Manual, Schedule, ExecuteWorkflow‑триггер (disabled) |
Disabled‑заглушки | 3 | 2 ноды scrapeCreators, Call “Hunter_Media” *P. S. Воркфлоу я назвал Hunter content = отсюда и названия контуров |
Set | 2 | финальные выходы контуров 1 и 1.5 |
Google Drive | 2 | upload + share publicly |
SplitInBatches | 1 | цикл по хендлам |
Wait | 1 | поллинг видео (10s) |
НЕЛЬЗЯagram (community) | 1 | публикация Reels |
Можно чётко увидеть, что больше трети нод — это защитная логика. Это в принципе осознанная цена автономности.
Теперь как говориться, инженерная нутрянка
Жемчужина: PCM — WAV на лету
TTS‑модель отдаёт сырой PCM (24 кГц, 16 бит, mono) без контейнера — ни n8n, ни НЕЛЬЗЯgram такой поток не понимают. Модель сгенерировала Code‑ноду, пришивающую корректный RIFF‑заголовок:
function wavHeader(len) { const sr = 24000, ch = 1, bits = 16; const b = Buffer.alloc(44); b.write('RIFF', 0); b.writeUInt32LE(36 + len, 4); b.write('WAVE', 8); b.write('fmt ', 12); b.writeUInt32LE(16, 16); b.writeUInt16LE(1, 20); b.writeUInt16LE(ch, 22); b.writeUInt32LE(sr, 24); b.writeUInt32LE(sr * ch * bits / 8, 28); b.writeUInt16LE(ch * bits / 8, 32); b.writeUInt16LE(bits, 34); b.write('data', 36); b.writeUInt32LE(len, 40); return b; } const pcm = await helpers.getBinaryDataBuffer(i, 'voice_mp3'); const wav = Buffer.concat([wavHeader(pcm.length), pcm]); bin.voice_mp3 = await helpers.prepareBinaryData(wav, 'voice.wav', 'audio/wav');
Я перепроверил каждый байт: 44-байтный заголовок — все вычисляются, а не хардкодятся, и используются правильные binary‑helpers n8n, а не наивное item.binary.data
Static Data: аккумулятор цикла без дублей
Логика сбора трендов: крутим цикл по хендлам в нише, бережно копим данные в static data воркфлоу, а на выходе вычитываем этот буфер, чистим его и до кучи делаем финальную дедупликацию по URL:
// внутри цикла: const sd = $getWorkflowStaticData('global'); sd.acf_trending = sd.acf_trending || []; sd.acf_trending.push(...$input.all().map(i => i.json)); // после цикла: const rows = sd.acf_trending || []; sd.acf_trending = []; // состояние не течёт между запусками const seen = new Set(); return rows.filter(r => { const key = r.post_url || r.shortcode; if (seen.has(key)) return false; seen.add(key); return true; }).map(r => ({ json: r }));
402 не равно 5xx: две разные смерти сервиса
Система различает между «сервис временно умер» и «кончились у.е.». Универсальная проверка, которую модель штампует в каждой error‑ветке:
const e = $json.error || {}; const sc = Number($json.statusCode || e.statusCode || e.status || 0); const msg = String(e.message || ''); const is402 = sc === 402 || msg.indexOf('402') !== -1;
Политика в данной схеме такая: 402 = алерт в Telegram + StopAndError (штамповать ретраи без денег бессмысленно); 5xx — retry помноженное на 3 = fail‑open: хендл пропускается, конвейер живёт. Отвал TTS не убивает рилс просто уйдёт без голоса, с warning в таблице.
Формула виральности в коде — не магическое число в условии, а именованная константа:
```javascript // Phase 1: average views per handle; views > avg * 2.5 => tag TRENDING. const TREND_MULTIPLIER = 2.5; ```
Под неё — defensive-обёртка pickNumber(), вытаскивающая счётчик просмотров из какой угодно формы ответа API.
Отдельная жемчужина — fail‑open нода реранкера. Если Qwen3 умер после трёх ретраев, всем документам присваивается нейтральный 0.5 = который порог 0.75 честно отсекает. Конвейер не ломается: он просто тихо пропускает раунд. Комментарий в ноде это признаёт дословно: «0.5 < MIN_RELEVANCE_SCORE (0.75), so the filter drops them; pipeline stays healthy».
Финальный мерджер бинарников
HTTP‑ноды в file‑режиме стирают бинарники из $input. stealth/ox‑alpha сама предложила вытягивать их напрямую из нод‑производителей, минуя текущий поток:
function grabBinary(nodeNames, keys) { for (const n of nodeNames) { try { const bin = ($(n).first() || {}).binary || {}; for (const k of keys) if (bin[k] && (bin[k].data || bin[k].fileName)) return bin[k]; } catch (e) {} } return null; } const vid = grabBinary(['Fetch Video'], ['video_mp4', 'video', 'data']); const voi = grabBinary(['PCM to WAV', 'Generate Voice'], ['voice_mp3']); const cov = grabBinary(['Download Cover', 'Normalize Cover'], ['cover_png']);
Где модель тупила и мои собственные затупы
Без этого подраздела статья была бы наверное в стиле пресс‑релиза, так что вот самы краткий список «болячек» (хотя как понимаете на 60 млн. токенов их было уйма):
Косяки модели:
require(‘crypto’)в Code‑ноде. В n8nrequireнедоступен — пришлось душить Cline переписывать на встроенные функции.Google стирает бинарники. Google Drive нода возвращает только свой json, и голос/видео терялись после апдейта строки. Родилась
нода Rebuild Handoff Item, восстанавливающая item из нод — производителей.Фантомные ноды. Пару раз в JSON приезжали
type/typeVersion, которых нет в нынешней версии n8n — сверял вручную.Хардкод
IG_USER_ID.Модель не догадалась вынестиID в credentials— в коде торчит константа. Для теста ок, для запуска — выносить в env.
Где я сам накосячил (выловил только на ручном аудите):
Порог реранкера разъехался. В стикере‑документации
MIN_RELEVANCE_SCORE = 0.75, а вIF-нодена время отладки стоит>= 0.4— и я честно забыл вернуть. Поймал себя на том самом"одном и том же релевантном рилсе каждый день". Вывод: конфиг должен жить в одном месте, а не в стикере и в ноде раздельно.Поллинг видео 20 помножить 10с. В часы пик очереди
Veo/Seedanceмогут быть длиннее —MAX_ATTEMPTSпридётся поднять.
А теперь пример затупов/косяков, и почему это не провал:

Видео не сгенерировалось = драфт не потерян, помечен MEDIA_FAILED. Публикация не прошла = алерт с причиной и ссылкой на Drive для ручной загрузки. Мелочь для внимательных: Telegram съел подчёркивания, и в сообщении красуется "MEDIAFAILED" — можно считать это бесплатной цензурой маркдауна.
Реальный запуск воркфлоу в цифрах: сколько это ест ресурсов

Скажу честно: когда я запускал этот тест (ведь ждал в конце хоть и кривую копеечную генерацию), то реально скрестил пальцы)). Ожидания оправдались: лог выполнения (Execution) выдал заветный зеленый статус!)))
Для тех, кто крутит тяжелую автоматизацию, эти цифры на скрине — самый сок:
Время выполнения (4м 13сек): Для сквозного процесса, где внутри сидят генерация видео через API (с постоянным поллингом статуса), озвучка от Gemini и кастомная склейка байтов, четыре минуты с копейками — это отличный результат. Основное время, понятное дело, уходит на ожидание ответов от серверов генерации.
Потребление памяти (8 MB): Весь запуск огромной махины сожрал всего 8 мегабайт. Помните наш трюк с пакетной сборкой трендов в
$getWorkflowStaticData('global')вместо раздувания стандартного контекста внутри цикла? Вот это и есть главное доказательство того, что оптимизация сработала. Мы не держим тяжелые бинарники в оперативной памяти n8n, благодаря чему сервер чувствует себя прекрасно и не улетает в Out of Memory.
А вот и результат в профиле


Рилс ушёл в публикацию через Graph API: в таблице статус PUBLISHED с permalink, у поста дата «3 дн.». Цепочка отработала целиком: скрапинг — реранкер — диспетчер — медиа‑цех — Drive — НЕЛЬЗЯgram. Поясню: это тестовый прогон на тестовом аккаунте — целью была проверка воркфлоу, а не сбор просмотров(!). Факт: текст, обложка, видео и публикация сгенерированы цепочкой; я лишь нажал ExecuteWorkflow.
Экономическая сторона: 60,9 млн токенов за примерно 4 у.е.

Вопрос возникает сходу: почему так дёшево?! Во‑первых, stealth‑окно было бесплатным. Во‑вторых, итерактивная разработка в Cline — это перечитывание одного и того же контекста, и prompt кэшинг превращает 85% запросов в кэш‑хиты.
Сразу закрою ожидание: это не обзор модели по бенчмаркам — таких с релиза вышло десяток, и все пересказывают одни и те же таблицы. Здесь 127 нод, живой тестовый НЕЛЬЗЯagram и счёт в долларах за реальные прогоны.
И факты по модели после деанона: Z.ai GLM 5.3 Flash — нативная мультимодальность (текст, картинки, видео на вход), контекст 1М токенов, релиз 26 августа. Цены сейчас: $0.075/$0.25 за 1M (in/out) при скидке Z.ai −50% до 9 сентября, кэш‑рид $0.015. И вишенка из статистики: по объёму токенов в топ-3 приложений модели входит Cline — тот самый, через который это всё и «навайбкодилось».
Сколько бы стоил такой объём на платных моделях (по самой верхней таксе, 90/10 input/output). Да, модели в таблице не по принципу «топ под задачу»! Честно‑ я просто ткнул пять моделей из разных ценовых категорий каталога OpenRouter, чтобы показать вилку. Это сравнение ценников, которые я посчитал по среднему, а не бенчмарк.
LLM | Цена за 1M (in/out) | Оценка за 60,9M |
Anthropic: Claude Opus 4.8 | $5 / $25 | около 426$ |
OpenAI: GPT-5.6 Terra | $2 / $12 | около 183$ |
Anthropic: Claude Sonnet 5 | $2 / $10 | около 171$ |
Qwen: Qwen3.8 27B | $0,35 / $2,75 | около 36$ |
DeepSeek: V3.1 Terminus ( единственный минус упомяну что у модели контекст всего 164К.) | $0,27 / $1 | около 21 $ |
stealth/ox‑alpha + кэш | $0,07 | около 4$ |
То есть формально, если говорить про именно LLM из таблицы, то все пять под задачу «агентный кодинг марафон» подходят по позиционированию, разница — в ценовой категории и размере окна. Единственная реальная оговорка что 164K у DeepSeek против проделанных мега сессий. И да, парадокс, который можно подчеркнуть: бесплатная загадочная модель построила фабрику, которая крутится на копеечных DeepSeek, Gemini-flash и seedance, которые жгут центы за публикацию.
Итоги
Модель — это джуниор разраб с энциклопедической памятью и нулевым опытом. Защитный код (
defensive-парсинги, fail-open, корректная бинарная арифметика) она выдаёт только тогда, когда защитный код запрошен в ТЗ. Мой промпт — не магия, а чёткие инструкции.Бенчмаркине показывают главное. Анонимная stealth‑модель бесплатно вытянула в принципе стабильную сборку с пятью API, бинарниками и асинхронщиной — это проверяется только спустя наверное с пару десятков запусков воркфлоу.
Отказоустойчивость — это наверное фишка номер 1. Ведь, блин, согласитесь, что
ценность не в том, что конвейер работает, когда всё работает, а в том, что он не теряет данные, когда всё падает!)
Зоны роста воркфлоу
От себя, могу в теории предложить развитие данного проекта (если бы это был реальный кейс) примерно в таком направлении:
разбор монолита на три воркфлоу
(Radar / Generate / Publish),Telegram‑бот с
human-in-the-loopуправлением («Опубликовать / Перегенерировать»)ветка нейроаватара ( модель, к примеру,
HeyGen: Avatar IVнедавно вышедшая — хорошо подойдёт на эту роль);
Вместо заключения
Из каждого угла сейчас можно прочитать: «...ИИ заменит программистов и ИТшников все, просто скажи „сделай мне сайт“...». Этот эксперимент = аргумент против. Модель за три дня сожгла 60,9 млн токенов, чтобы получилось то, что получилось: отличную заготовку, требующую ручного аудита каждого порога, каждой ноды, каждого байта заголовка WAV. «Сделай мне сайт» она бы сожгла за вечер — вместе с продакшеном. Заменит не ИИ. Заменит человек, который научился им пользоваться, тем же, кто умел пользоваться компилятором и Stack Overflow. Инструмент новый. Профессия та же: отвечать за результат.