После этой инструкции у вас будет датасет из 12 рабочих кейсов в Data table, ветка оценки, которая гоняет их через тот же воркфлоу без публикации наружу, четыре детерминированные метрики, одна оценка редакторского качества от модели-судьи и три числовых порога, по которым решение «выпускать или нет» принимается за минуту, а не за час спора.
Коротко.
- Восемь шагов, а не одна нода. Датасет → Evaluation Trigger → гейт побочных эффектов → Set Outputs → Set Metrics → судья → запуск → порог. Пропуск третьего шага стоит дороже всех остальных вместе.
- 12 кейсов, по 3 на каждый тип. Этого хватает, чтобы поймать регресс, и мало настолько, чтобы прогон занимал двадцать минут.
- Метрика в n8n — всегда число. Булево приводится к 1/0, редакторское качество даёт модель-судья по четырём критериям с шагом 0.25.
- Гейт формулируется до прогона. Наш:
compliance_pass ≥ 10/12, среднийeditorial_score ≥ 0.75, ни одного кейса с нулём источников. - Реальный прогон 26 августа 2026 года: 11/12 по соответствию правилам, средняя оценка 0.8073, минимум источников 1. Вердикт PASS, один кейс провален на запрещённом слове.
Зачем вообще нужны evals, чем они отличаются от зелёного статуса выполнения и что из этого доступно на каком тарифе — разобрано отдельно в статье «Evals для AI-контента в n8n». Здесь я не повторяю ни рассуждение, ни таблицу тарифов, ни каталог встроенных метрик. Здесь только руки: как это собирается в конкретном воркфлоу и какие числа получаются на выходе.
Пример не учебный. Это генератор постов для Telegram-канала отраслевого мероприятия: оператор задаёт тип поста и тему, воркфлоу собирает исследование по внешним источникам, пишет текст, прогоняет его через редактора и гуманизатор, проверяет на запрещённые формулировки и отправляет на утверждение. Четыре типа поста, разная длина, разная структура. Ровно та задача, где «посмотрим глазами» перестаёт работать после третьего прогона.
Как это работает: шесть строк концепции
Механика Evaluations в n8n короткая, и её стоит держать в голове целиком.
Датасет — это таблица, где каждая строка описывает один тестовый вход. Evaluation Trigger читает эту таблицу и отправляет строки через воркфлоу по одной, последовательно. Воркфлоу выполняется целиком, тот самый, что работает в бою, — не копия. Нода Evaluation с операцией Set Outputs записывает результат обратно в ту же строку датасета. Нода Evaluation с операцией Set Metrics превращает результат в числа. Вкладка Evaluations сводит числа по всем строкам в одну сводку и даёт провалиться внутрь любого кейса.
Источник по параметрам и операциям: Evaluation Trigger и Evaluation в документации n8n, обращение 6 сентября 2026 года.
Цикл оценки: строка датасета проходит через рабочий воркфлоу, результат возвращается в ту же строку, метрики сворачиваются в сводку прогона.
Важное следствие из «тот же воркфлоу»: всё, что воркфлоу делает наружу, он попытается сделать и на тестовом прогоне. Отправить сообщение в канал, списать кредит за картинку, дёрнуть платный API. Поэтому третий шаг ниже — не опция.
Шаг 1. Датасет: 12 строк, три на каждый тип
Датасет живёт в Data table. Создаётся она в проекте, колонки задаются при создании, дальше строки можно править прямо в интерфейсе или загружать из воркфлоу. Наша таблица называется eval_dataset и содержит девять колонок.
| Колонка | Что кладём | Зачем |
|---|---|---|
test_id | E01…E12 | Стабильный идентификатор кейса между прогонами |
post_type | news, explainer, digest, forum | Определяет ветку генерации и ожидаемую структуру |
topic | Тема поста строкой | Основной вход, то же самое пишет оператор в бою |
section | Номер тематического раздела каталога или пусто | Проверяем и привязанные к разделу кейсы, и свободные |
depth | standard или quick | Два режима исследования — оба должны работать |
period | неделя для дайджестов, иначе пусто | Окно сбора новостей |
expected_min_chars | 900 / 1500 / 1800 / 700 | Нижняя граница длины для типа |
expected_max_chars | 1800 / 3000 / 3200 / 1500 | Верхняя граница длины для типа |
rubric_notes | Текстовая заметка для судьи | Что именно считается хорошим ответом в этом кейсе |
Три кейса на каждый из четырёх типов — это минимум, при котором один плохой прогон не утаскивает весь тип в красное, и максимум, при котором вся оценка укладывается в двадцать минут. Внутри типа кейсы намеренно разные: один с привязкой к разделу и глубоким исследованием, один быстрый, один без раздела вовсе.
Одна строка целиком выглядит так:
{
"test_id": "E11",
"post_type": "forum",
"topic": "Малотоннажная химия: зачем производителю идти на отраслевой форум",
"section": 5,
"depth": "quick",
"period": null,
"expected_min_chars": 700,
"expected_max_chars": 1500,
"rubric_notes": "Пост должен ссылаться на реальную сессию из повестки, связанную с химией, и заканчиваться призывом к действию с хэштегом форума."
}
Кейсы берутся из рабочего потока, а не сочиняются. Все двенадцать тем — реальные запросы, которые оператор уже отправлял в воркфлоу руками. Идеальный придуманный пример проверяет, что система работает на идеальном придуманном примере, и больше ни на чём.
Путь одной строки: девять колонок входа проходят через воркфлоу и возвращаются пятью полями результата и девятью метриками.
Шаг 2. Evaluation Trigger: точка входа для оценки
Evaluation Trigger — отдельный триггер, который живёт в воркфлоу рядом с боевым. Параметр Source по умолчанию стоит в Data table, дальше выбирается сама таблица по имени или идентификатору. У нас это eval_dataset — и на этом настройка триггера заканчивается.
Есть два параметра, которые пригодятся на отладке. Limit Rows ограничивает число обрабатываемых строк — при включении задаётся Max Rows to Process. Filter Rows отбирает строки по значениям колонок. Пока вы отлаживаете саму ветку оценки, гоняйте одну строку: смысла жечь двенадцать полных генераций, чтобы увидеть опечатку в выражении, нет.
Строки идут через воркфлоу по одной, последовательно.
Шаг 3. Check If Evaluating: гейт побочных эффектов
Это шаг, который экономит вам репутацию.
Операция Check If Evaluating у ноды Evaluation не имеет параметров вовсе. Она даёт два выходных коннектора: один срабатывает, когда текущее выполнение — это оценка, второй — когда обычный прогон. Всё, что нельзя делать на тесте, вешается на вторую ветку.
В нашем воркфлоу этот гейт собран на признаке источника запуска: строка, пришедшая из Evaluation Trigger, несёт метку source: 'eval', и по ней Switch отсекает три вещи — отправку черновика в Telegram на утверждение, генерацию иллюстрации и публикацию в канал. Ветка оценки не делает ни одной из них. Изображение при этом не пропускается молча: в объект записывается image_skip_reason: 'eval', чтобы в разборе было видно, что картинки не было по замыслу, а не из-за сбоя. Если собираете с нуля, берите операцию Check If Evaluating — она даёт то же ветвление без собственного поля.
Забытый гейт — это двенадцать сообщений в живом канале. И, если в воркфлоу есть платная генерация изображений, двенадцать списанных кредитов за картинки, которые никто не увидит. Проверьте ветку до первого полного прогона, а не после.
Тот же принцип мы разбирали в материале о паттернах n8n: побочный эффект должен быть отделён от вычисления явной нодой, а не подразумеваться. Оценка просто делает эту границу обязательной.
Шаг 4. Set Outputs: что вернуть в датасет
Операция Set Outputs у ноды Evaluation записывает поля обратно в строку датасета. Формально это то же самое, что light evaluation — прогон с записью результата, — но нужен он и в полной схеме: без записанных выходов вы получите числа без текста, а разбирать провал по одному числу невозможно.
Секция Outputs — это список пар «имя — значение». У нас пять:
html = {{ $json.html }}
length = {{ $json.length }}
source_count = {{ ($json.sources_used_final || []).length }}
compliance_pass = {{ $json.compliance_pass }}
violations = {{ ($json.violations || []).join(" | ") }}
Две детали здесь не косметические.
|| [] перед обращением к массиву обязателен. Ветка, где источников не нашлось вовсе, вернёт undefined, и выражение .length на нём уронит ноду — а вместе с ней и всю строку прогона. Кейс, который должен был показать «ноль источников», вместо этого покажет ошибку выполнения, и вы потеряете ровно тот сигнал, ради которого затевали проверку.
violations склеивается в строку через |. Массив в ячейке датасета читается плохо, а одна строка с разделителем открывается глазами и ищется поиском.
Шаг 5. Set Metrics: четыре детерминированные метрики
Метрика в n8n — всегда число. Операция Set Metrics даёт секцию Metrics to Return с парами «имя — значение», пять встроенных вариантов и Custom Metrics для своих. Встроенные пять разобраны в концептуальной статье; нам нужны свои, потому что ни одна из встроенных не отвечает на вопрос «этот пост можно публиковать».
Первая нода Set Metrics считает то, что считается арифметикой, без всякой модели:
length_ok = {{ ($json.length >= $json.expected_min_chars
&& $json.length <= $json.expected_max_chars) ? 1 : 0 }}
cyrillic_ratio = {{ $('Route Output').first().json.cyrillic_ratio }}
source_count = {{ $json.source_count }}
compliance_pass = {{ $json.compliance_pass ? 1 : 0 }}
Все четыре объявлены с типом number — иначе метрика не попадёт в сводку.
length_ok — булево, приведённое к 1/0. В сводке по двенадцати кейсам среднее такой метрики читается как доля попаданий в вилку: 0.92 значит «один кейс вылез». Тот же приём работает для любой проверки «да/нет», и это самая дешёвая метрика из всех — она ничего не стоит и ловит целый класс регрессов, когда модель начинает писать длиннее или короче обычного.
cyrillic_ratio тянется из именованной ноды через $('Route Output'). Доля кириллицы в тексте — сторож против сваливания в английский, которое случается, когда исследование принесло много англоязычных источников и модель подхватила их регистр.
compliance_pass — результат отдельной проверки на запрещённые формулировки, стоп-слова и обязательные элементы. Она детерминированная и работает в бою тоже; оценка просто делает её видимой на всех двенадцати кейсах разом.
Шаг 6. LLM-as-judge: редакторская оценка как число
Длина, доля кириллицы и стоп-слова не отвечают на вопрос, хорош ли текст. На него отвечает вторая нода Set Metrics, которая забирает результат работы модели-судьи.
Судья — отдельный вызов Claude Sonnet с собственным промптом. На вход он получает запрос оператора, дайджест исследователя как источник истины по фактам и итоговый текст поста. Оценивает четыре критерия, каждый от 0 до 1 с шагом 0.25:
| Критерий | Что оценивает | Что даёт 0 |
|---|---|---|
fidelity | Фактическую верность дайджесту: каждый факт, число и название прослеживаются в исходных материалах | Выдуманные факты или ссылки |
register | Научно-популярный регистр для занятых профессионалов | Рекламный или школьный тон |
structure | Соответствие структуре заданного типа поста и длине, заголовок по сути, ссылки на месте | Структура не та |
naturalness | Отсутствие признаков машинного текста: шаблонные вводные, тройные перечисления, одинаковые начала абзацев | Текст читается как сгенерированный |
Итоговый score — среднее четырёх. Одно правило стоит отдельно: пост со fidelity = 0 получает score = 0 независимо от остального. Красиво написанный текст с выдуманным фактом хуже, чем средний текст с проверяемыми фактами, и шкала должна это признавать явно, а не усреднять.
Ответ судьи — только JSON, без обёртки markdown, с пятью числовыми полями и одним текстовым worst_problem на одно предложение. Строгий формат нужен потому, что выход парсится нодой; свободный текст здесь ломает всё.
Вторая нода Set Metrics выкладывает пять чисел:
editorial_score // среднее четырёх критериев, 0–1
judge_fidelity // 0–1, шаг 0.25
judge_register
judge_structure
judge_naturalness
Четыре подкритерия нужны не для красоты. Когда общая оценка проседает, они показывают, куда именно: падение naturalness при живом fidelity — это про промпт гуманизатора, падение fidelity — про исследование. Одно число такого различия не даёт.
Судья — тоже модель, и он тоже шумит. Между двумя прогонами без изменений в промптах отдельные кейсы сдвигаются примерно на 0.06 в обе стороны — это обычная дисперсия судьи. Планируйте порог с запасом и считайте материальной только ту дельту, которая заметно больше шума: у нас граница проведена по 0.10.
Отдельно про редакторский просмотр: судья не заменяет человека, он расставляет очередь. Тексты с оценкой 0.875 читаются по диагонали, тексты с 0.625 читаются целиком. Как это уживается с ручной правкой стиля, разобрано в материале про гуманизацию AI-текста.
Шаг 7. Запуск и чтение результатов
Прогон запускается из вкладки Evaluations кнопкой Run Test. Дальше вы смотрите на сводку по всем строкам и проваливаетесь в любой кейс.
Ниже — реальный прогон от 26 августа 2026 года, пятый по счёту в проекте и контрольный: он проверял, не испортило ли текст новое обязательное поле в промпте писателя и слой устойчивости к сбоям, добавленные после четвёртого. Все двенадцать кейсов завершились успешно.
| Кейс | Тип | Длина | Источники | Соответствие | Оценка |
|---|---|---|---|---|---|
| E01 | news | 1564 | 10 | ✅ | 0.8125 |
| E02 | news | 1547 | 8 | ✅ | 0.875 |
| E03 | news | 1172 | 1 | ✅ | 0.625 |
| E04 | explainer | 2758 | 11 | ✅ | 0.875 |
| E05 | explainer | 2746 | 10 | ✅ | 0.875 |
| E06 | explainer | 2971 | 9 | ✅ | 0.875 |
| E07 | digest | 2488 | 5 | ✅ | 0.875 |
| E08 | digest | 2274 | 7 | ✅ | 0.8125 |
| E09 | digest | 2735 | 7 | ❌ | 0.8125 |
| E10 | forum | 1338 | 5 | ✅ | 0.8125 |
| E11 | forum | 1236 | 8 | ✅ | 0.75 |
| E12 | forum | 1132 | 9 | ✅ | 0.6875 |
editorial_score по 12 кейсам, прогон r5 (26 августа 2026 года)
Редакторская оценка по двенадцати кейсам против порога 0.75 (на шкале диаграммы — 75 %). E09 — единственный провал по соответствию правилам, E03 и E12 — единственные, кто ушёл ниже порога по качеству.
Читается таблица за минуту, и она сразу задаёт три вопроса.
E09 провалил соответствие. В violations записано: запрещённая формулировка «инновационный». Ровно тот класс ошибки, ради которого детерминированная проверка и существует: слово из стоп-листа проскочило в текст поста, ни один человек его бы не заметил на беглом чтении, а редакционная политика канала его запрещает.
E03 — самая низкая оценка при формально нормальной длине. Причина видна в соседней колонке: один источник. Исследование в этот день принесло тонкий результат по теме, и судья честно снизил fidelity. Это не поломка воркфлоу, это поломка входных данных — и правильная реакция здесь не править промпт, а посмотреть на тему.
E12 даёт 0.6875 при формально девяти источниках — реально одном, об этом ниже. Тип forum — самый сложный: пост должен опираться на повестку мероприятия, а не на внешние новости, и модель регулярно сбивается на общие слова. Два из трёх самых слабых кейсов прогона — этого типа, и в предыдущем прогоне два самых слабых тоже были forum. Это устойчивая картина, а не случайность.
Шаг 8. Production gate: три числа вместо спора
Гейт формулируется до прогона, а не подгоняется под результат. Наш выглядит так:
| Критерий | Порог | Факт прогона | Итог |
|---|---|---|---|
compliance_pass | ≥ 10 из 12 | 11 из 12 | PASS |
Средний editorial_score | ≥ 0.75 | 0.8073 | PASS |
Кейсы с source_count = 0 | 0 | 0 (минимум — 1) | PASS |
Три порога и фактические значения прогона: соответствие правилам, среднее качество и наличие хотя бы одного источника в каждом кейсе.
Логика порогов простая. Соответствие правилам — не 12/12, потому что стоп-лист живой и одно попадание не должно блокировать релиз; но и не 8/12, потому что два провала подряд — это уже тенденция. Средняя оценка 0.75 — нижняя граница профессионально приемлемого текста. Нулевых источников не допускается вовсе: пост без опоры на источник — это не слабый пост, это другой продукт.
Дальше гейт работает как выключатель. Все три зелёные — изменение едет в бой. Любой красный — не едет, и разбирается конкретная строка. Ценность здесь не в самих числах, а в том, что они названы заранее: спор «достаточно ли это хорошо» переносится с момента релиза на момент проектирования, когда никто никуда не спешит.
Что мы узнали за пять прогонов
Метрика меряет ровно то, что вы в неё положили выражением. Поле source_count в трёх кейсах показывало число найденных источников, а не число реально оставшихся в тексте после обрезки: функция проверки считала правильное значение для своего предупреждения, но не клала его в возвращаемый объект. В таблице выше у E10, E11 и E12 стоят 5, 8 и 9, а фактически использованный источник в каждом из них один — как и у E03, который показывал единицу честно. Гейт это не пробило — минимум по прогону всё равно 1, а не 0, — но картина «один тонкий кейс из двенадцати» на самом деле была «четыре тонких кейса из двенадцати». Метрика была честной ровно настолько, насколько честным было выражение.
Дрейф судьи — это норма, а не сигнал. Между четвёртым и пятым прогоном средняя оценка сдвинулась на 0.0054, семь кейсов из двенадцати сдвинулись на 0.0625–0.125 в обе стороны. Единственная дельта, которую стоило разбирать, — минус 0.25 на E03, и у неё нашлась внятная причина во входных данных. Порог материальности в 0.10 оставил для разбора один кейс из семи.
Регресс ловится там, где его не ждёшь. Пятый прогон затевался, чтобы проверить, не испортило ли текст новое обязательное поле в промпте писателя и слой устойчивости к сбоям. Ответ — не испортило. Но тот же прогон показал провал по стоп-слову, никак не связанный с изменением. Оценка на двенадцати кейсах — это не проверка одной гипотезы, это регулярный снимок состояния.
Частые ошибки
Одна оценка на воркфлоу. В n8n нельзя настроить несколько независимых оценок в одном воркфлоу. Если нужно оценивать разные участки по отдельности, они выносятся в подворкфлоу и оцениваются каждый в своём. Источник: «Fix common issues», документация n8n, обращение 6 сентября 2026 года.
Второй триггер в воркфлоу. Когда рядом с боевым триггером появляется Evaluation Trigger, у воркфлоу две точки входа с разной формой данных. Ветки сводятся нодой Edit Fields (Set), которая приводит их к одному виду, и затем No-op, после которой идёт общая логика.
Разброс результатов между прогонами. Если метрики скачут, продублируйте строки датасета: один и тот же вход, прогнанный несколько раз, усредняет вариативность модели. Это дороже по времени, но честнее, чем делать выводы из одного прогона.
Тестовый прогон уходит наружу. Самая дорогая из всех — и единственная, которая не чинится задним числом. Гейт на Check If Evaluating ставится раньше, чем первая метрика.
Датасет из идеальных примеров. Если кейсы подобраны так, чтобы воркфлоу их проходил, прогон всегда зелёный и всегда бесполезен. В датасете должны быть темы, на которых система уже спотыкалась.
Порог, придуманный после прогона. Числа, подогнанные под полученный результат, не гейт, а его имитация. Формулируйте до, фиксируйте письменно, меняйте осознанно и с датой.
Ключевые тезисы
- •Оценка гоняет боевой воркфлоу целиком, поэтому первое, что нужно сделать, — отрезать побочные эффекты нодой Check If Evaluating.
- •12 кейсов, по 3 на каждый тип задачи, — рабочий минимум: ловит регресс и укладывается в двадцать минут прогона.
- •Метрика в n8n всегда число: булево приводится к 1/0, редакторское качество даёт модель-судья по четырём критериям с шагом 0.25.
- •Правило «fidelity = 0 обнуляет всю оценку» важнее самой шкалы: красивый текст с выдуманным фактом не должен усредняться до проходного.
- •Гейт формулируется до прогона. Наш: соответствие правилам ≥ 10/12, средняя оценка ≥ 0.75, ни одного кейса без источников.
- •Проверяйте выражения метрик отдельно от логики: поле, которое считалось правильно, но не попало в результат, в трёх кейсах показывало завышенное число источников.
Вопросы и ответы
Сколько кейсов нужно в датасете для старта?
Как не отправить тестовые результаты в продакшн во время оценки?
Чем LLM-as-judge отличается от встроенных метрик Correctness и Helpfulness?
Что делать, если прогон не проходит гейт?
Если вам нужен такой контур оценки в вашем n8n-пайплайне — на ваших кейсах, ваших запрещённых формулировках и вашем пороге приёмки, — напишите на agent@kelva.tech или оставьте заявку. Разберём на реальных прогонах вашей команды: как это выглядит на потоке кейсов и материалов, показано в статье про производство кейсов агентства.
