Как мерили
Спор «пишет ИИ пригодный код или не пишет» решается замером, иначе это обмен опытом, где обе стороны правы про свой случай. Мы построили пять фикстур на классах ошибок, которые реально случались у нас, — не на выдуманных задачках:
| Класс | Из какого нашего инцидента взят |
|---|---|
| Выдуманные числа | девять из двадцати пар расстояний на страницах оказались вымышленными; одно расстояние занижено вдвое против справочного |
| Дублирование в тексте | «в Алматы в Алматы», «Аренда Аренда» — 44 страницы, которых не увидел ни один гейт |
| Правило есть, эффекта нет | правило перенаправления прописано, а страницы отдают обычный ответ: 17 старых адресов жили как ни в чём не бывало |
| Устаревшая константа | налоговая ставка сменилась, а в коде семь месяцев стояла прежняя |
| Слепота выборки | сборщик переписки фильтровал по старому формату адресации и молча терял три четверти чатов, возвращая код успеха |
Как устроена одна клетка замера. Ключ ответа берётся из истории изменений, а не из нашего мнения о том, что тут дефект
fixture: invented_numbers # класс «выдуманные числа»
before: "Расстояние до города — 245 км. Время в пути — 3 часа."
after: "Расстояние до города — 487 км. Время в пути — 6 часов."
answer_key:
defect: "расстояние занижено вдвое против справочного"
source: "коммит-исправление в истории — объективный ключ"
runs: 3 # три прогона на клетку: вывод по одному не делается
score: [miss, false_alarm] # пропуски и ложные тревоги — РАЗДЕЛЬНОРаздельный учёт здесь не педантизм: модель, которая кричит на всё подряд, и модель, которая молчит, дают одинаково плохой результат, но чинятся по-разному. Сложенные в одну цифру, они выглядят как «средняя точность» и не говорят ничего.
У каждой фикстуры есть пара: материал с дефектом и тот же материал после реального исправления. Ключ ответа объективен — он взят из истории изменений, а не придуман. Каждая клетка прогонялась трижды, пропуски и ложные тревоги считались раздельно.
Что показал замер
- Одна модель из семи прошла все классы без единого промаха. Остальные шесть — нет. То есть «ИИ не справляется» и «ИИ справляется» одинаково неверны как общие утверждения: разброс между моделями на одной и той же задаче больше, чем разница между «хорошо» и «плохо».
- Худший класс — сверка двух чисел между собой. На странице стоят две цифры, которые противоречат друг другу; надо это заметить. 17 промахов из 21. Это ровно то, чем занят человек при вычитке спецификации, — и это самое слабое место моделей.
- Ложную тревогу проверки от настоящего дефекта не отличила ни одна модель. Практический смысл: отдавать модели «разбери выхлоп линтера и скажи, что чинить» — значит получить уверенный разбор, в котором настоящее перемешано с мусором.
- Разброс перекрывает разницу. Пять пунктов между двумя моделями при трёх прогонах не доказывают ничего. Мы это записали как правило: вывод по одному прогону не делается.
И отдельно про самопроверку. Приложение прошло 20 своих тестов из 20 — состязательная проверка нашла в нём 8 настоящих багов. Из 24 наших собственных замеров 19 оказались недействительными из-за дефектов стенда, а не измеряемого. Тот, кто пишет код, и тот, кто его принимает, не могут быть одним лицом — ни человеком, ни моделью.
Про требования — самое важное
Здесь у нас есть замер, который меняет вывод. Одна и та же задача, одна и та же модель: при запрете отказываться от ответа — 18 верных из 20; при разрешении отказаться — 1 из 20. Изменилось одно условие в постановке, а результат отличается в восемнадцать раз.
Вся разница — в одном условии. Задача, модель и данные одни и те же
# (A) отказ разрешён ────────────────────────────────── 1 верный из 20
Проверь страницу и скажи, что не так.
Если не уверен — так и напиши.
# (B) отказ запрещён, критерий приёмки внутри задания ─ 18 верных из 20
Проверь страницу и скажи, что не так.
Ответ обязателен: назови конкретное поле и конкретное расхождение.
«Не уверен» ответом не считается.
Выполненной работой считается пара «поле → чем противоречит».Второй вариант не «давит» на модель и не заставляет её выдумывать: он говорит, что считается результатом. Тот же приём работает и с людьми — просто с людьми недосказанность добирается в разговоре, а модель молча отдаёт то, что поняла.
Второй замер того же рода: дословный критерий приёмки, вписанный внутрь задания, убирал содержательные провалы полностью. Не «модель стала умнее» — стало понятно, что считается выполненной работой.
Из этого же следует, почему «выйдем на плато» — реалистичный прогноз. Обожгутся те, кто считает, что исчезла именно инженерная работа. Она не исчезла, а сменила место.
Где мы сами не беремся
- 1С. Не наш стек. Мы строим контур вокруг — обмен, документы, отчётность, — но расширения внутри не пишем и сроки по ним не оцениваем. Оценивать чужую платформу по аналогии с JavaScript и Python некорректно: там другая цена ошибки и другая отладка.
- Обучение моделей с нуля и классическое машинное обучение. Мы дообучаем готовые модели под свою задачу — это разные вещи, и мы их не смешиваем.
- Автоматическая приёмка без человека. Наш собственный замер показывает, почему: отличить ложную тревогу от дефекта модели пока не умеют.