Это не туториал и не истина в последней инстанции. Я просто делюсь своим опытом,как у меня родилась идея и как я её воплощала. Возможно, кому-то это поможет не наступать на те же грабли или подтолкнёт к собственным экспериментам.


Я аналитик. Я пишу ТЗ. Лучшее время для этого утро, пока голова свежая. Потому что потом наваливаются стендапы, встречи, работа, в голове мясорубка, а нужно сесть и написать хорошее ТЗ. Продумать его, ничего не упустить, разложить по полочкам.

Но даже когда садишься писать, есть одна проблема: глаз замыливается. Ты так глубоко погружена в контекст, так хорошо помнишь все устные договорённости, что перестаёшь замечать, чего в тексте не хватает. Разработчик прочитает буквально, а ты удивляешься: «Ну это же очевидно!».

Мы уже говорили про матрицу трассировки. Это крутой инструмент, который помогает ничего не потерять при проверке. Но проверка — это всё равно ручная работа. А я человек ленивый. И я подумала: а что, если часть этой работы отдать нейросети? Пусть она берёт на себя роль того самого «свежего глаза» и подсвечивает спорные места, пока я занимаюсь другими задачами.

Так родилась идея создать AI-агента, который умеет проверять ТЗ. Рассказываю, как я это делала.


Идея и первый подход к снаряду

Сначала всё казалось простым: «Ну, скормлю ТЗ нейросети, пусть найдёт ошибки». Я взяла GPT, дала промпт: «Найди противоречия в этом ТЗ». Он что-то нашёл. Но это было поверхностно и часто мимо.

Проблема была в том, что нейросеть не знала контекста. Она не понимала, что такое «хорошее ТЗ» для 1С, какие там бывают типовые ошибки, что важно для разработчика, а что для заказчика. Ей не хватало базы знаний.

Я поняла: нужен не просто запрос, а обучение на примерах.

Сбор материалов и создание репрезентативной выборки

Самый нудный, но самый важный этап. Я перерыла свои старые проекты и нашла:

  • 30 отличных ТЗ (которые потом легко ушли в разработку, минимум правок)

  • 30 плохих ТЗ (где потом были проблемы, переделки, конфликты с заказчиком)

  • 30 средненьких ТЗ (рабочих, но с недочётами, которые всплыли уже в процессе)

Итого 90 ТЗ с подробными рецензиями. Это позволило сделать выборку действительно репрезентативной и охватить разные типы ошибок, проектов и стилей написания.

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

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

Потом я разметила все ошибки по типам. Главная боль в ТЗ, это описаны только позитивные сценарии и непроверяемые требования. Люди уже не пишут «интерфейс должен быть удобным» в лоб, но умудряются формулировать так, что проверить всё равно нельзя.

Вот моя классификация:

Тип ошибки

Как выглядит

Пример

Только позитивные сценарии

Описано, как должно работать в идеале, но нет ни слова про ошибки, граничные состояния, исключения

«При проведении документа остатки уменьшаются». А что будет, если остатка нет? А если склад не заполнен? А если документ уже проведён?

Неоднозначность формулировок

Можно трактовать по-разному

«Отчет должен работать быстро» (как быстро?)

Отсутствие граничных условий

Не описано поведение в крайних случаях

Что делать, если на складе нет остатка?

Противоречия между пунктами

Пункт А противоречит пункту Б

В одном месте склад обязателен, в другом — не указан

Непроверяемые требования

Нельзя однозначно проверить результат

Разберём ниже подробно

Избыточность

Требования, которые не влияют на бизнес-задачу

Детализация, не нужная для разработки

Потерянные требования

Есть в обсуждениях, но нет в ТЗ

Обсуждали на встрече, но забыли записать

Типичные примеры непроверяемых требований (и как их переписать)

Разберём три классических случая, которые я часто встречаю в реальных ТЗ. Они выглядят безобидно, но проверять по ним результат — pure pain.

1. «Пользователь должен иметь возможность гибко настраивать отчет»

Звучит заботливо. Но что значит «гибко»?

  • Какие именно настройки имеются в виду? Группировки? Отборы? Сортировки? Сохранение вариантов?

  • Сколько уровней группировки должно быть?

  • Можно ли добавлять свои поля в отчет?

