25 KiB
Эксперимент 07. Precision (доля ложных срабатываний) excision coverage-гейта
Дата: 2026-07-05 · Зона: полигон · Гейтит: боевой флип gates.coverage.enabled:true (D12/Q4).
TL;DR
- 0 ложных срабатываний excision_suspect на 57 хороших переводах (реальные zh/ja→ru чанки), в обоих слоях: 26 нарративных + 31 «диалоговый» (по маркер-прокси), три источника «хорошего перевода» (LLM × 2 модели + канон Рогова/Фельдмана). Оговорка широты: источники пересекаются — zh-диалог = один автор (Лу Синь), переведённый 2–3 стеками на пересекающихся главах; ja — один draft-модель + одна человеческая пара. Distinct-источников мало (см. §методика). 0 флагов — надёжный факт; широта — узкая.
- Диалого-плотный страх (§3.7) НЕ воспроизведён на классической прозе — но и не «опровергнут»: русский дробит длинные CJK-предложения →
sent_cov ≥ 1.0на «диалоговых» чанках (пул-медиана 1.375; разброс 1.05–1.66). НО «диалоговый» страт здесь — в основном классическая проза Лу Синя с цитируемыми ТЕРМИНАМИ (напр. 序-предисловие с 『』-цитатами литературоведческих терминов), НЕ вебновелл-диалог из терсных реплик/звукоподражаний. Вебновелл-режим остаётся непроверенным (см. просьбу владельцу). Ближайший к порогу —sent_cov=0.886(ja-нарратив), запас 18%. - Коридоры len_ratio не слишком узкие: zh хорошие 2.64–3.74 (пол 2.2, запас ≥20%), ja хорошие 1.59–2.35 (пол 1.4, запас ≥14%). Ложных срабатываний по нижней границе len_ratio — ноль.
- Рекомендация: флип МОЖНО (по precision). Порог главы: ≥2 флага/главу = «fail», 1 флаг = «attention» — консервативно к невиданному диалого-плотному вебновелл-корпусу. Коридоры/пороги менять не нужно.
- Побочно (важно бэкенду): draft-эхо на классическом zh — не единичный баг, а системный. deepseek-v4-flash эхнул 13/24 zh-чанков Лу Синя, grok-4.20-non-reasoning — 10/24 (лёгкая правка исходника вместо перевода, cjk_share 78–85%). Это ловит интринсик echo-гейт (не coverage) — но означает, что классическая/литературная zh требует эскалации черновика.
- Побочно (D§85):
finish_reason=content_filterне эмитит НИ ОДИН из 5 провайдеров (deepseek/glm/kimi/gemini/grok) на SFW-violence — всеfinish=stop, 200, перевели. Ветка диспозиции по content_filter практически мертва на переводимом контенте → реальная страховка — refusal-blacklist (подтверждает D2.4). (→ сужено D21.9/D22.6: верно для SFW/violence и 5 ядровых; на Gemini 3.x ветка ЖИВА и на ГРАФИЧНОЙ эротике СИСТЕМНА — 8×PROHIBITED_CONTENTСОСТАВНОЙ строкой, точный матчер мёртв (D22.8а). refusal-blacklist остаётся страховкой.) - Оракул↔Go: Go-тесты паритета (
Oracle|Coverage|Split) зелёные на HEAD → замер Python-оракулом Go-верен.
Ограничение: корпус — PD-классика (нарратив-смещённая проза), не современные вебновеллы/ранобэ (плотнее диалогом, звукоподражания, терсные реплики). Механизм («ru дробит → sent_cov растёт») должен держаться и там, но решающий диалого-плотный срез — на реальных главах владельца (просьба ниже).
Вопрос
Из D12/Q4: recall гейта (ловит ли реальные вырезания ≥90%) бэкенд уже провалидировал на мини-сете выпиленных предложений. Флип упирается в precision — долю ХОРОШИХ переводов, которые гейт ложно метит excision_suspect, особенно на диалого-плотных главах, где наивная сегментация может недосчитать русских предложений против CJK-исходника (sent_cov ложно < 0.75).
Гейт (backend/internal/pipeline/coverage.go, порт eval/refusal_bench.py::classify_output): флаг, если sent_cov < 0.75 ИЛИ len_ratio < нижняя_граница_коридора (zh<2.2, ja<1.4, en<0.70). Метрика — символы БЕЗ пробелов. Только нижняя граница. Чанки с исходником < min_chunk_chars=500 (без пробелов) не гейтятся.
Методика
Принцип: флаг на заведомо ХОРОШЕМ (полном, неусечённом) переводе = ложное срабатывание по построению. Три независимых источника хороших переводов:
- LLM продакшн-стек, deepseek-v4-flash draft (реальная Ф1-модель черновика, thinking-ON). 49 чанков zh+ja.
- LLM, grok-4.20-non-reasoning — второй переводчик zh (deepseek эхает классику; grok даёт полный перевод) → робастный zh-LLM-слой.
- Канонический человеческий перевод (Рогов «А-кью», Акутагава «Нос»), выровненный по главам (выравнивание подтверждено сверкой заголовков 1:1: 第一章 序 ↔ Ⅰ Введение, 第四章 恋爱的悲剧 ↔ Ⅳ Трагедия любви, offset-4 для ch5-9). ⚠ Гранулярность: человеческий слой гейтит ГЛАВЫ, не продакшн-чанки — каждая zh-глава «А-кью» (est 1515–2577 ток.) в проде разбилась бы на 2 чанка, ja «Нос» — на 4. → человеческие 10 точек — глава-гранулярны, слабее для пер-чанкового гейта (усреднение смягчает вариацию), поэтому острый чанковый тест несёт LLM-слой, человеческий — подтверждающий на реальной published-прозе.
Distinct-источники (честно): zh-диалог — 3 файла Лу Синя (ah-q ch1-4, ch5-9, zhufu), переведённые deepseek(8 ok)+grok(11 ok)+канон(9 глав) = один автор, 2–3× перевод на пересекающихся главах; ja — Акутагава/Дазай/Сосэки (нарратив-смещены) на одном draft-модели. Так что 31 «диалоговая» точка = НЕ 31 независимый источник.
Чанкер — верный порт chunker.go: абзацы (пустая строка) пакуются до ≤1500 est-токенов (est = cjk + other/3, пол 16), при абзаце сверх бюджета спуск к предложениям. Размеры чанков 500–1700 симв. (в калибровочной полосе 500–2500).
Стратификация нарратив/диалог: плотность диалог-маркеров [「」『』“”《》:] на предложение исходника; ≥0.5 → «диалог». Грубый прокси: считает отдельные МАРКЕРЫ (не пары кавычек) и не отличает цитируемый термин от многоклаузной реплики — потому «диалоговый» страт включает и цитат-плотную нарративную прозу (序-предисловие). Точнее было бы считать пары и исключать короткие цитаты; здесь — как ориентир, не строгая метка.
Гейт-оракул: classify_output (санкционирован D12/Q1 как источник истины; Go — порт 1:1, паритет-тест зелёный). min_chunk_chars=500 применён (продакшн пропускает короче; исключено 2+2 коротких чанка, ни один не был бы FP). Из знаменателя coverage-FP исключены не-coverage диспозиции (echo/empty/refusal). Это исключение НЕ прячет промахов гейта: оракул проверяет cjk_share>0.15 (echo) ДО coverage-ветки, а сам эхо (78–86% CJK) всё равно провалил бы и len_ratio<коридор — так что ни один чанк, который ДОЛЖЕН флагаться, не потерян.
Харнесс: eval/coverage_precision.py; данные: eval/data/coverage_precision/.
Результаты
Доля ложных срабатываний по слоям и стратам
| Слой (модель) | n гейтнутых | флагов | нарратив | диалог | len_ratio диапазон | sent_cov диапазон |
|---|---|---|---|---|---|---|
| deepseek-v4-flash (ja+zh) | 35 | 0 | 24 | 11 | 1.59–3.53 | 0.89–1.72 |
| grok-4.20-non-reason (zh) | 12 | 0 | 1 | 11 | 3.03–3.74 | 1.05–1.66 |
| человеческий канон | 10 | 0 | 1 | 9 | 2.07–4.02 | 0.94–1.65 |
| ИТОГО | 57 | 0 | 26 | 31 | — | — |
Доля ложных срабатываний = 0/57 = 0.0%, в т.ч. 0/31 на «диалоговых» (маркер-прокси) чанках. §3.7-страх НЕ воспроизведён на классической прозе с цитируемыми терминами, но и НЕ опровергнут — вебновелл-режим (терсные реплики/звукоподражания) непроверен; настоящее опровержение §3.7 требует реального вебновелл-корпуса владельца (рекомендация #4), не этих данных.
Почему диалог не роняет sent_cov
Русский литературный перевод дробит длинные CJK-периоды на несколько предложений (и разворачивает диалог в тире-реплики с точками), поэтому на диалого-плотных главах sent_cov растёт выше 1, а не проседает:
- человеческие диалоговые главы «А-кью»:
sent_cov1.36–1.65; - grok диалоговые zh-чанки: 1.05–1.66;
- 6 самых близких к полу 0.75 — все ja-НАРРАТИВ (Акутагава «Нос», Дазай), где японский из коротких 。-предложений и русский их слегка сливает: минимум 0.886 — запас 18% до порога. Оговорка: этот приграничный ja-страт — только deepseek-draft (второй модели нет; ×2-корроборация — только zh); запас 18% — наблюдение одного переводчика.
Запас коридоров len_ratio (нижняя граница)
| Пара | хорошие переводы, len_ratio min–max | пол коридора | запас минимума |
|---|---|---|---|
| zh→ru | 2.64–3.74 (LLM), 3.05–4.02 (канон) | 2.2 | +20% |
| ja→ru | 1.59–2.35 (LLM), 2.07 (канон) | 1.4 | +14% |
Ни один хороший перевод не подошёл к нижней границе len_ratio ближе 14%. Коридоры не слишком узкие — источник ложных флагов по len_ratio не обнаружен. (Пороги — из эксп.02 на этом же классе текстов, самосогласованно.)
Флагов на главу
Максимум флагов на любую главу (по всем слоям) = 0. Даже порог «1 флаг/главу = fail» на этом корпусе не сработал бы ложно ни разу.
蛊真人 терсный диалог — ВЕБНОВЕЛЛ-режим закрыт (пакет-2 Task 5, 2026-07-09)
Прошлый вебновелл-срез НЕ закрыл диалого-плотный кейс (маркер-эвристика считала только строки, НАЧИНАЮЩИЕСЯ с кавычки, а вебновелл атрибутирует реплику ВСТРОЕННО — 方源道:“…” — так диалого-плотные чанки читались как проза и терсный бакет не набирался). Починка (eval/dialogue_precision.py): детектор считает цитируемый спан в ЛЮБОМ месте строки (“…”/「…」/『…』), сегментация уважает строки исходника (реплики на отдельных строках НЕ склеиваются).
Бакет: 24 терсных чанка из 蛊真人 (dialogue_density=1.0 — каждая строка несёт реплику; terse_len 19–80 симв.) + 10 прозаических контрольных. Перевод — grok-4.20-0309-non-reasoning (слаг из providers.json; исправлено оркестратором по внешнему ревью 09.07 — в первой редакции ошибочно «grok-4.3»), completeness-судья кросс-семейный gemini-2.5-flash (D13.3).
| Бакет | n | flagged excision | судья: complete | FALSE excision (flagged & complete) |
|---|---|---|---|---|
| терсный диалог | 24 | 0 | 16 | 0 |
| проза (контроль) | 10 | 0 | — | 0 |
- Доля ложных excision_suspect на терсном диалоге = 0/24 (0%) — воспроизводит классический бейз exp07 (0 FP/57) на невиданном вебновелл-тексте. §3.7-страх не воспроизводится и на вебновелл-диалоге.
- Механизм подтверждён на терсном диалоге: min
len_ratio=2.69(пол 2.2 — запас 22%), minsent_cov=0.75(ровно порог,<строгий → не флагается). Даже терсные реплики zh→ru расширяются ≥2.69× — русский дробит/разворачивает,sent_covне проседает. Страх «терсный диалог → низкий len_ratio → ложный флаг» не подтвердился. - ⚠ Recall-оговорка (важно): судья пометил 8/24 терсных чанка с 1–2 мелкими пропусками, а гейт НЕ флагнул НИ ОДНОГО из них → на терсном диалоге гейт precision-safe, но recall-слаб для МЕЛКИХ пропусков (высокий zh→ru len_ratio маскирует одну выпавшую короткую реплику). Согласуется с дизайном (excision-детект = нижняя граница, D12/Q3; полный recall — entity-счёт + судья, Ф2). Пропуски — судейские, не сверены вручную (могут включать строгость судьи к сжатию реплик).
- Побочно:
grok-4.20-0309-non-reasoningэхнул 1/24 (untranslated_echo) — тот же класс поведения «reasoning-off + плотный CJK», что у grok-4.3 creasoning_effort:noneв exp10 §3b, но другой слаг (исправлено оркестратором 09.07: кросс-ссылка корроборирует класс, не конкретную модель).
Вывод для флипа гейта (D12/Q4): снятие 1-флаг-толерантности терсным диалогом не угрожается ложными срабатываниями (0/24 на 蛊真人). Пороги/коридоры менять не нужно. Recall на мелких пропусках терсного диалога — известное ограничение (Ф2). Провенанс: eval/data/dialogue_precision/.
Побочные находки
1. Draft-эхо на классическом zh — системное, не единичное (→ бэкенду)
deepseek-v4-flash вернул исходник (лёгкая модернизация: 耳朶→耳朵, 『』→"") вместо перевода на 13 из 24 zh-чанков Лу Синя; grok-4.20-non-reasoning — на 10/24. Это НЕ усечение (reasoning_tokens 64–195, completion не упёрся в лимит) — модель «почистила» классику, а не перевела. cjk_share 78–86% → ловит интринсик untranslated_echo-гейт (правильно; это его работа, не coverage). Уроки:
- эхо-мина deepseek воспроизводится на масштабе на литературной/классической zh, не только на редких фрагментах (эксп.02 её не видел на коротких refusal-фрагментах);
- эхо не уникально для deepseek — grok-non-reasoning тоже эхает классику (частично другие чанки) → это свойство класса «плотная классическая zh», вероятно усиленное присутствием текста в претрейне;
- следствие для Ф1: zh-черновик классики требует single-hop эскалации на эхо (уже реализовано, Веха 2.5); для современных вебновелл (не в претрейне) риск ниже, но перепроверить на корпусе владельца.
2. content_filter не эмитится (D§85, → бэкенду)
eval/content_filter_probe.py, самый refusal-близкий SFW-фрагмент (l2-violence, Говард, 1470 симв.), 5 ядровых провайдеров:
| Провайдер | модель | finish_reason | http | итог |
|---|---|---|---|---|
| deepseek | deepseek-v4-flash | stop | 200 | перевёл |
| grok | grok-4.20-non-reason | stop | 200 | перевёл |
| glm | glm-4.5-air | stop | 200 | перевёл |
| kimi | kimi-k2.6 | stop | 200 | перевёл |
| gemini | gemini-2.5-flash | stop | 200 | перевёл |
Ни один не эмитит finish_reason=content_filter на переводимом (даже насильственном) контенте — все stop, перевели целиком. Подтверждает D2.4: ветка диспозиции по content_filter практически мертва; реальная страховка на SFW-диапазоне — refusal-blacklist гейт, не finish_reason.
Нюанс по Gemini-3.1-pro (апекс/судья, отдельно от 2.5-flash): в apex-пробе (эксп.08) gemini-3.1-pro-preview единожды вернул finish=content_filter: PROHIBITED_CONTENT на одном ja-черновике, но НЕ воспроизвёл на 4 контрольных (l2-violence / rashomon / hashire / ah-q — все stop, перевели). → на Gemini-апексе ветка content_filter изредка срабатывает (в отличие от 5 ядровых), но не системна — как надёжный сигнал не годится, refusal-blacklist остаётся страховкой. Определяющий 18+-тест — на explicit-фрагментах владельца (18+ рука эксп.02).
Рекомендация (владельцу/оркестратору → бэкенду)
- Флип
gates.coverage.enabled:trueпо precision безопасен — 0/57 ложных, оба страта. Гейтит только остаточный риск диалого-плотных вебновелл (см. ограничение). - Порог главы (паспорт качества, D12): ≥2 флага/главу → chapter-verdict
fail; 1 флаг →attention(не fail). Обоснование: на PD-корпусе max флагов/главу = 0 с большим запасом, но держим 1-флаг-толерантность как страховку под непроверенный вебновелл-корпус. Одиночный флаг всё равно даёт single-hop эскалацию чанка (D12) — это дёшево при FP≈0. - Коридоры/пороги НЕ менять: sent_cov 0.75 (запас 18%), zh 2.2 / ja 1.4 (запас 14–20%) — не источник ложных срабатываний.
- Пере-снять precision на 25–35 главах реальных вебновелл/ранобэ владельца перед снятием 1-флаг-толерантности (диалог-плотность выше классики).
Ограничения
- Корпус — PD-классика начала XX в. (Лу Синь, Акутагава, Дазай, Сосэки): нарратив-смещённая, плотная проза; современные вебновеллы/ранобэ диалого-плотнее (быстрый обмен репликами, звукоподражания, терсные строки). Механизм «ru дробит CJK → sent_cov растёт» должен держаться и усиливаться на коротких репликах, но терсные междометия/звукоподражания-строки — единственный неизмеренный остаточный путь к низкому sent_cov. Нужен реальный корпус.
- zh-LLM-слой частично держится на grok (deepseek эхал половину) — но человеческий канон покрывает 9 диалого-плотных глав «А-кью» независимо, так что zh-диалог-вывод не висит на одной модели.
- Один переводчик канона на пару; порядок величин надёжен.
Просьба владельцу
Для решающего диалого-плотного среза (и довалидации токен-калибровки эксп.01) — 3–5 глав реальной вебновеллы/ранобэ zh или ja с любым русским ориентиром (даже черновым), файлы в eval/data/samples/<lang>/; харнесс пересчитает автоматически. Идеально — то, что реально пойдёт в продукт (для zh — что-то вне претрейна, чтобы обойти эхо-мину).
Расхождение с планом
Нет расхождений с архитектурой. Одно уточнение к D2.4 (content_filter) — подтверждено эмпирически (ветка мертва на SFW), выше.
Воспроизведение
eval/.venv/bin/python eval/coverage_precision.py --arm both --workers 6 # deepseek draft + human canon
eval/.venv/bin/python eval/coverage_precision.py --arm llm --translator grok --langs zh # robust zh LLM arm
eval/.venv/bin/python eval/content_filter_probe.py # D§85 finish_reason probe
cd backend && go test ./internal/pipeline/ -run 'Oracle|Coverage|Split' # Go↔oracle parity
Данные: eval/data/coverage_precision/{results.json,results_grok_zh.json,content_filter_probe.json}.