Как собирается запрос
В каком порядке Read Frog собирает отправляемый промпт и что он делает с текстом, который модель присылает обратно.
Ваши два поля промпта — не то, что покидает браузер. Read Frog добавляет блоки правил, подставляет переменные, прикрепляет термины глоссария, а затем прилично работает с ответом, прежде чем хоть что-то из него дойдёт до страницы. Эта страница проходит обе половины по порядку.
Всё здесь — про LLM-провайдеров. Google Translate, Microsoft Translator и DeepL промпта не получают, и ни один из этих этапов к ним не относится.
Сборка запроса
1. Выбрать абзацы
Скрипт на странице собирает абзацы по мере их приближения к области просмотра, отбрасывает те, что исключены правилом пропуска или фильтром коротких текстов, и передаёт остальные в очередь. На LLM-провайдере очередь группирует совместимые абзацы в один запрос — тот же провайдер, та же языковая пара, тот же контекст страницы — в пределах лимитов по символам и абзацам со страницы Управление запросами и пакетный перевод. Эта группа и становится {{input}}.
2. Взять промпт
Read Frog находит выбранный вами идентификатор промпта. Если он указывает на встроенный, побеждает встроенный; иначе просматриваются ваши собственные промпты; если не совпало ни одно — например, промпт был удалён, пока оставался выбранным, — вместо ошибки происходит откат на По умолчанию.
3. Дописать блоки правил
Дополнительные инструкции дописываются в системный промпт — и только тогда, когда они нужны. Именно поэтому один и тот же промпт даёт разный запрос на разных абзацах.
| Блок | Дописывается, когда |
|---|---|
| Правила нескольких абзацев | Запрос несёт больше одного абзаца |
| Правило «уже переведено» | Запрос несёт больше одного абзаца, только для перевода страниц |
| Правила маркеров защищённого HTML | Текст содержит маркер data-rf-attr |
| Правила защищённых подстановок | Текст содержит нумерованную подстановку формулы |
Запрос с одним абзацем не получает ни одного из них. Перевод субтитров получает правила нескольких абзацев, но никогда — правило «уже переведено».
4. Подставить переменные
Теперь имена в {{...}} заменяются — в обоих полях — на значения, описанные на странице Переменные промпта. Заменяются только известные имена; всё остальное остаётся как написано.
5. Прикрепить глоссарий
Последними в системный промпт дописываются те термины из вашего глоссария, которые действительно встречаются в этом тексте. Они идут последними намеренно: термин — это набранный вами текст, и если бы он прикреплялся до подстановки, термин, случайно содержащий имя переменной, мог бы переписать промпт вокруг себя.
Готовый запрос
Два абзаца из англоязычной статьи, перевод на упрощённый китайский, промпт По умолчанию, умный контекст ИИ выключен. Уходящий системный промпт:
You are a professional Simplified Mandarin Chinese native translator who needs to fluently translate text into Simplified Mandarin Chinese.
## Translation Rules
1. Output only the translated content, without explanations or additional content ...
2. The returned translation must maintain exactly the same number of paragraphs and format as the original text.
3. If the text contains HTML tags, consider where the tags should be placed in the translation while maintaining fluency.
4. For content that should not be translated (such as proper nouns, code, etc.), keep the original text.
## Document Metadata for Context Awareness
Webpage title: Why your timestamps are eight hours off — devblog
Webpage summary: No summary available
## Multi-paragraph Translation Rules
1. If input contains a standalone line containing only %%, use a standalone %% line in your output ...
2. **CRITICAL**: Treat %% as a separator only when it appears on its own line ...
## OUTPUT FORMAT:
- **Single paragraph input** → Output translation directly (no separators, no extra text)
- **Multi-paragraph input** → Put %% on its own line between translations
## Already-translated Input Rule
Output only {{NO_TRANSLATION_NEEDED}} when only non-translatable names, brands, handles, URLs, numbers, or code differ from Simplified Mandarin Chinese. A foreign-language phrase or clause must be translated.И промпт:
Translate to Simplified Mandarin Chinese:
Every timestamp you store without a zone is a bug waiting for a plane ticket.
%%
The fix is boring: store UTC, render local, and never let the two meet in a database column.Обратите внимание на две пустые строки после двоеточия — они приходят из самого поля промпта, которое устроено как Translate to {{targetLanguage}}:, затем две пустые строки и {{input}}.
Чтение ответа
1. Обрезать и разделить
Ответ обрезается по краям, а затем делится по строкам, в которых нет ничего, кроме %%. Каждый кусок обрезается снова и сопоставляется с абзацем, стоявшим на том же месте в запросе. %% внутри предложения, примера кода или цитаты разделителем не является — только строка, в которой больше ничего нет.
2. Проверить количество
Read Frog ожидает ровно столько кусков, сколько отправил. Несовпадение — это жёсткий провал всей группы, а не частичный успех: запрос повторяется до трёх раз с растущей задержкой, и если сходимости всё равно нет, каждый абзац группы отправляется отдельно. Это медленнее и дороже, и именно поэтому промпт, подталкивающий к комментариям или к склейке абзацев, не просто неаккуратен, а дорог.
3. Разрешить «переводить нечего»
{{NO_TRANSLATION_NEEDED}} — тот ответ, который модели велено давать для абзаца, уже написанного на вашем целевом языке. Когда кусок в точности равен этому маркеру, Read Frog считает перевод пустым, а пустой перевод ничего не выводит: в двуязычном режиме второй строки под этим абзацем не появляется, а в режиме только перевода остаётся видимым оригинал.
Маркер хранится в кэше как есть, поэтому решённый так абзац при следующем посещении заново не отправляется. Его форма намеренно повторяет форму переменной: подстановка заменяет только известные ей имена, поэтому маркер проходит сборку промпта нетронутым и доходит до модели каждый раз написанным одинаково.
4. Отбросить перевод, который ничего не говорит
Модель, получившая текст на том же языке, часто отражает его обратно с косметическими отличиями вместо использования маркера: переформатированные пробелы, прямые кавычки, превращённые в типографские, полноширинная пунктуация. Read Frog сравнивает ответ с источником, сложив эти отличия, и если они совпадают, тоже считает результат пустым. Именно поэтому часть абзацев на странице со смешанными языками не показывает перевода, хотя запрос для них делался.
5. Проверить маркеры
Если текст несёт маркеры data-rf-attr, ответ обязан вернуть каждый из них ровно один раз и на элементе того же вида. Маркер, который отсутствует, продублирован, выдуман или переехал на другой тег, проваливает этот абзац вместо того, чтобы отрисовать ссылку, ведущую куда-то не туда.
Нумерованные подстановки формул проверяются мягче. Ответ, потерявший или продублировавший одну из них, всё равно показывается — недостающие формулы дописываются, — но он не попадает в кэш, поэтому следующее посещение получает новую попытку, а не навсегда испорченный абзац.
6. Сохранить
То, что уцелело, записывается в кэш переводов, и страница обновляется.
Ключ кэша
Кэшированный перевод ключуется, среди прочего, на готовый системный промпт и готовый промпт — после блоков правил, после подстановки, после глоссария.
Из этого следуют три вещи, о которых стоит знать:
- Правка промпта делает сиротами все переводы, сделанные прежним. Страницы, которые вы уже прочли, будут переведены — и оплачены — снова.
- Изменение глоссария делает сиротами только те абзацы, в которых нашёлся термин. Абзац, в котором не совпало ничего, даёт промпт, побайтово совпадающий с промптом без глоссария вообще, поэтому его запись в кэше уцелеет.
- Включение или выключение умного контекста ИИ меняет каждый ключ, потому что меняется переменная с кратким содержанием — с настоящего содержания на
No summary availableили обратно.
Очистка кэша через Настройки → Перевод удаляет сохранённые переводы и краткие содержания страниц. Ваших промптов, провайдеров и глоссариев это не касается.