Если это не конкретизировать, разработчик сделает стандартный отчёт с двумя отборами по периоду и контрагенту. Формально требование выполнено: пользователь что-то там настроил. А заказчик скажет: «Я думал, там можно будет поля добавлять и группировки менять». И будет прав.

Как переписать: «В отчете должны быть доступны настройки: период (произвольный интервал), контрагент (множественный выбор), склад (одиночный выбор), номенклатура (групповой выбор). Настройки должны сохраняться для каждого пользователя индивидуально. Должна быть возможность вывести отчет с группировкой по контрагентам и по складам».

2. «Система должна корректно обрабатывать большие объемы данных»

Тоже классика. Что значит «корректно»? Что значит «большие»?

  • 1000 документов — это уже большой объем?

  • 100 000 строк в табличной части?

  • Время обработки не оговаривается — может, она будет час считать, и это «корректно»?

  • Какая допустимая нагрузка на сервер?

Программист проверит на десяти документах, скажет «ок», а на реальных данных всё упадёт или будет тормозить. И снова формально требование выполнено.

Как переписать: «При загрузке 10 000 документов с общим количеством строк 500 000 время проведения не должно превышать 15 минут. Ошибок при проведении быть не должно. Использование оперативной памяти не более 2 ГБ. Процессор не более 50% загрузки в пике».

3. «Все экранные формы должны быть приведены к единому стилю»

Красивая фраза. Но как её проверять?

  • Цвета кнопок везде одинаковые?

  • Отступы везде 5px?

  • Шрифты везде одного размера и начертания?

  • Табличные части везде с одинаковым набором действий?

  • Кнопки «Сохранить» и «Провести» всегда в одном месте?

Разработчик может считать, что единый стиль, это «везде кнопка Сохранить есть». А заказчик хотел «как в Google-документах». Итог, недовольство и переделки.

Как переписать: «Во всех формах документов кнопки "Записать" и "Провести" должны находиться в правом верхнем углу. Цвет кнопок — зеленый (R=0, G=128, B=0). Шрифт — Arial, 10pt. Отступы от края формы — 10px. Табличные части должны иметь одинаковый набор действий: добавить строку, удалить строку, скопировать».

Как я добивалась репрезентативности:

Чтобы выборка была качественной, я соблюдала несколько принципов:

  1. Разные проекты — брала ТЗ из разных сфер: торговля, производство, услуги.

  2. Разные авторы — не только свои, но и коллег, чтобы не «приучать» модель к одному стилю.

  3. Разный размер — от мелких доработок до крупных внедрений.

  4. Разные годы — старые проекты (где были ошибки) и свежие (где я уже их учла).

Получилось 90 ТЗ с подробными рецензиями. Я разбила их на отдельные функциональные требования, вышло около 270 размеченных примеров для обучения классификатора.

Критерии приемки ТЗ: чему я учила агента

Прежде чем учить агента искать ошибки, нужно было понять, а что вообще считать хорошим ТЗ. Я сформулировала для себя чек-лист, который потом зашила в обучение. Вот основные критерии:

Критерий

Вопрос для проверки

Пояснение

Бизнес-цель

Понятно, какую бизнес-задачу решает доработка? Зачем это заказчику?

Если нет ответа на «чтобы что?», мы не сможем проверить, достигнута ли цель, и не отсеем лишние хотелки.

Полнота сценариев

Описаны не только позитивные, но и негативные и граничные случаи?

Что будет, если склад не выбран? Если остатка нет? Если документ уже проведён?

Однозначность

Можно ли трактовать требование по-разному?

Нет формулировок типа «быстро», «удобно», «гибко» без цифр и критериев.

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

Можно ли составить тест-кейс, который подтвердит выполнение?

Если нельзя придумать тест — требование бесполезно.

Согласованность

Нет ли противоречий между разделами ТЗ?

В одном месте склад обязателен, в другом — не указан.

Реализуемость

Выполнимо ли технически в рамках платформы и сроков?

Не просим невозможного.

Маппинг данных

