← Назад к блогу

локальные модели

Completion gate для локальных моделей: как проверить результат до оценки качества

Как разделить завершённость, детерминированные проверки и человеческую приёмку, чтобы технический обрыв не превращался в ошибку качества.

Плоская редакционная композиция на тёплом светлом фоне: один синий артефакт проходит через три разные полупрозрачные зоны проверки. Под ними остаются три отдельных следа — целый контур, выборочные внутренние отметки и янтарный отпечаток человеческого решения.

Локальная модель может вернуть правильный JSON, пройти схему и получить десять принятых результатов из десяти. Эти признаки ещё не отвечают на вопрос, пригодна ли её работа аналитику.

Сначала нужно доказать, что модель произвела целый результат, который вообще можно оценивать. Затем внешний код проверяет согласованные свойства артефакта. После этого человек решает, соответствует ли результат исходной задаче. Если смешать эти стадии в одну метрику, технический обрыв, ошибка содержания и человеческий отказ становятся одинаковыми нулями.

Для разделения этих состояний я добавил в контур оценки completion gate — проверку завершённости перед измерением качества.

Материал основан на работе с локальными моделями для Подмастерья аналитика (AnalystCraft Coworker), AI-напарника системного аналитика в Аналитической мастерской. Цель эксперимента состояла не в поиске «лучшей модели вообще». Нужно было понять, какая связка модели, запроса, схемы, среды исполнения и внешних проверок подходит для конкретных рабочих ролей.

Что такое completion gate

Completion gate — это набор проверок, который отвечает на один вопрос: существует ли полный результат, пригодный для последующей оценки?

Проверка не определяет качество анализа и не принимает работу за человека. Она отделяет завершённые артефакты от ответов, которые оборвались, не разбираются, нарушают обязательную структуру или состоят из заглушек.

Без такого фильтра система может поставить содержательный ноль ответу, который модель не успела закончить. Получается ложный вывод о качестве: инфраструктурный сбой записывают как неспособность модели понять задачу.

Обратная ошибка тоже возможна. Валидный ответ проходит схему, хотя вместо документов содержит пути к будущим файлам или текст «раздел будет добавлен позже». Форма существует, а рабочего результата нет.

Поэтому система запускает completion gate до оценки качества:

controlled sources
  → artifact contract
  → completion gate
  → deterministic checks
  → human acceptance
  → role routing decision

Каждая стадия сохраняет свою причину отказа. Тайм-аут не превращается в ошибку анализа, ремонт формата не исчезает из отчёта, а зелёный тест не становится автоматическим разрешением на выпуск.

Почему обычная оценка модели не отвечает на продуктовый вопрос

Публичные тесты моделей полезны для первичного отбора. Они сравнивают знания, способность рассуждать, писать код или следовать инструкции. Продуктовый контур задаёт более узкий вопрос: выполнит ли проверяемая конфигурация конкретную работу на конкретных входных данных?

В случае Подмастерья результатом служит не реплика в чате. Система должна подготовить связанные аналитические артефакты:

  • source map, или карту источников;
  • System Context Pack (SCP) с границами системы, фактами и ограничениями;
  • Review Findings с противоречиями, пробелами и рисками;
  • Task Pack для передачи проверенной постановки в реализацию.

Каждое значимое утверждение должно вести к источнику. Неизвестное остаётся неизвестным. Если два документа описывают разные способы авторизации, система показывает конфликт и не выбирает удобный вариант без основания.

Рабочая последовательность метода выглядит так:

Sources → Project-local RAG → System Context Pack → Review Findings → Task Pack → Export

Подмастерье помогает аналитику быстрее собрать контекст, увидеть слабые места и подготовить проверяемый черновик. Решение остаётся за человеком.

Контур оценки для такого сценария обязан проверять не красоту ответа, а производство этих артефактов и сохранение границ между фактами, конфликтами и решениями.

Сначала нужно зафиксировать источники

Результат нельзя воспроизвести, если набор входных данных меняется между прогонами. Поэтому оценка начинается с controlled sources, то есть с зафиксированного набора документов, кода, переписки и ожидаемых конфликтов.

