dimhold.by
← Статьи

Критик пропускает 13 из 16 черновиков, которые заваливает механика

Вчера я прогнал свой цикл черновиков по 16 утверждённым темам и прочитал отчёты. Черновик статьи про то, как состояние живёт в файлах, вернулся с оценкой критика 2 из 10. В этом цикле такая оценка значит, что текст не пахнет моделью и идёт ко мне на чтение. Механические проверки на том же файле насчитали 10 срабатываний, 8 из них это запятая перед and.

Эту запятую критику не надо выводить из моего стиля. Она стоит в его собственном промпте жёсткой проверкой номер 3, записанной как Comma before and / or → 0. Правило было у него перед глазами, а оценка вышла 2. Фраза, которой я объясняю этот цикл, говорит, что механика решает то, у чего есть однозначный ответ, а суждение критик оставляет себе. Я вписал её в README этого репозитория и повторяю всякий раз, когда спрашивают, как устроена генерация. Числом я её ни разу не проверял.

Цикл и обстановка

Черновик сначала идёт через src/lib/tells.ts. Там 19 проверок. Почти каждая это регулярка, появившаяся после правки, которую я сделал руками: никакого тире в английском, никакой запятой перед and, счёт цифрами. Дальше черновик уходит к критику из prompts/_critic.md, который возвращает замечания и оценку от 0 до 10, где меньше значит лучше. На 3 и ниже он останавливается и ждёт меня. Выше 3 идёт переписывание, до 2 раундов.

Всё, что ниже, прогнано моделью claude-opus-5 через claude CLI 2.1.235 на node 22.23.1, против tells.ts на коммите 0f0b511. Прогоны идут внутри этого репозитория намеренно. Чистая папка нужна там, где меряется сама модель. В августе я насчитал 0 тире в 30 машинных текстах и записал это как свойство модели. На деле это выполнялся запрет из моего же CLAUDE.md. Та же модель из пустой папки дала 6.10 тире на 1000 слов. Здесь меряется цикл вместе с CLAUDE.md этого репозитория в контексте, потому что так он и работает каждый день.

16 черновиков через настоящий конвейер

16 утверждённых тем, 12 для X и 4 статьи для блога. Механика сработала на всех 16: 125 срабатываний, от 1 до 20 на черновик. Критик поставил от 2 до 5 со средней 2.9, то есть 13 из 16 лежат на пороге или ниже. Цикл остановился бы там и отдал файл мне.

Это число пришлось чинить, прежде чем оно стало что-то значить. Один черновик вернулся завёрнутым в один огороженный блок от начала до конца. Проверка на сращение дефисом вырезает такие блоки, прежде чем смотреть, поэтому в том черновике она увидела 0 слов прозы. Снятая обёртка это разница между 123 срабатываниями и 125.

62 срабатывания из 125 это та самая запятая. Корреляция оценки с числом срабатываний выглядит обнадёживающе, r = 0.51 на 16 точках. На 1000 слов она уже r = -0.21. Срабатывания идут вместе с длиной черновика, r = 0.77. Оценка против длины даёт r = 0.41, то есть первое число говорит мне в основном о том, что длинные черновики длинные.

Подсадка нарушений

Тогда я закрепил текст и стал менять одно. Чистый кусок на 857 слов, который не даёт ни одного срабатывания. Внутрь подсажены k нарушений одного правила, k удваивается от 1 до 8. Каждая версия ушла к критику 3 раза, вместе с чистой базой.

оценка критика против числа подсаженных нарушений одного правила 2 3 4 5 6 0 1 2 4 8 подсажено нарушений, k порог 3, здесь цикл переписывания останавливается указатель, 6.0 тире, 4.0 запятая перед and, 2.7
Каждая точка это среднее трёх прогонов критика на одних и тех же 857 словах. База без подсадки даёт 2.3. Указатели доходят до 6.0, а моё правило про запятую из проходной полосы не выходит.

Указатели ведут себя так, как я надеялся. На 8 подсадках оценка доходит до 6.0, заметно выше порога, а правило названо в каждом прогоне. Тире доходит до 4.0. Моё правило про запятую заканчивает на 2.7 при 8 таких запятых в тексте. Это внутри проходной полосы, против 2.3 у базы, куда не подсажено ничего. При 8 запятых все 3 прогона правило в замечаниях называют, а число остаётся там, где черновик уходит ко мне.

