textmachine/eval/exp12/exp12_reflow_demo.py

66 lines
4.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
"""exp12 — ЭКСПЛОРАТОРНАЯ демонстрация (пост-фидбек владельца, ВНЕ слепого бейк-оффа).
Отвечает на прямые замечания владельца: (1) построчные абзацы (кит. «предложение=абзац»);
(2) 派→«фракции» вместо «секты»; (3) 磕头→«ударил головой» вместо «земной поклон»;
(4) 时辰→«шичэн» без перевода. Один вызов билингв-редактора с ЯВНЫМ разрешением
переверстать абзацы и чинить жанровые конвенции. НЕ арм пре-регистрации — иллюстрация фикса.
Материал: сцена смерти (пролог гл.1, 第一节) — ровно откуда кейсы владельца.
"""
from __future__ import annotations
import json, os, sys, urllib.request
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) # script now under eval/expNN/ — reach up to parent eval/ for the refusal_bench oracle
from refusal_bench import load_env_file
load_env_file()
DEMO = Path("/home/ubuntu/books/gu-zhenren/diag/reflow_demo")
SRC = (DEMO / "source.txt").read_text(encoding="utf-8").strip()
DRAFT = (DEMO / "draft.txt").read_text(encoding="utf-8").strip()
SYS = (
"Ты — литературный редактор художественного перевода китайской вебновеллы (сянься/культиваторка) на русский. "
"Тебе дан ИСХОДНИК (китайский) и его ЧЕРНОВОЙ перевод. Отредактируй черновик в живую издательскую прозу:\n"
"1. АБЗАЦЫ: собери предложения в логические ЕВРОПЕЙСКИЕ абзацы. Китайская манера «одно предложение — "
"один абзац» для русской прозы деструктивна: группируй повествование по смыслу. Реплики прямой речи "
"оставляй отдельными строками с тире.\n"
"2. СТИЛЬ: убери кальки с китайского и канцелярит, оживи синтаксис и ритм (школа Норы Галь).\n"
"3. СМЫСЛ: сверяйся с ИСХОДНИКОМ и исправляй искажения черновика; сохрани полноту, ничего не выбрасывай "
"и не пересочиняй.\n"
"4. РЕАЛИИ/КОНВЕНЦИИ: культиваторские 门派/派 — «секты» или «школы» (НЕ «фракции»); земной поклон 磕头 — "
"«отвесил земной поклон»/«коснулся лбом пола» (НЕ «ударил головой»); меры времени (时辰 = ~2 часа) — "
"переводи или глоссируй, не транслитерируй вслепую.\n"
"Выведи ТОЛЬКО отредактированный русский текст."
)
USER = f"ИСХОДНИК (zh):\n\n{SRC}\n\n---\n\nЧерновик перевода для редактуры:\n\n{DRAFT}"
SPEC = dict(model="gemini-3.1-pro-preview",
base="https://generativelanguage.googleapis.com/v1beta/openai",
keyenv="GEMINI_API_KEY", max_tokens=16000)
def main():
key = os.environ.get(SPEC["keyenv"], "")
body = {"model": SPEC["model"], "temperature": 0.4, "max_tokens": SPEC["max_tokens"],
"messages": [{"role": "system", "content": SYS}, {"role": "user", "content": USER}]}
req = urllib.request.Request(SPEC["base"].rstrip("/") + "/chat/completions",
data=json.dumps(body).encode(),
headers={"Content-Type": "application/json", "Authorization": f"Bearer {key}"})
with urllib.request.urlopen(req, timeout=300) as r:
data = json.loads(r.read())
text = data["choices"][0]["message"]["content"].strip()
(DEMO / "reflow_gemini.txt").write_text(text, encoding="utf-8")
def paras(t):
return len([l for l in t.split("\n") if l.strip()])
print(f"draft para-lines: {paras(DRAFT)} → reflow para-lines: {paras(text)}")
for probe, good in [("фракци", "секты/школы"), ("ударил головой", "земной поклон"),
("шичэн", "перевод времени"), ("невинност", "清白之身")]:
d = "фракци" in DRAFT.lower() if probe == "фракци" else probe in DRAFT
print(f" '{probe}': draft={probe in DRAFT} reflow={probe in text} (ждём: {good})")
print("\n=== REFLOW head (first 900 chars) ===\n" + text[:900])
if __name__ == "__main__":
main()