Для каждого сценария нужны:

  • идентификатор и версия набора данных;
  • хэш входных файлов;
  • ожидаемые факты и известные противоречия;
  • перечень данных, которые модель не должна раскрывать;
  • неизвестные значения, которые нельзя достраивать по шаблону;
  • человек, который утвердил эталонный ответ.

Последний пункт важен. Если автор результата одновременно определяет ожидаемый ответ, пишет тест и оценивает прохождение, одна неверная интерпретация может повториться во всех слоях проверки.

Контролируемые источники не гарантируют правильность эталона. Они делают ошибку локализуемой: становится видно, какую версию входа использовала система и какое ожидание нужно пересмотреть.

Artifact contract: контракт результата модели

Следующий слой задаёт контракт результата. В упрощённом виде модель должна вернуть один объект с четырьмя документами:

{
  "artifacts": {
    "source_map": "# Source Map\n...",
    "scp": "# System Context Pack\n...",
    "review_findings": "# Review Findings\n...",
    "task_pack": "# Task Pack\n..."
  }
}

JSON Schema проверяет наличие ключей и типы значений. Этого мало. Следующий объект формально проходит простую схему:

{
  "artifacts": {
    "source_map": "output/source_map.md",
    "scp": "output/scp.md",
    "review_findings": "output/review_findings.md",
    "task_pack": "output/task_pack.md"
  }
}

Парсер видит четыре строки. Аналитик не получает ни одного документа.

Другой ответ может содержать заголовки и общие обещания:

{
  "artifacts": {
    "source_map": "# Source Map\nИсточники будут перечислены позже",
    "scp": "# System Context Pack\nКонтекст описан в материалах",
    "review_findings": "# Review Findings\nРиски требуют проверки",
    "task_pack": "# Task Pack\nТребования необходимо реализовать"
  }
}

Такой результат непустой, но пользоваться им нельзя. Контракт должен проверять не только типы, но и минимальные признаки существующего артефакта: содержимое находится внутри ответа, обязательные разделы заполнены, заглушки отсутствуют, ссылки на доказательства имеют допустимый формат.

Как устроена воронка завершённости

Я сохраняю прохождение как последовательность состояний:

started
  → endpoint_completed | timeout | crash | out_of_memory
  → output_present
  → parseable
  → schema_valid_first_pass
      ↘ deterministic_repair → schema_valid_after_repair
  → artifacts_present
  → artifacts_non_placeholder
  → quality_eligible
  → quality_passed | quality_failed
  → accepted_by_human | rejected_by_human

Состояния до quality_eligible описывают завершённость. Затем начинаются проверки содержания. Финальный переход принадлежит человеку, который отвечает за исходную задачу.

Такой журнал сохраняет различия:

СостояниеЧто известноКакой вывод преждевременен
timeoutрантайм не завершил запрос вовремямодель не понимает задачу
parse_failedответ нельзя разобрать по контрактусодержание ответа неверно
schema_valid_after_repairвнешний код восстановил допустимую формумодель прошла контракт самостоятельно
quality_failedцелый артефакт нарушил проверяемое требованиеинфраструктура не работает
accepted_by_humanответственный человек принял результат в этом сценариимодель универсально подходит для роли

Для отчёта нужны отдельные знаменатели: сколько запусков началось, сколько завершилось, сколько прошло схему с первой попытки, сколько потребовало ремонта, сколько дошло до оценки качества и сколько принял человек.

Одна строка pass rate: 80% скрывает причины отказа и не помогает выбрать следующий эксперимент.

Детерминированные проверки подтверждают согласованные свойства

После completion gate внешний код проверяет артефакт. Модель не должна сама выставлять себе итоговую оценку.

Контрактные проверки отвечают за форму:

  • обязательные документы присутствуют;
  • ответы разбираются по схеме;
  • заглушки и пути вместо содержимого запрещены;
  • каждый артефакт проходит минимальную проверку полноты.

Сценарные проверки отвечают за наблюдаемое поведение:

  • при одном источнике система не выдумывает конфликт;
  • при двух несовместимых версиях API показывает обе и создаёт открытый вопрос;
  • неизвестное поле не достраивает из правдоподобного шаблона;
  • конфиденциальный фрагмент не попадает в запрещённый вывод;
  • Task Pack связывает требование с конкретным доказательством.

