
Мы разрабатываем CV-системы (машинное зрение для производств). А ещё мы принимаем на поддержку решения, которые для нас делают подрядчики. Подрядчики присылают нам документацию, и дальше начинается бюрократический ад.
Это наша общая боль, которая на протяжении двух лет медленно, но верно подтачивала боевой дух команды. Эта боль — проверка документации. Это не брошюра, это увесистый документ на десятки страниц. В нём описаны функциональные и нефункциональные требования к системе, бизнес-метрики, ожидания по точности, сроках и способах её измерения, формат сдачи отчётности и многое другое. Наша задача — провести ревью этого ТЗ и отчётной документации.
Это непохоже на ревью кода. Это похоже на рутинный чек-лист потому, что есть все разделы, есть все базовые критерии, числа друг другу не противоречат и так далее. И это должны делать очень дорогие специалисты — вместо реальных задач.
Количество итераций проверки одного документа — от 2 до 5. Серьёзно. Формулировки бывают настолько запутанными, что приходится писать кучу уточняющих вопросов.
Ещё есть ТЗ на разметку, там вообще становится понятно, почему Скайнет восстал. Например, надо обвести все надписи на вагоне. А если там мелом написано ХУZ, это должно попасть в распознавание? И вот инженеры сидят и принимают такие решения по каждой мелочи.
Заставлять инженера, который может писать сложнейшие алгоритмы, по три дня вычитывать по шаблону один и тот же документ — это жестокая история. Правда, очень важная. Просто ничего не делать — не получится.
Мы взялись это автоматизировать LLM’ками, но должны были избежать рисков, связанных с передачей информации о наших внутренних процессах на третью сторону и по галлюцинациям. И ещё пару, сейчас расскажу, что вышло.

Фото камер, установленных на весовом пункте, с которых поступают данные для распознавания номеров вагонов.
Второй тип задачи — разметка данных
Разрабатываем любую систему — сначала пишем ТЗ. Когда подрядчик разрабатывает для нас алгоритмы, он присылает нам ТЗ на разметку данных. Это инструкция для людей-аннотаторов, которые будут вручную обводить на картинках нужные нам объекты. Качественное ТЗ на разметку — это когда у разметчика не возникает ни одного вопроса, он не допускает ошибок и чётко понимает, что делать в любой, даже самой спорной ситуации.
Представьте, задача — разметка номеров на железнодорожных вагонах. Вроде всё просто: видишь цифры — выделяй. А что делать, если на вагоне есть другие надписи, другие циферки? Их выделять? А как быть, если цифра видна нечётко, затёрта или одна напечатана поверх другой? Я не уверен, это тройка или всё-таки восьмёрка. Как мне её выделить? Все эти моменты должны быть досконально описаны, с примерами и иллюстрациями.
Проверка всей этой кипы бумаг происходила вручную. И это никогда не заканчивалось одной итерацией. Никогда. Мы пишем комментарии, отправляем. Подрядчик что-то исправляет, что-то упускает, присылает обратно. Мы снова проверяем. Иногда можем «раскатать губу», ожидая, что во второй раз придут с исправленным, но нет — по второму кругу повторяем те же самые замечания.
Для инженеров это была абсолютно рутинная, демотивирующая работа. На дашборде у нашего руководителя есть специальный виджет, который показывает соотношение типов задач. Есть прямая взаимосвязь: как только доля вот этой «бумажной» работы ползёт вверх, мотивация команды стремительно падает.
А ведь команда должна быть счастлива. Иначе о перформансе можно забыть.



