Read Frog

リクエストの組み立て方

Read Frog が送信するプロンプトを組み立てる順番と、モデルから返ってきたテキストに対して行う処理。

自分で書いた 2 つの欄が、そのままブラウザーを出ていくわけではありません。Read Frog はルールブロックを追加し、変数を置換し、用語集の用語を添えます。そして返ってきた内容がページに載るまでにも、かなりの処理が入ります。このページでは、その前半と後半を順番に見ていきます。

ここで扱うのはすべて LLM プロバイダーの話です。Google Translate、Microsoft Translator、DeepL はプロンプトを受け取らないため、以下のどの段階も当てはまりません。

リクエストを組み立てる

1. 段落を選ぶ

コンテンツスクリプトは、段落がビューポートに近づいたところで集め、スキップルールや小さな段落のフィルターで除外されるものを落とし、残りをキューに渡します。LLM プロバイダーでは、キューが条件の合う段落 — 同じプロバイダー、同じ言語ペア、同じページコンテキスト — を 1 回のリクエストにまとめます。まとめる量はリクエスト制御とバッチ翻訳ページの文字数と段落数の上限までです。このまとまりが {{input}} の中身になります。

2. プロンプトを決める

Read Frog は選択されているプロンプトの id を引きます。それが組み込みを指していれば組み込みが使われ、そうでなければ自分のプロンプトの中を探します。どちらにも見つからない場合 — たとえば使用中のプロンプトを削除したときです — 失敗させるのではなく デフォルト に戻ります。

3. ルールブロックを追加する

追加の指示は システムプロンプト の末尾に付き、しかも必要なときだけ付きます。同じプロンプトでも段落によって違うリクエストになるのは、これが理由です。

ブロック追加される条件
複数段落のルールリクエストが 2 つ以上の段落を運ぶとき
翻訳済み入力のルールリクエストが 2 つ以上の段落を運ぶとき。ページ翻訳のみ
HTML マーカー保護のルールテキストに data-rf-attr マーカーが含まれるとき
プレースホルダー保護のルールテキストに番号付きの数式プレースホルダーが含まれるとき

段落が 1 つだけのリクエストには、どれも付きません。字幕翻訳には複数段落のルールは付きますが、翻訳済み入力のルールは決して付きません。

4. 変数を置換する

ここで {{...}} の名前が、両方の 欄で、プロンプト変数ページに書かれている値に置き換わります。置き換わるのは既知の名前だけで、それ以外は書いたまま残ります。

5. 用語集を添える

最後に、用語集の用語のうち、このテキストに実際に現れたものだけがシステムプロンプトの末尾に付きます。最後に回しているのは意図的です。用語は自分が入力したテキストなので、置換より前に付けてしまうと、変数名をたまたま含む用語が周囲のプロンプトを書き換えてしまえるからです。

出来上がったリクエスト

英語の記事から 2 段落、簡体字中国語への翻訳、デフォルト プロンプト、AI スマートコンテキストはオフ。送られるシステムプロンプトは次のとおりです。

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.

コロンのあとの空行 2 つに注意してください。これはプロンプト欄そのものから来ています。Translate to {{targetLanguage}}: のあとに空行が 2 つ続き、そのあとに {{input}} が置かれているためです。

返ってきたテキストの処理

1. 空白を落として分割する

返ってきたテキストは前後の空白を落としてから、%% だけの行で分割されます。各断片はもう一度前後を削られ、リクエストの中で同じ位置にあった段落と対応づけられます。文の途中、コード例、引用の中にある %% は区切りになりません。それ以外に何もない行だけが区切りです。

2. 数を確認する

Read Frog は、送った数とまったく同じ数の断片を期待します。数が合わないのは部分的な成功ではなく、そのまとまり全体の失敗です。リクエストは間隔を広げながら最大 3 回まで再試行され、それでも合わなければ、そのまとまりの段落が 1 つずつ再送されます。これは遅いうえに費用も増えます。だからこそ、モデルに講評を促したり段落を統合させたりするプロンプトは、体裁が崩れるだけではなく、実際に高くつくのです。

3.「翻訳不要」を解決する

{{NO_TRANSLATION_NEEDED}} は、すでにターゲット言語で書かれている段落に対してモデルが返すよう指示されている答えです。断片がちょうどこのマーカーだけだった場合、Read Frog は訳文を空として扱い、空の訳文は何も描画しません。対訳モードではその段落の下に 2 行目が現れず、翻訳のみモードでは原文がそのまま表示され続けます。

マーカーはそのままキャッシュに保存されるため、この形で決着した段落は次の訪問時に再送されません。これはわざと変数の形にしてあります。変数の置換は知っている名前だけを置き換えるので、マーカーはプロンプトの組み立てを無傷で通り抜け、毎回まったく同じ綴りでモデルに届きます。

4. 何も言っていない訳文を捨てる

同じ言語のテキストを渡されたモデルは、このマーカーを使わずに、見かけだけ違う形で原文を書き写して返してくることがよくあります。空白の入り直し、まっすぐな引用符が曲がった引用符になる、句読点が全角になる、といったものです。Read Frog はそうした差を折りたたんだうえで返答と原文を比べ、一致していればこれも空として扱います。言語の混ざったページで、リクエストは送られたのに訳文が出ない段落があるのは、これが理由です。

5. マーカーを検証する

テキストが data-rf-attr マーカーを運んでいた場合、返答はそれぞれをちょうど 1 回、同じ種類の要素に付けて返さなければなりません。マーカーが欠けている、重複している、勝手に作られている、別のタグに移っている、といった場合は、別の場所を指すリンクを描画するのではなく、その段落を失敗とします。

番号付きの数式プレースホルダーは、もう少し緩く扱われます。プレースホルダーを落としたり重複させたりした返答も表示はされます — 欠けた数式は末尾に付け足されます — が、キャッシュには 書き込まれません。その段落が劣化したまま固定されるのではなく、次の訪問でもう一度試せるようにするためです。

6. 保存する

生き残ったものが翻訳キャッシュに書き込まれ、ページが更新されます。

キャッシュのキー

キャッシュされた訳文のキーには、ほかの要素とあわせて 出来上がったシステムプロンプトと出来上がったプロンプト が含まれます。ルールブロックを追加し、置換し、用語集を添えたあとの、あの 2 つです。

そこから、知っておく価値のある結果が 3 つ出てきます。

  • プロンプトを編集すると、古いプロンプトで作った訳文はすべて行き場を失います。 すでに読んだページも、もう一度翻訳され、もう一度課金されます。
  • 用語集を変更しても、影響を受けるのは用語が一致した段落だけです。 何も一致しなかった段落が送るプロンプトは、用語集がまったくない場合とバイト単位で同一なので、そのキャッシュはそのまま残ります。
  • AI スマートコンテキストのオン・オフはすべてのキーを変えます。 要約の変数が変わるからです — 実際の要約から No summary available へ、あるいはその逆へ。

設定 → 翻訳 → ページ翻訳 からキャッシュを消すと、保存されている訳文とページ要約が削除されます。プロンプト、プロバイダー、用語集には影響しません。

On this page