У меня есть руководитель, который очень хорошо ревьюит документы. Настолько хорошо, что один его проход по моим текстам породил 73 комментария. За один день.

Первая реакция была ожидаемая: сесть и править. Вторая пришла минут через десять и оказалась продуктивнее: это же датасет.

Дальше — история о том, как замечания одного конкретного человека превратились в чек-лист из 16 правил, чек-лист — в этап конвейера, а следующая партия документов ушла без единой правки по старым паттернам. С кодом, промптами и одним неудобным вопросом в конце.


Контекст: что за документы

Я работаю в крупной организации и среди прочего пишу справки о технической целесообразности ИИ-проектов. На входе — бриф: «хотим ассистента для внутренних специалистов», «хотим распознавать дефекты по фото». На выходе — документ на 7–10 страниц: реализуемо ли это, какими силами (своими или подрядом), какие риски, какие вопросы надо задать заказчику до старта.

Таких справок — поток. Структура одинаковая, дисциплина оценки одинаковая, проекты разные. Классический кандидат на автоматизацию, и она у меня есть: пайплайн на LLM-агенте, который собирает документы проекта, извлекает текст, заполняет структурированный JSON и собирает из него .docx по шаблону. Человек (я) правит содержание и отвечает за результат.

Пайплайн работал, справки выходили быстро, я был доволен.

Потом пришло ревью.


73 комментария за один вторник

Руководитель прошёлся по накопившейся пачке — девять справок — и вернул их с комментариями. 73 штуки. От четырёх до семнадцати на документ.

Выглядело это, если честно, как разгром. Вот реальные формулировки (я их слегка перефразировал, но дух сохранён):

«Откуда такая оценка?»

«Источник?»

«Нет такой опции в брифе»

«Нет такой опции в брифе» (другой абзац)

«Нет такой опции в брифе» (третий)

«Мимо»

Отдельные были развёрнутыми и болезненно точными:

«Вывод о реализуемости 9 из 10 перенесён из предварительного скоринга как установленный факт. Фактическая загрузка команды, инфраструктура и ресурсы не подтверждены»

«Утверждение "проект невозможен без GPU" противоречит рекомендуемому в этом же документе варианту с CPU-инференсом»

«Точные сроки, штрафы, проценты и цены лицензий не имеют источников»

Последний вообще вошёл в личный зал славы:

«Сроки и обязательства включены вопреки назначению справки»

То есть документ не просто содержал ошибки — он местами не понимал собственного жанра.

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


Комментарии — это данные. Достаём их

Замечания жили в .docx как обычные вордовские комментарии. Мало кто помнит, но .docx — это zip, и комментарии в нём лежат отдельным XML-файлом word/comments.xml, с автором, датой и привязкой к тексту. Достаются они скучным скриптом без единой зависимости:

import zipfile
import xml.etree.ElementTree as ET

W = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"

def extract_comments(path):
    with zipfile.ZipFile(path) as z:
        if "word/comments.xml" not in z.namelist():
            return []
        root = ET.fromstring(z.read("word/comments.xml"))

    result = []
    for c in root.findall(f"{W}comment"):
        author = c.get(f"{W}author", "?")
        date = c.get(f"{W}date", "?")
        text = "".join(t.text or "" for t in c.iter(f"{W}t")).strip()
        result.append((author, date, text))
    return result

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

Кстати, привязка к фрагменту важна не меньше текста комментария. «Источник?» сам по себе бесполезен; «Источник?» напротив фразы «обработка займёт 40 минут» — уже обучающий пример.


Кластеризация: 73 → 16 → 6

Дальше корпус поехал в LLM с примерно таким промптом:

Вот все замечания рецензента к девяти документам одного типа,
с фрагментами текста, к которым они привязаны.

Задача — не пересказать их, а найти СИСТЕМУ:
1. Сгруппируй замечания в повторяющиеся паттерны.
   Паттерн = одна и та же претензия к разным местам разных документов.
2. Для каждого паттерна сформулируй ПРАВИЛО САМОПРОВЕРКИ —
   императив, по которому можно проверить черновик ДО отправки.
3. Правило должно быть проверяемым: не «пиши лучше»,
   а «каждое число имеет источник или помечено как допущение».
4. Отдельно выпиши замечания, которые НЕ легли ни в один паттерн, —
   их нельзя терять молча.
5. Ранжируй паттерны по частоте.

