diff --git a/eval/role_topology/phase2b.py b/eval/role_topology/phase2b.py index 5d9b3d36..5a2f8805 100644 --- a/eval/role_topology/phase2b.py +++ b/eval/role_topology/phase2b.py @@ -285,12 +285,20 @@ def picked(arm: str, uid: str, k_qe: int = 3) -> list[dict]: return sorted(out, key=lambda r: r["i"]) -def fix_one(source: str, sent: str, why: str, tag: str) -> dict: - """Один вызов фиксера. Правит ОДНО предложение, видя исходник окна.""" +def fix_one(source: str, sent: str, why: str, tag: str, bank: str = "") -> dict: + """Один вызов фиксера. Правит ОДНО предложение, видя исходник окна. + + ⚠ `bank` — закон-блок канонических терминов. Первый прогон шёл БЕЗ него, и это оказалось + решающим дефектом: фиксер правит предложение вслепую и переписывает канон по своему вкусу + («истинную ци» → «первобытную энергию», «Гу» → «гу»). Покрытие канона упало 0.917 → 0.895, + а по судье арм проиграл даже черновику (−1.38). Это ровно тот дефект, который аудит нашёл + для редактора `A` и который объявлен условием прод-конфига; в фиксере он был повторён. + """ sys_msg = ("Ты — корректор художественного перевода. Тебе дан ИСХОДНИК фрагмента на китайском " "и ОДНО предложение русского перевода, в котором найден дефект. Верни ТОЛЬКО " "исправленное предложение, без пояснений, без кавычек-обёрток. Если дефекта нет — " - "верни предложение без изменений. Ничего, кроме этого предложения, не выводи.") + "верни предложение без изменений. Ничего, кроме этого предложения, не выводи." + + (f"\n\n{bank}" if bank else "")) usr = f"ДЕФЕКТ: {TYPE[why]}\n\nИСХОДНИК:\n{source}\n\nПРЕДЛОЖЕНИЕ:\n{sent}" return BUY.purchase(LED_P2B, tag, FIXER, BO.client(FIXER), dict(model=FIXER, messages=[{"role": "system", "content": sys_msg}, @@ -299,6 +307,45 @@ def fix_one(source: str, sent: str, why: str, tag: str) -> dict: why=why, tag_kind="fix") +def bank_for(u: dict) -> str: + """Закон-блок ровно тех терминов, что есть в исходнике окна — как у редакторских армов.""" + tms = [x for x in BO.IP.TERMS if x in u["source"]] + return BO.P.editor_block(tms, BO.P.HEADER_LAW_PLAIN, None) if tms else "" + + +def cmd_arms2() -> None: + """Пере-замер C и E С БАНКОМ у фиксера. Меняется ровно один фактор.""" + for arm, base in (("C2", "F3"), ("E2", "D_")): + src_arm = arm[0] + for u in BO.units(): + uid = u["uid"] + text = BO.text3_of(base, u) + sents = sentences(text) + todo = picked(src_arm, uid) + bank = bank_for(u) + for it in (1, 2): + if not todo: + break + for r in todo: + rec = fix_one(u["source"], sents[r["i"]], r["why"], + f"p2b-{arm}-{uid}-s{r['i']}-i{it}", bank) + if rec.get("skipped"): + print("⛔ потолок Ф2б") + return + new = (rec.get("content") or "").strip() + if new: + old = sents[r["i"]] + sents[r["i"]] = new + (old[len(old.rstrip()):] or " ") + time.sleep(0.05) + todo = [dict(i=i, sent=s, why=mech_flags(s)[0]) + for i, s in enumerate(sents) if mech_flags(s)] + (OUT / f"p2b-{arm}-{uid}.json").write_text(json.dumps( + dict(arm=arm, uid=uid, base=base, content="".join(sents)), + ensure_ascii=False), encoding="utf-8") + print(f" {arm} {uid[:8]} готов", flush=True) + print(f"куплено · касса ${LED_P2B.spent():.5f} из ${CEIL_P2B}") + + def cmd_arms() -> None: """Купить починки. Кап 2 итерации; ре-гейт после каждой — МЕХАНИЧЕСКИЙ (см. оговорку ниже).""" for arm, base in (("C", "F3"), ("E", "D_")): @@ -412,5 +459,5 @@ def cmd_plan() -> None: if __name__ == "__main__": a = sys.argv[1:] or ["--plan"] {"--plan": cmd_plan, "--flags": cmd_flags, "--arms": cmd_arms, - "--oracle": cmd_oracle, "--score": cmd_score}.get( + "--oracle": cmd_oracle, "--score": cmd_score, "--arms2": cmd_arms2}.get( a[0], lambda: print(__doc__))()