Детерминированная проверка тоже может быть неверной. Она способна подтвердить наличие четырёх заголовков и пропустить пустой текст. Может искать точное слово и отклонить содержательно верную формулировку. Может воспроизвести то же ошибочное понимание задачи, из которого агент построил ответ.

Поэтому зелёный тест подтверждает соответствие согласованному правилу. Он не доказывает, что правило выражает потребность пользователя.

Human acceptance: человеческая приёмка после автоматической проверки

Человеческая приёмка связывает технические доказательства с исходным пользовательским результатом.

Ответственный человек проверяет:

  1. Критерий был определён до появления результата.
  2. Проверки относятся к согласованному сценарию, а не только к удобным свойствам реализации.
  3. Все отклонения и ремонты видны.
  4. Ограничения результата понятны людям, которые будут его использовать.
  5. Остаточный риск принял тот, у кого есть соответствующие полномочия.

Один человек иногда пишет критерий и принимает результат. Роли всё равно полезно разделять логически: исполнитель показывает воспроизводимые доказательства, а владелец исхода принимает или отклоняет работу.

AI готовит заготовку, мастер проверяет и принимает решение. Это и есть Подмастерье аналитика.

Что изменил completion gate в сохранённых данных

Здесь важно не объединять разные эксперименты в одну линию «раньше было хуже, теперь стало лучше».

Старая состязательная матрица и Benchmark v2 используют разные сценарии и разные метрики. Значение 59,7% относилось к оценке качества на одном сценарии старой матрицы. Оно не было долей пройденных сценариев.

Позже появился Benchmark v2 с десятью рабочими ролями: быстрый черновик, общий анализ, поиск пробелов, скан конфликтов, подготовка Task Pack и обработка длинного документа. Результат 10/10 означает число принятых сценариев, включая случаи после ограниченного ремонта. В этот набор не вошли некоторые состязательные проверки старой матрицы: подмена инструкций, утечка конфиденциального и специально подготовленное противоречие.

Поэтому 59,7% нельзя сравнивать с 10/10 или переводить в «59,7% против 100%». Это разные вопросы, наборы и знаменатели.

Статус чисел

Значения ниже сверены с пятью первичными JSON-файлами Benchmark v2 и повторного прогона completion gate. Контрольные суммы файлов зафиксированы в пакете доказательств. У набора остаётся ограничение: записи Benchmark v2 содержат outputPreview, а не полные ответы моделей.

В сохранённой сводке повторный прогон completion gate для одного исторического сценария содержит 21 запись. Четыре записи дошли до состояния quality_eligible, а 17 оказались незавершёнными или повреждёнными.

Этот результат нельзя описывать как рост качества. Completion gate изменил знаменатель: система перестала считать тайм-ауты, оборванные ответы и повреждённые объекты содержательными провалами.

Сводка Benchmark v2 содержит три маршрута:

МаршрутПринятоМедианаРемонты среди принятых
Qwen-only10 из 1028,9 с3
Bonsai 8B-only10 из 1099,1 с2
смешанный маршрут10 из 1071,0 с1

Эта таблица не выбирает победителя.

Во-первых, «принято» включает ремонты. Таблица измеряет связку модель + контракт + внешний ремонт, а не модель в изоляции.

Во-вторых, ролевой набор не содержит всех состязательных сценариев старой матрицы. Прохождение десяти ролей не доказывает устойчивость к подмене инструкций или утечке данных.

В-третьих, предварительные семантические значения 0,82, 0,87 и 0,88 рассчитаны по сохранённым фрагментам ответа. Полные ответы именно этих запусков не сохранились. Поэтому значения годятся для выбора следующего прогона, но не для вывода о превосходстве маршрута или полноценной оценки качества ответов.

Наконец, речь идёт об отдельных сохранённых запусках. Они не показывают стабильность между повторами и чувствительность к версии запроса, схемы, модели или рантайма.

Зачем маршрутизировать модели по ролям

Одна универсальная модель упрощает эксплуатацию, но рабочие роли предъявляют разные требования.

Для черновика важны скорость и способность держать контракт. Небольшая модель может подготовить первый вариант, если следующие стадии обнаруживают пропуски и не позволяют автоматически выпустить результат.