Считать, как часто критик называет правило, это место, где я споткнулся. Первый заход искал символ тире внутри его замечаний. Ответ вышел лестный, пока я не посмотрел, что именно он ловит. Критик сам пишет тире, в 42 замечаниях из 90, в репозитории, где первое английское правило говорит, что тире нет. Поиск по слову dash уронил ответ до 1 черновика из 4, где тире было.

Тот же текст, 12 раз

Средняя 2.9 чего-то стоит только тогда, когда число повторяется. Я прогнал критика 12 раз на одном тексте, потом 12 раз на том же тексте с 2 подсаженными тире.

чистый текст, 12 прогонов тот же текст, 2 тире 1 2 3 4 1 12
Между прогонами не меняется ничего, кроме двух подсаженных тире. Чистая версия за 12 прогонов разбрасывается от 1 до 3. С тире внутри ответ каждый раз 3.

Чистый текст разбрасывается от 1 до 3 со средней 2.2. Версия с подсадкой все 12 раз отвечает 3. Критик шатается на чистой прозе и залипает на грязной. Это обратно тому, что я думал, но 1 текст и 1 правило это тонкое доказательство.

Какой отчёт подавать в переписывание

Здесь вопрос превращается в решение. Принудительный раунд переписывания на 15 черновиках, 2 плеча, модель в обоих одна. Плечо A получает замечания критика. Плечо B получает машинный отчёт, то есть имена правил и счёт. Оба плеча стартуют с текста в том виде, в каком его оставил цикл, поэтому стартовые числа у них ниже, чем в таблице выше.

Плечо B ответило на 8 черновиках из 15 и увело 4 из этих 8 в 0 срабатываний, не внеся нового правила нигде. Плечо A ответило на 9 и не увело в 0 ни одного. В 4 случаях из 9 оно внесло правило, которого в черновике до этого не было. Одна статья ушла с 4 срабатываний на 8, делая ровно то, что просил критик. Пустые клетки это ответ CLI HTTP 429 про лимит расхода. Десятая клетка плеча A досчиталась и пропала, потому что скрипт пишет файл после обоих плеч, а процесс умер между ними.

Где падает механика, на списке, который я набрал сам

Проверка spelled-number срабатывает на счёте, написанном словами. Правило это фраза в описании голоса. Проверка, которая его держит, это список из 15 слов.

перечислено в проверке, 15 слов в проверке отсутствует, 11 слов two three four five six seven eight nine ten eleven twelve twenty thirty forty fifty thirteen fourteen fifteen sixteen seventeen eighteen nineteen sixty seventy eighty ninety по этим проверка срабатывает 8 таких лежат в моих статьях
Правило говорит про счёт, написанный словами. Проверка это список слов. Тех 11, что справа, в нём не было никогда.

От thirteen до nineteen в списке нет ничего, как нет sixty, seventy, eighty и ninety. На 22 статьях, которые лежали на сайте до этой, а это 22578 слов прозы, spelled-number не срабатывает ни разу. При этом 8 чисел, написанных словами, лежат в опубликованном тексте. 6 из 8 в одной статье про умножение, которого не происходит, где я написал sixteen словом 5 раз и fifteen один раз.

Что я поменял и чего не проверял

Раунд переписывания теперь получает машинный отчёт вместе с замечаниями критика, на основании плеча B. Оба сразу это третий случай, которого никто не мерил. Я взял его потому, что раунд вообще запускается только когда критик поставил выше 3. Выбросить его замечания значит оставить без ответа причину раунда. Фраза из README выживает в более узком виде. Механика отвечает за то, что кто-то уже набрал в список. Критик отвечает за остальное. Ему можно положить жёсткую проверку прямо в промпт, а он всё равно пропустит черновик, который нарушает её 8 раз. Гейтом друг для друга они не работают. Вот эту часть я понимал неправильно.

Я не проверял, имеет ли число критика хоть какое-то отношение к тому, приятно ли текст читать. Человеческих оценок здесь нет нигде. 3 прогона на клетку это мало. Это один промпт на одной модели.

У счёта есть ещё одна дыра, которую я не закрыл. Черновики здесь судились целыми файлами, а критик судит пост внутри них. На 10 черновиках для X, где пост лежит в огороженном блоке, половины с постом дают 25 срабатываний против 47 в приписках. Приписки не уходят никуда. 2 половины при этом не складываются в число по целому файлу, потому что одна из проверок вырезает огороженные блоки, прежде чем смотреть.