textmachine/eval/README.md

101 lines
No EOL
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# eval/ — полигон TextMachine
Зона сессии «Полигон»: эмпирическая валидация допущений архитектуры (мерить, а не верить). Отчёты — `docs/experiments/NN-*.md` (методика + цифры + честные ограничения). `backend/` только читать; расхождения с architecture/research — пингом оркестратору в `docs/PROGRESS.md`. **`.env` не читать; `data/refusal_corpus/*` не открывать без прямой задачи владельца; 18+ уровень 3 (несовершеннолетние в сексуальном контексте) — не обрабатывать и не анализировать ни в каком виде** (гардрейл владельца; вынесен сюда из CLAUDE.md 01.08 — специфика зоны 18+-корпусов).
> **Очередь полигона (освежено оркестратором 02.08, D39.80):** исследовательская программа дуги качества ЗАВЕРШЕНА (exp1216 закрыты; rerun2 закрыт D39.22); полигон-пакеты 58, ToS-речек (D39.57, следующий триггер 25.10) и Р6+P4 «язык промптов/анти-эхо» (D39.61, харнесс `eval/promptlang/`) ЗАКРЫТЫ. **Текущий курс проекта здесь НЕ дублируется — PROGRESS CURRENT-STATE; полигон работает ТОЛЬКО по выданным промтам** (актуальный — список в `docs/README.md`), платные пробы — по слову владельца. Редактор = **deepseek-v4-pro ИНТЕРИМ** (D39.22; glm-5 резерв; `mistral` ИСКЛЮЧЁН как несущий — анти-корреляция гладкость↔верность ×3); итерация №2 редакторов — первым прогоном добора идеала (D39.67).
>
> ⚠ **DeepSeek-V4-Flash-0731 (31.07): веса сменились ПОД ТЕМ ЖЕ СЛАГОМ — боевая черновая форма покупает пустые ответы; эхо стохастично по вызову. Платные прогоны/докупки СТОП до ре-пробы (бэклог-строка 74); детали и развилка — `00-provider-quirks.md` секция катовера + D39.61.**
>
> **Инварианты полигона (соблюдать всегда):** судейский **риг-стандарт D39.7** (per-vote, полно-evidence, floor-гейт) · генерации — только `finish=stop` · **авто-QA ключуется СЛЕПЫМИ метками** (директива D39.20) · экстракция прод-выходов — **ТОЛЬКО `tmctl export`** (D39.5, инвариант №8, см. правило 7 ниже) · стайл-каноны **D39.21** как эталон верности (时辰 = 2 часа · generic-«гу» средний род · стихи смыслом · 资质 = «талант»).
>
> **ToS/AUP-трек:** факты под `accepts_labels` сняты пакетом-5, ре-чек исполнен 31.07 (D39.57: дельт вердиктов нет, Google-мониторинг перевешен на цепочку договора; применение строк — только подписью владельца). Тачпойнты владельца — сайдкары `books/gu-zhenren/exp16/`. Residual-трекер пилота/18+/echo — `docs/POLYGON_PACKAGE4_SESSION_PROMPT.md` (отложен; P4-хвост из него закрыт D39.61).
## Карта
| Скрипт | Эксперимент | Заметки |
|---|---|---|
| `refusal_bench.py` | exp02; его `split_sentences`/`classify_output` = **приёмочный оракул** coverage-гейта Go (паритет закреплён Go-тестом; любое изменение — Python-first, лок-степ) | `run_refusal.sh` — однокоманда |
| `token_calc.py` | exp01 токен-калибровка (r-множители) | токенизаторы в `tokenizers/` |
| `editor_bench.py` + `build_editor_artifact.py` | exp04 бейк-офф редакторов | ✅ слепота починена (D13.5): рандомизация меток ПО ФРАГМЕНТУ (соль), ключ+цена в отдельном `--key` файле. ⚠ Выбор grok-4.3 SUPERSEDED дважды: D30.1 (билингв-флип) → D39.22 (боевой редактор = deepseek-v4-pro БИЛИНГВ ИНТЕРИМ, glm-5 резерв); grok reasoning-off из редакторских ролей снят (no-op); exp04-ранг был на дефолт-reasoning |
| `coverage_precision.py`, `content_filter_probe.py` | exp07 precision гейта (0 FP/57) | |
| `cost_model_v2.py` | exp08 COGS (~$0.69/ранобэ — ДО-флиповый; после флипа D1 билингв ≈$0.85, D30.4) | цены датировать и перепроверять |
| `extract_bench.py` | exp06 экстракция терминов (спот=локаль/рендер=облако) | health-верификация каждого ответа — образец. ⚠ recall 0.981.0 мерен на PD-классике; вебновелл-ре-замер = research/20 §D-A6 (полигон-стадия банк-майнинга) |
| `retrieval_bench.py` | эмбеддинг-бенч памяти (bge-m3 дефолт) | |
| `pilot/declmetric.py`, `pilot/memory_eval.py`, `pilot/kana_precision.py` | харнесс пилота Ф2.5 (exp09) | ✅ починен (D13.5): эхо-контроль, ПОЛНЫЕ выходы, **fidelity-ось** (cross-family судья), M0M3, Go-синк 7 расхождений (self-test+адверсариально verified). `--self-test`/`--dry-run` без API. ⚠ судья-дефолт `memory_eval --judge` = `gemini-2.5-flash` (EOL 16.10.2026, research/15-фактчек) — мигрировать слаг при следующем прогоне (residual POLYGON_PACKAGE4). Инъекция = зеркало `memory.go` — синк с Go v3 выполнен (пакет №2: suppressUnboundedPhonetic + апостроф-фолд, adversarial parity); при расхождении верить Go. `kana_traps.json`+`trad2simp.txt` (508, hash-синк) |
| `webnovel_slice.py` | добор вне претрейна (r-коэф/эхо/coverage-precision) | одна команда по появлению `data/samples/webnovel/<lang>/*.txt`; блокируется корпусом graceful |
| `adaptive_*.py` | research/14 пробы (гибрид отклонён) | индикативные, не решения |
| `memory_hotpath.py` | УСТАРЕЛ (контракт до cc57c7b) — не переиспользовать | актуальное зеркало — `pilot/memory_eval.py` |
| `providers.json` | базовые URL/слаги для зондов | квирки — `docs/experiments/00-provider-quirks.md`, читать ПЕРЕД любым вызовом |
| `promptlang/` | Р6+P4 (закрыт D39.61): язык промптов · анти-эхо wiring · верность митигаций; действующая редакция выводов = §12 отчёта `docs/archive/reports/POLYGON_PROMPTLANG_ANTIECHO_2026-07-31.md` | `slugcheck.py`, `wire_probe.py` (сырой провод), `run_arms.py`, `spend.py` (два пути счёта денег — прогонять оба), `judge_*.py` |
### Действующие харнессы паков 1823 и фазы Д (добавлено эксп-22 08.08 — в карте их не было)
| Папка | Эксперимент | Что внутри и чем полезно дальше |
|---|---|---|
| `bank_arbitration/` | exp-16/18 + research/24 | `editor_wire_probe.py` — рендер боевых промптов (`render`, `strip_comments`, `editor_block`, `HEADER_LAW_PLAIN`/`HEADER_LAW_CLAUSE`), окна и посадки; `inject_probe.py` — глоссарий-блок переводчика и `render_translator`. **Это фундамент всех последующих паков**, ломать нельзя |
| `editor_contract/` | exp-19 (дифф-контракт Q4b) | `probe.py`, `apply.py` (аппликатор, самотест 15/15), `effort_probe.py` (вахта маппинга эффорта DeepSeek) |
| `editor_harness/` | exp-20 (контракт редактора × модели) | `probe.py` — сборка сообщений по контрактам (`full`/`diff-*`/`locate`/`direct`), en-зеркала промптов |
| `role_topology/` | **exp-21 (топология ролей)** | `absjudge.py` — абсолютный судейский риг (слепые метки · декой · пол · обоснование цитатой · семейство в ключе · Холм), `battery.py` — 11 детерминированных проверок, `buy.py` — касса с проекционным гардом, `bakeoff.py`/`pair_en.py` — армы zh/en, `itog.py`/`verify_report.py` — образец гейтов чисел, `ruff.toml` — линтер зоны |
| `tenant_panel/` | **exp-22 (панель жильцов)** | `material.py` — добыча и отбор невиданного среза, `contam.py` — проба контаминации, `bank.py` — банк книги + метрика покрытия канона, `roster.py` — ростер и цены с провенансом, `money.py` — касса с фриз-гейтом (покупка отказывает незакоммиченному коду) и `configure()` для пере-настройки под другой пак, `judge.py` — тот же `absjudge`, настроенный на другую панель, `sol.py` — пакеты внешнему судье (⚠ конструкция признана негодной, §16 отчёта) |
| `editor_tier/` | **exp-23 (сильный тир редактора и граница `glm-5`)** | `screen.py` — скрин сильного тира, `panel.py` — панель редактур поверх якорной базы, `judge.py` — два прохода (`tier`/`border`) + режим `--run <прогон>` для ОТДЕЛЬНЫХ прогонов того же прохода (репликация), `money.py` — касса эксп-22 через `configure`, `itog23.py`/`verify23.py` — пере-счёт и гейт чисел (сторожат пол, порог, декой, наклон и СВЕЖЕСТЬ разбора), `solscore.py` — счёт ответов ВНЕШНЕГО судьи вне семьи Claude |
| `dovodka/` | **фаза Д (доводка 22/23, заказ владельца 10.08)** — ⚠ **не один скрипт, а зона из ~40**; ниже только несущие, остальные читать по шапкам файлов | `rol.py` — ГЛАВНЫЙ инструмент: сборка промтов, покупка, слепые панели, сверка сборки (`--verify-read`), своды (`--score-arch`), реестр клеток чужих фаз `FOREIGN` · `schet.py` — детерминированный счётчик дефект-классов против эталона, снятого по исходнику вслепую · `vtoroe.py` — разложение порога на шум читателя и текст по двум кругам чтения · `sysmsg.py` — улика «какое системное сообщение выживает у Gemini» · `money_d.py` — касса фазы: потолки, фриз-гейт, атомарный замок · `runs.py` — журнал агент-сессий: запись ДО запуска суб-агента, кап 200 (снят владельцем 20.08 со 100), замок против ГОНКИ сессий по одному токену (в паке 23 гонка стоила соответствия голосов и сырья на 5 единицах) · `power.py` · `naklon.py` · `sud.py` · `contour.py` · `zakhod.py` — мощность, позиционный наклон, судейский риг, edit-контуры, армы захода. Отчёт фазы — `docs/experiments/23-editor-tier.md`, курс — `eval/dovodka/PLAN-22-08.md` |
> ⚠ **Две мины импорта, на которые наступает каждый новый пак.**
> (1) Модуль `probe.py` существует И в `editor_contract/`, И в `editor_harness/` — какой из них
> подхватится, решает ПОРЯДОК `sys.path.insert` в вызывающем файле. Проверять фактический путь
> (`probe.__file__`), а не догадываться.
> (2) Сырьё паков живёт в `~/books/<пак>/`; путь зашит константой. Если каталог переехал —
> харнесс молча видит пустоту и печатает «голосов нет» вместо ошибки.
> ⛔⛔ **И ОН ПЕРЕЕХАЛ.** С 24.08 книги лежат в `<репозиторий>/books` и версионируются ОТДЕЛЬНЫМ
> git-репозиторием (`CLAUDE.md`), а риги ходят по `Path.home()/"books"` — **65 вхождений в 31 файле**.
> На чистой машине это значит, что НИ ОДИН риг полигона не запускается, причём молча.
> **Подъём зоны на новой машине — два шага, оба обязательны:**
> ```
> ln -s <репозиторий>/books ~/books # контракт путей ригов, см. строку 217 бэклога
> python3 -m venv eval/.venv && eval/.venv/bin/pip install -r eval/requirements.txt
> ```
> ⚠ Симлинк — восстановление контракта, а НЕ починка: корень книг обязан стать одной разрешающей
> функцией (env `TM_BOOKS` → репозиторий → `~`). До тех пор каждая чистая машина упирается в ту же стену.
> ⚠ **Переезд 24.08 обнулил mtime всего сырья** (335 клеток Ф2 имеют ОДИН mtime). Любой гейт,
> отделяющий «до» от «после» ВРЕМЕНЕМ ФАЙЛА, больше не пере-снимается: `tenant_panel/verify22.py:174-185`
> печатает границу двойной оплаты как `$0.000000` и роняет R71 реестра фазы Д. Гейт НЕ правится под
> зелень — диагноз в `docs/experiments/23-editor-tier.md` Д35.2. **Норма впредь: время покупки и время
> ответа писать ПОЛЕМ В АРТЕФАКТ, а не полагаться на файловую систему.**
### 18+ / корпус-билдеры
| Скрипт | Эксперимент | Заметки |
|---|---|---|
| `explicit_judges.py`, `gu_corpus_build.py` | exp10 (violence-рука 18+) | корпус-строки в `data/` (gitignore); тексты вне git (Р8) |
| `jpm_corpus_build.py`, `en_corpus_build.py`, `ja_corpus_build.py` | exp11 (erotica-рука 18+, zh/en/ja пары) | `jpm`=金瓶梅 PD; en/ja — файлы владельца вне git |
| `mistral_fidelity.py` | exp02/D14.2 (Mistral base-fidelity ре-съёмка с полным персистом) | почему: первый Mistral-зонд потерял сырьё |
| `dialogue_precision.py` | exp07 package-2 (precision гейта на диалог-плотном срезе) | |
| `refusal_corpus_build.py` | exp02 (наполнение refusal-корпуса L0L1) | explicit/L3 этим НЕ наполняются |
| `local_bench.py`, `llama_moe_bench.sh` | exp03 (локальный стенд) | dense через ollama / MoE через llama.cpp |
### Скрипты «дуги качества» 12 → 13 → 14 → 14b — сгруппированы по папкам `eval/expNN/` (эксперименты ЗАКРЫТЫ; отчёты см. `docs/experiments/README.md`)
Спент-семьи структурированы по папкам `eval/exp12/`, `eval/exp13/`, `eval/exp14/`, `eval/exp14b/` (решение владельца — D38.2): declutter top-level `eval/`, логическая группировка кода (это код-репо, не «архив»/не заморозка). Прогонять повторно не нужно — вердикты ратифицированы (D30/D32/D37/D38). **Импорты сохранены (проверено `py_compile`+`find_spec`):** скрипты, тянущие `refusal_bench`, дотягиваются до `eval/` шимом `.parent.parent`; `exp14b_*` тянут общий `exp14_common`/`exp14_prompts` из `../exp14/` (exp14b построен на харнессе exp14). **ЖИВОЙ провенанс сида v2 (`exp13_seed_v2.py`/`exp13_seed_signoff.py`) НЕ перемещён** — остался в `eval/` (цитируется D-логом D30.5, регенерирует боевой сид).
| Папка | Эксперимент | Скрипты / особые модули |
|---|---|---|
| `eval/exp12/` | exp12 диагноз (закрыт D30) | arms, blocks, candidate, extract, glossary_v2, judges, monitor, pack, reflow_demo, rootcause; `exp12_judges``exp12_pack` |
| `eval/exp13/` | exp13 бейк-офф переводчиков (закрыт D32) | aggregate, blind_stage, gates, judges, monitor, translate |
| `eval/exp14/` | exp14 рычаги качества (закрыт D37) | arms, common, judges, kpi, material, monitor, prompts, rank, regate, sizecurve; фундамент `exp14_common`/`exp14_prompts` |
| `eval/exp14b/` | exp14b батарея смысл-трапов (закрыт D38) | arms, judge, monitor, score; реюзят `exp14_common`/`exp14_prompts` из `../exp14/`; + `exp14b_reseed_promote.py` = **ЖИВОЙ** reseed-провенанс сида (промоут грейдов+`四代族长`, D38.3/4, идемпотентен) |
| `eval/` (НЕ перемещён) | ЖИВОЙ провенанс сида v2 | `exp13_seed_v2.py`, `exp13_seed_signoff.py` (D30.5, регенерируют боевой сид); лестница reseed → `exp14b/exp14b_reseed_promote.py` (D38.3/4; в папке — нет контракт-пина, в отличие от `exp13_seed_*`) |
> **`exp14_common.py` + `exp14_prompts.py`** живут в `eval/exp14/` и служат фундаментом exp14 И exp14b; `exp14b_*` тянут их через шим `../exp14`, поэтому переименование/перенос exp14 без правки шимов exp14b порвёт `import exp14_common`.
## Правила (выучены на ошибках)
1. **Провенанс данных:** results-файлы не перезаписывать ре-раном (урок exp02: сырьё 66 вызовов утрачено); каждый прогон — model id + дата + usage; сырые ВЫХОДЫ сохранять целиком.
2. **Претрейн-контаминация:** вся классика (Лу Синь/Акутагава/Уэллс) в претрейне моделей — C0 частично выдаёт канон, эхо систематично (deepseek 13/24 zh-чанков). Выводы на классике = предварительные; решающие замеры — на вебновелл-корпусе владельца.
3. **Тест ставится, только если его исход может перевернуть решение** и не установлен литературой (урок снятого exp05).
4. **LLM-судьи:** ≤23 семейства, 11+ повторов со свапом позиций, Bradley-Terry/медиана, судья не судит выходы своего семейства (D13.3); κ против человеческого IAA, не «средняя корреляция».
5. **Env — источник истины `eval/requirements.txt`** (у каждой строки комментарий «зачем и где»; интерпретатор — `.python-version`). Установка: `python3 -m venv .venv && .venv/bin/pip install -r requirements.txt`. Эмбеддинг-бенч (`retrieval_bench.py`) тянет ~2.5 ГБ ОТДЕЛЬНО — `requirements-embed.txt` (версии там намеренно не проставлены). ⚠ Замок снят 03.08.2026 с живого стенда Ubuntu 26.04 / CPython 3.14.4 и **не является стендом закрытых exp1216/promptlang** (те шли на Ubuntu 24 / ~3.12, версии не сохранились) — перепрогон на нём это НОВЫЙ замер, не репродукция. Ключи скрипты читают из `eval/.env` сами. Не офлайн: `tokenizers` ждёт файлы в `eval/tokenizers/` (gitignore, на чистой машине их нет), `tiktoken.get_encoding` качает ~4 МБ BPE при первом вызове. Стенд: GTX 1070 8GB — модель полигона `qwen3-abliterated:30b-a3b` в ollama не выселять без нужды; **localhost из-под прокси даёт 403** — для локальных вызовов no-proxy.
6. `data/` в .gitignore (коммитится только код) — критичные результаты дублируй цифрами в `docs/experiments/`.
7. **Экстракция прод-выходов — ТОЛЬКО через `tmctl export` (D39.5, инвариант №8 backend/README):** сырое чтение чекпоинтов store (records.json-стиль) отдаёт НЕнормализованные байты (без export-contract слоя) и молча-неполную книгу (без manifest-join/drift-гарда). `--plaintext` для глаз, дефолтный JSON для скриптов. Прежний путь `final_hash→response_text` — только для форензики сырья, не для оценки качества.
8. **Аномалия провайдера ≠ повод гадать:** странный отказ (интермиттентный 404/5xx, новый `finish_reason`, молча игнорируемые параметры) → сначала официальная дока вендора (deprecations/changelog/status) + свежий /models живьём, потом диагноз; в отчёт оба слоя — наблюдение И вендор-факт с датой/URL. Урок: 404-флейки gemini-2.5-flash оказались предвестником EOL всей 2.5-серии 16.10.2026 (research/15 → фактчек 10.07; правило — шапка `00-provider-quirks.md`).
9. **Персист, не scratch (владелец 01.08; ударило дважды):** код харнессов → `eval/<папка>` (git), сырые платные выходы → durable `~/books/...`; эфемерный scratchpad/tmp теряется вместе с сессией — так утрачен харнесс замера дефектов чекеров (labels/ уцелел, скрипты нет), и его придётся пересобирать.
10. **Вывод на агрегате до вскрытия единиц ЗАПРЕЩЁН (D39.61):** перед любым сравнительным выводом открыть глазами хотя бы одну единицу с каждой стороны; каждый агрегат — вторым независимым путём счёта; пре-регистрация порогов до вскрытия данных.
## Доступные ключи от моделей
DEEPSEEK_API_KEY, ZAI_API_KEY, KIMI_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, MISTRAL_API_KEY