Поиск конфликтов требует удерживать несколько версий решения, цитировать основания и сохранять неопределённость. Такой этап может оправдывать более медленный маршрут.

Task Pack связывает требования, открытые вопросы и доказательства. Здесь заполненная схема без трассировки создаёт ложное чувство готовности.

Контрактные проверки и ограниченный ремонт формата лучше выполнять внешним детерминированным кодом. Человеческая приёмка остаётся отдельной стадией.

Рабочая гипотеза выглядит так:

быстрый черновик
  → Qwen-route

поиск пробелов и конфликтов
  → Bonsai-route

проверка формы и обязательных доказательств
  → deterministic checks

ограниченный ремонт допустимого формата
  → bounded deterministic repair

решение о пригодности результата
  → проверка мастера

Смешанный маршрут пока остаётся гипотезой. Один сохранённый прогон потребовал меньше ремонтов, но работал медленнее Qwen-only. Для продуктового решения нужно сравнить стоимость и задержку на принятый результат в серии одинаковых прогонов.

Что должен хранить воспроизводимый прогон

Название модели и итоговый балл не позволяют повторить эксперимент. Для каждого сценария нужно сохранять:

  • идентификаторы прогона, профиля, датасета и сценария;
  • точный артефакт модели, квантование и хэш версии;
  • версию рантайма и параметры генерации;
  • версии запроса и JSON Schema;
  • хэш входных данных;
  • полный исходный и разобранный ответы;
  • количество входных и выходных токенов;
  • тайм-аут, падение процесса и нехватку памяти как разные события;
  • ошибки разбора и схемы;
  • тип ремонта и число попыток;
  • результат completion gate;
  • результаты детерминированных проверок;
  • решение человека и причину отказа;
  • наблюдаемое время и потребление памяти.

Полные входы и ответы могут содержать проектные данные. В открытый отчёт попадают агрегаты, хэши и обезличенные примеры. Исходные артефакты остаются в защищённом хранилище.

Повторный запуск создаёт новый run_id, а изменение схемы или запроса создаёт новую версию профиля. Перезапись неудачного результата лишает эксперимент проверяемости.

Какие проверки нужны дальше

Текущий срез доказательств формирует план эксперимента, но не закрывает выбор маршрута.

Одинаковые полные ответы

Qwen-only, Bonsai-only и смешанный маршрут должны пройти одинаковые сценарии с одними версиями входа, запроса и схемы. Для каждого запуска нужен полный ответ.

Повторяемость

Один запуск показывает возможность. Серия повторов показывает стабильность и распределение задержки, ремонтов и человеческих отказов.

Состязательные сценарии

В ролевой набор нужно вернуть подмену инструкций, утечку конфиденциального, конфликт версий, числовую согласованность и молчаливый пробел.

Стоимость принятого результата

Маршруты следует сравнивать по суммарному времени, числу ремонтов, повторным вызовам и доле результатов, которые принял человек. Цена первого вызова не описывает стоимость рабочего результата.

Верхняя граница локального контура

Отдельный эксперимент должен показать, какие сценарии укладываются в рабочую станцию, а какие требуют другого развёртывания. Private cloud пока остаётся непроверенной гипотезой.

Чек-лист перед сравнением локальных моделей

Перед следующим запуском я проверяю семь условий:

  1. Зафиксирована точная связка модели, квантования, рантайма, запроса, схемы и оборудования.
  2. Завершённость, качество и человеческая приёмка представлены разными состояниями.
  3. Система хранит полные исходные ответы и все ремонты.
  4. Для каждой метрики указан знаменатель.
  5. Маршруты проходят одинаковые сценарии.
  6. Набор содержит сложные и состязательные случаи.
  7. У результата есть человек, который принимает решение и отвечает за его использование.

Completion gate не улучшает модель. Он устанавливает границу, после которой результат можно честно оценивать. Контролируемые источники делают вход воспроизводимым. Контракт артефакта задаёт форму работы. Детерминированные проверки подтверждают согласованные свойства. Человек принимает результат. Только после этого маршрутизация по ролям становится инженерным решением, а не красивой таблицей с несопоставимыми числами.