AI-переклад
Мова: English · Українська
Picoripi розмовляє з LLM через Settings → AI Translation. Збірка глосарія — Settings → AI Glossary (опційно той самий ключ). Рекомендований локальний проксі: 5. Gemini Web2API.
Обробники: handlers/translation_handler.py, handlers/translation/. Провайдери: core/translation/providers.py. Типові значення: core/translation/config.py. Промпти: Edit Prompts JSON і translation_prompts/prompts.json плагіна.
Файли промптів зливаються по ключах, пізніші перекривають раніші: translation_prompts/prompts.json → plugins/common/defaults/prompts.json → plugins/<name>/translation_prompts/prompts.json → копія-перевизначення проєкту або користувача. Файл плагіна, що містить лише розділ translation, все одно отримує розділи glossary, glossary_occurrence_update та mempalace зі спільного файлу (core/translation/prompt_files.py).
Прохід перевірки — необов'язковий другий запит на кожен фрагмент у тій самій розмові, що й переклад: модель бачить ті самі правила, рядки глосарію, мовців, адресатів і сцену, свою чернетку та прохання виправити лише справжні помилки (зміст, неперекладені слова, терміни глосарію, рід і відмінок, ти/ви, описки, кальки). Вона повертає лише виправлені рядки з причиною (у журналі налагодження); виправлення проходить ті самі перевірки, що й чернетка, а все, що їх не пройшло, лишає чернетку. Типово увімкнений; "review_enabled": false у конфігурації перекладу вимикає його, а "review_model" задає для нього іншу модель. Він додає один запит на кожен фрагмент. Виміряно на вичитаному Minish Cap (2026-10-04): він змінює приблизно один рядок із дванадцяти й у двох випадках із трьох робить краще.
Одне джерело — один переклад у межах прогону. Перед початком прогону блока (або проєкту) рядки з точно однаковим текстом згортаються: один надсилається, решта отримує його переклад, коли фрагмент повертається. Два рядки згортаються лише тоді, коли збігається й усе інше, що визначає формулювання, — мовець, адресат, вікно, у яке текст має вміститися, відомості плагіна про рядок і ваші ручні перевизначення сюжету; тож репліка, яку вимовляють два різні персонажі, все одно перекладається двічі. Рядок, що вже має переклад, згортання не перезаписує — так само, як його не перезаписує модель. Щоб надсилати кожен рядок, задайте "fold_duplicates": false у конфігурації перекладу. Плагін може замінити в цьому тесті вікно і контекст перекладу власним контекстом (get_duplicate_context_for_string, D46): так роблять посібники 3DS, тож один абзац з однаковим текстом у двох посібниках перекладається один раз. Придатність перевіряється для кожного місця: перевірка розкладки плагіна (get_text_fit_problems_for_string) відхиляє місце, де текст не вміщається, і воно лишається неперекладеним після прогону (смуга стану показує кількість; перекладіть його або запустіть знову). Кожен прогін також веде пам'ять прогону: коли в пізнішому фрагменті трапляється рядок, що відрізняється від уже перекладеного лише тегами, регістром чи пробілами, запит містить already_translated_in_this_run (не більше 10 рядків), а моделі сказано зберігати формулювання. Пам'ять очищується на початку нового прогону; друга фаза режиму «спершу сюжет, потім решта» продовжує пам'ять першої.
Пам'ять перекладів серії. Проєкт, що має глосарії серії (вікі 8, Глосарії серії), записує себе в projects.json поруч із кожним із них (назва проєкту → його translation_memory.json) і при відкритті читає файли пам'яті інших проєктів із цього списку (core/translation/series_memory.py; читається раз у воркері завантаження, нічого не копіюється). Далі: ім'я чи окремий термін ніколи не береться з іншої гри; його перекладає глосарій серії (вікі 8, Fill Terms from the Glossary). Речення (більше двох слів, series_sentence_words) з іншої гри пропонується лише тоді, коли увімкнено Пропонувати речення, перекладені в інших іграх серії (Налаштування, сторінка AI; типово вимкнено). Текст має збігатися точно. Мовця порівнюють за англійським іменем; рядок без нього ніколи не стартує позначеним. Кожен запропонований рядок має прапорець у списку Речення з інших ігор серії: англійський текст, переклад з іншої гри і її назву, обидва імені мовців і причину. Безпечний збіг стартує позначеним, коли увімкнено Безпечні збіги починаються з позначкою (типово так); сумнівний (імена мовців різні чи відсутні, адресат різний, текст задовгий для цього вікна, теги не відповідають) стартує без позначки. Вибрати безпечні, Вибрати все і Очистити змінюють позначки. Застосувати вибрані записує лише позначені рядки як правки, які можна скасувати; рядок, що не пройшов перевірку ширини чи тегів, лишається без змін і йде до запиту AI. Нічого не застосовується автоматично. Запит фрагмента містить translated_in_other_games_of_the_series (не більше 10 рядків, кожен із project), запит одного рядка перелічує їх у TRANSLATION MEMORY з позначкою in <project>; а смужка над редактором каже Translated in get_series_tag_map; наприклад розрив сторінки або ім'я, яке вставляє гра): його теги записуються синтаксисом цієї гри. Тег без відповідника блокує перенесення, а смуга пам'яті пояснює причину.
Пам'ять перекладів між прогонами. Кожен переклад, який Picoripi зберігає як резервну копію (saved_translations.json у теці проєкту, з ключем за позицією), запам'ятовується ще й за вихідним текстом у файлі translation_memory.json поруч. Коли прогін має перекласти рядок, для позиції якого збереженого перекладу немає, але такий самий текст уже перекладено й збережено деінде в проєкті, вікно Cached Translation пропонує і цей переклад — з позначкою (same text elsewhere) — після тієї самої перевірки розкладки, що й для відновлення за позицією: OK заповнює рядок без запиту, Translate Anew надсилає його моделі. Відновлюється лише точно такий самий текст. Текст, що трапляється в проєкті більше одного разу, пропонується лише тоді, коли збережений рядок мав того самого мовця, адресата й контекст (той самий тест, що й для згортання дублікатів); репліку іншого мовця перекладено наново, а рядок, збережений до цього правила, для такого тексту не пропонується, доки репліку не збережено знову. Плагін із власним контекстом повторів (D46) лишає такий рядок для його власного місця. У вікні кожен рядок має прапорець, позначений за замовчуванням: OK заповнює позначені рядки без запиту, рядок без позначки йде до моделі, а Translate Anew надсилає всі рядки моделі. Запит на переклад одного рядка додатково містить розділ TRANSLATION MEMORY (same source elsewhere) — до трьох збережених перекладів того самого тексту, включно з написаннями, що відрізняються лише тегами, регістром чи пробілами, — щоб модель зберегла формулювання; запит на варіанти цього розділу не отримує. Проєкт, збережений до появи цієї можливості, будує пам'ять із наявних збережених перекладів, коли вона вперше знадобиться. Файл > Оновити пам'ять перекладу з контекстом дає рядкам, збереженим до цього правила, їхній контекст (мовця, адресата і ключ згортання) зі збережених перекладів, тож повторюваний текст знову пропонується. Дія виконується у фоновому потоці, її можна скасувати; попередня пам'ять зберігається як translation_memory.before_context.json, а Файл > Повернути пам'ять перекладу до оновлення контексту повертає її.
Сталі написи інтерфейсу. Повторювані слова інтерфейсу — OK, Yes, No, Back — покладіть у розділ глосарію з назвою UI. Рядок гри, який увесь є точно таким терміном (або одним із його псевдонімів; той самий регістр, без зайвих символів), заповнюється перекладом із глосарію ще до початку прогону: без запиту і без запитань. Рядок, що вже має переклад, не чіпається; переклад, який не вкладається в розкладку рядка, силоміць не вставляється; запис, переклад якого ще є непідтвердженою пропозицією ШІ, нічого не фіксує. Інші розділи можна назвати в конфігурації перекладу: "fixed_output_sections": ["UI", "Menu"]; порожній список вимикає цю можливість.
Розкладка відповіді. Модель пише слова, Picoripi їх верстає. Кожен рядок має клас розкладки (core/translation/layout_class.py): його називає плагін (layout_class у get_translation_context_for_string, за типом вікна) або рушій вгадує з оригіналу: кілька коротких рядків без розділових знаків у кінці — це lines (меню, назва, вибір, титри), усе інше — prose. Запит каже, який саме (layout_class: "lines" на елементі; prose — типово) і дає бюджет у літерах замість пікселів: max_chars_per_line, виміряний українською абеткою у шрифті гри (lines_per_window × max_chars_per_line на сторінку). Для prose модель може писати кожну сторінку суцільним текстом; при застосуванні відповіді слова кожної сторінки переносить верстальник (core/typesetter.py) зі шрифтом гри: заповнює до цільової ширини (warn_width), ніколи не лишає «і», «в», «на» та інші одно- і дволітерні службові слова в кінці рядка, ніколи не лишає одне слово на останньому рядку, а за ціль виходить лише до межі (max_width), коли цього вимагають ці правила. Той самий верстальник розбиває надто широкий рядок в автовиправленні ширини. Рядок класу lines зберігає рядки моделі як є. Відповідь і далі має зберегти порожні рядки (розриви сторінок) і кінцевий перенос, інакше її чанк валиться. Прохід скорочення: після чернетки (і перевірки) Picoripi верстає кожен елемент; prose-елемент, якому після цього треба більше вікон, ніж в оригіналі, або lines-елемент із рядком, ширшим за межу, один раз повертається до моделі в тій самій розмові з shorten_by_letters (скільки літер, виміряно) і причиною; скорочений рядок береться лише тоді, коли влазить краще, інакше лишається чернетка. "shorten_enabled": false у конфігурації перекладу вимикає прохід. Підсумок прогону рахує layout: N did not fit, M shortened. Дві ширини типу вікна — його ціль і межа; плагін, який знає лише одну з них, задає width_tolerance_percent у config.json (типово 5), і друга виводиться.
Запит на один рядок також містить рядок Addressee:, коли плагін знає, до кого звернено репліку, — ту саму відомість, що й елемент пакетного запиту.
Форми звертання (ти/ви). Tools → Forms of Address... — невелика таблиця, збережена в проєкті (address_forms у метаданих .uiproj, core/address_forms.py): Characters з рисами вільними словами (child, adult, elder, royalty, deity, male, female...; список починається з імен, які показує поле Speaker), Rules між рисами в порядку пріоритету (типово: будь-хто → royalty, deity або elder на ви, далі child → adult на ви, adult → child на ти, child → child на ти; * — будь-хто) і Pairs (один мовець до одного адресата), які сильніші за будь-яке правило. Для рядка, адресата якого називає плагін, перша збіжна пара чи правило стає address_form: "formal" або "informal" в елементі пакета і рядком Address form: у запиті одного рядка; перевірочний прохід звіряє ти/ви з ним. Немає збігу — немає поля: модель вирішує, як раніше. Налаштуйте раз на старті проєкту — працює для кожного наступного прогону.
Увімкнути провайдера
Settings → AI Translation
| Поле | Значення |
|---|---|
| Target Language | напр. Ukrainian, Spanish, German |
| Active Provider | Disabled · OpenAI Compatible · Ollama Chat · Gemini · Perplexity |
| Preset | Save Preset / Delete Preset (збереження з наявним ім’ям перезаписує) |
| Parallel Requests | 1–16, типово 6. Паралельні запити під час пакетного/чанкованого перекладу |
| Test Provider | Один крихітний запит. Неактивне, поки провайдер Disabled |
OpenAI Compatible (для Web2API):
| Поле | Нотатки |
|---|---|
| API Key | Bearer-токен (поле пароля) |
| API Key Env Var | типове ім’я OPENAI_API_KEY (також з .env через settings_manager) |
| Endpoint | плейсхолдер містить https://api.openai.com/v1 або http://127.0.0.1:8081/v1 |
| Model | плейсхолдер gpt-4o-mini або gemini-3.7-flash |
| Temperature | 0.0–2.0, типово 0.0 |
| Max Output Tokens | 0 = Provider default |
| Request Timeout | 1–600 с, типово 60. З Web2API ставте 180 s |
Ollama Chat API: Base URL http://localhost:11434, Model llama3, таймаут типово 120 с, Keep Alive.
Google Gemini API: Base URL необов’язковий (http://127.0.0.1:8081/v1 або порожньо для API Google), API Key необов’язковий для локального проксі, Model gemini-3.7-flash.
Perplexity API: Bearer-токен, Base URL https://api.perplexity.ai, плейсхолдер моделі sonar-medium-8x7b-chat.
Edit Prompts JSON редагує збережені шаблони. Для разової правки Ctrl-клік AI Translate або AI Variation.
Global → Show prompt editor before AI requests відкриває редактор на кожному запиті.
У редакторі системний промпт закінчується рядком --- REQUEST RULES (added by Picoripi …) ---, а далі йдуть сталі правила для цього типу запиту (формат відповіді, розмітка рядків, глосарій, теги, необов’язкові поля контексту). Вони однакові для кожного фрагмента прогону, тож провайдер може їх кешувати; їх можна змінити на один запуск, але при збереженні промпта зберігається лише частина над цим рядком. Повідомлення користувача містить заголовок і дані: для блока — layout_defaults один раз і по одному рядку на кожну репліку лише з тим, що властиве саме їй.
Типовий конфіг provider — "disabled", поки не виберете.
Переклад у редакторі
AI Translate (над Editable):
- Клік: перекласти поточний рядок. Якщо переклад уже є в базі бекапів — бере його (без нового запиту).
- Ctrl-клік: редактор промпта і ігнор збереженого перекладу (завжди новий запит).
- Кілька рядків: виділіть у Strings in block, правий клік (там теж Ctrl-клік для редактора промпта).
- Понад 12 елементів в одній задачі йде чанкованим перекладом (
translate_specific_strings).
Якщо вже йде задача: діалог AI Busy.
Нічого не вибрано (physical_block_idx == -1): кнопка нічого не робить.
AI Variation:
- Клік: інше формулювання поточного перекладу (
request_type='variation_list'; температура 0.7). - Спочатку виділіть фрагмент в Editable — перепише лише його.
- Ctrl-клік: редактор промпта.
- Вибір з AI Translation Variations; Refresh / Ctrl-клік ігнорує кеш у пам’яті.
AI Chat (тулбар, Ctrl+Shift+C): вікно AI Chat. Обговорити переклади. Ctrl+Enter / Send надсилає; Enter — новий рядок. Опційно Web Search. Містить кнопку Retry («Повторити», Ctrl+Shift+R) для миттєвого перезапуску останньої репліки (зі зміною моделі/налаштувань або після збою мережі) без повторного введення тексту, кнопку Stop під час генерації, чергу повідомлень із бейджем [In Queue] та дію Reset Context («Скинути контекст»). Чат не пише в Editable; скопіюйте пропозицію самі або скористайтесь AI Translate.
Конвеєри та режими пакетного перекладу
Пакетний переклад можна запустити з головного тулбара (кнопка AI), заголовка дерева блоків, пункту Tools → AI Batch Translation ➔ або кроку 5 Майстра локалізації. Це відкриває діалогове вікно AI Batch Translation Dialog (AIBatchTranslationDialog).
Доступні режими
- Translate Story First (Chronological):
- Використовує
core/translation/block_classifier.pyта зіставлення зі скриптом MemePalace для виділення реплік основного сюжету. - Перекладає рядки в хронологічному порядку, тож сюжетний текст готовий раніше за допоміжні блоки. - Translate Remaining Blocks (Semantic & System): - Перекладає решту блоків інтерфейсу, меню, інвентарю, крамниць і міні-ігор. - Використовує той самий глосарій і контекст рядка, що й будь-який інший прогін. Більше нічого з фази 1 не переноситься: узгодженість із сюжетом дають глосарій і вже перекладені сусідні рядки.
- Run Full Pipeline (Story ➔ Semantic): - Автоматично виконує фазу 1, а потім одразу фазу 2 в єдиному багатоетапному проході.
- Translate All Blocks (Chronological Legacy): - Об'єднує всі блоки в єдиний хронологічний таймлайн і перекладає суцільним потоком.
Мультиагентний консиліум перекладу
Під час пакетного перекладу обробка реплік виконується спільною взаємодією кількох агентів ШІ: - Основний перекладач: генерує варіанти тексту з урахуванням лімітів ширини та керівних тегів. - Вбудований арбітр / редактор (Arbiter/Editor): агент-супервізор, який перевіряє термінологію за активним глосарієм, коригує фразування та стежить за єдністю тону персонажів перед збереженням перекладу.
Що потрапляє в промпт
Рушій не хардкодить словник гри. Плагін може додати (get_translation_context_for_string):
| Ключ | Ефект у промпті |
|---|---|
window_type |
Window Type: <value> |
content_role |
Content Role: <value> |
role_instruction |
вставляється дослівно (плагін сам учить модель свої ролі) |
has_speaker |
False пропускає пошук спікера |
glossary_section |
секція для нового терміна з цього рядка |
force_glossary |
рядок мусить дати запис глосарія |
Плюс спікер (після Merge Speakers), входження глосарія (далі, з нижчим пріоритетом, рядки зв'язаного глосарію серії для термінів, яких немає в глосарії проєкту — 8), сцена MemePalace якщо зібрана, опційно get_ai_flow_context_for_string / get_ai_flow_overview.
Як прогін ділиться на запити. Один запит містить щонайбільше 12 рядків. Рядки однієї сцени MemePalace їдуть разом; у межах сцени (і серед рядків без сцени) репліки однієї розмови — як про неї повідомляє плагін через get_ai_flow_group_for_string — лишаються в одному запиті, коли вміщаються, тож запитання не відокремлюється від відповідей, а вибір — від варіантів. Розмова ріжеться лише тоді, коли вона сама довша за 12 реплік. Плагіни без цього гачка отримують звичайний поділ за кількістю. Переклад, розпочатий до цієї версії, продовжується з тим поділом, з яким його було почато.
Мовно-залежні директиви транскрипції
Системні та плагінні промпти підтримують блоки умовних директив за мовою перекладу:
[IF_TARGET_LANG: <Language>]...[/IF_TARGET_LANG].
Коли цільова мова збігається (наприклад, Ukrainian), директиви розгортаються, надаючи моделі суворі академічні правила практичної транскрипції та транслітерації:
- Англійський проривний звук G передається як українська Ґ (Ganon -> Ґанон, Goron -> Ґорон, Gengar -> Ґенґар), тоді як придиховий H передається як Г (Hyrule -> Гайрул, Hogwarts -> Гоґвортс).
- Спільний корінь Hy- [haɪ] у всесвіті Zelda послідовно уніфікується через Г та дифтонг ай: Hyrule -> Гайрул, Hylia -> Гайлія, Hylian -> гайлійський / гайлієць (зокрема всі похідні назви, істоти й риби: Lake Hylia -> озеро Гайлія, Hylian Shield -> гайлійський щит, Hyrule Bass -> гайрульський окунь, Hylian Loach -> гайлійський в'юн). Категорично заборонені російські кальки «Хайрул» та розсинхронні читання «Гілія / Хілія / гілійці».
- Японські імена та терміни передаються за академічною системою Коваленка (shi -> сі, chi -> ті, tsu -> цу, ji -> дзі, дзвінкий проривний g -> ґ) з категоричним неприйняттям поліванівщини через російське посередництво (Satoshi -> Сатосі, Shigeru -> Сіґеру, Fuji -> Фудзі).
Якщо обрано іншу цільову мову (наприклад, Spanish), такі блоки автоматично вирізаються, зберігаючи промпти абсолютно чистими від непотрібної кирилиці (вимога AUD-L1).
Контекст референсних перекладів
Коли завантажено зовнішні патчі або розпаковані мультимовні ROM, відповідні репліки з усіх доступних референсних мов додаються до промпту у блоці REFERENCE TRANSLATIONS (для окремого рядка) або у полі reference_translations (для пакетного перекладу).
Рушій встановлює чіткі межі роботи моделі:
- Первинне джерело: переклад завжди здійснюється з оригінального тексту (Input text (Original source): або поле "text").
- Виключно контекст: референсні переклади слугують виключно контекстними свідченнями для уточнення змісту, інтонації репліки та статі персонажа з інших релізів чи локалізацій.
- Сувора заборона: промпт прямо забороняє перекладати з будь-якої референсної мови чи копіювати референсний переклад як цільовий результат.
- Скільки: запит на один рядок показує всі завантажені референсні мови. Пакетний запит типово надсилає всі завантажені мови для кожного рядка; щоб обмежити кількість, задайте "max_reference_languages" у блоці налаштувань перекладу (першими йдуть мови, завантажені раніше; 0 — не надсилати). Російська, якщо завантажена, завжди йде останньою, і промпт позначає її як найменш надійний орієнтир, тож обмеження відкидає її першою.
AI глосарія
Settings → AI Glossary
| Поле | Нотатки |
|---|---|
| Provider | OpenAI Compatible · Ollama · Gemini |
| API Key | |
| Use API key from AI Translation | |
| Model | |
| Text Chunk Size | 1000–32000 символів |
| Parallel Requests | 1–16. Ширше за кількість акаунтів проксі лише ставить зайве в чергу на кулдаун |
| Retry Delay | 0–600 с. Серверний Retry-After перемагає |
Запуск пайплайну: Tools → Prepare Glossary… або крок майстра Prepare and enrich the glossary. Див. 8.
Parallel Requests
translation_workers_spin / glossary_workers_spin. Проксі з ротацією кількох акаунтів (Web2API) можуть 4–8. Один акаунт: ставте 1.
Чого не робити
- Не тисніть Translate з Active Provider Disabled.
- Не лишайте Request Timeout 60 с на Web2API (проксі ретраїть по акаунтах).
- Не вважайте повторно використаний бекап свіжим виводом моделі — Ctrl-клік, щоб форсувати.
- Не запускайте другий Translate, поки AI Busy.
- Не кладіть ключі API чи cookies у вікі, README чи коміти. Settings або
.env. - Не ставте Parallel Requests набагато вище за Active-акаунти; зайві воркери чекають кулдаун.