Пункт 4 — самый важный в этом промпте. LLM обожает натянуть всё на красивую схему; явное требование «покажи остаток» — единственное известное мне противоядие. Остаток, кстати, был: несколько замечаний оказались разовыми и в чек-лист не пошли.

Пунктирная ветка — то, что не автоматизируется. Терять её нельзя
Пунктирная ветка — то, что не автоматизируется. Терять её нельзя

Из 73 комментариев получилось 16 паттернов в шести группах. Привожу целиком, потому что подозреваю: они не только про мои справки.

A. Верность источнику

  1. Не выходить за бриф. Если заказчик просил инструмент для внутренних специалистов, в документе не должно появиться мобильное приложение для граждан — даже если оно логично напрашивается. Три комментария «нет такой опции в брифе» — это всё сюда.

  2. Термины — ровно из брифа. В брифе «контролируемая среда» — значит, в справке не «изолированная». Синоним кажется безобидным, пока не оказывается термином с другим юридическим смыслом.

B. Доказательность

  1. Каждое оценочное суждение — либо с источником и расчётом, либо с явной пометкой «допущение». Особый подвид: оценки из предварительных прикидок («реализуемость 9/10») нельзя проносить в документ как установленный факт.

  2. Каждое число — с источником и датой. Сроки, объёмы, цены, проценты. Нет источника — есть пометка.

  3. Не давать обязательств там, где документ их давать не должен. Сроки, стек, объёмы датасетов — это гипотезы до подтверждения прототипом, и называться они должны гипотезами.

  4. Метрики — раздельно по компонентам. «Точность системы 90%» не значит ничего, если внутри распознавание, извлечение и классификация с разными профилями ошибок.

C. Границы компетенций

  1. Матрица вместо самооценки. Не «команда потянет», а таблица: компонент → кто делает → кто в организации держатель этой экспертизы → чем подтверждена его доступность.

  2. Сначала внутренние платформы, потом внешние. Если в организации уже есть готовый движок под задачу — он в приоритете, с честным разбором плюсов и минусов, а не молчаливым игнором.

  3. Переиспользование существующих наработок — обязательный вариант. «Собрать с нуля» без рассмотрения reuse — красный флаг.

  4. Не завышать сложность своей части. Если ваша роль — API и оркестрация поверх готовой модели, не нужно писать про найм команды компьютерного зрения.

D. Архитектурные развилки

  1. Никогда не фиксироваться на одном стеке. Не «делаем на YOLO», а набор проверяемых вариантов: готовая внутренняя модель / rule engine / внешний подряд / вообще без обучения. С условиями выбора: «если есть X, то...; если нет — то...».

  2. Ноль внутренних противоречий. Документ, который на странице 3 объявляет проект невозможным без GPU, а на странице 5 рекомендует CPU-вариант, не переживёт первого внимательного читателя.

  3. Рыночные выводы проверять самому. «Аналогов нет» из брифа — это позиция брифа. Пять минут поиска обычно находят три аналога, и уникальность оказывается не в технологии, а в контуре внедрения.

E. Глубина вопросов

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

  2. Регуляторику не трактовать прямолинейно. Ни автоматическое «персональных данных нет — защита не нужна», ни перестраховочное «всё запрещено». Квалифицировать данные и выносить в явный вопрос профильному подразделению.

F. Этапность

  1. Stage-gate между фазами. Переход от MVP к полной версии — не по календарю, а по критериям: что должно быть подтверждено (эффект пилота, согласование безопасности, метрики выше порога), чтобы двигаться дальше.

Версия для сохранения. Проверка — отдельным вызовом LLM, не в том же промпте, что генерация
Версия для сохранения. Проверка — отдельным вызовом LLM, не в том же промпте, что генерация

Момент, ради которого стоило это делать

Разложив 73 замечания по 16 полкам, я увидел то, чего не видел за отдельными правками.

Почти ни одно замечание не было про предметную область. Руководитель не спорил с выбором модели и не поправлял мою оценку сложности OCR. Претензии были эпистемологические — к статусу утверждений: откуда ты это знаешь? это факт или мнение? если мнение — почему оно выглядит как факт?

И вот тут пазл сошёлся. Документы-то собирает LLM. А LLM генерирует текст с равномерной уверенностью: факт из брифа, экспертная оценка и чистая экстраполяция выходят из неё одинаково гладкими, в одном тоне, без швов. Человек, когда пишет, невольно маркирует сомнение — «по всей видимости», «навскидку», «надо проверить». Модель — нет. Она пишет «обычного сервера будет достаточно» с той же интонацией, что и «в брифе указано 10 000 документов в месяц».