Не заменить человека, а снять с него первые две итерации боли
У нас не было цели полностью заменить ревью инженера. Даже если попытаться, это того не стоит. Понимание нетривиальных моментов, знание специфики конкретной задачи — это всегда останется за человеком. Мы хотели автоматизировать рутину: проверку базовых шаблонов, наличия всех разделов, отсутствия явных противоречий. Основная задача была — снять с нас первые две, самые мучительные итерации проверки. Чтобы инженер получал документ, уже очищенный от очевидных, шаблонных ошибок, и мог сразу сфокусироваться на сути.
LLM бесконечно терпеливы. Они могут объяснить не очень хорошо понимающему подрядчику, что нужно. Подробно, с примерами, с возможными формулировками, с ссылочками и визуальными маркерами.
Идея родилась в обсуждениях с командой. У нас демократия, иногда даже либеральная история. Как-то раз руководство закинуло мысль об автоматизации, её подхватили.
Но мы не знали, что делать с галлюцинациями.
Галлюцинации
Мы не стали обучать модель с нуля. В компании уже была развёрнута инфраструктура с несколькими LLM-архитектурами, поднятыми в нашем внутреннем контуре. Это важно, потому что мы работаем с внутренними данными и не можем отправлять трафик куда-то наружу.
Наша главная задача была — правильно настроить модель и подготовить данные. И тут мы столкнулись с классикой жанра — галлюцинациями. В первых же тестах модель начала чудить. Она могла придумать что-то левое — в отчёте появлялась информация о требовании, которого в исходном документе просто не существовало.
Примеры галлюцинаций, которые возникали при проверке документов. В основном сеть изобретала новые требования и давала от себя рекомендации разной степени безумия вместо того, чтобы выдать сухой результат проверки непосредственно по озвученным критериям. Разительного негативного влияния на качество проверки это не оказывало, но создавало дополнительный объём информации, который нужно было пропускать через себя при изучении отчёта.

Сеть выдала рекомендацию попробовать конкретные архитектуры сетей для сегментации в ТЗ на разметку для одной из задач сегментации. Хотя сам документ по своей природе не описывает, какими методами будет производиться анализ изображений — он только описывает, что и как должно быть размечено человеком.

Сеть выдумала, что было бы полезно обращаться к целому специализированному отделу. О таком в требовании не говорится в принципе. Не хотите ли для консультаций создать и подключить к работе целый отдел для поддержки?
В какой-то момент модель начала выдавать отчёт на дикой смеси русского и английского. Она пишет на русском, а потом вставляет английские термины, причём не как цитату, а просто её глюкануло. «Смотря какой fabric смотря сколько details» — мы эти мемы потом подставляли к скриншотам, так похоже это было.

