textmachine/eval/dovodka/contam_d.py

96 lines
6.8 KiB
Python
Raw 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.

#!/usr/bin/env python3
"""КОНТАМИНАЦИОННАЯ ПРОБА ФАЗЫ Д — ЖИЛЬЦАМИ и на книгах, которые фаза реально покупает. Платный.
Заказ (Д3 и Д6) требует пробу «ЖИЛЬЦАМИ» — правило эксп-22 §1.1: гонять теми, кто работает,
а не удобной моделью. Непригоден по пробе → СТОП и пинг, замену без слова владельца не искать.
Риг НЕ пере-изобретается: берётся `eval/role_topology/contamination.py` и настраивается через
свои глобали — тем же приёмом, каким `money_d` настраивает кассу, а `sud` — судейский риг. Метод
пробы остаётся его: УЗНАВАНИЕ («что за произведение и кто автор») плюс КЛОУЗ ПО ИМЕНИ (из отрывка
вырезано имя собственное, модель называет пропущенное). Пороги — его же, объявленные до данных:
узнавание ≥3/5 = «знает о книге», клоуз ≥2/5 = «знает конкретику, то есть текст был в обучении».
⚠ ЧТО ЗДЕСЬ ДОБАВЛЕНО И ЗАЧЕМ.
1. **Книги фазы.** Прошлый прогон мерил `gu-zhenren`, `jinpingmei`, `fifty_shades`, `kristoff` и
СТАРУЮ японскую книгу. Новая японская (`enkan_no_hate`, замена по слову владельца после
срабатывания гардрейла 18+) не мерена ВООБЩЕ, а Д6 покупается именно на ней.
2. **Жильцы вместо удобной модели.** Прошлый прогон гнался `gpt-5.6-luna`. Это не жилец: черновики
делает `deepseek-v4-flash`, редактуру `deepseek-v4-pro`. Знание книги ИМИ и есть то, что
завышает качество перевода, а знание посторонней модели не значит ничего.
3. **Бюджет вывода поднят.** Редакция 1 прошлой пробы звала flash с 16000 токенов и получала
046 знаков: у DeepSeek размышление тарифицируется и считается ВНУТРИ бюджета, поэтому на
короткий ответ ничего не оставалось (стена quirks §10; ровно эта же стена сегодня съела 14
клеток арма A1B). Ответ здесь нужен КОРОТКИЙ, а думать модель будет много — значит бюджет
должен вмещать размышление ЦЕЛИКОМ, иначе «НЕ ЗНАЮ» будет означать «не успел сказать».
⚠ Если и при поднятом бюджете жилец возвращает пустоту — это НЕ «книга чиста», а непригодность
пробы на этом жильце, и она объявляется отдельно, а не растворяется в нуле.
4. **Положительный контроль обязателен на КАЖДОМ жильце.** Нулевой результат неинтерпретируем:
«модель не знает книгу» и «проба не работает на этой модели» дают одну картину. Контроль —
`jinpingmei` (минский канон, public domain, заведомо в претрейне). Не сработал контроль —
аннулируется весь прогон этого жильца, а не отдельная книга.
Запуск: contam_d.py --dry # план, $0
contam_d.py # платный
"""
from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
REPO = Path("/home/ubuntu/projects/textmachine")
ZONE = Path(__file__).resolve().parent
for d in ("dovodka", "role_topology", "tenant_panel"):
sys.path.insert(0, str(REPO / "eval" / d))
def _load(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
sys.modules[name] = mod
spec.loader.exec_module(mod)
return mod
MONEY = _load("money_d", ZONE / "money_d.py")
CT = _load("contam21", REPO / "eval" / "role_topology" / "contamination.py")
# Жильцы: те, кто реально работает на парах. Проба на каждом отдельно.
RESIDENTS = ("deepseek-v4-flash", "deepseek-v4-pro")
# Книги, которые фаза Д покупает, плюс обязательный положительный контроль.
BOOKS_D = {
"enkan-ja": dict(path=Path.home() / "books" / "enkan_no_hate_ja.txt", lang="ja",
titles=["円環の果てに", "enkan", "円環"],
note="ja-ось Д6; первая публикация 2026-07-30, 18 глав — НЕ мерена ни разу"),
"kristoff-en": dict(path=Path.home() / "books" /
"Kristoff_Jay_-_Empire_of_the_Vampire_3_-_Empire_of_the_Dawn.epub",
lang="en", titles=["empire of the dawn", "empire of the vampire",
"кристофф", "kristoff"],
note="en-ось Д3; luna узнала СЕРИЮ 1 раз из 5 — жильцами не мерена"),
"jinpingmei": dict(path=Path.home() / "books" / "jinpingmei" / "jinpingmei-ctext-zhs.txt",
lang="zh", titles=["金瓶梅", "золотой лотос", "jin ping mei"],
note="ПОЛОЖИТЕЛЬНЫЙ КОНТРОЛЬ — обязателен на каждом жильце"),
}
def main() -> int:
dry = "--dry" in sys.argv
print("КОНТАМИНАЦИОННАЯ ПРОБА ФАЗЫ Д — жильцами\n")
print(f"{'книга':14s}{'язык':>6s} что это")
for b, m in BOOKS_D.items():
ok = "" if m["path"].exists() else " ⛔ ФАЙЛА НЕТ"
print(f"{b:14s}{m['lang']:>6s} {m['note']}{ok}")
print(f"\nжильцы: {' · '.join(RESIDENTS)}")
print("пороги (объявлены ДО данных, взяты из рига эксп-21): "
"узнавание ≥3/5 = знает о книге · клоуз ≥2/5 = знает конкретику")
if dry:
print("\n--dry: покупок нет")
return 0
print("\n⚠ платный режим ещё не подключён к кассе фазы — см. TODO ниже")
return 0
if __name__ == "__main__":
sys.exit(main())