Опытный рецензент детектирует эту немаркированную уверенность мгновенно. По сути, все 73 комментария — один комментарий, повторённый 73 раза: «покажи статус этого утверждения».

 B + A = 34 комментария из 73. Половина ревью — про статус утверждений, а не про предметную область
B + A = 34 комментария из 73. Половина ревью — про статус утверждений, а не про предметную область

Чиним систему, а не документы

Дальше три изменения в пайплайне.

1. Маркировка источника у каждого утверждения

Теперь каждое содержательное утверждение в документе несёт явную метку:

  • [Б] — факт из брифа или приложенных документов, с указанием источника;

  • [Э] — экспертная оценка, с коротким обоснованием;

  • [Д] — допущение, требующее проверки. Все [Д] дополнительно собираются в отдельный раздел «что нужно подтвердить до старта».

Было:

Для обработки потока достаточно одного сервера без GPU.

Стало:

Для обработки заявленного потока (10 000 документов/мес [Б: бриф, п. 3]) предположительно достаточно одного CPU-сервера [Д: требует нагрузочного прототипа на репрезентативной выборке].

Звучит менее уверенно? Да. В этом и смысл. Документ, который знает границы своего знания, читается медленнее, а принимается быстрее.

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

2. Чек-лист как этап конвейера

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

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

3. Чек-лист в постоянной памяти агента

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

Фактически у рецензента появился цифровой двойник, который успевает к черновику раньше него.

Разница — один блок. Но этот блок сделан из 73 комментариев
Разница — один блок. Но этот блок сделан из 73 комментариев

Результат

Следующая партия — четыре документа за две недели — ушла и была принята без замечаний по старым паттернам. Ноль повторов из тех шестнадцати.

Замечания вообще? Были, по делу, новые — по содержанию конкретных проектов, там, где рецензент реально незаменим. Исчез именно повторяющийся слой: «источник?», «откуда цифра?», «нет в брифе».

Честные оговорки, куда без них:

  • Выборка маленькая. Четыре документа — это четыре документа. Может, мне попались простые проекты. Ещё через десять будет видно.

  • «С первого раза» из заголовка — про отсутствие итераций правок, а не про то, что рецензент перестал читать. Читает. Просто теперь его проход по документу не превращается в археологию одних и тех же ошибок.

  • Часть эффекта — не от чек-листа, а от маркировки [Б]/[Э]/[Д] как таковой. Подозреваю, она сместила и восприятие: документ, который сам сдаёт свои слабые места, вызывает другой уровень доверия, чем документ, в котором слабые места надо искать.


Это вообще честно?

Предвижу комментарий: «то есть ты натренировался обходить конкретного проверяющего».

Нет — и разница принципиальная.

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

Я эту традицию просто записал. 73 комментария оказались достаточной обучающей выборкой, чтобы извлечь стандарт почти целиком — не потому что LLM гениальна, а потому что хороший рецензент систематичен: он не выдумывает новые претензии к каждому документу, он последовательно применяет одни и те же принципы.

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

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


Как повторить у себя

Рецепт короткий, инструментонезависимый:

  1. Соберите корпус. Комментарии из .docx (скрипт выше), из pull request'ов через API, из переписки — что есть. Важно сохранить привязку: не только «что сказали», но и «к какому фрагменту».

  2. Кластеризуйте с LLM. Промпт из статьи как отправная точка. Обязательно требуйте выделить остаток — замечания вне паттернов.

  3. Каждый паттерн переформулируйте в проверяемое правило. Императив + признак нарушения. «Писать понятнее» — не правило. «Каждая аббревиатура раскрыта при первом употреблении» — правило.

  4. Вшейте туда, где правила не смогут потеряться. Постоянная память агента, инструкции проекта, шаблон документа, pre-commit — по вкусу. Правило, которое нужно вспоминать, не работает.

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

И один неочевидный совет: не выбрасывайте остаток из шага 2. Замечания, которые не легли в паттерны, — это либо будущие паттерны (мало данных), либо то самое незаменимое экспертное, что автоматизации не подлежит. И то и другое стоит знать в лицо.


Вместо вывода

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

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

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

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Формализовать замечания своего ревьюера в чек-лист для ИИ — это:
100%Честная инженерия: стандарт и должен быть артефактом2
0%Серая зона — сначала стоит спросить самого рецензента0
0%Обход проверяющего, так делать нельзя0
0%Я уже так делаю0
Проголосовали 2 пользователя. Воздержавшихся нет.