やりたかったこと
クライアントワークでサイトを作ると、ほぼ毎回「よくある質問」ページが発生します。そのたびに手作業していたのが2つあって、
- FAQの叩き台づくり — クライアントに質問を出してもらっても埋まらないので、結局こちらで既存ページから拾って書く
-
FAQPageの JSON-LD を手書きする — 構造化データを入れたいが、手で書くと面倒だし、書き間違えるとリッチリザルトに出ない
サイトには既に情報が書いてあるので、それを読ませてFAQ案とJSON-LDを吐かせれば済むのではと思って作りました。
登録不要・無料です。URLを入れて15〜20秒でFAQ案が出ます。
出力
実際にURLを1つ入れて生成した結果です。18件出ました。
汎用的な「営業時間は?」ではなく、そのページに書いてある内容から質問を組み立てます。出た案はその場で編集・削除できます。
出力は3形式です。
一番作りたかったのが FAQPage の JSON-LD で、そのまま <head> に貼れる形で出します。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "コードを貼るのは難しくないですか?",
"acceptedAnswer": {
"@type": "Answer",
"text": "プログラミングは不要です。発行された1行を、サイトの終了タグの前に貼るだけで設置できます。"
}
}
]
}
</script>
HTML出力は <details> / <summary> のアコーディオンなので、JSなしでそのまま貼ればFAQページになります。
FAQPage は「ページ上に同じFAQを表示していること」が条件です。JSON-LDだけ貼って本文にFAQが無いと、Googleのガイドライン違反になります。ツールの出力にもその注意書きを入れています。
実装で気をつけたこと
無認証でAIを叩くツールなので、防御周りが本題でした。
SSRF対策
入力URLを取得する処理なので、内部アドレスを弾く必要があります。169.254.0.0/16(メタデータエンドポイント)や 127.0.0.1、プライベートIPレンジを遮断し、リダイレクト先も再検証しています。不正な形式のURLもエラーで返します。
取得サイズと時間の上限
2MB・10秒・本文12,000字で打ち切り。巨大なページや応答しないサーバーに引っ張られないようにしています。
同一ドメインのキャッシュ
同じページを何度も生成させないよう、24時間だけキャッシュします。キャッシュヒットならAPIを呼ばないので費用ゼロ、応答も281msでした。24時間で消えるので、他人のサイトの内容をこちら側に残しません。
生成回数の上限
AIのAPIコストが実費で出るので、1日あたりの生成回数に上限を置いています。上限に達したら停止し、運営側に通知が飛びます。原価は1件あたり数円なので、上限まで使われても1日数百円に収まる設計です。
モデル
Anthropic の Claude Haiku 4.5 を使っています。1回の生成でAPIを1回呼ぶだけの構成です。
なお、プロンプトキャッシュを入れていたのですが、FAQが小さいと効きませんでした。Haiku 4.5 のキャッシュ最小長が4,096トークンで、それ未満だとキャッシュが作られません。実測すると、24問(約2,300トークン)では cache_creation_input_tokens が0のまま。120問(約11,800トークン)にすると効き始めて、1件あたりの原価が約1/2になりました。小さい入力ではキャッシュ前提のコスト試算が成立しないという、当たり前だが見落としやすい点でした。
おまけ
作ったFAQは、そのままサイトに置くチャットボットにもできます(元々そちらが本体で、FAQ生成はその一部を切り出したものです)。答えられなかった質問が管理画面に溜まるので、それをFAQに追加していく作りにしています。
まとめ
- FAQの叩き台とJSON-LDの手書きが面倒だったので、URLから自動化した
- https://faquick.net/faq-maker/ (登録不要・無料)
- 触ってみて「ここが惜しい」があれば教えてください

