Чому я за це взявся
На fixops.pro чотири мови: англійська як основна, а також німецька, грецька й українська. Перекладати вручну кожну сторінку, кожен підпис у формі й кожну назву рубрики довго, а автоматичний переклад самого плагіна часто виходить сухим і неточним. Я вирішив спробувати інший підхід: доручити рутину ШІ-агентові, а контроль залишити собі.
Це дослідження про те, як усе влаштовано, що вийшло і які помилки я виловив дорогою.
Експеримент із Claude
Я давно користуюся ШІ в роботі й захотів перевірити, як далеко можна зайти з Claude від Anthropic в одній конкретній задачі: багатомовному сайті на WordPress. Мені було важливо не «попросити модель перекласти абзац», а вбудувати її в реальний процес: щоб вона сама знаходила неперекладені рядки, записувала результат туди, де його чекає плагін, і не ламала при цьому сайт.
Як це влаштовано технічно
Сам TranslatePress реєструє у WordPress лише кілька дій із налаштуваннями (наприклад, список мов), і для агентів через MCP вони за замовчуванням закриті. Дій для читання й запису самих перекладів у нього немає. Цю відсутню частину я написав як невеликий плагін, TranslatePress AI Bridge. Він додає на сайт «можливості» (abilities) для роботи зі словником, а далі до них підключаються агенти.
Рівень сайту: WordPress Abilities
Починаючи з WordPress 6.9 у ядрі є Abilities API: плагін оголошує невеликі операції з описом їхніх вхідних і вихідних даних. Мій плагін оголошує сім таких операцій:
| Ability | Що робить |
|---|---|
get-strings | Повертає рядки словника вибраної мови посторінково. За замовчуванням лише неперекладені. |
register-page-strings | Завантажує сторінку цільовою мовою, щоб TranslatePress додав її рядки до словника. |
save-translations | Записує пари «ідентифікатор і переклад» через власний шар запитів TranslatePress. |
get-excluded-selectors і update-excluded-selectors | Читає та змінює список «Не перекладати ці селектори». |
purge-strings | Видаляє непотрібні неперекладені рядки за ідентифікатором або регулярним виразом. |
translate-via-api | Перекладає неперекладені рядки за допомогою Claude через API-ключ, указаний у плагіні. |
Рівень зв'язку: MCP
Model Context Protocol підключає такі можливості до ШІ-агента як інструменти. На сайті працює MCP Adapter, який публікує позначені можливості. Агент спершу питає в сайту, що той уміє і які параметри в кожної дії, а потім викликає їх.
Тож у чаті я кажу Claude «переклади рядки грецькою», і він сам читає словник, перекладає й записує результат. Мені не потрібно відкривати візуальний редактор TranslatePress і чекати на його admin-ajax чергу запитів.
Автономний рівень: мій власний ключ Anthropic API
Робота через чат означає, що я маю сидіти й дивитися. Щоб сайт міг перекладати сам, без клієнта й без відкритої MCP-сесії, я додав у плагін підтримку Anthropic API з моїм власним ключем (рахунок виставляє Anthropic власникові ключа). Запустити прогін можна трьома способами:
- кнопка в налаштуваннях плагіна;
- команда WP-CLI:
wp trpab translate --lang=de_DE --dry-run, а потім те саме без--dry-run; - можливість
translate-via-apiабо вбудований рушій «Claude (Anthropic API)» в автоматичному перекладі TranslatePress.
За замовчуванням плагін використовує модель claude-haiku-4-5 надсилає по 40 рядків за запит і не більше 200 рядків за прогін. У налаштуваннях можна задати глосарій і стильові нотатки, наприклад «писати Website, а не Webseite». Ключ можна зберігати в wp-config.php, у змінній середовища або в зашифрованому вигляді в базі даних. Останній варіант більше ніколи не показує ключ.
Модель довіри
Довіру я побудував так, щоб агент міг помилятися без великих наслідків:
- Права доступу. Такі самі, як у редактора TranslatePress (
manage_optionsза замовчуванням). - Статус «машинний».
save-translationsзберігає переклади зі статусом «машинний» і за замовчуванням ніколи не перезаписує рядки, які перевірила людина. - Пробний прогін. Запис, видалення й переклад через API за замовчуванням виконуються як пробні, тобто показують, що буде зроблено, нічого не змінюючи.
- Лише власний сайт.
register-page-stringsзвертається лише до адрес власного домену сайту. - Резервна копія. Перед масовими операціями потрібна копія
wp_trp_dictionary_*таблиць.
Принцип простий: агент пропонує й записує, а я задаю правила, дивлюся на результат і ухвалюю рішення.
Що пішло не так
Сміття у словнику
Щойно агент зареєстрував першу сторінку, у словнику з'явилося багато зайвого:
- назви іконок (
check_circle,gpp_bad,volunteer_activism). Це шрифт Material Symbols, де іконка задається текстом, і плагін сумлінно прийняв його за слова; - шаблонний текст Divi на кшталт lorem ipsum і «Your content goes here»;
- тестові дописи на кшталт «Hello world!»;
- рядок із друкованим текстом у шапці: він з'являється по літері, і кожна проміжна версія (
checking client-c.io … res,… resp,… respo) стала окремим рядком; - числа й часовий пояс, як-от
18msіGMT+2.
У кожній мові набралося близько п'ятдесяти таких рядків. Я видаляв їх за регулярним виразом, спершу в пробному режимі, де видно, що саме буде видалено, і лише потім по-справжньому.
Але чистка словника лікує симптом. Причина в іншому, тому я зробив дві речі:
- я додав у винятки плагіна контейнери, де живе динаміка (
#tickerText,[data-count-to],.notranslate); - я переніс іконки з тексту в CSS: замість слова в розмітці іконка тепер малюється через
contentу таблиці стилів. Плагін такого тексту не бачить, і рядки більше не з'являються.
Ідентифікатори не спільні
Та сама англійська фраза в різних мовах має різні номери. Мій грецький словник відрізнявся від німецького зі зсувом на десятки ідентифікаторів. Якщо застосувати список ідентифікаторів однієї мови до іншої, переклад запишеться не в ті рядки. Тому агент для кожної мови отримує свій список заново.
Кеш показує старе
Я записав переклади, відкрив сторінку й побачив англійську. Причина була в кеші LiteSpeed: він віддавав збережену копію. Щоб переконатися, що переклади на місці, я запитував сторінку з довільним параметром в адресі, що обходить кеш. Після очищення кешу все стало на свої місця.
Сторінки без публікацій не перекладаються
Рубрику «Off the Grid» було створено, але без дописів, і її сторінка відповідала помилкою 404. Рядки з її назвою з'явилися у словнику лише після того, як рубрика почала відображатися на інших сторінках.
Де ШІ помилявся
Це найважливіша частина. Переклади виглядали гладко, але коли я уважно перечитав їх, то знайшов справжні помилки.
У грецькій:
- неіснуюче слово замість «я почав» (у тексті було «Ύργισα» замість «Ξεκίνησα»);
- фраза, що означає «сайти, які губляться через хакерів», замість «сайти, які зламали»;
- пункти списку закінчувалися крапкою з комою. У грецькій це знак питання, тож список читався як ланцюжок запитань;
- слово «програма» замість «компанія», де йшлося про агенцію;
- кілька помилок друку та узгодження.
В українській: в одному слові була латинська літера i всередині кирилиці. Оком цього не помітити, але пошук за текстом таке слово не знайде.
Я виправив близько тридцяти грецьких рядків і один український. Німецьку я вручну не перечитував, і це чесна слабка ланка.
Висновок: переклад від ШІ придатний як чернетка, але не як кінцевий результат. Особливо це стосується мов, якими ви самі не читаєте.
Як я контролюю якість
- Статус рядка. Кожен переклад зберігається зі статусом «машинний». Рядки, які перевірила людина, отримують статус «перевірено», і агент їх за замовчуванням не чіпає.
- Пробний прогін. Будь-яка масова дія, особливо видалення, спершу виконується в режимі, який нічого не змінює й лише показує список.
- Перевірка носієм. Для мов, яких ви не знаєте, потрібен принаймні один читач. Для грецької це був би крок, який я зробив би раніше.
- Перевірка на живій сторінці. Я не вірю запису у словник, доки не побачу переклад на живій сторінці з обходом кешу.
Що перевірити, перш ніж повторювати
- Ліцензія й умови. Мій плагін розрахований на безкоштовний TranslatePress і працює через його власний шар запитів. Платні версії й додатки можуть мати власні умови використання, тож перш ніж підключати до них ШІ-агента, прочитайте їх і за сумніву запитайте підтримку.
- Чиї це тексти. Рядки йдуть у модель. Для вашого власного сайту це нормально, а клієнтські тексти без згоди так надсилати не можна.
- Чий це рахунок. При роботі через API кожен запуск оплачується за вашим ключем. Починайте з пробного прогону: він показує, скільки рядків і токенів знадобиться.
- Резервна копія. Перед масовими операціями зробіть копію таблиць словника.
Підсумки
За один день я отримав переклад допису, інтерфейсу й рубрик трьома мовами та привів словник до ладу. Вручну це зайняло б значно більше часу.
Але головний результат інший. Агент прискорює рутину, а відповідальність за точність залишається в людини. Без перевірки в грецькому тексті залишилося б слово, якого не існує.
Давайте працювати разом
Якщо вам потрібна багатомовна версія сайту на WordPress, допомога з TranslatePress або акуратне впровадження ШІ в такі процеси без втрати якості, напишіть мені. Відповідаю швидко й без зайвих дзвінків.