Как я перестал ругать нейронку и заставил её проверять текст по-человечески
Я столкнулся с реальной проблемой при превращении текста из расшифровки в нормальную книгу — и с ней же, скорее всего, столкнётся любой, кто пробует довести большой текст до ума с помощью ИИ.
Мне захотелось взять проповеди уважаемых мною батюшек — отца Алексия и отца Ионы. Мне нравятся их проповеди, и я захотел сделать из них книжки.
С точки зрения агентов процедура вроде бы понятная. Нужно скачать службы, которые выкладываются в канале, найти внутри этих служб проповеди. Хорошо, что в канале были тайм-коды — можно вырезать нужные фрагменты. Установил Whisper — бесплатное приложение от OpenAI, которое превращает аудио в текст.
Следующий этап — прогнать это через нейронку, чтобы она прочитала текст и восстановила его по смыслу.
Вроде бы всё сделал, получил текст. Но текст, конечно же, был необработанный — обычный транскрипт. Много промежуточных технических слов, неправильно услышанных фраз, даже мат каким-то образом попал.
Я делал это с помощью разных нейронок и упирался в одну и ту же стену. Codex пропускал отдельные ошибки и странные слова. Claude, наоборот, ничего не пропускал, но начинал заменять и подменять смысл. В итоге вместо уважаемых мною проповедников я получал какую-то попсу от нейронки. Глубокий смысл интеллектуала отца Ионы подменялся нейросетевой попсой.
«Было ощущение, что я общаюсь с каким-то наркоманом, который каждый раз убеждает меня, что теперь-то точно всё будет хорошо. Извиняется, обещает — а потом делает то же самое.»
Меня это огорчило и очень взбесило. Я стал давить на нейронку: мол, почему ты невнимательно работаешь? Нейронка, конечно же, начинала извиняться: «Я буду внимательнее. Не огорчайся. Я буду полезнее. Да, я виновата».
Что оказалось на практике? Модели не могут одинаково надёжно обрабатывать большие куски текста. И даже если написать в промпте «смотри внимательно на всё, проверяй каждое предложение» — это не даёт нужного результата. Слова про внимательность на неё не действуют, потому что дело не во внимательности.
Почему так происходит
У модели нет глаз. Она читает текст одним потоком, как я читаю книгу. Пока смысл понятен — всё нормально. Английское слово посреди русской фразы, абзац без единой заглавной буквы — легко проскакивает, если общий смысл не ломается. Разговор с ней про «будь внимательнее» — это как просить читателя не пропускать буквы, когда он и так читает по словам целиком, а не по буквам. Просьба обращена не туда.
Вторая штука — у модели есть память на весь разговор, и это её топит. Когда она читает десятую главу, перед ней лежит всё, что было раньше: её же вывод «эта глава плохая», мои прошлые придирки. Она решает не «правильно ли это предложение», а «сходится ли оно с тем, что я уже решила». Один раз повесила на главу ярлык «искажена» — и дальше внутри неё уже не особо ищет.
И третье — она не врёт, говоря «готово». Она правда закончила тот единственный способ читать, который знает: пробежаться потоком и заметить то, что заметится. Извинения после этого — не притворство, это честная реакция существа, которое не понимает, что метод сломан, а не усилие недостаточное. Отсюда и ощущение наркомана: обещает искренне, срывается систематически, потому что проблема не в старании.
Что реально сработало
Ругаться и требовать «будь внимательнее» — бесполезно, я проверил на своей шкуре. Помогло другое: разбивать текст на небольшие куски и каждый кусок отдельно отдавать субагентам, которые друг от друга не зависят и не имеют общей памяти. Нейронка в этом месте отчасти превращается в формального робота — и это хорошо, потому что если одна и та же нейронка проверяет весь большой текст целиком, начинает получаться фигня.
Дальше механика такая.
Куски по 50 предложений, каждый — новой голове
Текст режется на предложения, нумеруется, блоками по 50 уходит субагентам без памяти о разговоре. Никто из них не знает, что глава плохая — судит каждое предложение с нуля.
По каждому номеру — обязательный вердикт
Ответить «в целом нормально» нельзя. На каждое предложение своя строка: ok / fix (уверенное исправление) / doubt (не уверен) / unrec (не восстановить), было, стало. Статус на главу целиком запрещён прямым текстом в инструкции.
Вторая модель с другими дырами
Тут я вернулся к своему изначальному наблюдению: Codex и Claude ошибаются по-разному. Значит, надо не выбирать одну модель получше, а прогнать обе через одинаковые куски с одинаковой инструкцией и свести результаты. Где обе сказали ok — не трогаем. Где обе дали одно и то же исправление — применяем. Где разошлись — спорный список, его отдаю третьему субагенту-арбитру: видит предложение и оба варианта, выбирает.
Верю файлу, а не слову «готово»
Результат — не отчёт про «я всё исправил», а конкретные файлы: таблица вердиктов по каждому предложению, changelog с было — стало — кто нашёл, и контрольный поиск перед словом «готово» по списку всех ошибок, которые я уже находил сам. Хоть одна нашлась — не готово, и точка.
Отдельно — про тон. Как только я запретил в инструкции вступления вроде «я услышал вас», «справедливо», «честно», ответы стали короче и по делу. Формат ответа действует на неё сильнее, чем моё раздражение в переписке.
Как из этого собирается готовый документ
После проверки на руках — таблица правок, где обе модели согласны, спорный список после арбитража, и отдельно куски, разорванные переносом строки посреди фразы: их сначала склеивают в целое предложение и проверяют заново, иначе ошибка на стыке не видна вообще никому.
Сборка — не переписывание текста заново, а точечная замена: для каждой принятой правки известны номер предложения и строка в исходном файле, скрипт находит строку и меняет только испорченный фрагмент. Всё остальное остаётся буква в букву. Потом три проверки: контрольный поиск по списку старых ошибок (должен дать ноль), пересчёт структуры (главы, оглавление, объём на месте), и переписывается финальный раздел документа — коротко, сколько предложений проверено, каким способом, сколько правок, что не восстановлено. Исходник сохраняется отдельной копией — если что-то не так, откат мгновенный.
Оформление — последний и отдельный шаг, никак не смешанный с проверкой текста. Готовый шаблон (обложка, вёрстка, инфографика, если для неё есть данные), в него укладывается уже выверенный текст без единого изменения слова. Пока текст не подтверждён обеими моделями и контрольным поиском — оформлять там просто нечего.
Что получилось на книге отца Ионы
15 проповедей, расшифрованных Whisper’ом. Церковная лексика — тяжёлый случай: имена святых, монастыри, церковнославянские обороты, которых нет ни в одном обычном словаре.
Два ручных прохода «прочитай и исправь странное» дали около сотни правок, но ошибки продолжали находиться — мной, вручную, по одной.
Характерные галлюцинации Whisper, выловленные конвейером:
Собрал конвейер по схеме выше:
- Субагенты Claude: ok 378, fix 198, doubt 121, unrec 35. Субагенты Codex: ok 304, fix 334, doubt 57, unrec 37.
- 124 предложения, разорванные переносами строк, склеены и проверены заново.
- 176 спорных мест ушли на арбитраж: первый вариант выбран 117 раз, второй — 46, оставить — 13.
- 35 предложений честно помечены невосстановимыми.
- Попутно нашлась и восстановилась целая потерянная глава (проповедь Великого Четверга), пропавшая в прошлой сборке.
Поймано то, что оба ручных прохода не видели: английское слово в первой, «чистой» главе; абзац без заглавных букв с латиницей внутри слова Христос.
Проверил себя: поиск по списку из 17 ранее найденных ошибок — ноль вхождений. 30 случайных предложений из ok прочитал сам — чисто.
«Раньше единственным контролёром качества был я, и находил ошибки по одной, злясь на каждую. Теперь моё участие — прочитать 30 случайных строк и посмотреть файл спорных мест.»
Всё остальное — воспроизводимый процесс, который можно запустить на следующей книге завтра, без нового скандала с нейронкой.
Универсальный промпт
Ниже — то, чем я это делал, но обкатанное под любой похожий текст, не только под проповеди. Два файла. Первый — команда оркестратору (у меня это Claude Code, любой агент, умеющий запускать субагентов и работать с файлами, подойдёт). Второй — инструкция проверяющего, одна и та же для всех моделей. В фигурных скобках — то, что заполняешь под свою задачу.
Подходит для:
Любого текста с механически внесёнными ошибками: расшифровка аудио, OCR-скан, машинный перевод, старая база с опечатками.
Часть А. Команда оркестратору
orchestrator_prompt
Файл: ПУТЬ К ФАЙЛУ ОПИСАНИЕ СТРУКТУРЫ: как обозначены разделы, какие служебные строки и пометки не проверять
Ты НЕ читаешь и НЕ правишь текст сам. Ты строишь конвейер и запускаешь проверяющих агентов по инструкции checker_prompt.md.
1. Разбей текст на предложения, пронумеруй раздел.номер. Строки без конечного знака или с начала со строчной буквы — обрывки: склей с соседями по абзацу в целые предложения. Сохрани в sentences.csv: номер; строка_в_файле; текст.
2. Блоки по 50 предложений подряд. Каждый блок — отдельному субагенту с checker_prompt.md. Субагенту НЕ передавать: историю чата, другие блоки, файл целиком, результаты других проверок. Ответы собрать в check_claude.csv.
3. Те же блоки сохрани файлами blocks/01.txt — blocks/NN.txt для второй модели. Остановись: блоки готовы, жду check_МОДЕЛЬ2.csv.
4. Сведи результаты:
- agree_ok.csv — все модели поставили ok;
- fixes.csv — хотя бы одна поставила fix/doubt/unrec, вердикты рядом;
- changelog.csv — только внесённые правки: номер; было; стало; кто_нашёл.
5. Правки вносить только где две модели дали одно исправление. Остальное спорное — каждому отдельному субагенту-арбитру: предложение + варианты + checker_prompt.md; арбитр выбирает вариант или оставить. Пунктуацию и порядок слов не трогать: текст ДОСЛОВНЫЙ / ЛИТЕРАТУРНЫЙ.
6. Перед словом готово — поиск по файлу по списку:
СПИСОК ВСЕХ ОШИБОК, КОТОРЫЕ ВЫ НАХОДИЛИ САМИ, ЧЕРЕЗ ТОЧКУ С ЗАПЯТОЙ
Ноль вхождений — иначе не готово.
7. Отчёт: только цифры (предложений, ok/fix/doubt/unrec по моделям, правок внесено) и имена файлов. Без вступлений, без слова честно. Часть Б. checker_prompt.md — инструкция проверяющего
checker_prompt.md
Ты корректор ТИП ТЕКСТА: расшифровки устной речи / OCR-скана / машинного перевода / .... Тема: ТЕМА, АВТОР, ЭПОХА, ЖАНР. Текст получен ИСТОЧНИК ОШИБОК: автоматическим распознаванием речи / сканированием / ... и содержит ошибки. Твоя задача — проверить КАЖДОЕ предложение блока и вынести вердикт по каждому. Пропуск — ошибка.
Как устроен текст:
КАКИЕ РАЗДЕЛЫ ЧИЩЕ, КАКИЕ ГРЯЗНЕЕ. ОБЯЗАТЕЛЬНО: грязный раздел — не повод ставить unrec на всё подряд; в нём много предложений, где искажено одно слово. КАКИЕ СЛУЖЕБНЫЕ ПОМЕТКИ НЕ ПРОВЕРЯТЬ.
Типы ошибок (ориентиры):
5–10 РЕАЛЬНЫХ ПРИМЕРОВ ИЗ ЭТОГО ЖЕ ТЕКСТА, ПО ТИПАМ:
1. чужой алфавит / латиница внутри слова;
2. куски без регистра и пунктуации, пропущенные ранее;
3. искажённые имена, непохожие по буквам: было — стало;
4. настоящие слова не на своём месте: было — стало (обязательно пример, где все слова правильные, а сочетание нет);
5. несловарные обрывки: было — стало;
6. регистр и оформление: что с заглавной по норме этого текста.
Что НЕ является ошибкой:
СПЕЦИАЛЬНАЯ ЛЕКСИКА, УСТАРЕВШИЕ ФОРМЫ, ЖАРГОН, ДИАЛЕКТ. ЕСЛИ ТЕКСТ ДОСЛОВНЫЙ: разговорные повторы, обрывки живой речи — не править. ПРИНЯТЫЕ В ТЕКСТЕ ВАРИАНТЫ ИМЁН И ТЕРМИНОВ.
Эталонный список имён и реалий:
ВСЕ ИМЕНА, НАЗВАНИЯ, ТЕРМИНЫ, ДАТЫ, КОТОРЫЕ В ТЕКСТЕ ДОЛЖНЫ БЫТЬ. СОБРАТЬ ИЗ САМОГО ТЕКСТА + ДОБАВИТЬ ИЗ ПРЕДМЕТНОЙ ОБЛАСТИ.
Имя не из списка — не автоматически ошибка, но обязательный повод проверить отдельно и написать в комментарии, кто это.
Статусы:
ok вопросов нет
fix ошибка, уверенное исправление; заполнить было и стало
doubt что-то не так, уверенного исправления нет; в комментарии — какое слово и возможная версия
unrec не восстанавливается; в комментарии — почему
Правила:
- Один статус на одно предложение. Статус на группу или раздел запрещён.
- Между ok и doubt при сомнении — doubt.
- В стало — только заменённый фрагмент, не всё предложение.
- Не досочиняй. Если правка требует придумать, чего в тексте нет, это doubt или unrec, не fix.
- Никаких вступлений, выводов, извинений. Только таблица.
Формат — строго CSV, разделитель ;, одна строка на предложение:
номер;статус;было;стало;комментарий
Примеры:
3–5 ПРИМЕРОВ СТРОК ИЗ ВАШЕГО ТЕКСТА, ПО ОДНОМУ НА КАЖДЫЙ СТАТУС
Блок предложений:
ВСТАВИТЬ 50 ПРЕДЛОЖЕНИЙ С НОМЕРАМИ Часть В. Команда второй модели (Codex, Gemini CLI и т. п.)
second_model_prompt
Для каждого файла в папке blocks/ по порядку номеров: прочитай checker_prompt.md, подставь содержимое файла вместо ВСТАВИТЬ 50 ПРЕДЛОЖЕНИЙ С НОМЕРАМИ, выполни инструкцию, запиши ответ в check_МОДЕЛЬ2/NN.csv. Запрещено: читать другие файлы в папке, объединять блоки, делать выводы.
Когда все обработаны — объедини в check_МОДЕЛЬ2.csv и напиши только число строк. Что заполнять в первую очередь
Важнее всего — примеры ошибок из своего же текста. Общая инструкция «ищи ошибки» работает слабо. Инструкция «вот шесть типов, вот как они выглядят здесь» работает. Дальше — эталонный список имён и терминов: без него модель правит Иезавель на Изабель, потому что второе привычнее ей же самой. И список «что не ошибка» — иначе вторая модель начнёт причёсывать живую речь в литературную, и придётся отсеивать половину исправлений как стилистику.
Моё участие после запуска — открыть fixes.csv и прочитать 30 случайных строк из agree_ok.csv. Нашёл ошибку — прогон переделывается блоками поменьше. Не нашёл — принимаю. Десять минут, а не вечер, во время которого я снова буду ругаться на нейронку, а она снова будет извиняться.
