101 lines
6.2 KiB
Python
101 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
||
"""Проба P1/P2: voice-exemplars A/B/C/D + реестр ты/вы пар. Индикатив (малый N).
|
||
|
||
Дизайн по итогам веб-ресёрча research/15:
|
||
- C-арм: экземпляры как скрипт-строки «Имя: реплика» (приближение к RoleLLM
|
||
dialogue-turns в рамках одного system-блока), 3-4 реплики на спикера, отбор
|
||
по разнообразию, НЕ по similarity (Enron-находка).
|
||
- D-арм: гибрид «voice sheet» (1 строка регистра) + 2-3 экземпляра (STYLL-паттерн).
|
||
- R-арм (P2): только реестр обращений пар (ты/вы) без экземпляров.
|
||
Инъекция аппроксимируется добавочным блоком в КОНЦЕ system (боевой слот — отдельное
|
||
system-сообщение после кэш-границы; call_provider двухсообщенчатый — честная оговорка).
|
||
"""
|
||
import json
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||
import probe_runner as pr
|
||
|
||
SCRATCH = Path(__file__).resolve().parent
|
||
|
||
BASE_SYSTEM = """Ты — профессиональный литературный переводчик с китайского языка на русский.
|
||
Жанр книги: сянься (уся-фэнтези о культивации). Аудитория: взрослые читатели вебновелл. Книга: «Гу Чжэньжэнь» (蛊真人).
|
||
|
||
Правила перевода (translation brief):
|
||
- Транскрипция имён и реалий: система Палладия.
|
||
- Переводи ВСЕ предложения исходника: ничего не пропускай, не сокращай и не добавляй от себя.
|
||
- Сохраняй разбивку на абзацы и прямую речь как в оригинале.
|
||
- Пиши живым литературным русским языком; избегай канцелярита и калек с китайского.
|
||
|
||
Выведи ТОЛЬКО перевод, без комментариев, пояснений и заголовков."""
|
||
|
||
GLOSS = """
|
||
ГЛОССАРИЙ (используй эти утверждённые переводы имён последовательно):
|
||
方源 → Фан Юань
|
||
方正 → Фан Чжэн
|
||
沈翠 → Шэнь Цуй
|
||
古月 → Гу Юэ
|
||
舅母 → тётушка (жена дяди)
|
||
舅父 → дядюшка (брат матери)
|
||
元石 → камень стихий
|
||
蛊 → гу
|
||
月光蛊 → гу лунного света"""
|
||
|
||
DESCRIPTORS = """
|
||
ГОЛОСА ПЕРСОНАЖЕЙ (передавай речь каждого в его манере, различимо):
|
||
- Фан Юань — ледяной, властный; короткие рубленые фразы; к слугам и младшему брату на «ты», повелительно; ирония холодная, без эмоций.
|
||
- Шэнь Цуй — заискивающая молодая служанка; слащавая, кокетливая, самоуничижительная речь («ваша служанка»); к хозяину — «молодой господин», строго на «вы».
|
||
- Фан Чжэн — наивный, вспыльчивый подросток; многословный, эмоциональный, обидчивый; к брату на «ты».
|
||
- Тётушка — приторно-ласковая, лицемерно-заботливая; к племянникам сверху вниз, ласково, на «ты».
|
||
- Дядюшка — снисходительно-важный, ворчливый; к племянникам на «ты»."""
|
||
|
||
EXEMPLARS = """
|
||
ОБРАЗЦЫ РЕЧИ ПЕРСОНАЖЕЙ (канонические реплики из утверждённого перевода ранних глав; держи голос каждого персонажа в этой манере):
|
||
{exemplars}"""
|
||
|
||
REGISTER_PAIRS = """
|
||
РЕЕСТР ОБРАЩЕНИЙ (строго соблюдай форму обращения в каждой паре говорящий → адресат):
|
||
- Шэнь Цуй → Фан Юань: на «вы», «молодой господин» (служанка к хозяину)
|
||
- Фан Юань → Шэнь Цуй: на «ты», повелительно (хозяин к служанке)
|
||
- Фан Юань → Фан Чжэн: на «ты» (старший брат к младшему)
|
||
- Фан Чжэн → Фан Юань: на «ты», «брат» (младший к старшему; семья, не «вы»)
|
||
- Тётушка/дядюшка → племянники: на «ты»
|
||
- Фан Чжэн → тётушка/дядюшка: на «вы», почтительно"""
|
||
|
||
TEST_CHUNKS = {
|
||
"T1": (SCRATCH / "chunk-T1-shencui-test.txt").read_text(),
|
||
"T2": (SCRATCH / "chunk-T2-brothers-test.txt").read_text(),
|
||
}
|
||
|
||
|
||
def translate(tag: str, injection: str, chunk: str):
|
||
system = BASE_SYSTEM + GLOSS + injection
|
||
user = "Переведи следующий фрагмент:\n\n" + chunk
|
||
text, err, usage = pr.call("deepseek", system, user, tag)
|
||
return text
|
||
|
||
|
||
def main():
|
||
exemplars = (SCRATCH / "exemplar-pool.txt").read_text()
|
||
arms = {
|
||
"A": "", # база: только глоссарий
|
||
"B": DESCRIPTORS, # дескрипторы
|
||
"C": EXEMPLARS.format(exemplars=exemplars), # экземпляры
|
||
"D": (SCRATCH / "voice-sheet-hybrid.txt").read_text(),# гибрид
|
||
"R": REGISTER_PAIRS, # P2: только реестр пар
|
||
}
|
||
only = sys.argv[1:] or list(arms)
|
||
for chunk_id, chunk in TEST_CHUNKS.items():
|
||
for arm, inj in arms.items():
|
||
if arm not in only:
|
||
continue
|
||
tag = f"p1-{chunk_id}-{arm}"
|
||
if (pr.RAW / f"{tag}.json").exists():
|
||
print(f"[skip] {tag} exists", file=sys.stderr)
|
||
continue
|
||
translate(tag, inj, chunk)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|