Более качественный детектор ИИ-комментариев к коду
- title
- Более качественный детектор ИИ-комментариев к коду
- type
- summary
- summary
- kqr пересобрал калиброванный классификатор комментариев к коду на открытых данных: 77% balanced accuracy, n-граммы POS-тегов как сильнейшие признаки
- tags
- llm, stylometry, ai-disclosure, machine-learning
- sources
- better-ai-comment-classifier
- created
- 2026-09-13
- updated
- 2026-09-14
- lang
- ru
- translation_of
- ai-comment-classifier
- source_updated
- 2026-09-14
- translated
- 2026-09-14
- translator
- lllm/antigravity/gemini-3.7-flash-medium
kqr в блоге entropicthoughts пересобрал свой прежний классификатор комментариев к коду - на этот раз на открытых данных, чтобы им можно было делиться. Он работает в браузере по адресу xkqr.org/aicomment, вставленный текст не покидает страницу, а клик по любому фрагменту ввода показывает, какие признаки там сработали и насколько сильно каждый из них повлиял на вердикт. Статья в основном посвящена процессу разработки и честно рассказывает обо всех ошибках.
Цифры
Сбалансированная точность (balanced accuracy) на кросс-валидации составляет 77% в предположении, что написанные человеком и сгенерированные комментарии равновероятны. На заведомо человеческом тексте модель определяет человека в 73% случаев; на заведомо сгенерированном определяет генерацию в 80% случаев. На меньшем наборе реальных комментариев, проверенном вручную, результат оказался выше: 88% точности (специфичность 89%, полнота 86%), что автор объясняет тем, что реальные примеры разделять проще, чем синтетические обучающие данные. Этот второй набор невелик и проверялся самим автором, так что результат скорее обнадёживающий, чем окончательный.
Куда более полезное свойство - калибровка. Выводимый процент вероятности соответствует реальному шансу оказаться правым независимо от длины комментария: температурный параметр подгоняется под квадратный корень длины ввода, поэтому для длинных текстов предсказания делаются более уверенно. В итоге общая доля ошибок около 25% не так страшна, как кажется: при уверенности вердикта от 80% и выше риск ложноположительного срабатывания составляет около 5%, а вердикт в районе 50% честно указывает на случайное угадывание (подбрасывание монеты). Все замеры проводились исключительно на комментариях к коду. Модель может классифицировать и другой текст, но без каких-либо гарантий точности.
Сбор датасета
Замысел состоял в том, чтобы взять репозитории с разрешительными лицензиями, переключиться на их последний коммит за 2021 год (чтобы человеческие комментарии предшествовали инструментам написания кода на базе LLM), выбрать случайные файлы, удалить из них все комментарии и заставить несколько LLM написать к тем же файлам новые комментарии. Балансировка количества токенов на файл между человеком и каждой моделью как раз не даёт классификатору выучить, из какого репозитория взят комментарий, вместо того чтобы определять его автора.
По оценке автора, при правильном подходе сбор данных обходится примерно в $30, а качество классификатора растёт логарифмически относительно потраченных денег. С первого раза правильно сделать не удалось, и данные собирались трижды. Ошибки здесь - самая полезная часть: разные файлы для разных моделей (утечка тематики), файлы с чересчур малым числом человеческих комментариев (снова утечка), оставленные docstring'и, из-за которых модели подражали существующему стилю, пропущенный синтаксис комментариев в некоторых языках, оставшиеся сверхкороткие комментарии человека вроде "Alias", из-за которых классификатор решил, что люди пишут небрежно, а также единственный фиксированный промпт для генерации, сузивший разнообразие сгенерированного текста.
Признаки
Тестирование каждого подмножества из 15 признаков-кандидатов потребовало бы обучить более 30 000 классификаторов, причём каждый по пять раз. Вместо этого каждый признак оценивался по отдельности на нескольких парных задачах (человек против модели и модель против модели) и ранжировался с построением графа, показывающего расхождения в этих рангах. N-граммы частей речи (POS-тегов) оказались сильнее всего независимо от движка разметки, поскольку они фиксируют структуру фраз источника, не отвлекаясь на конкретный выбор слов. Посимвольные n-граммы тоже показали хороший результат. Частоты отдельных слов, обычно рискованные из-за привязки к теме, здесь отработали приемлемо: сбалансированный датасет почти не оставил тематических зацепок. Финальный набор признаков, по словам автора, был выбран довольно произвольно, когда перебор комбинаций попросту надоел.
Сведение семи классов к двум
Модель представляет собой логистическую регрессию по L1-нормализованным признакам, обученную на семь классов: люди, GPT 5.6, Gemini 3.7, Claude 5, Kimi K2.7, Grok 4.6 и GLM 5.2. Kimi и GLM постоянно оказывались вероятными источниками вообще всего, а график центроидов признаков показал, что их стиль перекрывает все остальные модели. Вместо переобучения классификатор перераспределяет любую вероятность, назначенную этим двум, обратно между моделями, из которых черпал данные при обучении. В сноске автор добавляет, что не знает, как работает дистилляция, но похоже, что дело в ней. Затем вероятности повторно нормализуются к априорному распределению 50/50 (человек/модель), поскольку на практике важен вопрос, написал ли текст человек, а не какая именно модель это сделала.
Запуск в браузере потребовал двух компромиссов. Модель была квантована, а словарь урезан по порогу документной частоты в 0.05%, что уменьшило её размер до 355 кБ. Кроме того, для разметки пришлось взять wink-nlp - библиотеку слабее nltk или spaCy, которую затем задействовали и в пайплайне обучения, чтобы входные данные при классификации не выбивались из распределения; для этого Python'у пришлось вызывать процесс Node.js.
Код и причина остановки разработки
Реализация выложена на sourcehut, и автор прямо говорит, что код сгенерирован LLM и переписывать его ему лень. Он также отмечает, что, скорее всего, прекратит работу над проектом, так как новые правила использования sourcehut, вступающие в силу на следующий день после публикации поста, запрещают размещение сгенерированного LLM кода.
Связь со страницами базы о детекции
ai-detector-arms-race утверждает, что поверхностная детекция ошибается в обе стороны и никакой детектор не способен восстановить процесс создания текста. Этот классификатор не столько опровергает этот тезис, сколько подкрепляет цифрами его частный случай. Он работает на одном жанре, против конкретных версий моделей, которые неизбежно устареют, всё ещё ошибается примерно на каждом четвёртом заведомо человеческом комментарии и честно сообщает о степени неуверенности в каждом вердикте, чего большинство коммерческих детекторов не делает. Дрейф, предсказанный на странице о гонке вооружений, заложен в самой сути: классификатор, обученный на Claude 5 и GPT 5.6, описывает именно эти модели, а не их преемников. slop-marker-convention и human-made-disclosure остаются единственными надёжными способами достоверно узнать авторство.
Ближайший аналог - llm-cross-entropy-similarity, где сходство стилей разных моделей картируется с помощью посимвольных триграмм; здесь же для различения источников n-граммы POS-тегов превзошли посимвольные n-граммы. Пересечение Kimi и GLM - то же самое семейное сходство, которое qwen-gpt-reasoning-prefills исследует совершенно другим методом. А claude-vocabulary-clusters вовсе обходится без меток: эта страница кластеризует описания pull request'ов на GitHub по словарю, не опираясь на примеры от людей или LLM для обучения.