少し間が空いたけど、今もAIでなんかWebサービス作ろうと考えてます。
今回はGemini APIを調査しました。
利用制限
ネットにGemini APIなら無料で1日1,500回使えて画像生成も出来ちゃう! と魅力的なことが書かれていました。
しかし確認してみると、Gemini3Flashは現在1日20回しか使えませんでした。Gemini2.5系と合わせても60回。ちょっと少ないな。そして画像生成は2026年1月15日で無料枠廃止したとのこと。やれやれ…
レート制限の表です。
RPM:1分あたりの最大リクエスト数
TPM:1分あたりの最大入力トークン数
RPD:1日あたりの最大リクエスト数
その代わりGemmaは1日14,400回使えます。性能やTPM小さいのが気になるけど数的には十分です。
無料枠でも商用利用可能です。ただし入力データがGeminiの学習に使われるので注意。
とりあえず何とかなりそう、ということで先に進みます。
APIキー取得
Google AI StudioのGet API Keyから取得できます。
「右上のAPIキーを作成」ボタンからキー名を入力し、プロジェクトを作成すれば完了です。プロジェクトでは「お支払い情報を設定」というリンクが出るけど無料枠で使うならそのままスルーでOK。
API呼び出し
早速API叩いてみます。実際はPostman使って実行してますが、ここではCurlコマンドで書きます。
いちばんシンプルな例
最低限必要なパラメータのみ入れたものです。
モデル名:gemini-2.5-flash-lite, gemma-3-27b-it など
APIキー:取得したキー
curl "https://generativelanguage.googleapis.com/v1beta/models/(モデル名):generateContent" \
-H 'Content-Type: application/json' \
-H 'X-goog-api-key: (APIキー)' \
-X POST \
-d '{
"contents": [
{
"parts": [{"text": "こんにちは、今日は何ができる?"}]
}
]
}'
実行結果は以下です。textに返答が入ってますね。長いので省略してます。
{
"candidates": [
{
"content": {
"parts": [
{
"text": "こんにちは!今日は、以下のようなことができます。\n\n**情報提供・質問回答:**\n\n* **調べ物:** 知りたいこと、疑問に思っていることを質問してください。(以下略)"
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 7,
"candidatesTokenCount": 430,
"totalTokenCount": 437,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 7
}
]
},
"modelVersion": "gemini-2.5-flash-lite",
"responseId": "RThuad2lE82-vr0PzaziuAs"
}
簡単だね。
会話を引き継ぐ
上記のままだと過去の会話が無視されてしまいます。ちゃんと会話のキャッチボールするため、過去の会話内容を一緒に渡します。
role:user(ユーザ), model(AI)
上が古く、下が新しい会話です。引き継ぐテキストは10往復程度が良さそうです。それ以上続く場合は裏側で「これまでの会話の要約」を生成し、それを渡します。
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=(APIキー)" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [
{
"role": "user",
"parts": [{ "text": "私はプログラマーです。" }]
},
{
"role": "model",
"parts": [{ "text": "承知しました。コードの記述などお手伝いします。" }]
},
{
"role": "user",
"parts": [{ "text": "私の職業を覚えていますか?" }]
}
]
}'
ただGemmaはTPM小さいのであんまり会話続けられないかも。
安全フィルター追加
Webサービスとして利用する場合、悪意あるユーザからの入力を防ぐ必要があります。元々フィルターは入っていて、その制限を強めたり弱めたりできます。
フィルターは4種類。
・ハラスメント(HARM_CATEGORY_HARASSMENT)
・ヘイトスピーチ(HARM_CATEGORY_HATE_SPEECH)
・性的表現(HARM_CATEGORY_SEXUALLY_EXPLICIT)
・危険なコンテンツ(HARM_CATEGORY_DANGEROUS_CONTENT)
フィルターの強さも4種類。
・全てブロック(BLOCK_LOW_AND_ABOVE)
・グレーゾーンは通す(BLOCK_MEDIUM_AND_ABOVE)※デフォルト
・危険なもののみブロック(BLOCK_ONLY_HIGH)
・ブロックなし(BLOCK_NONE)※ただし超危険なものはブロックされる
Curlで投げるbodyに以下を追加します。
"safetySettings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_LOW_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_LOW_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
}
]
フィルターに引っかかった場合、以下のようなレスポンスとなります。
{
"candidates": [
{
"content": {
"parts": [
{
"text": "" // 空、もしくは警告文
}
],
"role": "model"
},
"finishReason": "SAFETY", // ここがSAFETYなら以下に理由が書かれる
"safetyRatings": [
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"probability": "HIGH" // なぜブロックされたかがわかる
},
...
]
}
],
...
}
これで悪用されなくなるはずです。
実際にAPI叩いてみると…
503エラー出まくるんだけど(汗) 503は混み合っててサーバ側で処理しきれなかったエラーです。世界中の人々が無料枠でアクセスするんだから当然か。
その後数日ほど試したところ、全然アクセス出来なかったのは初日だけでした。たまたま調子悪かっただけかな? とはいえ1日数回はエラーになると言われてるので、ある程度の割り切りは必要かもしれません。
まとめ
これで簡単なチャットは作成できるようになりました。もちろん今更チャット作っても仕方ないので、他のサービス考える必要あるけどね。

コメント