Read Frog

プロンプト変数

Read Frog のプロンプトで使えるすべての変数と、それぞれが実際に置き換わる値。

変数は {{name}} の形で書きます。リクエストを送る直前に、Read Frog は既知の変数をそれぞれ文字列に置き換えます。それ以外は一切触りません。{{url}} のような知らない名前は、{{url}} という文字のままプロンプトに残ります。

以下の例はすべて同じページから採ったものです。https://devblog.example.com/posts/timestamps にある英語の記事を、簡体字中国語に翻訳しています。

どの変数がどこで使えるか

変数ページプロンプト字幕プロンプト
{{targetLanguage}}使える使える
{{input}}使える使える
{{webTitle}}使える使える
{{webDescription}}使える使える
{{webContent}}使える
{{webSummary}}使える
{{videoSummary}}使える

ページプロンプトで {{videoSummary}} を使っても、字幕プロンプトで {{webContent}} を使っても、残るのは文字そのものです。各欄の下にある変数ボタンは、その一覧が値を埋められるものだけを出します。

{{targetLanguage}}

翻訳先の言語の英語名です。言語コードではなく、インターフェースの言語に合わせて訳されることもありません。

Simplified Mandarin Chinese

ほかの例:EnglishTraditional Mandarin ChineseJapaneseSpanish。つまり Translate to {{targetLanguage}}: と書いたプロンプトは、Translate to Simplified Mandarin Chinese: として届きます。

{{input}}

翻訳するテキストです。プロンプトがこれなしでは成り立たない、唯一の変数です。

1 段落ずつ — 前後の空白は削られ、見えない文字は取り除かれます。

Every timestamp you store without a zone is a bug waiting for a plane ticket.

まとめて複数段落。LLM プロバイダーでバッチ翻訳を有効にしているときに実際に起きることです。段落は %% だけの行でつながれ、その両側に空行が 1 つずつ入ります。

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.

%%

Ordering by a naive timestamp works until the clocks change, and then it works wrongly.

モデルには、同じ順番で同じ数の段落を、同じ区切り方で返すことが期待されます。Read Frog はその %% の行で返答を切り分けます。プロンプトを書き換えて区切りを変えたり、段落に番号を付けさせたり、段落を統合させたりすると、分割は失敗し、そのバッチは再試行されたうえで 1 段落ずつ再送されます。

HTML があるとき。段落にインラインのマークアップが含まれる場合です。残さなければならない属性は取り出され、要素には data-rf-attr の印が付くので、モデルには URL ではなく目印が見えます。

The fix is <a data-rf-attr="0">boring</a>: store <code data-rf-attr="1">UTC</code>, render local.

数式やインラインの記号があるとき。番号付きのプレースホルダーに置き換えられ、翻訳が返ってきたあとで元の要素が複製されて戻されます。

Converting is just {{0}}, which is why nobody gets it wrong twice.

プロンプトを書いているときに、この 2 つの形を目にすることはあまりありません。ただ、リクエストに余分なルールブロックが現れる理由はこれです。Read Frog が data-rf-attr と番号付きプレースホルダーについての指示を付けるのは、送るテキストに実際にそれが含まれているときだけです。

{{webTitle}}

ページの <title> です。ブラウザーのタブに表示されているものと同じです。

Why your timestamps are eight hours off — devblog

字幕 プロンプトでは、こちらは動画のタイトルになります。

{{webDescription}}

ページ自身が持っている説明文です。<meta name="description"><meta property="og:description"><meta name="twitter:description"> のうち、内容がある最初のものを取ります。

A short tour of the three places a naive timestamp can go wrong, and the one rule that prevents all three.

字幕 プロンプトでは、こちらは動画の説明になります。

{{webContent}}

ページの本文です。Markdown として抽出し、先頭 2000 文字 で切ります。ナビゲーション、サイドバー、フッターは落とされます。組み込みプロンプトはどれもこれを使っていません。タイトルだけでは足りないプロンプトのために用意されています。

# Why your timestamps are eight hours off

Every timestamp you store without a zone is a bug waiting for a plane ticket.
It works on your laptop, it works in CI, and it fails the first time somebody
in another country opens the report.

## Three places it goes wrong

1. **At the boundary.** A form posts `2026-03-14 09:00` and the server decides
   what that means.
2. **In the column.** `timestamp without time zone` is not a moment in time; it
   is a picture of a wall clock.
3. **On the way out.** Formatting in UTC and labelling it local is the same bug
   wearing a hat.

The fix is boring: store UTC, render local, and never let the tw

切り取りは単純な文字数で、文や段落の区切りは見ません。そのため値はたいてい単語の途中で終わります — 上の例もそうです。本文が完全なものだとモデルに伝えるプロンプトは、2 画面分を超えるページでは必ず誤りになります。

{{webSummary}}

自分の LLM プロバイダーが書いたページの要約です。これは別のモデル呼び出しで、ページ単位でキャッシュされ、一度だけ作られてそのページのすべての段落で再利用されます。

A technical blog post arguing that timestamps should be stored in UTC and rendered in the reader's local zone. It identifies three failure points — form input, database column type, and output formatting — and recommends a single rule for all three. Written for backend developers; uses PostgreSQL column types as examples.

これには AI スマートコンテキスト(設定 → 翻訳 → ページ翻訳)が必要です。オフのときは差し込む要約がないため、この変数は下に挙げる代替文字列になります。デフォルトのプロンプトは {{webSummary}} を使っているので、スマートコンテキストをオフのままにしていると、デフォルトのシステムプロンプトには常に Webpage summary: No summary available と書かれることになります。

{{videoSummary}}

字幕側の対応物です。動画の要約で、こちらも AI スマートコンテキストが前提、オフのときは同じく代替文字列になります。

A conference talk on time zone handling in web applications. The speaker walks through a production incident caused by naive timestamps, then demonstrates a UTC-in, local-out pattern. Names mentioned: PostgreSQL, Temporal, Luxon.

値が取れないとき

変数が空のまま残ることも、消えることもありません。値がない、空、空白だけのいずれかの場合、Read Frog は決まった英文に置き換えます。

変数代わりに入る内容
{{webTitle}}No title available
{{webDescription}}No description available
{{webContent}}No content available
{{webSummary}}{{videoSummary}}No summary available

そのため、メタ情報が何もなく、スマートコンテキストもオフのページでは、デフォルトのシステムプロンプトはこう届きます。

## Document Metadata for Context Awareness
Webpage title: No title available
Webpage summary: No summary available

これがいちばん影響するのは few-shot の例を書くときです。ページのタイトルから例を組み立てるプロンプトは、タイトルのないページでは「No title available」というページについての例をモデルに見せることになり、モデルはその一文を翻訳したり、それについて論評したりします。プロンプトがメタ情報の変数に頼っているなら、値が「No ... available」だったときにどうするかをプロンプト自身に書いてください。

{{input}}{{targetLanguage}} には代替値がありません。{{targetLanguage}} には常に値があり、{{input}} はその段落そのものです — 空のテキストにリクエストが送られることはありません。

このあとに起きること

置換が済んだテキストはリクエストの全部ではありません。このあとルールブロックと自分の用語集の用語が追加され、出来上がった結果が翻訳キャッシュのキーになります。リクエストの組み立て方を参照してください。

On this page