В процессе работы экспериментировали с сетями, некоторые комбинации архитектур и параметров иногда давали забавный эффект.
Ниже приведён фрагмент из списка рекомендаций, в котором сеть выдавала ответ, смешивая языки:
Рекомендация 1:
«Missing объяснения узкоспециальных терминов (например, поток ore, stones).Требуется добавить definitions терминов в раздел Introduction или отдельный subsection с пояснениями».
Рекомендация 2:
«Short описание задачи слишком brief и не explains цели annotation. Требуется expand описание задачи в 1–3 paragraphs, включив цель annotation (например, automation сортировки ore)».
Рекомендация 3:
«Attributes класса Ore (например, size камней) не перечислены в brief списке classes.Требуется include attributes класса в brief список classes в разделе Requirements к разметке».
Рекомендация 4:
«Missing contact лицо для уточнения details. Требуется add contact лицо в раздел General информация или Contacts».
3 – 3. Например, была проблема, что модель при оценке на соответствие критериям рассматривала атрибуты класса как отдельные объекты (например, класс «Яблоко» с атрибутом «Гнилое» превращался в два отдельных класса «Яблоко гнилое» и «Яблоко не гнилое»). Чтобы такое поведение исправить, prompt был дополнен следующим уточнением:
Response JSON format:{
"per_class_annotation_rules": [ #in this list only object classes should be listed as items, not object's properties or attributes - they should go into their corresponding class as in the structure
{...}
}
Такое уточнение позволило исправить проблему на всех документах.
Чем сильнее мы «затягиваем болты» в промпте, тем лучше результат.
Мы пошли двумя путями.
Во-первых, мы ввели многоэтапный анализ. Была проведена куча исследований в поисках разумного баланса между сложностью разрабатываемого решения и качеством получаемого отчёта о проверке, от простого заваливания LLM вопросами по документу до комплексных пайплайнов. В итоге мы остановились на простом, но эффективном для нашей задачи подходе: Вместо того чтобы скармливать модели весь документ с общей задачей «проверь всё», мы начали делить его на главы и для каждой главы составлять свой, узкоспециализированный запрос. Мы фокусировали её внимание: «Посмотри вот в этот блок, найди там вот это и проверь на соответствие вот этому». Ей больше не нужно было искать иголку в стоге сена по всему тексту.
Во-вторых, мы начали «учить» её на конкретных примерах хороших и плохих формулировок. У нас за два года скопился огромный архив документов с нашими правками. Это была наша нефть. Мы брали из него примеры и буквально показывали модели: «Смотри, вот это — плохо. А вот это — хорошо».
Классический пример — описание точности. Подрядчик пишет: «Точность сервиса должна быть 95%». Формально — число есть, требование есть. Но для меня как для инженера машинного обучения эта фраза не значит абсолютно ничего. Какая точность? На русском вроде слово одно, а на английском таких метрик n штук, да и считать одну и ту же метрику можно по-разному. Хорошая формулировка звучит так: «Количество найденных объектов относительно всех объектов (метрика полноты) должно быть 95% минимум». Вторая фраза даёт реальную методику измерения, которую можно проверить. И вот такие нюансы мы и объясняли модели, калибруя её понимание того, что для нас значат слова «понятное» и «измеримое».

Как сейчас работает
Сейчас наш процесс выглядит так. Инженер из нашей команды, ответственный за проект, берёт ТЗ от подрядчика. Никаких UI мы не делаем, нам комфортно работать с консолью. Он забирает наш скрипт из репозитория, запускает его, указав путь к файлу. Подрядчики, кстати, вообще не знают, что у них теперь есть автоматический проверяющий. Для них ничего не изменилось.


Как камера распознаёт номера вагонов
На выходе скрипт создаёт два файла.
Первый — «Рекомендации для разработчика». Это внешний, отполированный отчёт, который можно смело отправлять подрядчику. В нём чётко и по пунктам расписаны все недочёты с указанием на конкретные места в документе.
Второй файл — внутренний, наше «итоговое ревью». Он гораздо детальнее. Там расписано, по какому нашему внутреннему критерию шла проверка и почему модель сочла тот или иной пункт недоработанным. Эту кухню мы не показываем наружу, чтобы не началась игра в полицейского и нарушителя, когда документы начнут просто подгонять под наши чек-листы. Этот файл также помогает нам самим валидировать работу нейросети и отлавливать ложноположительные срабатывания или моменты, где она что-то пропустила.

Проекту сейчас около двух месяцев, он на этапе прототипирования. Первая версия, для проверки ТЗ на разметку, уже показала себя отлично. Уже готова вторая версия, для более сложных ТЗ на проекты. Сейчас ищем ту самую калибровку границ между достаточно и недостаточно. Я думаю, на полную стабилизацию решения и расширение на все типы документов, включая 100-страничные отчёты, у нас уйдёт ещё 12–16 месяцев.
Система лишь помогает, но именно специалист проверяет результат и отвечает за него. Потому, к сожалению, полностью убрать человека из задачи проверки документов не получится.
Осталось только проверить отчётную документацию на эту систему перед приёмкой её в эксплуатацию.
Отдельная благодарность моему руководителю, Насте Старобыховской @AnnGareeva. Тот самый человек, который всегда за команду и её интересы. Поэтому Настя принимала прямое участие в реализации этого проекта.
Комментарии (11)

beswalod
19.06.2026 06:10Ещё есть ТЗ на разметку, там вообще становится понятно, почему Скайнет восстал. Например, надо обвести все надписи на вагоне. А если там мелом написано ХУZ, это должно попасть в распознавание? И вот инженеры сидят и принимают такие решения по каждой мелочи.
Представьте, задача — разметка номеров на железнодорожных вагонах. Вроде всё просто: видишь цифры — выделяй. А что делать, если на вагоне есть другие надписи, другие циферки? Их выделять? А как быть, если цифра видна нечётко, затёрта или одна напечатана поверх другой? Я не уверен, это тройка или всё-таки восьмёрка. Как мне её выделить? Все эти моменты должны быть досконально описаны, с примерами и иллюстрациями.
Если в работе много нюансов, мелочей и деталей, как вы смогли создать инициирующий промт, который, скорее всего, представляет собой объёмный файл или даже несколько файлов? Типа как в такой работе можно учесть все детали, описать это для LLM и это не сожрёт всё контекстное окно? Как будто "если написано мелом ХУZ -- игнорируй", это скорее творческая человеческая работа, если даже инженеры "сидят и принимают решения по каждой мелочи". Или все эти мелочи уже давно известны и новых требований к ТЗ точно нет?

VP_AI Автор
19.06.2026 06:10>Если в работе много нюансов, мелочей и деталей, как вы смогли создать инициирующий промт, который, скорее всего, представляет собой объёмный файл или даже несколько файлов? Типа как в такой работе можно учесть все детали, описать это для LLM, и это не сожрёт всё контекстное окно?
Это на самом деле, наверное, было более времязатратной задачей, чем написать сам проверщик документов. Нужно было собрать все документы с требованиями по наполнению и оформлению (которые мы, естественно, передаём подрядчикам перед тем, как они начнут работу), собрать со всех коллег, которые работают с этим типом документов и занимаются их проверкой, всю информацию о возможных нюансах, и затем представить всё это в виде усвоябельного LLM перечня требований и критериев проверки. Постфактум я даже сделал «методичку» по составлению такого перечня для коллег из других отделов, которые захотят себе подобную систему. Эта методичка нескольких человек уже отпугнула. По поводу контекстного окна — сейчас оно уже не является такой проблемой, как пару лет назад. У современных LLM под наши задачи его хватает с большим запасом.
>Как будто «если написано мелом ХУZ — игнорируй», это скорее творческая человеческая работа, если даже инженеры «сидят и принимают решения по каждой мелочи».Да, всё так. Конкретно момент, который вы привели в цитате, является инструкцией от составителя размечающему и является примером краевого случая, который может возникнуть на объекте. Знание краевых случаев для каждого проекта, объекта и камеры делегировать LLM пока кажется так себе идеей. В задаче проверки ТЗ на разметку это знание от LLM и не требуется — требуется проверка на соответствие перечню требований, производится проверка по нюансам и моментам, которые извлекли из специалистов работающих с такими документами.
>Или все эти мелочи уже давно известны и новых требований к ТЗ точно нет?
Касательно новых требований — формат документа ещё до введения LLM в работу был зафиксирован, но если появится новая версия требований — соответственно их придётся обновить в промте. За время работы и проверки документов пронаблюдали большое количество ошибок и недоработок от подрядчиков, все моменты, которые удалось вспомнить, — зафиксировали в перечне для LLM. Я думаю, естественно, от них будут появляться новые приколы. Тогда придётся дорабатывать промпты.

karikov
19.06.2026 06:10Именно поэтому аналитики занимаются подобными задачами, а не инженеры за дофига денег.

ksbes
19.06.2026 06:10Бывают такие АНАЛитики, что ещё хуже LLMок. Там уже не галюцинации, а такие сочные, бурные, красочные фантазии. Причём упорные - прям не сдвинуть никак! Инженеров не от хорошей жизни к такому привлекают - т.к. он зачастую единственные адекватные хранители истины.

beswalod
19.06.2026 06:10Ага, а бывают разработчики, которые даже по простецкому ТЗ реализуют непонятно что и даже беглого тестирования не проводят. Единственные хранители истины, не иначе

ksbes
19.06.2026 06:10Это когда единственный хранитель истинны - хорошо проспиртованый фрезеровщик сохранившийся со времён Великой Откчественной :)