Для интеграций: прописаны ли соответствия полей?

Какое поле 1С соответствует какому полю в Честном Знаке, IIKO и т.д.

Права доступа

Указано ли, какие роли имеют доступ к новому объекту или функции?

Кто может видеть кнопку? Кто может проводить документ?

Атомарность

Можно ли разбить требование на отдельные задачи?

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

Эти критерии я превратила в набор вопросов, которые агент должен задавать к каждому требованию.

Выбор архитектуры: почему деревья решений и RAG

Я не программист, поэтому полезла изучать, как вообще делают таких агентов. Нашла несколько open-source проектов, но лезть в глубокий learning не хотела. Мне нужно было простое и понятное решение.

В итоге я пошла путём RAG (Retrieval Augmented Generation) в сочетании с классификацией на основе деревьев решений для типовых ошибок.

Почему деревья решений? Потому что они:

  • Дают прозрачную логику — видно, по какому пути пошло решение

  • Хорошо работают с табличными данными (а моя размеченная выборка — это таблица)

  • Позволяют оценить важность признаков — какие ошибки чаще всего встречаются

Пример дерева решений (упрощённо):

Вопрос 1: Содержит ли требование конкретные числовые показатели?
│
├── Нет → Вероятно, непроверяемое требование (например, «быстро», «удобно»).  
│   └── Проверяем по словарю: есть ли слова-маркеры «гибкий», «интуитивный», «качественный»? Если да → помечаем как «непроверяемое».
│
└── Да → Вопрос 2: Описаны ли негативные сценарии?
    │
    ├── Нет → Помечаем как «только позитивные сценарии».
    │
    └── Да → Вопрос 3: Указаны ли граничные условия?
        │
        ├── Нет → Помечаем как «отсутствие граничных условий».
        │
        └── Да → Требование скорее всего корректно, но проверяем на противоречия с другими пунктами.

ВАЖНЫЙ ТЕХНИЧЕСКИЙ МОМЕНТ:
Дерево решений (например, из Scikit-learn) не работает с сырым текстом напрямую. Ему нужны числовые признаки. Поэтому перед передачей данных в классификатор, LLM-агент (Анализатор) выполняет промежуточную работу: он извлекает из каждого требования параметры и превращает их в структурированный JSON-объект — своего рода «паспорт требования».

Этот паспорт содержит признаки вроде:

  • has_numbers (1 — есть цифры/конкретика, 0 — нет)

  • has_negative_keywords (1 — есть слова вроде «иначе», «если», «исключение»)

  • boundary_conditions_mentioned (1 — упомянуты граничные случаи)

  • stopword_score (вес слов-маркеров вроде «гибкий», «интуитивный», «быстрый»)

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

Зачем здесь RAG?
RAG используется в Агентe-анализаторе следующим образом: когда приходит новое ТЗ, агент ищет в моей базе знаний (той самой коллекции рецензий на 90 ТЗ) фрагменты, похожие на текущее требование. Это помогает модели «вспомнить», как в похожих случаях классифицировались ошибки, и улучшить качество извлечения признаков в JSON-паспорт. По сути, RAG здесь работает как внешняя память, дополняющая контекст запроса к LLM.

Схема агентов получилась такая:

  1. Агент-анализатор (на базе LLM + RAG) — получает ТЗ, разбивает на требования, выделяет сущности, ищет в моей базе знаний похожие кейсы, формирует JSON-паспорта требований.

  2. Классификатор (дерево решений) — для каждого требования проверяет по его числовому паспорту, нет ли в нём типовых ошибок (обучен на моей выборке из 270 требований). Дерево решений помогает ранжировать признаки по важности.

  3. Агент-критик — проверяет каждое требование по чек-листу (понятно ли? проверяемо ли? не противоречит ли другим?)

  4. Агент-генератор тестов — на основе требований предлагает тест-кейсы (позитивные, негативные и граничные)

  5. Агент-суммаризатор — собирает всё в отчёт

    Важно: Классификатор работает на уровне отдельных требований (микроанализ), выявляя формальные ошибки: непроверяемость, отсутствие негативных сценариев, неоднозначность. Агент-критик работает на уровне всего ТЗ целиком (макроанализ) и проверяет сквозные вещи: согласованность между разделами, наличие маппинга данных, описание прав доступа. Это разные уровни, поэтому дублирования нет.

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

