google-gemini-api について
google-gemini-api は、現行 SDK と API の直接呼び出しを解説する、開発者向けの Google Gemini API スキルです。テキストやマルチモーダル生成、ストリーミング、関数呼び出し、応用機能のほか、SDK 移行や実装上の注意点を扱います。
主な機能
- 01Node.js SDK と Fetch の使用例
- 02テキスト生成とストリーミング応答
- 03画像、動画、音声、PDF の入力
- 04関数呼び出しと並列呼び出し
- 05コンテキストキャッシュ、コード実行、検索 grounding
- 06SDK 移行とエラー処理のガイド
活用シーン
- 01Node.js アプリへの Gemini の組み込み
- 02エッジランタイムから Fetch で API 呼び出し
- 03マルチモーダル入力を処理するアプリの構築
- 04関数呼び出しやストリーミング実装の問題調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill google-gemini-apiインストール後、Claude Code で/google-gemini-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.md.claude-plugin/plugin.jsonreferences/code-execution-patterns.mdcontext-caching-guide.mdfunction-calling-patterns.mdgeneration-config.mdgrounding-guide.mdmodels-guide.mdmultimodal-guide.mdsdk-migration-guide.mdstreaming-patterns.mdthinking-mode-guide.mdtop-errors.mdrules/google-gemini-api.mdscripts/check-versions.shtemplates/cloudflare-worker.tscode-execution.tscombined-advanced.tscontext-caching.tsfunction-calling-basic.tsfunction-calling-parallel.tsgrounding-search.tsmultimodal-image.tsmultimodal-video-audio.tspackage.jsonstreaming-chat.tsstreaming-fetch.tstext-generation-basic.tstext-generation-fetch.tsthinking-mode.ts詳細
Google Gemini API - 完全ガイド
バージョン: 3.0.0(既知の問題を14件追加) パッケージ: @google/[email protected](⚠️ @google/generative-ai ではありません) 最終更新日: 2026-01-21
⚠️ SDK の重大な移行に関する警告
非推奨の SDK: @google/generative-ai(2025年11月30日にサポート終了)
現在の SDK: @google/genai v1.27+
@google/generative-ai を使用したコードを見つけた場合、それは古いコードです!
このスキルでは、現在の正しい SDK を使用し、完全な移行ガイドを提供します。
ステータス
✅ フェーズ 1 完了:
- ✅ テキスト生成(基本機能+ストリーミング)
- ✅ マルチモーダル入力(画像、動画、音声、PDF)
- ✅ 関数呼び出し(基本機能+並列実行)
- ✅ システム指示と複数ターンのチャット
- ✅ 思考モードの設定
- ✅ 生成パラメーター(temperature、top-p、top-k、停止シーケンス)
- ✅ Node.js SDK(@google/genai)と fetch の両方のアプローチ
✅ フェーズ 2 完了:
- ✅ コンテキストのキャッシュ(TTL ベースのキャッシュによるコスト最適化)
- ✅ コード実行(組み込みの Python インタープリターとサンドボックス)
- ✅ Google 検索によるグラウンディング(リアルタイムのウェブ情報+引用)
📦 個別のスキル:
- 埋め込み: text-embedding-004 については
google-gemini-embeddingsスキルを参照してください
目次
フェーズ 1 - コア機能:
- クイックスタート
- 現在のモデル(2025)
- SDK と fetch のアプローチ
- テキスト生成
- ストリーミング
- マルチモーダル入力
- 関数呼び出し
- システム指示
- 複数ターンのチャット
- 思考モード
- 生成の設定
フェーズ 2 - 高度な機能: 12. コンテキストのキャッシュ 13. コード実行 14. Google 検索によるグラウンディング
共通リファレンス: 15. 既知の問題の防止 16. エラー処理 17. レート制限 18. SDK 移行ガイド 19. 本番環境のベストプラクティス
クイックスタート
インストール
正しい SDK:
npm install @google/[email protected]
❌ 誤り(非推奨):
npm install @google/generative-ai # DO NOT USE!
環境の設定
export GEMINI_API_KEY="..."
または、.env ファイルを作成します:
GEMINI_API_KEY=...
最初のテキスト生成(Node.js SDK)
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Explain quantum computing in simple terms'
});
console.log(response.text);
最初のテキスト生成(fetch - Cloudflare Workers)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [{ parts: [{ text: 'Explain quantum computing in simple terms' }] }]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
現在のモデル(2025)
Gemini 3 シリーズ(2025年12月)
gemini-3-flash
- コンテキスト: 入力トークン 1,048,576 個 / 出力トークン 65,536 個
- ステータス: 🆕 一般提供開始(2025年12月)
- 説明: 本番ワークロード向けの、Google で最も高速かつ効率的な Gemini 3 モデルです
- 最適な用途: 高スループットのアプリケーション、低レイテンシの応答、コスト重視の本番環境
- 機能: 強化されたマルチモーダル機能、関数呼び出し、ストリーミング、思考モード
- ベンチマーク性能: gemini-2.5-flash の速度とコストで、gemini-2.5-pro と同等の品質を実現します
- 推奨用途: 速度と品質のバランスが求められる本番環境のユースケース
gemini-3-pro-preview
- コンテキスト: 未定(ドキュメント準備中)
- ステータス: プレビュー版(2025年11月18日)
- 説明: 最先端の推論能力を備えた、Google の最新かつ最も高性能な AI モデルです
- 最適な用途: 最も複雑な推論タスク、高度なマルチモーダル理解、ベンチマークが重要なアプリケーション
- 機能: 強化されたマルチモーダル機能(テキスト、画像、動画、音声、PDF)、関数呼び出し、ストリーミング
- ベンチマーク性能: 主要なすべての AI ベンチマークで Gemini 2.5 Pro を上回ります
- ⚠️ プレビューモデルに関する警告: プレビューモデルには SLA がなく、予告がほとんどないまま変更または非推奨になる可能性があります。本番環境では、一般提供(GA)モデルを使用してください。Issue #13 を参照してください
Gemini 2.5 シリーズ(一般提供 - 安定版)
gemini-2.5-pro
- コンテキスト:入力トークン 1,048,576 個/出力トークン 65,536 個
- 説明:複雑な推論に対応する、最先端の思考モデル
- 最適な用途:コード、数学、STEM、複雑な問題解決
- 機能:思考モード(デフォルトでオン)、関数呼び出し、マルチモーダル、ストリーミング
- 知識カットオフ:2025 年 1 月
gemini-2.5-flash
- コンテキスト:入力トークン 1,048,576 個/出力トークン 65,536 個
- 説明:価格と性能のバランスに優れた、頼れるモデル
- 最適な用途:大規模な処理、低レイテンシー、高ボリューム、エージェント型のユースケース
- 機能:思考モード(デフォルトでオン)、関数呼び出し、マルチモーダル、ストリーミング
- 知識カットオフ:2025 年 1 月
gemini-2.5-flash-lite
- コンテキスト:入力トークン 1,048,576 個/出力トークン 65,536 個
- 説明:コストを最適化した、2.5 モデルで最速のモデル
- 最適な用途:高スループット、コスト重視のアプリケーション
- 機能:思考モード(デフォルトでオン)、関数呼び出し、マルチモーダル、ストリーミング
- 知識カットオフ:2025 年 1 月
モデル機能マトリックス
| 機能 | 3-Flash | 3-Pro(プレビュー) | 2.5-Pro | 2.5-Flash | 2.5-Flash-Lite |
|---|---|---|---|---|---|
| 思考モード | ✅ デフォルトでオン | 未定 | ✅ デフォルトでオン | ✅ デフォルトでオン | ✅ デフォルトでオン |
| 関数呼び出し | ✅ | ✅ | ✅ | ✅ | ✅ |
| マルチモーダル | ✅ 強化 | ✅ 強化 | ✅ | ✅ | ✅ |
| ストリーミング | ✅ | ✅ | ✅ | ✅ | ✅ |
| システム指示 | ✅ | ✅ | ✅ | ✅ | ✅ |
| コンテキストウィンドウ | 入力 1,048,576 個 | 未定 | 入力 1,048,576 個 | 入力 1,048,576 個 | 入力 1,048,576 個 |
| 出力トークン | 最大 65,536 個 | 未定 | 最大 65,536 個 | 最大 65,536 個 | 最大 65,536 個 |
| ステータス | GA | プレビュー | 安定版 | 安定版 | 安定版 |
⚠️ コンテキストウィンドウの訂正
正確な情報(Gemini 2.5):Gemini 2.5 モデルがサポートするのは、入力トークン 1,048,576 個です(200 万個ではありません!) 古い情報:200 万トークンのコンテキストウィンドウを備えていたのは、前世代の Gemini 1.5 Pro のみです GEMINI 3:コンテキストウィンドウの仕様は、公式ドキュメントの公開待ちです
よくある間違い:Gemini 2.5 が 200 万トークンに対応していると記載すること。実際には対応していません。このスキルは、この誤りを防ぎます。
SDK と Fetch のアプローチ
Node.js SDK(@google/genai)
メリット:
- TypeScript で型安全
- API が使いやすい(よりシンプルな構文)
- チャット用ヘルパーを内蔵
- ストリーミング時の SSE 解析を自動化
- エラー処理がより優れている
デメリット:
- Node.js または互換性のあるランタイムが必要
- バンドルサイズが大きい
- すべてのエッジランタイムで動作するとは限らない
**使用する場面:**Node.js アプリ、Next.js Server Actions/Components、または Node.js 互換環境で開発する場合
Fetch ベース(REST API を直接使用)
メリット:
- あらゆる JavaScript 環境(Cloudflare Workers、Deno、Bun、ブラウザー)で動作
- 依存関係が最小限
- バンドルサイズが小さい
- リクエストを完全に制御可能
デメリット:
- 構文がより冗長
- ストリーミング時に SSE の解析が手動で必要
- チャット用ヘルパーが内蔵されていない
- エラー処理が手動で必要
**使用する場面:**Cloudflare Workers、ブラウザークライアント、または軽量なエッジランタイムにデプロイする場合
テキスト生成
基本的なテキスト生成(SDK)
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Write a haiku about artificial intelligence'
});
console.log(response.text);
基本的なテキスト生成(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{
parts: [
{ text: 'Write a haiku about artificial intelligence' }
]
}
]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
レスポンス構造
{
text: string, // Convenience accessor for text content
candidates: [
{
content: {
parts: [
{ text: string } // Generated text
],
role: string // "model"
},
finishReason: string, // "STOP" | "MAX_TOKENS" | "SAFETY" | "OTHER"
index: number
}
],
usageMetadata: {
promptTokenCount: number,
candidatesTokenCount: number,
totalTokenCount: number
}
}
ストリーミング
SDK でのストリーミング(非同期イテレーション)
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: 'Write a 200-word story about time travel'
});
for await (const chunk of response) {
process.stdout.write(chunk.text);
}
Fetch でのストリーミング(SSE 解析)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [{ parts: [{ text: 'Write a 200-word story about time travel' }] }]
}),
}
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.trim() === '' || line.startsWith('data: [DONE]')) continue;
if (!line.startsWith('data: ')) continue;
try {
const data = JSON.parse(line.slice(6));
const text = data.candidates[0]?.content?.parts[0]?.text;
if (text) {
process.stdout.write(text);
}
} catch (e) {
// Skip invalid JSON
}
}
}
要点:
generateContentではなく、streamGenerateContentエンドポイントを使用します- Server-Sent Events(SSE)形式を解析します:
data: {json}\n\n - バッファー内の不完全なチャンクを処理します
- 空行と
[DONE]マーカーはスキップします
マルチモーダル入力
Gemini 2.5 モデルは、同じリクエスト内でテキスト、画像、動画、音声、PDF をサポートします。
画像(ビジョン)
SDK のアプローチ
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// From file
const imageData = fs.readFileSync('/path/to/image.jpg');
const base64Image = imageData.toString('base64');
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
{
parts: [
{ text: 'What is in this image?' },
{
inlineData: {
data: base64Image,
mimeType: 'image/jpeg'
}
}
]
}
]
});
console.log(response.text);
Fetch のアプローチ
const imageData = fs.readFileSync('/path/to/image.jpg');
const base64Image = imageData.toString('base64');
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{
parts: [
{ text: 'What is in this image?' },
{
inlineData: {
data: base64Image,
mimeType: 'image/jpeg'
}
}
]
}
]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
サポートされる画像形式:
- JPEG(
.jpg、.jpeg) - PNG(
.png) - WebP(
.webp) - HEIC(
.heic) - HEIF(
.heif)
画像の最大サイズ:1 枚あたり 20 MB
動画
// Video must be < 2 minutes for inline data
const videoData = fs.readFileSync('/path/to/video.mp4');
const base64Video = videoData.toString('base64');
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
{
parts: [
{ text: 'Describe what happens in this video' },
{
inlineData: {
data: base64Video,
mimeType: 'video/mp4'
}
}
]
}
]
});
console.log(response.text);
対応動画形式:
- MP4 (
.mp4) - MPEG (
.mpeg) - MOV (
.mov) - AVI (
.avi) - FLV (
.flv) - MPG (
.mpg) - WebM (
.webm) - WMV (
.wmv)
最大動画長(インライン):2 分 最大動画サイズ:2GB(より大きなファイルには File API を使用してください - フェーズ 2)
音声
const audioData = fs.readFileSync('/path/to/audio.mp3');
const base64Audio = audioData.toString('base64');
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
{
parts: [
{ text: 'Transcribe and summarize this audio' },
{
inlineData: {
data: base64Audio,
mimeType: 'audio/mp3'
}
}
]
}
]
});
console.log(response.text);
対応音声形式:
- MP3 (
.mp3) - WAV (
.wav) - FLAC (
.flac) - AAC (
.aac) - OGG (
.ogg) - OPUS (
.opus)
最大音声サイズ:20MB
const pdfData = fs.readFileSync('/path/to/document.pdf');
const base64Pdf = pdfData.toString('base64');
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
{
parts: [
{ text: 'Summarize the key points in this PDF' },
{
inlineData: {
data: base64Pdf,
mimeType: 'application/pdf'
}
}
]
}
]
});
console.log(response.text);
最大 PDF サイズ:30MB PDF の制限事項:テキストベースの PDF が最適です。スキャン画像は精度が低くなる場合があります。
複数の入力
1 つのリクエストで複数のモダリティを組み合わせることができます。
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
{
parts: [
{ text: 'Compare these two images and describe the differences:' },
{ inlineData: { data: base64Image1, mimeType: 'image/jpeg' } },
{ inlineData: { data: base64Image2, mimeType: 'image/jpeg' } }
]
}
]
});
関数呼び出し
Gemini は関数呼び出し(ツールの使用)をサポートしており、モデルを外部 API やシステムに接続できます。
基本的な関数呼び出し(SDK)
import { GoogleGenAI, FunctionCallingConfigMode } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Define function declarations
const getCurrentWeather = {
name: 'get_current_weather',
description: 'Get the current weather for a location',
parametersJsonSchema: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name, e.g. San Francisco'
},
unit: {
type: 'string',
enum: ['celsius', 'fahrenheit']
}
},
required: ['location']
}
};
// Make request with tools
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What\'s the weather in Tokyo?',
config: {
tools: [
{ functionDeclarations: [getCurrentWeather] }
]
}
});
// Check if model wants to call a function
const functionCall = response.candidates[0].content.parts[0].functionCall;
if (functionCall) {
console.log('Function to call:', functionCall.name);
console.log('Arguments:', functionCall.args);
// Execute the function (your implementation)
const weatherData = await fetchWeather(functionCall.args.location);
// Send function result back to model
const finalResponse = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: [
'What\'s the weather in Tokyo?',
response.candidates[0].content, // Original assistant response with function call
{
parts: [
{
functionResponse: {
name: functionCall.name,
response: weatherData
}
}
]
}
],
config: {
tools: [
{ functionDeclarations: [getCurrentWeather] }
]
}
});
console.log(finalResponse.text);
}
関数呼び出し(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{ parts: [{ text: 'What\'s the weather in Tokyo?' }] }
],
tools: [
{
functionDeclarations: [
{
name: 'get_current_weather',
description: 'Get the current weather for a location',
parameters: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name'
}
},
required: ['location']
}
}
]
}
]
}),
}
);
const data = await response.json();
const functionCall = data.candidates[0]?.content?.parts[0]?.functionCall;
if (functionCall) {
// Execute function and send result back (same flow as SDK)
}
並列関数呼び出し
Gemini は、独立した複数の関数を同時に呼び出すことができます。
const tools = [
{
functionDeclarations: [
{
name: 'get_weather',
description: 'Get weather for a location',
parametersJsonSchema: {
type: 'object',
properties: {
location: { type: 'string' }
},
required: ['location']
}
},
{
name: 'get_population',
description: 'Get population of a city',
parametersJsonSchema: {
type: 'object',
properties: {
city: { type: 'string' }
},
required: ['city']
}
}
]
}
];
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What is the weather and population of Tokyo?',
config: { tools }
});
// Model may return MULTIPLE function calls in parallel
const functionCalls = response.candidates[0].content.parts.filter(
part => part.functionCall
);
console.log(`Model wants to call ${functionCalls.length} functions in parallel`);
関数呼び出しモード
import { FunctionCallingConfigMode } from '@google/genai';
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What\'s the weather?',
config: {
tools: [{ functionDeclarations: [getCurrentWeather] }],
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY, // Force function call
// mode: FunctionCallingConfigMode.AUTO, // Model decides (default)
// mode: FunctionCallingConfigMode.NONE, // Never call functions
allowedFunctionNames: ['get_current_weather'] // Optional: restrict to specific functions
}
}
}
});
モード:
AUTO(デフォルト):関数を呼び出すかどうかをモデルが判断しますANY:モデルが少なくとも 1 つの関数を呼び出すよう強制しますNONE:このリクエストでは関数呼び出しを無効にします
システム指示
システム指示はモデルの動作を導き、コンテキストを設定します。会話メッセージとは別個のものです。
SDK を使用する方法
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
systemInstruction: 'You are a helpful AI assistant that always responds in the style of a pirate. Use nautical terminology and end sentences with "arrr".',
contents: 'Explain what a database is'
});
console.log(response.text);
// Output: "Ahoy there! A database be like a treasure chest..."
Fetch を使用する方法
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
systemInstruction: {
parts: [
{ text: 'You are a helpful AI assistant that always responds in the style of a pirate.' }
]
},
contents: [
{ parts: [{ text: 'Explain what a database is' }] }
]
}),
}
);
主なポイント:
- システム指示は
contents配列の一部ではありません - リクエストのトップレベルで一度設定します
- (複数ターンのチャットを使用する場合)会話全体を通じて維持されます
- ユーザーまたはモデルのメッセージとしてカウントされません
複数ターンのチャット
履歴を含む会話では、SDK のチャットヘルパーを使用するか、会話状態を手動で管理してください。
SDK チャットヘルパー(推奨)
const chat = await ai.models.createChat({
model: 'gemini-2.5-flash',
systemInstruction: 'You are a helpful coding assistant.',
history: [] // Start empty or with previous messages
});
// Send first message
const response1 = await chat.sendMessage('What is TypeScript?');
console.log('Assistant:', response1.text);
// Send follow-up (context is automatically maintained)
const response2 = await chat.sendMessage('How do I install it?');
console.log('Assistant:', response2.text);
// Get full chat history
const history = chat.getHistory();
console.log('Full conversation:', history);
チャットの手動管理(Fetch)
const conversationHistory = [];
// First turn
const response1 = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{
role: 'user',
parts: [{ text: 'What is TypeScript?' }]
}
]
}),
}
);
const data1 = await response1.json();
const assistantReply1 = data1.candidates[0].content.parts[0].text;
// Add to history
conversationHistory.push(
{ role: 'user', parts: [{ text: 'What is TypeScript?' }] },
{ role: 'model', parts: [{ text: assistantReply1 }] }
);
// Second turn (include full history)
const response2 = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
...conversationHistory,
{ role: 'user', parts: [{ text: 'How do I install it?' }] }
]
}),
}
);
メッセージのロール:
user:ユーザーメッセージmodel:アシスタントの応答
⚠️ 重要:チャットヘルパーはSDK 専用です。fetch では、会話履歴を手動で管理する必要があります。
思考モード
Gemini 2.5 モデルでは、品質向上のため思考モードがデフォルトで有効になっています。思考バジェットを設定できます。
思考バジェットの設定(SDK)
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Solve this complex math problem: ...',
config: {
thinkingConfig: {
thinkingBudget: 8192 // Max tokens for thinking (default: model-dependent)
}
}
});
思考バジェットの設定(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [{ parts: [{ text: 'Solve this complex math problem: ...' }] }],
generationConfig: {
thinkingConfig: {
thinkingBudget: 8192
}
}
}),
}
);
思考レベルの設定(SDK)- v1.30.0 で新登場
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Solve this complex problem: ...',
config: {
thinkingConfig: {
thinkingLevel: 'MEDIUM' // 'LOW' | 'MEDIUM' | 'HIGH'
}
}
});
思考レベル:
LOW:最小限の内部推論(高速、品質は低め)MEDIUM:バランスの取れた推論(デフォルト)HIGH:最大限の推論の深さ(低速、品質は高め)
主なポイント:
- Gemini 2.5 モデルでは思考モードが常に有効です(無効にはできません)
- 思考バジェットを大きくすると、より多くの内部推論が可能になります(レイテンシが増加する場合があります)
thinkingLevelはthinkingBudgetより簡単に制御できます(v1.30.0 で新登場)- デフォルトのバジェットはモデルによって異なります(通常、ほとんどのタスクには十分です)
- 非常に複雑な推論タスクでのみ、バジェット/レベルを引き上げてください
生成設定
生成パラメーターを使用して、モデルの動作をカスタマイズできます。
すべての設定オプション(SDK)
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Write a creative story',
config: {
temperature: 0.9, // Randomness (0.0-2.0, default: 1.0)
topP: 0.95, // Nucleus sampling (0.0-1.0)
topK: 40, // Top-k sampling
maxOutputTokens: 2048, // Max tokens to generate
stopSequences: ['END'], // Stop generation if these appear
responseMimeType: 'text/plain', // Or 'application/json' for JSON mode
candidateCount: 1 // Number of response candidates (usually 1)
}
});
すべての設定オプション(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [{ parts: [{ text: 'Write a creative story' }] }],
generationConfig: {
temperature: 0.9,
topP: 0.95,
topK: 40,
maxOutputTokens: 2048,
stopSequences: ['END'],
responseMimeType: 'text/plain',
candidateCount: 1
}
}),
}
);
パラメーターのガイドライン
| パラメーター | 範囲 | デフォルト | 用途 |
|---|---|---|---|
| temperature | 0.0-2.0 | 1.0 | 低いほど焦点が絞られ、高いほど創造的になります |
| topP | 0.0-1.0 | 0.95 | 核サンプリングのしきい値 |
| topK | 1-100+ | 40 | 上位 K 個のトークンに制限します |
| maxOutputTokens | 1-65536 | モデルの最大値 | 応答の長さを制御します |
| stopSequences | 配列 | なし | 特定の文字列で生成を停止します |
ヒント:
- 事実に基づくタスクでは、temperature を低くします(0.0-0.3)
- 創造的なタスクでは、temperature を高くします(0.7-1.5)
- topP と topK はどちらもランダム性を制御します。どちらか一方を使用し、両方は使用しないでください
- 過剰な生成を防ぐため、maxOutputTokens は常に設定してください
コンテキストキャッシュ
コンテキストキャッシュを使用すると、頻繁に使用するコンテンツ(システム指示、大きなドキュメント、動画ファイルなど)をキャッシュして、コストを**最大90%**削減し、レイテンシを改善できます。
仕組み
- 繰り返し使用するコンテンツでキャッシュを作成します
- 以降のリクエストでキャッシュを参照します
- トークンを節約します。キャッシュされたトークンのコストは大幅に低くなります
- TTL を管理します。キャッシュは指定した時間が経過すると期限切れになります
メリット
- コスト削減:キャッシュされたトークンのコストを最大90%削減
- レイテンシの低減:処理済みのコンテンツを再利用して応答を高速化
- 一貫したコンテキスト:複数のリクエストで同じ大きなコンテキストを使用
キャッシュの作成(SDK)
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Create a cache for a large document
const documentText = fs.readFileSync('./large-document.txt', 'utf-8');
const cache = await ai.caches.create({
model: 'gemini-2.5-flash',
config: {
displayName: 'large-doc-cache', // Identifier for the cache
systemInstruction: 'You are an expert at analyzing legal documents.',
contents: documentText,
ttl: '3600s', // Cache for 1 hour
}
});
console.log('Cache created:', cache.name);
console.log('Expires at:', cache.expireTime);
キャッシュの作成(Fetch)
const response = await fetch(
'https://generativelanguage.googleapis.com/v1beta/cachedContents',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
model: 'models/gemini-2.5-flash',
displayName: 'large-doc-cache',
systemInstruction: {
parts: [{ text: 'You are an expert at analyzing legal documents.' }]
},
contents: [
{ parts: [{ text: documentText }] }
],
ttl: '3600s'
}),
}
);
const cache = await response.json();
console.log('Cache created:', cache.name);
キャッシュの使用(SDK)
// Generate content using the cache
const response = await ai.models.generateContent({
model: cache.name, // Use cache name as model
contents: 'Summarize the key points in the document'
});
console.log(response.text);
キャッシュの使用(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/${cache.name}:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{ parts: [{ text: 'Summarize the key points in the document' }] }
]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
キャッシュ TTL の更新(SDK)
import { UpdateCachedContentConfig } from '@google/genai';
await ai.caches.update({
name: cache.name,
config: {
ttl: '7200s' // Extend to 2 hours
}
});
有効期限を指定したキャッシュの更新(SDK)
// Set specific expiration time (must be timezone-aware)
const in10Minutes = new Date(Date.now() + 10 * 60 * 1000);
await ai.caches.update({
name: cache.name,
config: {
expireTime: in10Minutes
}
});
キャッシュの一覧表示と削除(SDK)
// List all caches
const caches = await ai.caches.list();
for (const cache of caches) {
console.log(cache.name, cache.displayName);
}
// Delete a specific cache
await ai.caches.delete({ name: cache.name });
動画ファイルのキャッシュ
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Upload video file
const videoFile = await ai.files.upload({
file: fs.createReadStream('./video.mp4')
});
// Wait for processing
while (videoFile.state.name === 'PROCESSING') {
await new Promise(resolve => setTimeout(resolve, 2000));
videoFile = await ai.files.get({ name: videoFile.name });
}
// Create cache with video
const cache = await ai.caches.create({
model: 'gemini-2.5-flash',
config: {
displayName: 'video-analysis-cache',
systemInstruction: 'You are an expert video analyzer.',
contents: [videoFile],
ttl: '300s' // 5 minutes
}
});
// Use cache for multiple queries
const response1 = await ai.models.generateContent({
model: cache.name,
contents: 'What happens in the first minute?'
});
const response2 = await ai.models.generateContent({
model: cache.name,
contents: 'Describe the main characters'
});
主なポイント
キャッシュを使用する場面:
- 繰り返し使用する大きなシステム指示
- 複数回分析する長いドキュメント
- 異なるプロンプトで問い合わせる動画/音声ファイル
- 会話セッション間で一貫したコンテキストを維持する場合
TTL の目安:
- 短いセッション:300s(5 min)~3600s(1 hour)
- 長いセッション:3600s(1 hour)~86400s(24 hours)
- 最大:7 days
コスト削減:
- キャッシュされた入力トークン:通常のトークンより約90%低コスト
- 出力トークン:通常と同じ料金(キャッシュされません)
重要:
- 明示的なモデルバージョンのサフィックスを使用する必要があります(例:
gemini-2.5-flash-001。gemini-2.5-flashのみではありません) - キャッシュは TTL の期限が切れると自動的に削除されます
- キャッシュの有効期間を延長するには、期限切れ前に TTL を更新してください
コード実行
Gemini モデルは、計算、データ分析、可視化を必要とする問題を解決するために、Python コードを生成して実行できます。
仕組み
- モデルが実行可能な Python コードを生成します
- コードが安全なサンドボックスで実行されます
- 結果がモデルに返されます
- モデルが結果を応答に反映します
対応する操作
- 数学的な計算
- データ分析と統計
- ファイル処理(CSV、JSON など)
- チャートやグラフの生成
- アルゴリズムの実装
- データ変換
利用可能な Python パッケージ
標準ライブラリ:
math、statistics、random、datetime、json、csv、recollections、itertools、functools
データサイエンス:
numpy、pandas、scipy
可視化:
matplotlib、seaborn
注:通常の Python 環境と比べて、利用可能なパッケージは限られています
基本的なコード実行(SDK)
import { GoogleGenAI, Tool, ToolCodeExecution } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What is the sum of the first 50 prime numbers? Generate and run code for the calculation.',
config: {
tools: [{ codeExecution: {} }]
}
});
// Parse response parts
for (const part of response.candidates[0].content.parts) {
if (part.text) {
console.log('Text:', part.text);
}
if (part.executableCode) {
console.log('Generated Code:', part.executableCode.code);
}
if (part.codeExecutionResult) {
console.log('Execution Output:', part.codeExecutionResult.output);
}
}
基本的なコード実行(Fetch)
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
tools: [{ code_execution: {} }],
contents: [
{
parts: [
{ text: 'What is the sum of the first 50 prime numbers? Generate and run code.' }
]
}
]
}),
}
);
const data = await response.json();
for (const part of data.candidates[0].content.parts) {
if (part.text) {
console.log('Text:', part.text);
}
if (part.executableCode) {
console.log('Code:', part.executableCode.code);
}
if (part.codeExecutionResult) {
console.log('Result:', part.codeExecutionResult.output);
}
}
コード実行を使ったチャット(SDK)
const chat = await ai.chats.create({
model: 'gemini-2.5-flash',
config: {
tools: [{ codeExecution: {} }]
}
});
let response = await chat.sendMessage('I have a math question for you.');
console.log(response.text);
response = await chat.sendMessage(
'Calculate the Fibonacci sequence up to the 20th number and sum them.'
);
// Model will generate and execute code, then provide answer
for (const part of response.candidates[0].content.parts) {
if (part.text) console.log(part.text);
if (part.executableCode) console.log('Code:', part.executableCode.code);
if (part.codeExecutionResult) console.log('Output:', part.codeExecutionResult.output);
}
データ分析の例
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: `
Analyze this sales data and calculate:
1. Total revenue
2. Average sale price
3. Best-selling month
Data (CSV format):
month,sales,revenue
Jan,150,45000
Feb,200,62000
Mar,175,53000
Apr,220,68000
`,
config: {
tools: [{ codeExecution: {} }]
}
});
// Model will generate pandas/numpy code to analyze data
for (const part of response.candidates[0].content.parts) {
if (part.text) console.log(part.text);
if (part.executableCode) console.log('Analysis Code:', part.executableCode.code);
if (part.codeExecutionResult) console.log('Results:', part.codeExecutionResult.output);
}
可視化の例
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Create a bar chart showing the distribution of prime numbers under 100 by their last digit. Generate the chart and describe the pattern.',
config: {
tools: [{ codeExecution: {} }]
}
});
// Model generates matplotlib code, executes it, and describes results
for (const part of response.candidates[0].content.parts) {
if (part.text) console.log(part.text);
if (part.executableCode) console.log('Chart Code:', part.executableCode.code);
if (part.codeExecutionResult) {
// Note: Chart image data would be in output
console.log('Execution completed');
}
}
応答の構造
{
candidates: [
{
content: {
parts: [
{ text: "I'll calculate that for you." },
{
executableCode: {
language: "PYTHON",
code: "def is_prime(n):\n if n <= 1:\n return False\n ..."
}
},
{
codeExecutionResult: {
outcome: "OUTCOME_OK", // or "OUTCOME_FAILED"
output: "5117\n"
}
},
{ text: "The sum of the first 50 prime numbers is 5117." }
]
}
}
]
}
エラー処理
for (const part of response.candidates[0].content.parts) {
if (part.codeExecutionResult) {
if (part.codeExecutionResult.outcome === 'OUTCOME_FAILED') {
console.error('Code execution failed:', part.codeExecutionResult.output);
} else {
console.log('Success:', part.codeExecutionResult.output);
}
}
}
主なポイント
コード実行を使用する場面:
- 複雑な数学的計算
- データ分析と統計
- アルゴリズムの実装
- ファイルの解析と処理
- チャートの生成
- 計算を必要とする問題
制限事項:
- サンドボックス環境(ファイルシステムへのアクセスは限定的です)
- 利用可能な Python パッケージは限られています
- 実行時間に制限があります
- コードからネットワークにアクセスできません
- 実行間で状態は保持されません
ベストプラクティス:
- 必要な計算や分析を明確に指定してください
- コード生成を明示的にリクエストしてください(「コードを生成して実行してください……」)
- エラーがないか
outcomeフィールドを確認してください - 一般的なプログラミングではなく、決定論的な計算に使用してください
重要:
- すべての Gemini 2.5 モデル(Pro、Flash、Flash-Lite)で利用できます
- セキュリティのため、コードは分離されたサンドボックスで実行されます
- 標準ライブラリと一般的なデータサイエンスパッケージを含む Python に対応しています
Google 検索によるグラウンディング
グラウンディングを使用すると、モデルをリアルタイムのウェブ情報に接続でき、ハルシネーションを減らし、引用付きの最新かつ事実確認済みの応答を提供できます。
仕組み
- モデルが最新情報が必要かどうかを判断します
- Google 検索を自動的に実行します
- 検索結果を処理します
- 調査結果を回答に反映します
- 引用とソース URL を提示します
メリット
- リアルタイム情報:最新のニュースやデータにアクセスできます
- ハルシネーションの低減:ウェブソースに基づいた回答が得られます
- 検証可能:引用によりファクトチェックが可能です
- 最新情報への対応:モデルの学習データのカットオフに制限されません
グラウンディングのオプション
1. Google 検索(googleSearch) - Gemini 2.5 に推奨
const groundingTool = {
googleSearch: {}
};
機能:
- シンプルな設定
- 必要に応じて検索を自動実行
- すべての Gemini 2.5 モデルで利用可能
2. FileSearch - v1.29.0 で追加(プレビュー)
const fileSearchTool = {
fileSearch: {
fileSearchStoreId: 'store-id-here' // Created via FileSearchStore APIs
}
};
機能:
- 独自のドキュメントコレクションを検索
- カスタムナレッジベースをアップロードしてインデックス化
- 独自データ向けのウェブ検索の代替手段
- プレビュー機能(FileSearchStore のセットアップが必要)
注:ストアの作成と管理については、FileSearch のドキュメントを参照してください。
3. Google 検索 Retrieval(googleSearchRetrieval) - レガシー(Gemini 1.5)
const retrievalTool = {
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: 'MODE_DYNAMIC',
dynamicThreshold: 0.7 // Only search if confidence < 70%
}
}
};
機能:
- 動的な閾値制御
- Gemini 1.5 モデルで使用
- より多くの設定オプション
基本的なグラウンディング(SDK) - Gemini 2.5
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Who won the euro 2024?',
config: {
tools: [{ googleSearch: {} }]
}
});
console.log(response.text);
// Check if grounding was used
if (response.candidates[0].groundingMetadata) {
console.log('Search was performed!');
console.log('Sources:', response.candidates[0].groundingMetadata);
}
基本的なグラウンディング(Fetch) - Gemini 2.5
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-goog-api-key': env.GEMINI_API_KEY,
},
body: JSON.stringify({
contents: [
{ parts: [{ text: 'Who won the euro 2024?' }] }
],
tools: [
{ google_search: {} }
]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
if (data.candidates[0].groundingMetadata) {
console.log('Grounding metadata:', data.candidates[0].groundingMetadata);
}
動的な取得(SDK) - Gemini 1.5
import { GoogleGenAI, DynamicRetrievalConfigMode } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Who won the euro 2024?',
config: {
tools: [
{
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: DynamicRetrievalConfigMode.MODE_DYNAMIC,
dynamicThreshold: 0.7 // Search only if confidence < 70%
}
}
}
]
}
});
console.log(response.text);
if (!response.candidates[0].groundingMetadata) {
console.log('Model answered from its own knowledge (high confidence)');
}
グラウンディングメタデータの構造
{
groundingMetadata: {
searchQueries: [
{ text: "euro 2024 winner" }
],
webPages: [
{
url: "https://example.com/euro-2024-results",
title: "UEFA Euro 2024 Final Results",
snippet: "Spain won UEFA Euro 2024..."
}
],
citations: [
{
startIndex: 42,
endIndex: 47,
uri: "https://example.com/euro-2024-results"
}
],
retrievalQueries: [
{
query: "who won euro 2024 final"
}
]
}
}
グラウンディングを使ったチャット(SDK)
const chat = await ai.chats.create({
model: 'gemini-2.5-flash',
config: {
tools: [{ googleSearch: {} }]
}
});
let response = await chat.sendMessage('What are the latest developments in quantum computing?');
console.log(response.text);
// Check grounding sources
if (response.candidates[0].groundingMetadata) {
const sources = response.candidates[0].groundingMetadata.webPages || [];
console.log(`Sources used: ${sources.length}`);
sources.forEach(source => {
console.log(`- ${source.title}: ${source.url}`);
});
}
// Follow-up still has grounding enabled
response = await chat.sendMessage('Which company made the biggest breakthrough?');
console.log(response.text);
グラウンディングと関数呼び出しの組み合わせ
const weatherFunction = {
name: 'get_current_weather',
description: 'Get current weather for a location',
parametersJsonSchema: {
type: 'object',
properties: {
location: { type: 'string', description: 'City name' }
},
required: ['location']
}
};
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What is the weather like in the city that won Euro 2024?',
config: {
tools: [
{ googleSearch: {} },
{ functionDeclarations: [weatherFunction] }
]
}
});
// Model will:
// 1. Use Google Search to find Euro 2024 winner
// 2. Call get_current_weather function with the city
// 3. Combine both results in response
グラウンディングが使用されたかどうかの確認
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What is 2+2?', // Model knows this without search
config: {
tools: [{ googleSearch: {} }]
}
});
if (!response.candidates[0].groundingMetadata) {
console.log('Model answered from its own knowledge (no search needed)');
} else {
console.log('Search was performed');
}
重要なポイント
グラウンディングを使用する場面:
- 最新のニュースや時事問題
- リアルタイムデータ(株価、スポーツのスコア、天気)
- ファクトチェックと検証
- 最近の動向に関する質問
- モデルの学習データのカットオフ以降の情報
使用しない場面:
- 一般知識に関する質問
- 数学的な計算
- コード生成
- クリエイティブライティング
- 内部推論のみで対応できるタスク
コストに関する考慮事項:
- グラウンディングを使うとレイテンシーが増加します(検索に時間がかかります)
- 取得したコンテンツに対する追加のトークンコストが発生します
- 検索を実行するタイミングは、
dynamicThresholdで制御できます(Gemini 1.5)
重要な注意事項:
- グラウンディングには Google Cloud プロジェクト が必要です(API キーだけでは利用できません)
- 検索結果の品質は、クエリの表現に左右されます
- 引用ですべての回答内容が網羅されるとは限りません
- 信頼度に基づいて検索が自動的に実行されます
Gemini 2.5 と 1.5 の違い:
- Gemini 2.5:
googleSearchを使用します(シンプルで推奨) - Gemini 1.5:
dynamicThresholdと併せてgoogleSearchRetrievalを使用します
ベストプラクティス:
- 検索が使用されたかどうかを確認するため、必ず
groundingMetadataを確認します - 透明性を確保するため、引用をユーザーに表示します
- より良い検索結果を得るため、具体的で明確な質問をします
- ハイブリッドなワークフローでは、関数呼び出しと組み合わせます
既知の問題の防止
このスキルは、文書化されている 14 件の問題を防止します。
問題 #1:ストリーミング中のマルチバイト文字の破損
エラー:英語以外のテキストを含む応答をストリーミングすると、文字化けしたテキストや � 記号が表示されます
出典:GitHub Issue #764
発生する理由:TextDecoder が {stream: true} オプションなしでチャンクを文字列に変換します。マルチバイトの UTF-8 文字(中国語、日本語、韓国語、絵文字)がチャンク間で分割されると、無効な文字列が生成されます。
防止策:
// The SDK already fixes this, but if implementing custom streaming:
const decoder = new TextDecoder();
const { value } = await reader.read();
const text = decoder.decode(value, { stream: true }); // ← stream: true required
影響を受ける対象:マルチバイト文字を使用するすべての英語以外の言語 状況:SDK では修正済みですが、カスタム実装向けに記載しています
Issue #2:Safety Settings のメソッドパラメーターがサポートされていない
エラー:「Gemini API では method パラメーターはサポートされていません」
ソース:GitHub Issue #810
発生する理由:safetySettings の method パラメーターは Vertex AI Gemini API でのみ機能し、Gemini Developer API や Google AI Studio では機能しません。SDK は検証せずにこのパラメーターを渡せるようになっています。
予防策:
// ❌ WRONG - Fails with Gemini Developer API:
config: {
safetySettings: [{
category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
method: HarmBlockMethod.SEVERITY // Not supported!
}]
}
// ✅ CORRECT - Omit 'method' for Gemini Developer API:
config: {
safetySettings: [{
category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE
// No 'method' field
}]
}
影響を受ける対象:Gemini Developer API と Google AI Studio のユーザー
ステータス:既知の制限です。method パラメーターが必要な場合は Vertex AI を使用してください。
Issue #3:Safety Settings のしきい値はモデルごとに異なる
エラー:厳格な Safety Settings を設定しているにもかかわらずコンテンツが通過する、または safetyRatings に NEGLIGIBLE と表示され、出力が空になる
ソース:GitHub Issue #872
発生する理由:モデルによってブロックのしきい値が異なります。gemini-2.5-flash は gemini-2.0-flash より厳格にブロックします。また、promptFeedback が表示されるのは入力がブロックされた場合のみです。モデルが拒否メッセージを生成した場合、safetyRatings に NEGLIGIBLE と表示されることがあります。
予防策:
// Check BOTH promptFeedback AND empty response:
if (response.candidates[0].finishReason === 'SAFETY' ||
!response.text || response.text.trim() === '') {
console.log('Content blocked or refused');
}
// Be aware: Different models have different thresholds
// gemini-2.5-flash: Lower threshold (stricter blocking)
// gemini-2.0-flash: Higher threshold (more permissive)
影響を受ける対象:Safety Settings を使用するすべてのモデル ステータス:既知の動作です。モデルごとのしきい値の違いは仕様です。
Issue #4:FunctionCallingConfigMode.ANY によって無限ループが発生する
エラー:モデルがツールを呼び出し続け、テキスト応答を返さない
ソース:GitHub Issue #908
発生する理由:FunctionCallingConfigMode.ANY を自動関数呼び出し(CallableTool)と組み合わせると、モデルは各ターンで少なくとも 1 つのツールを呼び出すよう強制され、実際には停止できません。そのため、呼び出し回数の上限に達するまでループします。
予防策:
// ❌ WRONG - Loops forever:
config: {
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY // Forces tool calls forever
}
}
}
// ✅ CORRECT - Use AUTO mode (model decides):
config: {
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.AUTO // Model can choose to answer directly
}
}
}
// Or use manual function calling (check for functionCall, execute, send back)
影響を受ける対象:CallableTool による自動関数呼び出し
ステータス:既知の制限です。AUTO モードまたは手動の関数呼び出しを使用してください。
Issue #5:構造化出力でエスケープされたバックスラッシュが保持されない(Gemini 3)
エラー:構造化出力に対する JSON.parse が失敗する、またはバックスラッシュを含むキーが正しくない
ソース:GitHub Issue #1226
発生する理由:エスケープされたバックスラッシュを含むスキーマキー(例:キー \a に対する \\a)を使用して responseMimeType: "application/json" を指定すると、モデルの出力で JSON のエスケープが保持されません。単一のバックスラッシュが出力され、無効な JSON になります。
予防策:
// Avoid using backslashes in JSON schema keys
// Or manually post-process if required:
let jsonText = response.text;
// Add custom escaping logic if needed
影響を受ける対象:キーにバックスラッシュを含む構造化出力を使用する Gemini 3 モデル ステータス:既知の問題です。回避策が必要です。
Issue #6:S3 の署名付き URL から取得した大きな PDF で「Document has no pages」エラーが発生する
エラー:ApiError: {"error":{"code":400,"message":"The document has no pages.","status":"INVALID_ARGUMENT"}}
ソース:GitHub Issue #1259
発生する理由:AWS S3 の署名付き URL から取得した大きな PDF(例:20MB)は、fileData.fileUri 経由で渡すと失敗します。API は署名付き URL から PDF を取得または処理できません。
予防策:
// ❌ WRONG - Fails with large PDFs from S3:
contents: [{
parts: [{
fileData: {
fileUri: 'https://bucket.s3.region.amazonaws.com/file.pdf?X-Amz-Algorithm=...'
}
}]
}]
// ✅ CORRECT - Fetch and encode to base64:
const pdfResponse = await fetch(signedUrl);
const pdfBuffer = await pdfResponse.arrayBuffer();
const base64Pdf = Buffer.from(pdfBuffer).toString('base64');
contents: [{
parts: [{
inlineData: {
data: base64Pdf,
mimeType: 'application/pdf'
}
}]
}]
影響を受ける対象:外部の署名付き URL にある PDF ファイル ステータス:既知の制限です。代わりにインラインの base64 データを使用してください。
Issue #7:Gemini 3 モデルでアップロードした動画を使用すると 404 NOT_FOUND が発生する
エラー:Gemini 3 モデルでアップロードした動画ファイルを使用すると 404 NOT_FOUND が発生する
ソース:GitHub Issue #1220
発生する理由:一部の Gemini 3 モデル(gemini-3-flash-preview、gemini-3-pro-preview)は無料枠では利用できないか、有料アカウントでもアクセスが制限されています。動画ファイルのアップロードは 404 で失敗します。
予防策:
// ❌ WRONG - 404 error with Gemini 3:
const response = await ai.models.generateContent({
model: 'gemini-3-pro-preview', // 404 error
contents: [{
parts: [
{ text: 'Describe this video' },
{ fileData: { fileUri: videoFile.uri }}
]
}]
});
// ✅ CORRECT - Use Gemini 2.5 for video understanding:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash', // Works
contents: [{
parts: [
{ text: 'Describe this video' },
{ fileData: { fileUri: videoFile.uri }}
]
}]
});
影響を受ける対象:動画をアップロードする Gemini 3 プレビューモデル ステータス:既知の制限です。動画には Gemini 2.5 モデルを使用してください。
Issue #8:クォータ内にもかかわらず Batch API が 429 を返す
エラー:文書化されたクォータ内でも、Batch API の使用時に 429 RESOURCE_EXHAUSTED が発生します ソース:GitHub Issue #1264 発生する理由:Batch API には、サーバー負荷に応じた動的なレート制限や、静的なクォータ以外の文書化されていない制限が設定されている場合があります。
予防策:
// Implement exponential backoff for Batch API:
async function batchWithRetry(request, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await ai.batches.create(request);
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
影響を受ける対象:有料プランの Batch API ユーザー ステータス:調査中です。再試行ロジックを使用してください
Issue #9:コンテキストキャッシュが Gemini 1.5 モデルでしか機能しない
エラー:Gemini 2.0、2.5、または 3.0 モデルでキャッシュを作成すると 404 NOT FOUND が発生します ソース:GitHub Issue #339 発生する理由:コンテキストキャッシュは Gemini 1.5 Pro と Gemini 1.5 Flash モデルのみをサポートしています。ドキュメントの例では、誤って Gemini 2.0 以降のモデルが示されています。
予防策:
// ❌ WRONG - 404 error:
const cache = await ai.caches.create({
model: 'gemini-2.5-flash', // Not supported
config: { /* ... */ }
});
// ✅ CORRECT - Use Gemini 1.5 with explicit version:
const cache = await ai.caches.create({
model: 'gemini-1.5-flash-001', // Explicit version required
config: { /* ... */ }
});
影響を受ける対象:コンテキストキャッシュを使用しようとしているすべての Gemini 2.x および 3.x ユーザー ステータス:既知の制限です。キャッシュをサポートするのは Gemini 1.5 モデルのみです
Issue #10:構造化出力でバッククォートが返され、JSON.parse エラーが発生することがある
エラー:JSON 応答の解析時に SyntaxError: Unexpected token '' が発生します **ソース**:[GitHub Issue #976](https://github.com/googleapis/js-genai/issues/976) **発生する理由**:responseMimeType: "application/json" を使用すると、応答に JSON を囲む Markdown コードフェンスのバッククォート(`` ```json\n{...}\n``` ``)が含まれることがあり、JSON.parse()` が失敗します。
予防策:
// Strip markdown code fences before parsing:
let jsonText = response.text.trim();
if (jsonText.startsWith('```json')) {
jsonText = jsonText.replace(/^```json\n/, '').replace(/\n```$/, '');
} else if (jsonText.startsWith('```')) {
jsonText = jsonText.replace(/^```\n/, '').replace(/\n```$/, '');
}
const data = JSON.parse(jsonText);
影響を受ける対象:responseMimeType: "application/json" を使用して構造化出力を行うすべてのモデル
ステータス:既知の断続的な問題です。回避策が必要です
Issue #11:Gemini 3 で温度を 1.0 未満にすると、ループや推論品質の低下が発生する
エラー:複雑なタスクで無限ループが発生する、または推論品質が低下します ソース:公式トラブルシューティングドキュメント 発生する理由:Gemini 3 モデルは温度 1.0 に最適化されています。温度を 1.0 未満に下げると、複雑な数学や推論タスクでループが発生したり、パフォーマンスが低下したりする場合があります。
予防策:
// ❌ WRONG - May cause issues with Gemini 3:
const response = await ai.models.generateContent({
model: 'gemini-3-flash',
contents: 'Solve this complex math problem: ...',
config: {
temperature: 0.3 // May cause looping/degradation
}
});
// ✅ CORRECT - Keep default temperature:
const response = await ai.models.generateContent({
model: 'gemini-3-flash',
contents: 'Solve this complex math problem: ...',
config: {
temperature: 1.0 // Recommended for Gemini 3
}
});
// Or omit temperature config entirely (uses default 1.0)
影響を受ける対象:Gemini 3 シリーズのモデル ステータス:公式の推奨事項です。温度は 1.0 に保ってください
Issue #12:2025 年 12 月に大幅なレート制限の引き下げが発生(無料プラン)
エラー:2025 年 12 月 6 日以降、突然 429 RESOURCE_EXHAUSTED エラーが発生します ソース:LaoZhang AI Blog | HowToGeek 発生する理由:Google は広く告知することなく無料プランのレート制限を 80~90%引き下げたため、開発者が不意を突かれました。
変更内容:
- Gemini 2.5 Pro:1 日あたりのリクエスト数を 80%削減(100 RPD、以前は約 250)
- Gemini 2.5 Flash:1 日あたり約 20 リクエスト(以前は約 250)— 90%削減
- 無料プランは本番環境での利用に適さなくなりました
予防策:
// For production, upgrade to paid tier:
// https://ai.google.dev/pricing
// For free tier, implement aggressive rate limiting:
const rateLimiter = {
requests: 0,
resetTime: Date.now() + 24 * 60 * 60 * 1000,
async checkLimit() {
if (Date.now() > this.resetTime) {
this.requests = 0;
this.resetTime = Date.now() + 24 * 60 * 60 * 1000;
}
if (this.requests >= 20) {
throw new Error('Daily limit reached');
}
this.requests++;
}
};
await rateLimiter.checkLimit();
const response = await ai.models.generateContent({/* ... */});
影響を受ける対象:無料プランのユーザー(2025 年 12 月 6 日以降) ステータス:恒久的な変更です。本番環境では有料プランにアップグレードしてください
Issue #13:プレビューモデルには SLA がなく、予告なく変更される可能性がある
エラー:予期しない動作の変更、非推奨化、またはサービスの中断が発生します
ソース:Arsturn Blog | 公式ドキュメント
発生する理由:プレビューおよび実験的なモデル(例:gemini-2.5-flash-preview、gemini-3-pro-preview)にはサービスレベル契約(SLA)がなく、本質的に不安定です。Google はほとんど予告せずに、これらのモデルを変更または非推奨化する場合があります。
予防策:
// ❌ WRONG - Using preview models in production:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash-preview', // No SLA!
contents: 'Production traffic'
});
// ✅ CORRECT - Use GA (generally available) models:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash', // Stable, with SLA
contents: 'Production traffic'
});
// Or use specific version numbers for stability:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash-001', // Pinned version
contents: 'Production traffic'
});
影響を受ける対象:プレビュー/実験的なモデルを本番環境で使用するユーザー ステータス:既知の制限です。本番環境では GA モデルを使用してください
Issue #14:API キー漏えい時の自動ブロック(セキュリティ強化)
エラー:「Invalid API key」(キーを誤って GitHub にコミットした後に発生) ソース:AI Free API Blog | 公式トラブルシューティング 発生する理由:Google は、公開されている API キー(例:GitHub リポジトリ内のキー)を事前にスキャンし、セキュリティ対策として Gemini API へのアクセスを自動的にブロックします。
予防策:
// Best practices:
// 1. Use .env files (never commit)
// 2. Use environment variables in production
// 3. Rotate keys if exposed
// 4. Use .gitignore:
// .gitignore
.env
.env.local
*.key
影響を受けるユーザー:公開リポジトリに API キーを誤ってコミットしたユーザー ステータス:セキュリティ機能です。キーが漏えいした場合はローテーションしてください。
エラー処理
よくあるエラー
1. 無効な API キー(401)
{
error: {
code: 401,
message: 'API key not valid. Please pass a valid API key.',
status: 'UNAUTHENTICATED'
}
}
解決策:GEMINI_API_KEY 環境変数が正しく設定されていることを確認してください。
2. レート制限超過(429)
{
error: {
code: 429,
message: 'Resource has been exhausted (e.g. check quota).',
status: 'RESOURCE_EXHAUSTED'
}
}
解決策:指数バックオフによる再試行戦略を実装してください。
3. モデルが見つからない(404)
{
error: {
code: 404,
message: 'models/gemini-3.0-flash is not found',
status: 'NOT_FOUND'
}
}
解決策:正しいモデル名を使用してください:gemini-2.5-pro、gemini-2.5-flash、gemini-2.5-flash-lite
4. コンテキスト長超過(400)
{
error: {
code: 400,
message: 'Request payload size exceeds the limit',
status: 'INVALID_ARGUMENT'
}
}
解決策:入力サイズを小さくしてください。Gemini 2.5 モデルがサポートする入力トークンの上限は 1,048,576 です。
指数バックオフのパターン
async function generateWithRetry(request, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await ai.models.generateContent(request);
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
レート制限
⚠️ 2025 年 12 月の更新 — 無料枠を大幅に縮小
重要:Google は 2025 年 12 月 6~7 日に、広く告知することなく無料枠の制限を 80~90%引き下げました。現在、無料枠は主にプロトタイピング向けです。
ソース:LaoZhang AI | HowToGeek
無料枠(Gemini API)— 現在の制限
レート制限はモデルによって異なります。
Gemini 2.5 Pro:
- 1 分あたりのリクエスト数:5 RPM
- 1 分あたりのトークン数:125,000 TPM
- 1 日あたりのリクエスト数:100 RPD(2025 年 12 月以前は約 250)— 80%減
Gemini 2.5 Flash:
- 1 分あたりのリクエスト数:10 RPM
- 1 分あたりのトークン数:250,000 TPM
- 1 日あたりのリクエスト数:約 20 RPD(2025 年 12 月以前は約 250)— 90%減
Gemini 2.5 Flash-Lite:
- 1 分あたりのリクエスト数:15 RPM
- 1 分あたりのトークン数:250,000 TPM
- 1 日あたりのリクエスト数:1,000 RPD(変更なし)
有料枠(Tier 1)
Google Cloud プロジェクトに課金アカウントをリンクする必要があります。
Gemini 2.5 Pro:
- 1 分あたりのリクエスト数:150 RPM
- 1 分あたりのトークン数:2,000,000 TPM
- 1 日あたりのリクエスト数:10,000 RPD
Gemini 2.5 Flash:
- 1 分あたりのリクエスト数:1,000 RPM
- 1 分あたりのトークン数:1,000,000 TPM
- 1 日あたりのリクエスト数:10,000 RPD
Gemini 2.5 Flash-Lite:
- 1 分あたりのリクエスト数:4,000 RPM
- 1 分あたりのトークン数:4,000,000 TPM
- 1 日あたりのリクエスト数:指定なし
上位の枠(Tier 2、Tier 3)
Tier 2(250 ドル以上の利用と 30 日間の待機が必要):
- さらに高い制限を利用できます
Tier 3(1,000 ドル以上の利用と 30 日間の待機が必要):
- 最大の制限を利用できます
ヒント:
- 指数バックオフを使ってレート制限への対処を実装する
- 大量のタスクにはバッチ処理を使用する
- Google AI Studio で使用状況を監視する
- レート制限の要件に応じて適切なモデルを選択する
- 公式のレート制限:https://ai.google.dev/gemini-api/docs/rate-limits
SDK 移行ガイド
@google/generative-ai から @google/genai への移行
1. パッケージを更新する
# Remove deprecated SDK
npm uninstall @google/generative-ai
# Install current SDK
npm install @google/[email protected]
2. インポートを更新する
旧(非推奨):
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(apiKey);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
新(現行):
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey });
// Use ai.models.generateContent() directly
3. API 呼び出しを更新する
旧:
const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();
新:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt
});
const text = response.text;
4. ストリーミングを更新する
旧:
const result = await model.generateContentStream(prompt);
for await (const chunk of result.stream) {
console.log(chunk.text());
}
新:
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: prompt
});
for await (const chunk of response) {
console.log(chunk.text);
}
5. チャットを更新する
旧:
const chat = model.startChat();
const result = await chat.sendMessage(message);
const response = await result.response;
新:
const chat = await ai.models.createChat({ model: 'gemini-2.5-flash' });
const response = await chat.sendMessage(message);
// response.text is directly available
本番環境でのベストプラクティス
1. 必ず行うこと
✅ @google/genai を使用する(@google/generative-ai ではない) ✅ maxOutputTokens を設定する - 過剰な生成を防ぐため ✅ レート制限の処理を実装する - 指数バックオフを使用 ✅ 環境変数を使用する - API キー用(ハードコードは絶対にしない) ✅ 入力を検証する - API に送信する前に(コスト削減) ✅ ストリーミングを使用する - 長い応答での UX 向上のため ✅ 用途に合ったモデルを選ぶ - 複雑な推論には Pro、バランスには Flash、速度には Flash-Lite ✅ エラーを適切に処理する - try-catch を使用 ✅ トークン使用量を監視する - コスト管理のため ✅ 正しいモデル名を使用する: gemini-2.5-pro/flash/flash-lite
2. 絶対に行わないこと
❌ @google/generative-ai を絶対に使用しない(非推奨!) ❌ API キーをコードに絶対にハードコードしない ❌ Gemini 2.5 で 2M コンテキストと絶対に主張しない(入力トークンは 1,048,576 です) ❌ クライアントサイドのコードで API キーを絶対に公開しない ❌ エラー処理を絶対に省略しない(常に try-catch) ❌ 汎用的なレート制限を絶対に使用しない(モデルごとに制限が異なります - 公式ドキュメントを確認してください) ❌ ユーザーの同意なく PII を絶対に送信しない ❌ 検証せずにユーザー入力を絶対に信頼しない ❌ レート制限を絶対に無視しない(429 エラーが発生します) ❌ gemini-1.5-pro のような古いモデル名を絶対に使用しない(2.5 モデルを使用してください)
3. セキュリティ
- API キーの保管: 環境変数またはシークレットマネージャーを使用してください
- サーバーサイドのみ: ブラウザの JavaScript で API キーを絶対に公開しないでください
- 入力の検証: API 呼び出しの前にすべてのユーザー入力をサニタイズしてください
- レート制限: 悪用を防ぐために独自のレート制限を実装してください
- エラーメッセージ: エラーログに API キーや機密データを公開しないでください
4. コストの最適化
- 適切なモデルを選ぶ: ほとんどのタスクには Flash を使用し、必要なときだけ Pro を使用してください
- トークン制限を設定する: maxOutputTokens を使用してコストを管理してください
- リクエストをバッチ処理する: 複数の項目を効率的に処理してください
- 結果をキャッシュする: 適切な場合は応答を保存してください
- 使用量を監視する: Google Cloud Console でトークン消費を追跡してください
5. パフォーマンス
- ストリーミングを使用する: 長い応答での体感レイテンシが向上します
- 並列リクエスト: 独立した呼び出しには Promise.all() を使用してください
- エッジデプロイ: 低レイテンシのために Cloudflare Workers にデプロイしてください
- コネクションプーリング: 可能な場合は HTTP 接続を再利用してください
クイックリファレンス
インストール
npm install @google/[email protected]
環境
export GEMINI_API_KEY="..."
モデル(2025-2026)
gemini-3-flash(1,048,576 in / 65,536 out) - NEW 速度と品質のバランスが最良gemini-2.5-pro(1,048,576 in / 65,536 out) - 複雑な推論に最適gemini-2.5-flash(1,048,576 in / 65,536 out) - 実績のある価格性能バランスgemini-2.5-flash-lite(1,048,576 in / 65,536 out) - 最速、最もコスト効率が高い
基本的な生成
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Your prompt here'
});
console.log(response.text);
ストリーミング
const response = await ai.models.generateContentStream({...});
for await (const chunk of response) {
console.log(chunk.text);
}
マルチモーダル
contents: [
{
parts: [
{ text: 'What is this?' },
{ inlineData: { data: base64Image, mimeType: 'image/jpeg' } }
]
}
]
関数呼び出し
config: {
tools: [{ functionDeclarations: [...] }]
}
最終更新: 2026-01-21 本番環境で検証済み: すべての機能を @google/[email protected] でテスト済み フェーズ: 2 完了 ✅(すべてのコア機能 + 高度な機能) 既知の問題: 14 件の文書化されたエラーを防止 変更点: トレーニングカットオフ後の期間(2025 年 5 月〜2026 年 1 月)にコミュニティで調査された 14 件の知見を含む「既知の問題の防止」セクションを追加