BelerafonL
19.06.2026 06:10А пробовали запускать 10 раз с одним промптом и потом из 10 результатов агрегировать те замечания что повторились больше 7 раз, например? Мне такой оверсемплинг показался очень хорошим способом отсеять галлюцинации. А если бы ещё и модели разные, так вообще супер. Мой типичный пайплайн по аналогичной вычитке документов по чек-листам - это сделать 10 прогонов и агрегатору собрать топ 10 самых частых замечаний, например. Так уходят вообще все галлюцинации, и остаются пусть и иногда надуманные, но реально имеющиеся в документе проблемы. Даже на самых мелких qwen3-35b и подобных. И писать такое можно прямо в скиллах - написать промпт для оркестратора в одном файле, который запускает субагентов для которых промпт написан в другом файле, а потом запустить агрегатора с промптом в третьем файле. У всех субагентов чистый контекст, “программирование” агентов идет на естественном языке, и таким простым промптам как
запусти последовательно 10 субагентов, каждого строго с промптом “прочитай и выполни task_01.md” сам ничего не делай, только запускай субагентов.
даже самые тупые модели следуют норм.

aldekotan
19.06.2026 06:10Напоминает делегирование от опытного руководителя. Когда вместо одного дорогого работника-комбайна задача распределяется на десять дешёвых работников с задачами попроще.

sashatorstevv
19.06.2026 06:10Кажется, что основная ценность решения не в модели, а в разбиении задачи на маленькие проверяемые куски

Andreas_Fogel
19.06.2026 06:10Так и не понял кто мне в карму влепил минус, за слова поддержки автора. В каком дутом глобусе люди находятся, если позитив это для них негатив. Ну класс теперь писать статьи не могу.
Andreas_Fogel
Отличная и правильная статья. Ваш подход к внедрению правильный. Не даром же вы инженером являетесь.)