Обучение на ошибках: итеративный подход

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

Я стала записывать все его ошибки и добавлять их в обучающую выборку. Например:

  • «Не заметил, что в ТЗ не указан формат даты»

  • «Пропустил требование без явной бизнес-цели»

  • «Спутал обязательное требование с опциональным»

  • «Пропустил типичную непроверяемую формулировку "гибкая настройка"»

На основе этих ошибок я пересматривала набор признаков (feature engineering) и переобучала модель на расширенной выборке. Например, если классификатор часто не замечал отсутствие граничных условий, я добавляла в паспорт требования новый признак boundary_conditions_mentioned и пополняла обучающую выборку примерами, где этот признак был важен. Это классический итеративный процесс улучшения модели через уточнение признаков и данных, а не ручная правка дерева.

Я также анализировала статистику своих правок:

  • Какие типы ошибок классификатор пропускал чаще всего?

  • Какие формулировки в ТЗ вызывали у него трудности?

  • Где он был слишком строг, а где слишком мягок?

На основе этой статистики я дообучала модель: добавляла новые примеры, меняла веса классов, уточняла признаки.

Через 5-6 итераций классификатор начал выдавать адекватные замечания. Не идеально, но уже полезно. Сам агент использует эти результаты: он получает от классификатора «сырые» пометки, добавляет к ним пояснения и упаковывает в удобный отчёт.

Метрики: как я измеряю качество агента

Ты спросишь: а почему я не использую классические метрики вроде recall, accuracy? Да, я знаю про них, но они не очень подходят для моей задачи.

Мой агент не классифицирует ТЗ на «хорошее/плохое». Он генерирует список замечаний, предлагает тест-кейсы, задаёт вопросы. Это задачи генерации, где нет одного «правильного» ответа. Если бы я попыталась считать recall, мне пришлось бы сравнивать ответы агента с эталонной рецензией супер-аналитика. Но кто этот супер-аналитик? И кто сказал, что его мнение — истина?

Понятно, что я делаю модель для себя, а значит, эталонный аналитик — я сама. И если в мире академических метрик это звучит как ересь, то в мире “я и мой агент” это называется “доверительные отношения”. Мы с ним договариваемся: он ищет ошибки, я решаю, что считать ошибкой. Демократия, однако. Но я пошла по другому пути...

Поэтому я использую другие метрики, которые реально отражают прогресс:

1. Task Success Rate (TSR) — процент найденных реальных проблем

Беру 10 старых ТЗ, где я уже знаю все дыры. Смотрю: сколько проблем агент нашёл? Если из 5 ошибок нашёл 4 — TSR = 80%. Если придумал лишнее, считаю ложные срабатывания отдельно.

Я осознаю, что эта метрика субъективна и опирается на моё экспертное знание «всех ошибок» в старых ТЗ. Однако для моей задачи, оценить, помогает ли агент мне лично находить проблемы, этого достаточно. Если бы я делала продукт для массового использования, потребовались бы более строгие метрики и краудсорсинг разметки.

Также отдаю себе отчет, что TSR по сути является прикладным аналогом метрики Recall. Но для меня и моего бизнес-процесса важнее не абстрактная «полнота выборки», а конкретный результат: решена ли задача аналитика по выявлению критичных ошибок в ТЗ.

2. Precision (точность) — сколько из замечаний действительно по делу

Если агент выдал 10 замечаний, а по факту реальных проблем только 7 (остальное он выдумал или неправильно понял) — precision = 70%. Мне важно, чтобы агент не заваливал меня шумом.

3. LLM-as-a-Judge — оценка качества отчета другой моделью

Использую отдельную языковую модель (или того же агента в режиме критика), чтобы оценить его же отчёт по критериям: полнота, релевантность, полезность. Ставлю оценки от 1 до 5. Если они растут, значит, агент умнеет.

4. Человеческая оценка (мой личный контроль)

