textmachine/eval/dovodka/plan.py

139 lines
9.7 KiB
Python
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.

#!/usr/bin/env python3
"""СМЕТА ФАЗЫ Д ПО ЗАМЕРЕННЫМ ЦЕНАМ КЛЕТОК. $0.
⚠ Почему скриптом, а не в столбик. Пак 23 поднял потолок фазы, сославшись на «панель $1.844» —
это была ПРОЕКЦИЯ `--c-plan` по медианам, а фактическая панель стоила $1.798638 и влезала в
исходный потолок. Смета, посчитанная руками и не пере-снимаемая, ровно так и ошибается. Здесь
каждая цена берётся из СЫРЬЯ уже купленных клеток (медиана по модели и роли), и любой читатель
пере-считает командой.
Потолок фазы — САНКЦИЯ ВЛАДЕЛЬЦА $4.50 (10.08). История: промт называл $10.00, владелец при
запуске сказал $4.00, затем поднял до $4.50, когда приёмка другого модельного семейства нашла,
что дизайн не отвечает на H-1 и H-4, а починка стоит $0.48. ⚠ Сессия называла честным потолком
без стопов посреди фазы $4.80; владелец выбрал $4.50 — резерв $0.03, и срабатывание гарда есть
СТОП и вопрос владельцу, а не сокращение оси решением сессии.
Запуск: eval/.venv/bin/python eval/dovodka/plan.py [--gemini N]
"""
from __future__ import annotations
import collections
import json
import statistics as st
import sys
from pathlib import Path
T = Path.home() / "books" / "tenant-panel"
E = Path.home() / "books" / "editor-tier"
# ⚠ Потолок берётся ИЗ КАССЫ, а не дублируется числом: копия отстала от санкций владельца
# ($4.50 против фактических $6.15) и смета сверялась с несуществующей границей.
import importlib.util as _il # noqa: E402
_sp = _il.spec_from_file_location("_money_d", Path(__file__).resolve().parent / "money_d.py")
_md = _il.module_from_spec(_sp); _sp.loader.exec_module(_md)
PACK_CEILING = _md.PACK_CEILING
def measured() -> dict[tuple[str, str], float]:
"""Медиана $/клетка по (роль, модель) из КУПЛЕННОГО сырья обоих паков."""
acc: dict[tuple[str, str], list[float]] = collections.defaultdict(list)
for d, pat in ((T, "tp*.json"), (E, "et-*.json")):
for f in d.glob(pat):
try:
r = json.loads(f.read_text(encoding="utf-8"))
except (ValueError, OSError):
continue
if isinstance(r, dict) and r.get("cost_usd") and r.get("model"):
acc[(r.get("role") or "?", r["model"])].append(r["cost_usd"])
return {k: st.median(v) for k, v in acc.items() if len(v) >= 3}
def main() -> int:
m = measured()
n_gem = 16
if "--gemini" in sys.argv:
n_gem = int(sys.argv[sys.argv.index("--gemini") + 1])
draft = m[("draft", "deepseek-v4-flash")]
edit = m[("edit", "deepseek-v4-pro")]
gem = 0.14702 # ЕДИНСТВЕННАЯ состоявшаяся клетка Ф3 эксп-22, n=1
# Производные цены армов edit-контура. Обоснование множителей — в отчёте §Д0; они ПРОГНОЗ,
# и расхождение с фактом печатается при закрытии фазы как сверка сметы.
fixer = 0.60 * edit # точечная починка: тот же вход, выход много короче
critic = 2.14 * edit # «поиск ≈2.14× переписа» — цифра из заказа владельца
onepass = edit # однопроходка: вход короче, размышление длиннее — вничью
print("ЗАМЕРЕННЫЕ ЦЕНЫ (медиана по сырью обоих паков):")
for k in (("draft", "deepseek-v4-flash"), ("edit", "deepseek-v4-pro"),
("editor3", "glm-5"), ("edit", "glm-5.2"), ("edit", "gpt-5.6-terra"),
("edit", "grok-4.5")):
if k in m:
print(f" {k[0]:8s}{k[1]:22s}${m[k]:.5f}")
print(f" {'edit':8s}{'gemini-3.1-pro-preview':22s}${gem:.5f} ⚠ n=1, "
f"{gem / edit:.0f}× боевого редактора")
print("\nПРОИЗВОДНЫЕ (прогноз, сверяется с фактом при закрытии):")
print(f" фиксер ${fixer:.5f} (0.60× переписа)")
print(f" критик ${critic:.5f} (2.14× переписа — множитель из заказа владельца)")
rows = []
# ── Д4 edit-контур zh, 32 единицы (16 эксп-22 + 16 эксп-23); A0 уже куплен обоими паками
n4 = 32
d4 = n4 * (fixer + onepass + (critic + fixer) + fixer) + 16 * fixer
rows.append(("ФД-A", "Д4 edit-контур zh: A1 флаги→фиксер · A2 однопроходка · "
f"A3 критик→фиксер · A4 канон-фиксер, n={n4} + свой пол", d4))
# ── Д3 en ось, 16 единиц
n3 = 16
d3 = (0.005 + 0.004 # банк-майнинг + проба контаминации
+ n3 * draft + n3 * edit + n3 * onepass
+ n3 * (fixer + critic + fixer) + n3 * edit) # два контура + пол
rows.append(("ФД-B", f"Д3 en→ru несущая: банк · контам-проба · связка · однопроходка · "
f"оба edit-контура · пол, n={n3}", d3))
# ── Д6 ja разведка, 9 единиц
n6 = 9
d6 = 0.004 + n6 * (draft + edit + onepass + edit)
rows.append(("ФД-C", f"Д6 ja→ru разведка: контам-проба · связка · однопроходка · пол, n={n6}",
d6))
# ── Д7 самооценка
rows.append(("ФД-D", "Д7 микро-проба самооценки жильцов по трём книгам", 0.05))
# ── Д1 gemini
# ⚠ ДВА АРМА, ЗАВЕДЁННЫЕ ПРИЁМКОЙ ДРУГОГО МОДЕЛЬНОГО СЕМЕЙСТВА. Без них фаза не отвечает на
# H-1 и H-4, и это нашёл не автор: H-1 говорит про «КАЧЕСТВЕННЫЙ черновик + точечный редактор»,
# а все армы Д4 ставят фиксер на flash-черновик — то есть на полумусор по самой гипотезе;
# H-4 про смену ПОРЯДКА жильцов на другой паре, а на en-оси редактор был ровно один.
rows.append(("ФД-F", "H-1: dspro-черновик эксп-22 (уже куплен, $0) + оба edit-контура, n=16 — "
"прямой носитель гипотезы «качественный черновик + точечный редактор»",
16 * (fixer + critic + fixer)))
rows.append(("ФД-G", "H-4: ВТОРОЙ редактор (glm-5) на en-оси поверх той же базы, n=16 — "
"без него порядок жильцов на en не проверяется вовсе", 16 * m[("editor3", "glm-5")]))
rows.append(("ФД-E", f"Д1 добивка gemini-3.1-pro-preview, {n_gem} клеток "
f"(503-отказы бесплатны, платим только за отгруженные)", n_gem * gem))
print(f"\n{'фаза':7s}{'что покупается':78s}{'смета':>9s}")
tot = 0.0
for tag, what, cost in rows:
tot += cost
print(f"{tag:7s}{what[:78]:78s}{cost:9.3f}")
print(f"{'ИТОГО':7s}{'':78s}{tot:9.3f} при потолке ${PACK_CEILING:.2f}")
free = PACK_CEILING - tot
print(f"{'резерв':7s}{'':78s}{free:9.3f}")
if free < 0:
print("\nНЕ ВЛЕЗАЕТ. Резать ось или кандидата решением сессии ЗАПРЕЩЕНО "
"(промт, анти-лень) —\n это СТОП и вопрос владельцу.")
elif free < 0.30:
print("\n⚠ Резерв меньше 8% пакета. Ре-гены эхо-мины и ретраи в паках 22/23 съедали "
"до +16%\n сверх сметы фазы — при таком резерве первый же эхо-ре-ген упрётся "
"в потолок.")
print(f"\n⚠ ДОЛЯ ОДНОЙ МОДЕЛИ: Д1 = ${n_gem * gem:.2f} = "
f"{n_gem * gem / PACK_CEILING * 100:.0f}% всего пакета фазы.")
print(f" Цена клетки ${gem:.5f} против ${edit:.5f} у боевого редактора — это "
f"${gem * 1500:.0f} за книгу\n при ${edit * 1500:.0f} у боевого. Продуктовым выбором "
"модель быть не может ни при каком исходе;\n ценность замера — закрыть гипотезу "
"эксп-04 «аутлаер прозы», не более.")
print(f"\n Сколько единиц Д1 влезает при остальном плане: "
f"{int((PACK_CEILING - (tot - n_gem * gem) - 0.35) / gem)} "
"(с резервом $0.35 на ре-гены).")
return 0
if __name__ == "__main__":
sys.exit(main())