Самое надёжное. Раз в неделю беру 2–3 случайных отчёта агента и оцениваю их сама: 0 — бесполезно, 1 — есть пара дельных мыслей, 2 — хороший отчёт, 3 — лучше, чем я сама написала бы. Это субъективно, но это мой агент, и важно, чтобы он удовлетворял именно моим критериям.

5. Время работы и стоимость

Для локального агента через Ollama время не критично, но если вы будете делать облачную версию, следите за токенами и скоростью.

Да, на первых итерациях я действительно оценивала результаты «на глаз» и только потом формализовала метрики. Это типичный путь для эксперимента: сначала проверяешь гипотезу, потом вводишь количественные измерения. Моя рекомендация, делать это сразу, чтобы не потерять время на субъективных оценках.

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

Что даёт проверка своего же ТЗ

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

  2. Негативные сценарии. Автор чаще всего пишет «как должно быть». Агент специально обучен искать: а что, если всё пойдёт не по плану?

  3. Конкретика. Агент подсвечивает размытые формулировки — те самые «гибкие настройки», которые кажутся нормальными, пока не попробуешь их проверить.

  4. Экономия времени. Найти проблему до того, как ТЗ ушло разработчику, — это сэкономить дни переделок.

Теперь я всегда прогоняю своё ТЗ через агента. Агент стал моим вторым взглядом — холодным, въедливым и бесконечно тупым в хорошем смысле: он не додумывает, он читает только то, что написано. И это спасает.

Как это работает сейчас

Сейчас у меня есть работающий прототип на Python с использованием LangChain и локальной LLM через Ollama.

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

В качестве модели я использую квантованную версию (4-bit) одной из моделей семейства Mistral или Llama 3 8B. Такие модели занимают около 6-8 ГБ оперативной памяти и вполне комфортно работают на обычном ПК с 16 ГБ RAM. Для более тяжелых моделей (70B) железа, конечно, не хватит, но для моих задач и датасета из 90 ТЗ модели 7B-8B справляются отлично.

Наверняка будет вопрос: как аналитик собрал это на Python?

Отвечаю: я не программист и не пишу код с нуля. Я продумала логику и структуру, а собрать работающий скрипт на LangChain мне помог ИИ-ассистент. Я выступала в роли "заказчика-контролера": проверяла, чтобы код делал именно то, что мне нужно, и исправляла ошибки вместе с нейронкой. Сейчас это нормальный инструмент: ты даешь алгоритм, а ИИ помогает с синтаксисом.

Процесс такой:

  • Я загружаю ТЗ (в текстовом формате)

  • Агент проходит по всем этапам и выдаёт отчёт:

    • Список требований (как он их понял)

    • Потенциальные проблемы (неоднозначности, пробелы) с классификацией по типам

    • Предложения по тест-кейсам (позитив, негатив, граничные)

    • Вопросы, которые стоит задать заказчику

    • Оценку «зрелости» ТЗ по моим критериям

Я не доверяю ему на 100%, но как второй взгляд — вещь незаменимая.

Планы на будущее

Сейчас я хочу:

  • Добавить поддержку ТЗ в формате Excel (где требования в табличках)

  • Научить агента проверять не только текст, но и схемы данных (например, структуру регистров в 1С)

  • Улучшить дерево решений, добавить больше признаков и протестировать случайный лес для сравнения

  • Сделать простой интерфейс


Что я поняла за это время

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

Не код, а данные являются самым сложным. Качество агента прямо зависит от того, на каких примерах его учили. Мусор на входе приводит к мусору на выходе. Репрезентативная выборка составляет 80% успеха. Деревья решений служат отличным инструментом для анализа. Они просты, прозрачны и позволяют понять, на какие признаки вообще стоит обращать внимание. Важность признаков в дереве показывает, какие метрики JSON-паспорта (например, has_numbers или has_negative_keywords) вносят наибольший вклад в классификацию ошибок. Это помогает понять, на что обращать внимание при написании ТЗ.

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


А вы пробовали создавать своих агентов для работы? Или maybe пользуетесь готовыми? Делитесь опытом в комментариях — интересно, кто и как автоматизирует рутину.