
Google Gemini Api
- 64 installs
- 51 repo stars
- Updated November 25, 2025
- ovachiever/droid-tings
Helps with ai & agent building tasks during AI-assisted development.
About
google-gemini-api is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- google-gemini-api
- AI & Agent Building
- AI-coding skill
Google Gemini Api by the numbers
- 64 all-time installs (skills.sh)
- Ranked #6,008 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ovachiever/droid-tings --skill google-gemini-apiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 64 |
|---|---|
| repo stars | ★ 51 |
| Last updated | November 25, 2025 |
| Repository | ovachiever/droid-tings ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Google Gemini API - Complete Guide
Version: Phase 2 Complete + Gemini 3 ✅ Package: @google/genai@1.27.0 (⚠️ NOT @google/generative-ai) Last Updated: 2025-11-19 (Gemini 3 preview release)
---
⚠️ CRITICAL SDK MIGRATION WARNING
DEPRECATED SDK: @google/generative-ai (sunset November 30, 2025) CURRENT SDK: @google/genai v1.27+
If you see code using `@google/generative-ai`, it's outdated!
This skill uses the correct current SDK and provides a complete migration guide.
---
Status
✅ Phase 1 Complete:
- ✅ Text Generation (basic + streaming)
- ✅ Multimodal Inputs (images, video, audio, PDFs)
- ✅ Function Calling (basic + parallel execution)
- ✅ System Instructions & Multi-turn Chat
- ✅ Thinking Mode Configuration
- ✅ Generation Parameters (temperature, top-p, top-k, stop sequences)
- ✅ Both Node.js SDK (@google/genai) and fetch approaches
✅ Phase 2 Complete:
- ✅ Context Caching (cost optimization with TTL-based caching)
- ✅ Code Execution (built-in Python interpreter and sandbox)
- ✅ Grounding with Google Search (real-time web information + citations)
📦 Separate Skills:
- Embeddings: See
google-gemini-embeddingsskill for text-embedding-004
---
Table of Contents
Phase 1 - Core Features: 1. Quick Start 2. Current Models (2025) 3. SDK vs Fetch Approaches 4. Text Generation 5. Streaming 6. Multimodal Inputs 7. Function Calling 8. System Instructions 9. Multi-turn Chat 10. Thinking Mode 11. Generation Configuration
Phase 2 - Advanced Features: 12. Context Caching 13. Code Execution 14. Grounding with Google Search
Common Reference: 15. Error Handling 16. Rate Limits 17. SDK Migration Guide 18. Production Best Practices
---
Quick Start
Installation
CORRECT SDK:
npm install @google/genai@1.27.0❌ WRONG (DEPRECATED):
npm install @google/generative-ai # DO NOT USE!Environment Setup
export GEMINI_API_KEY="..."Or create .env file:
GEMINI_API_KEY=...First Text Generation (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);First Text Generation (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);---
Current Models (2025)
Gemini 3 Series (Preview - November 2025)
gemini-3-pro-preview
- Context: TBD (documentation pending)
- Status: 🆕 Preview release (November 18, 2025)
- Description: Google's newest and most intelligent AI model with state-of-the-art reasoning
- Best for: Most complex reasoning tasks, advanced multimodal understanding, benchmark-critical applications
- Features: Enhanced multimodal (text, image, video, audio, PDF), function calling, streaming
- Benchmark Performance: Outperforms Gemini 2.5 Pro on every major AI benchmark
- ⚠️ Preview: Use for evaluation. Consider gemini-2.5-pro for production until stable release
Gemini 2.5 Series (General Availability - Stable)
gemini-2.5-pro
- Context: 1,048,576 input tokens / 65,536 output tokens
- Description: State-of-the-art thinking model for complex reasoning
- Best for: Code, math, STEM, complex problem-solving
- Features: Thinking mode (default on), function calling, multimodal, streaming
- Knowledge cutoff: January 2025
gemini-2.5-flash
- Context: 1,048,576 input tokens / 65,536 output tokens
- Description: Best price-performance workhorse model
- Best for: Large-scale processing, low-latency, high-volume, agentic use cases
- Features: Thinking mode (default on), function calling, multimodal, streaming
- Knowledge cutoff: January 2025
gemini-2.5-flash-lite
- Context: 1,048,576 input tokens / 65,536 output tokens
- Description: Cost-optimized, fastest 2.5 model
- Best for: High throughput, cost-sensitive applications
- Features: Thinking mode (default on), function calling, multimodal, streaming
- Knowledge cutoff: January 2025
Model Feature Matrix
| Feature | 3-Pro (Preview) | 2.5-Pro | 2.5-Flash | 2.5-Flash-Lite |
|---|---|---|---|---|
| Thinking Mode | TBD | ✅ Default ON | ✅ Default ON | ✅ Default ON |
| Function Calling | ✅ | ✅ | ✅ | ✅ |
| Multimodal | ✅ Enhanced | ✅ | ✅ | ✅ |
| Streaming | ✅ | ✅ | ✅ | ✅ |
| System Instructions | ✅ | ✅ | ✅ | ✅ |
| Context Window | TBD | 1,048,576 in | 1,048,576 in | 1,048,576 in |
| Output Tokens | TBD | 65,536 max | 65,536 max | 65,536 max |
| Status | Preview | Stable | Stable | Stable |
⚠️ Context Window Correction
ACCURATE (Gemini 2.5): Gemini 2.5 models support 1,048,576 input tokens (NOT 2M!) OUTDATED: Only Gemini 1.5 Pro (previous generation) had 2M token context window GEMINI 3: Context window specifications pending official documentation
Common mistake: Claiming Gemini 2.5 has 2M tokens. It doesn't. This skill prevents this error.
---
SDK vs Fetch Approaches
Node.js SDK (@google/genai)
Pros:
- Type-safe with TypeScript
- Easier API (simpler syntax)
- Built-in chat helpers
- Automatic SSE parsing for streaming
- Better error handling
Cons:
- Requires Node.js or compatible runtime
- Larger bundle size
- May not work in all edge runtimes
Use when: Building Node.js apps, Next.js Server Actions/Components, or any environment with Node.js compatibility
Fetch-based (Direct REST API)
Pros:
- Works in any JavaScript environment (Cloudflare Workers, Deno, Bun, browsers)
- Minimal dependencies
- Smaller bundle size
- Full control over requests
Cons:
- More verbose syntax
- Manual SSE parsing for streaming
- No built-in chat helpers
- Manual error handling
Use when: Deploying to Cloudflare Workers, browser clients, or lightweight edge runtimes
---
Text Generation
Basic Text Generation (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);Basic Text Generation (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);Response Structure
{
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
}
}---
Streaming
Streaming with SDK (Async Iteration)
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);
}Streaming with Fetch (SSE Parsing)
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
}
}
}Key Points:
- Use
streamGenerateContentendpoint (notgenerateContent) - Parse Server-Sent Events (SSE) format:
data: {json}\n\n - Handle incomplete chunks in buffer
- Skip empty lines and
[DONE]markers
---
Multimodal Inputs
Gemini 2.5 models support text + images + video + audio + PDFs in the same request.
Images (Vision)
SDK Approach
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 Approach
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);Supported Image Formats:
- JPEG (
.jpg,.jpeg) - PNG (
.png) - WebP (
.webp) - HEIC (
.heic) - HEIF (
.heif)
Max Image Size: 20MB per image
Video
// 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);Supported Video Formats:
- MP4 (
.mp4) - MPEG (
.mpeg) - MOV (
.mov) - AVI (
.avi) - FLV (
.flv) - MPG (
.mpg) - WebM (
.webm) - WMV (
.wmv)
Max Video Length (inline): 2 minutes Max Video Size: 2GB (use File API for larger files - Phase 2)
Audio
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);Supported Audio Formats:
- MP3 (
.mp3) - WAV (
.wav) - FLAC (
.flac) - AAC (
.aac) - OGG (
.ogg) - OPUS (
.opus)
Max Audio Size: 20MB
PDFs
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);Max PDF Size: 30MB PDF Limitations: Text-based PDFs work best; scanned images may have lower accuracy
Multiple Inputs
You can combine multiple modalities in one request:
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' } }
]
}
]
});---
Function Calling
Gemini supports function calling (tool use) to connect models with external APIs and systems.
Basic Function Calling (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);
}Function Calling (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)
}Parallel Function Calling
Gemini can call multiple independent functions simultaneously:
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`);Function Calling Modes
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
}
}
}
});Modes:
AUTO(default): Model decides whether to call functionsANY: Force model to call at least one functionNONE: Disable function calling for this request
---
System Instructions
System instructions guide the model's behavior and set context. They are separate from the conversation messages.
SDK Approach
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 Approach
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' }] }
]
}),
}
);Key Points:
- System instructions are NOT part of
contentsarray - They are set once at the top level of the request
- They persist for the entire conversation (when using multi-turn chat)
- They don't count as user or model messages
---
Multi-turn Chat
For conversations with history, use the SDK's chat helpers or manually manage conversation state.
SDK Chat Helpers (Recommended)
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);Manual Chat Management (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?' }] }
]
}),
}
);Message Roles:
user: User messagesmodel: Assistant responses
⚠️ Important: Chat helpers are SDK-only. With fetch, you must manually manage conversation history.
---
Thinking Mode
Gemini 2.5 models have thinking mode enabled by default for enhanced quality. You can configure the thinking budget.
Configure Thinking Budget (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)
}
}
});Configure Thinking Budget (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
}
}
}),
}
);Key Points:
- Thinking mode is always enabled on Gemini 2.5 models (cannot be disabled)
- Higher thinking budgets allow more internal reasoning (may increase latency)
- Default budget varies by model (usually sufficient for most tasks)
- Only increase budget for very complex reasoning tasks
---
Generation Configuration
Customize model behavior with generation parameters.
All Configuration Options (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)
}
});All Configuration Options (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
}
}),
}
);Parameter Guidelines
| Parameter | Range | Default | Use Case |
|---|---|---|---|
| temperature | 0.0-2.0 | 1.0 | Lower = more focused, higher = more creative |
| topP | 0.0-1.0 | 0.95 | Nucleus sampling threshold |
| topK | 1-100+ | 40 | Limit to top K tokens |
| maxOutputTokens | 1-65536 | Model max | Control response length |
| stopSequences | Array | None | Stop generation at specific strings |
Tips:
- For factual tasks: Use low temperature (0.0-0.3)
- For creative tasks: Use high temperature (0.7-1.5)
- topP and topK both control randomness; use one or the other (not both)
- Always set maxOutputTokens to prevent excessive generation
---
Context Caching
Context caching allows you to cache frequently used content (like system instructions, large documents, or video files) to reduce costs by up to 90% and improve latency.
How It Works
1. Create a cache with your repeated content 2. Reference the cache in subsequent requests 3. Save tokens - cached tokens cost significantly less 4. TTL management - caches expire after specified time
Benefits
- Cost savings: Up to 90% reduction on cached tokens
- Reduced latency: Faster responses by reusing processed content
- Consistent context: Same large context across multiple requests
Cache Creation (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);Cache Creation (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);Using a Cache (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);Using a Cache (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);Update Cache TTL (SDK)
import { UpdateCachedContentConfig } from '@google/genai';
await ai.caches.update({
name: cache.name,
config: {
ttl: '7200s' // Extend to 2 hours
}
});Update Cache with Expiration Time (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
}
});List and Delete Caches (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 });Caching with Video Files
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'
});Key Points
When to Use Caching:
- Large system instructions used repeatedly
- Long documents analyzed multiple times
- Video/audio files queried with different prompts
- Consistent context across conversation sessions
TTL Guidelines:
- Short sessions: 300s (5 min) to 3600s (1 hour)
- Long sessions: 3600s (1 hour) to 86400s (24 hours)
- Maximum: 7 days
Cost Savings:
- Cached input tokens: ~90% cheaper than regular tokens
- Output tokens: Same price (not cached)
Important:
- You must use explicit model version suffixes (e.g.,
gemini-2.5-flash-001, NOT justgemini-2.5-flash) - Caches are automatically deleted after TTL expires
- Update TTL before expiration to extend cache lifetime
---
Code Execution
Gemini models can generate and execute Python code to solve problems requiring computation, data analysis, or visualization.
How It Works
1. Model generates executable Python code 2. Code runs in secure sandbox 3. Results are returned to the model 4. Model incorporates results into response
Supported Operations
- Mathematical calculations
- Data analysis and statistics
- File processing (CSV, JSON, etc.)
- Chart and graph generation
- Algorithm implementation
- Data transformations
Available Python Packages
Standard Library:
math,statistics,random,datetime,json,csv,recollections,itertools,functools
Data Science:
numpy,pandas,scipy
Visualization:
matplotlib,seaborn
Note: Limited package availability compared to full Python environment
Basic Code Execution (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);
}
}Basic Code Execution (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);
}
}Chat with Code Execution (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);
}Data Analysis Example
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);
}Visualization Example
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');
}
}Response Structure
{
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." }
]
}
}
]
}Error Handling
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);
}
}
}Key Points
When to Use Code Execution:
- Complex mathematical calculations
- Data analysis and statistics
- Algorithm implementations
- File parsing and processing
- Chart generation
- Computational problems
Limitations:
- Sandbox environment (limited file system access)
- Limited Python package availability
- Execution timeout limits
- No network access from code
- No persistent state between executions
Best Practices:
- Specify what calculation or analysis you need clearly
- Request code generation explicitly ("Generate and run code...")
- Check
outcomefield for errors - Use for deterministic computations, not for general programming
Important:
- Available on all Gemini 2.5 models (Pro, Flash, Flash-Lite)
- Code runs in isolated sandbox for security
- Supports Python with standard library and common data science packages
---
Grounding with Google Search
Grounding connects the model to real-time web information, reducing hallucinations and providing up-to-date, fact-checked responses with citations.
How It Works
1. Model determines if it needs current information 2. Automatically performs Google Search 3. Processes search results 4. Incorporates findings into response 5. Provides citations and source URLs
Benefits
- Real-time information: Access to current events and data
- Reduced hallucinations: Answers grounded in web sources
- Verifiable: Citations allow fact-checking
- Up-to-date: Not limited to model's training cutoff
Two Grounding APIs
1. Google Search (googleSearch) - Recommended for Gemini 2.5
const groundingTool = {
googleSearch: {}
};Features:
- Simple configuration
- Automatic search when needed
- Available on all Gemini 2.5 models
2. Google Search Retrieval (googleSearchRetrieval) - Legacy (Gemini 1.5)
const retrievalTool = {
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: 'MODE_DYNAMIC',
dynamicThreshold: 0.7 // Only search if confidence < 70%
}
}
};Features:
- Dynamic threshold control
- Used with Gemini 1.5 models
- More configuration options
Basic Grounding (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);
}Basic Grounding (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);
}Dynamic Retrieval (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-1.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)');
}Grounding Metadata Structure
{
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"
}
]
}
}Chat with Grounding (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);Combining Grounding with Function Calling
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 responseChecking if Grounding was Used
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');
}Key Points
When to Use Grounding:
- Current events and news
- Real-time data (stock prices, sports scores, weather)
- Fact-checking and verification
- Questions about recent developments
- Information beyond model's training cutoff
When NOT to Use:
- General knowledge questions
- Mathematical calculations
- Code generation
- Creative writing
- Tasks requiring internal reasoning only
Cost Considerations:
- Grounding adds latency (search takes time)
- Additional token costs for retrieved content
- Use
dynamicThresholdto control when searches happen (Gemini 1.5)
Important Notes:
- Grounding requires Google Cloud project (not just API key)
- Search results quality depends on query phrasing
- Citations may not cover all facts in response
- Search is performed automatically based on confidence
Gemini 2.5 vs 1.5:
- Gemini 2.5: Use
googleSearch(simple, recommended) - Gemini 1.5: Use
googleSearchRetrievalwithdynamicThreshold
Best Practices:
- Always check
groundingMetadatato see if search was used - Display citations to users for transparency
- Use specific, well-phrased questions for better search results
- Combine with function calling for hybrid workflows
---
Error Handling
Common Errors
1. Invalid API Key (401)
{
error: {
code: 401,
message: 'API key not valid. Please pass a valid API key.',
status: 'UNAUTHENTICATED'
}
}Solution: Verify GEMINI_API_KEY environment variable is set correctly.
2. Rate Limit Exceeded (429)
{
error: {
code: 429,
message: 'Resource has been exhausted (e.g. check quota).',
status: 'RESOURCE_EXHAUSTED'
}
}Solution: Implement exponential backoff retry strategy.
3. Model Not Found (404)
{
error: {
code: 404,
message: 'models/gemini-3.0-flash is not found',
status: 'NOT_FOUND'
}
}Solution: Use correct model names: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite
4. Context Length Exceeded (400)
{
error: {
code: 400,
message: 'Request payload size exceeds the limit',
status: 'INVALID_ARGUMENT'
}
}Solution: Reduce input size. Gemini 2.5 models support 1,048,576 input tokens max.
Exponential Backoff Pattern
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;
}
}
}---
Rate Limits
Free Tier (Gemini API)
Rate limits vary by model:
Gemini 2.5 Pro:
- Requests per minute: 5 RPM
- Tokens per minute: 125,000 TPM
- Requests per day: 100 RPD
Gemini 2.5 Flash:
- Requests per minute: 10 RPM
- Tokens per minute: 250,000 TPM
- Requests per day: 250 RPD
Gemini 2.5 Flash-Lite:
- Requests per minute: 15 RPM
- Tokens per minute: 250,000 TPM
- Requests per day: 1,000 RPD
Paid Tier (Tier 1)
Requires billing account linked to your Google Cloud project.
Gemini 2.5 Pro:
- Requests per minute: 150 RPM
- Tokens per minute: 2,000,000 TPM
- Requests per day: 10,000 RPD
Gemini 2.5 Flash:
- Requests per minute: 1,000 RPM
- Tokens per minute: 1,000,000 TPM
- Requests per day: 10,000 RPD
Gemini 2.5 Flash-Lite:
- Requests per minute: 4,000 RPM
- Tokens per minute: 4,000,000 TPM
- Requests per day: Not specified
Higher Tiers (Tier 2 & 3)
Tier 2 (requires $250+ spending and 30-day wait):
- Even higher limits available
Tier 3 (requires $1,000+ spending and 30-day wait):
- Maximum limits available
Tips:
- Implement rate limit handling with exponential backoff
- Use batch processing for high-volume tasks
- Monitor usage in Google AI Studio
- Choose the right model based on your rate limit needs
- Official rate limits: https://ai.google.dev/gemini-api/docs/rate-limits
---
SDK Migration Guide
From @google/generative-ai to @google/genai
1. Update Package
# Remove deprecated SDK
npm uninstall @google/generative-ai
# Install current SDK
npm install @google/genai@1.27.02. Update Imports
Old (DEPRECATED):
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(apiKey);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });New (CURRENT):
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey });
// Use ai.models.generateContent() directly3. Update API Calls
Old:
const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();New:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt
});
const text = response.text;4. Update Streaming
Old:
const result = await model.generateContentStream(prompt);
for await (const chunk of result.stream) {
console.log(chunk.text());
}New:
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: prompt
});
for await (const chunk of response) {
console.log(chunk.text);
}5. Update Chat
Old:
const chat = model.startChat();
const result = await chat.sendMessage(message);
const response = await result.response;New:
const chat = await ai.models.createChat({ model: 'gemini-2.5-flash' });
const response = await chat.sendMessage(message);
// response.text is directly available---
Production Best Practices
1. Always Do
✅ Use @google/genai (NOT @google/generative-ai) ✅ Set maxOutputTokens to prevent excessive generation ✅ Implement rate limit handling with exponential backoff ✅ Use environment variables for API keys (never hardcode) ✅ Validate inputs before sending to API (save costs) ✅ Use streaming for better UX on long responses ✅ Choose the right model based on your needs (Pro for complex reasoning, Flash for balance, Flash-Lite for speed) ✅ Handle errors gracefully with try-catch ✅ Monitor token usage for cost control ✅ Use correct model names: gemini-2.5-pro/flash/flash-lite
2. Never Do
❌ Never use @google/generative-ai (deprecated!) ❌ Never hardcode API keys in code ❌ Never claim 2M context for Gemini 2.5 (it's 1,048,576 input tokens) ❌ Never expose API keys in client-side code ❌ Never skip error handling (always try-catch) ❌ Never use generic rate limits (each model has different limits - check official docs) ❌ Never send PII without user consent ❌ Never trust user input without validation ❌ Never ignore rate limits (will get 429 errors) ❌ Never use old model names like gemini-1.5-pro (use 2.5 models)
3. Security
- API Key Storage: Use environment variables or secret managers
- Server-Side Only: Never expose API keys in browser JavaScript
- Input Validation: Sanitize all user inputs before API calls
- Rate Limiting: Implement your own rate limits to prevent abuse
- Error Messages: Don't expose API keys or sensitive data in error logs
4. Cost Optimization
- Choose Right Model: Use Flash for most tasks, Pro only when needed
- Set Token Limits: Use maxOutputTokens to control costs
- Batch Requests: Process multiple items efficiently
- Cache Results: Store responses when appropriate
- Monitor Usage: Track token consumption in Google Cloud Console
5. Performance
- Use Streaming: Better perceived latency for long responses
- Parallel Requests: Use Promise.all() for independent calls
- Edge Deployment: Deploy to Cloudflare Workers for low latency
- Connection Pooling: Reuse HTTP connections when possible
---
Quick Reference
Installation
npm install @google/genai@1.27.0Environment
export GEMINI_API_KEY="..."Models (2025)
gemini-2.5-pro(1,048,576 in / 65,536 out) - Best for complex reasoninggemini-2.5-flash(1,048,576 in / 65,536 out) - Best price-performance balancegemini-2.5-flash-lite(1,048,576 in / 65,536 out) - Fastest, most cost-effective
Basic Generation
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Your prompt here'
});
console.log(response.text);Streaming
const response = await ai.models.generateContentStream({...});
for await (const chunk of response) {
console.log(chunk.text);
}Multimodal
contents: [
{
parts: [
{ text: 'What is this?' },
{ inlineData: { data: base64Image, mimeType: 'image/jpeg' } }
]
}
]Function Calling
config: {
tools: [{ functionDeclarations: [...] }]
}---
Last Updated: 2025-10-25 Production Validated: All features tested with @google/genai@1.27.0 Phase: 2 Complete ✅ (All Core + Advanced Features)
{
"name": "google-gemini-api",
"description": "Integrate Gemini API with correct current SDK (@google/genai v1.27+, NOT deprecated @google/generative-ai). Supports text generation, multimodal (images/video/audio/PDFs), function calling, and thinking mode. 1M input tokens. Use when: integrating Gemini API, implementing multimodal AI, using thinking mode for reasoning, function calling with parallel execution, streaming responses, deploying to Cloudflare Workers, building chat, or troubleshooting SDK deprecation, context window, model not foun",
"version": "1.0.0",
"author": {
"name": "Jeremy Dawes",
"email": "jeremy@jezweb.net"
},
"license": "MIT",
"repository": "https://github.com/jezweb/claude-skills",
"keywords": ["gemini api","@google/genai","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-3-pro-preview","multimodal gemini","thinking mode","google ai","genai sdk","function calling gemini","streaming gemini","gemini vision","gemini video","gemini audio"]
}
google-gemini-api
Google Gemini API Skill for Claude Code CLI
Status: Phase 2 Complete ✅ Latest SDK: @google/genai@1.27.0 (⚠️ NOT @google/generative-ai which is DEPRECATED) API Coverage: Text Generation, Multimodal, Function Calling, Streaming, Thinking Mode, Context Caching, Code Execution, Grounding with Google Search
---
⚠️ CRITICAL: SDK Migration Warning
DEPRECATED: @google/generative-ai (sunset Nov 30, 2025) CURRENT: @google/genai v1.27+ (use this!)
If you see code using @google/generative-ai, it's outdated! This skill uses the correct current SDK.
---
What This Skill Does
This skill provides comprehensive knowledge for building applications with Google Gemini API using the correct current SDK (@google/genai v1.27+) and accurate 2025 model information.
Key Capabilities
Phase 1 - Core Features
✅ Text Generation with Gemini 2.5 Pro/Flash/Flash-Lite (GA models) ✅ Streaming with Server-Sent Events (SSE) and async iteration ✅ Multimodal inputs (text + images + video + audio + PDFs) ✅ Function calling (basic + parallel execution) ✅ Thinking mode (adaptive reasoning on 2.5 models) ✅ System instructions for behavior guidance ✅ Multi-turn chat (conversation history management) ✅ Both Node.js SDK (@google/genai) and fetch-based (Cloudflare Workers) approaches ✅ Accurate context windows: 1,048,576 input / 65,536 output tokens (NOT 2M for 2.5 models!)
Phase 2 - Advanced Features
✅ Context Caching (cost optimization with TTL-based caching - up to 90% savings) ✅ Code Execution (built-in Python sandbox for data analysis and computation) ✅ Grounding with Google Search (real-time web information + citations)
---
Auto-Trigger Keywords
Primary Keywords (Core API)
gemini apigoogle gemini@google/genaigemini-2.5-progemini-2.5-flashgemini-2.5-flash-litegenai sdkgoogle aigemini sdk
Model Names
gemini 2.5gemini 2.0gemini progemini flashgemini flash lite
Text Generation
gemini text generationgenerate content geminigemini chatgemini completiongemini response
Streaming
gemini streamingstream geminigemini sseserver-sent events geminiasync iteration geministreaming tokens gemini
Multimodal Keywords
gemini multimodalgemini visiongemini imagegemini videogemini audiogemini pdfimage understanding geminianalyze image geminivideo understanding geminiaudio transcription geminipdf parsing gemini
Function Calling
function calling geminigemini toolstool calling geminifunction declarations geminiparallel function calling geminicompositional function callinggemini tool use
Thinking Mode
thinking mode geminigemini thinkingadaptive reasoning geminithinking budget geminigemini reasoning
System Instructions & Chat
system instructions geminigemini system promptmulti-turn geminiconversation history geminichat history geminigemini chat sdk
Configuration
gemini temperaturegemini top-pgemini top-kstop sequences geminigeneration config geminiresponse mime type gemini
Context Caching (Phase 2)
context caching geminigemini cachinggemini cache ttlprompt caching geminicache tokens geminigemini cost optimizationreduce cost geminigemini cache videocache documents gemini90% savings gemini
Code Execution (Phase 2)
code execution geminigemini pythongemini code interpreterrun code geminiexecutable code geminigemini data analysisgemini calculationsgemini pandasgemini numpygemini matplotlibgenerate and run code
Grounding with Google Search (Phase 2)
grounding geminigoogle search geminigemini groundingreal-time information geminigemini search retrievalgemini citationsfact-checking geminigemini sourcesweb search geminicurrent events gemini
SDK Migration
@google/generative-ai deprecatedmigrate gemini sdkgemini sdk migrationgenerative-ai deprecatedupdate gemini sdk
Context Window
gemini context windowgemini token limitgemini 1m tokensgemini 2m tokens(⚠️ only Gemini 1.5 Pro has 2M, NOT 2.5 models!)context length gemini
Error Keywords
gemini api errorgemini 401gemini 429gemini rate limitinvalid api key geminimodel not found geminigemini context window exceededfunction calling error geminitool schema invalid geministreaming parse error geminimultimodal format error geminithinking mode not supporteddeprecated sdk error@google/generative-ai not found
Error Keywords - Phase 2
cache not found geminicache ttl expiredinvalid model version geminicode execution failed geminiexecution timeout geminipython package not available geminigrounding requires google cloudgrounding not working geminino grounding metadata
Integration Keywords
nextjs geminireact geminicloudflare workers geminivercel geminigemini backendgemini servergemini edge runtime
Comparison Keywords
gemini vs openaigemini vs claudegemini vs gptgoogle ai vs openai
---
When to Use This Skill
✅ Use google-gemini-api When:
- Building AI applications with Google's Gemini models
- Need multimodal AI (text + images + video + audio + PDFs)
- Implementing long-context applications (1M+ tokens)
- Using thinking mode for complex reasoning
- Need function calling with parallel execution
- Want streaming responses for better UX
- Deploying to Cloudflare Workers or other edge runtimes
- Building chat applications with conversation history
- Need to migrate from deprecated @google/generative-ai
❌ Don't Use google-gemini-api When:
- You specifically need embeddings (see separate
google-gemini-embeddingsskill for text-embedding-004) - You're using a different AI API provider (OpenAI, Anthropic Claude, etc.)
---
Quick Example
Text Generation (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);Text Generation (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);Streaming
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: 'Write a 200-word story about AI'
});
for await (const chunk of response) {
process.stdout.write(chunk.text);
}---
Known Issues Prevented
| Issue | Cause | Solution in Skill |
|---|---|---|
| Using deprecated SDK | Installing @google/generative-ai | Prominent warnings + migration guide |
| Wrong context window claims | Claiming 2M tokens for 2.5 models | Accurate: 1,048,576 input tokens |
| Model not found errors | Using old/wrong model names | Current model list (gemini-2.5-pro/flash/flash-lite) |
| Chat not working with fetch | Chat is SDK-only feature | Document SDK requirement for chat helpers |
| Function calling on Flash-Lite | Model doesn't support it | Model capabilities matrix |
| Invalid API key (401) | Missing GEMINI_API_KEY | Environment setup guide |
| Rate limit errors (429) | Too many requests | Exponential backoff pattern |
| Streaming parse errors | Incorrect SSE parsing | Complete SSE implementation |
| Multimodal format errors | Wrong image/video encoding | Base64/URL examples |
| Function schema errors | Invalid OpenAPI subset | Schema validation examples |
| Thinking mode on old models | Only 2.5 models support it | Model feature matrix |
| Parameter conflicts | Using unsupported params | Generation config reference |
| Token counting errors | Multimodal token estimation | Token counting guide |
| System instruction placement | Wrong position in request | Correct structure examples |
| Parallel function call errors | Dependencies not handled | Compositional vs parallel guide |
---
Current Models (2025)
Gemini 2.5 Series (General Availability)
- gemini-2.5-pro: State-of-the-art thinking model (1,048,576 input / 65,536 output tokens)
- gemini-2.5-flash: Best price-performance (1,048,576 input / 65,536 output tokens)
- gemini-2.5-flash-lite: Cost-optimized, fastest (1,048,576 input / 65,536 output tokens)
Feature Matrix
| Feature | Pro | Flash | Flash-Lite |
|---|---|---|---|
| Thinking Mode | ✅ | ✅ | ✅ |
| Function Calling | ✅ | ✅ | ❌ |
| Multimodal | ✅ | ✅ | ✅ |
| Streaming | ✅ | ✅ | ✅ |
| System Instructions | ✅ | ✅ | ✅ |
⚠️ Note: Gemini 2.5 Flash-Lite does NOT support function calling!
---
Token Efficiency
Without Skill
- Research APIs + SDK: ~22,000 tokens
- Fall into deprecated SDK trap: +5,000 tokens (debugging)
- Context window confusion: +3,000 tokens (debugging)
- Total: ~30,000 tokens
With Skill
- Skill discovery + implementation: ~10,500 tokens
- Zero debugging (all errors prevented)
- Total: ~10,500 tokens
Savings: ~65% (19,500 tokens)
---
What You Get
SKILL.md Content
- Complete API reference (1200+ lines)
- Gemini 2.5 specific guidance
- Streaming patterns (SDK + fetch)
- Function calling (basic + parallel)
- Multimodal examples (images, video, audio, PDFs)
- Thinking mode configuration
- System instructions & chat
- SDK migration guide
- Top 15 errors with solutions
- Production best practices
11 Templates
1. package.json (dependencies) 2. text-generation-basic.ts (SDK) 3. text-generation-fetch.ts (Cloudflare Workers) 4. streaming-chat.ts (SDK with async iteration) 5. streaming-fetch.ts (SSE parsing) 6. multimodal-image.ts (vision) 7. multimodal-video-audio.ts (video/audio understanding) 8. function-calling-basic.ts (tool use) 9. function-calling-parallel.ts (parallel execution) 10. thinking-mode.ts (configure thinking budget) 11. cloudflare-worker.ts (complete Worker example)
8 Reference Docs
1. models-guide.md (2.5 Pro/Flash/Flash-Lite comparison with ACCURATE context windows) 2. sdk-migration-guide.md (complete migration from deprecated SDK) 3. function-calling-patterns.md (tool use best practices) 4. multimodal-guide.md (images, video, audio, PDFs) 5. thinking-mode-guide.md (when to use, budget configuration) 6. generation-config.md (all parameters explained) 7. streaming-patterns.md (SSE implementation for SDK + fetch) 8. top-errors.md (15+ documented errors with solutions)
1 Script
- check-versions.sh (verify @google/genai version, warn if using deprecated SDK)
---
Installation
# From claude-skills repo root
./scripts/install-skill.sh google-gemini-api
# Verify installation
ls -la ~/.claude/skills/google-gemini-api---
Quick Reference
Package Version
npm install @google/genai@1.27.0⚠️ NOT:
npm install @google/generative-ai # DEPRECATED!Environment Variables
export GEMINI_API_KEY="..."Models Overview (2025)
- Gemini 2.5 Pro:
gemini-2.5-pro(thinking, function calling, multimodal) - Gemini 2.5 Flash:
gemini-2.5-flash(best price-performance) - Gemini 2.5 Flash-Lite:
gemini-2.5-flash-lite(fastest, no function calling)
Context Windows (ACCURATE)
- Gemini 2.5 models: 1,048,576 input / 65,536 output tokens
- NOT 2M tokens (only Gemini 1.5 Pro has 2M, which is an older model)
---
Official Documentation
- Gemini API Overview: https://ai.google.dev/gemini-api/docs
- @google/genai SDK: https://github.com/googleapis/js-genai
- Models Guide: https://ai.google.dev/gemini-api/docs/models
- Text Generation: https://ai.google.dev/gemini-api/docs/text-generation
- Function Calling: https://ai.google.dev/gemini-api/docs/function-calling
- Multimodal: https://ai.google.dev/gemini-api/docs/vision
- Streaming: https://ai.google.dev/gemini-api/docs/streaming
- Migration Guide: https://ai.google.dev/gemini-api/docs/migrate-to-genai
---
Production Validated: Templates tested with @google/genai@1.27.0 Last Updated: 2025-10-25 Maintainer: Jeremy Dawes | Jezweb
Code Execution Patterns
Complete guide to using code execution with Google Gemini API for computational tasks, data analysis, and problem-solving.
---
What is Code Execution?
Code Execution allows Gemini models to generate and execute Python code to solve problems requiring computation, enabling the model to:
- Perform precise mathematical calculations
- Analyze data with pandas/numpy
- Generate charts and visualizations
- Implement algorithms
- Process files and data structures
---
How It Works
1. Model receives prompt requiring computation 2. Model generates Python code to solve the problem 3. Code executes in sandbox (secure, isolated environment) 4. Results return to model for incorporation into response 5. Model explains results in natural language
---
Enabling Code Execution
Basic Setup (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', // Or gemini-2.5-pro
contents: 'Calculate the sum of first 50 prime numbers',
config: {
tools: [{ codeExecution: {} }] // Enable code execution
}
});Basic Setup (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: 'Calculate...' }] }]
}),
}
);---
Available Python Packages
Standard Library
math,statistics,randomdatetime,time,calendarjson,csv,recollections,itertools,functools
Data Science
numpy- numerical computingpandas- data analysis and manipulationscipy- scientific computing
Visualization
matplotlib- plotting and chartsseaborn- statistical visualization
Note: This is a limited sandbox environment - not all PyPI packages are available.
---
Response Structure
Parsing Code Execution Results
for (const part of response.candidates[0].content.parts) {
// Inline text
if (part.text) {
console.log('Text:', part.text);
}
// Generated code
if (part.executableCode) {
console.log('Language:', part.executableCode.language); // "PYTHON"
console.log('Code:', part.executableCode.code);
}
// Execution results
if (part.codeExecutionResult) {
console.log('Outcome:', part.codeExecutionResult.outcome); // "OUTCOME_OK" or "OUTCOME_FAILED"
console.log('Output:', part.codeExecutionResult.output);
}
}Example Response
{
"candidates": [{
"content": {
"parts": [
{ "text": "I'll calculate that for you." },
{
"executableCode": {
"language": "PYTHON",
"code": "primes = []\nnum = 2\nwhile len(primes) < 50:\n if is_prime(num):\n primes.append(num)\n num += 1\nprint(sum(primes))"
}
},
{
"codeExecutionResult": {
"outcome": "OUTCOME_OK",
"output": "5117\n"
}
},
{ "text": "The sum is 5117." }
]
}
}]
}---
Common Patterns
1. Mathematical Calculations
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Calculate the 100th Fibonacci number',
config: { tools: [{ codeExecution: {} }] }
});Prompting Tip: Use phrases like "generate and run code" or "calculate using code" to explicitly request code execution.
2. Data Analysis
const prompt = `
Analyze this sales data:
month,revenue,customers
Jan,50000,120
Feb,62000,145
Mar,58000,138
Calculate:
1. Total revenue
2. Average revenue per customer
3. Month-over-month growth rate
Use pandas or numpy for analysis.
`;
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt,
config: { tools: [{ codeExecution: {} }] }
});3. Chart Generation
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Create a bar chart showing prime number distribution by last digit (0-9) for primes under 100',
config: { tools: [{ codeExecution: {} }] }
});Note: Chart image data appears in codeExecutionResult.output (base64 encoded in some cases).
4. Algorithm Implementation
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Implement quicksort and sort this list: [64, 34, 25, 12, 22, 11, 90]. Show the sorted result.',
config: { tools: [{ codeExecution: {} }] }
});5. File Processing (In-Memory)
const csvData = `name,age,city
Alice,30,NYC
Bob,25,LA
Charlie,35,Chicago`;
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: `Parse this CSV data and calculate average age:\n\n${csvData}`,
config: { tools: [{ codeExecution: {} }] }
});---
Chat with Code Execution
Multi-Turn Computational Conversations
const chat = await ai.chats.create({
model: 'gemini-2.5-flash',
config: { tools: [{ codeExecution: {} }] }
});
// First turn
let response = await chat.sendMessage('I have a data analysis question');
console.log(response.text);
// Second turn (will use code execution)
response = await chat.sendMessage(`
Calculate statistics for: [12, 15, 18, 22, 25, 28, 30]
- Mean
- Median
- Standard deviation
`);
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('Results:', part.codeExecutionResult.output);
}---
Error Handling
Checking Execution Outcome
for (const part of response.candidates[0].content.parts) {
if (part.codeExecutionResult) {
if (part.codeExecutionResult.outcome === 'OUTCOME_OK') {
console.log('✅ Success:', part.codeExecutionResult.output);
} else if (part.codeExecutionResult.outcome === 'OUTCOME_FAILED') {
console.error('❌ Execution failed:', part.codeExecutionResult.output);
}
}
}Common Execution Errors
Timeout:
Error: Execution timed out after 30 secondsSolution: Simplify computation or reduce data size.
Import Error:
ModuleNotFoundError: No module named 'requests'Solution: Use only available packages (numpy, pandas, matplotlib, seaborn, scipy).
Syntax Error:
SyntaxError: invalid syntaxSolution: Model generated invalid code - try rephrasing prompt or regenerating.
---
Best Practices
✅ Do
1. Be Explicit: Use phrases like "generate and run code" to trigger code execution 2. Provide Data: Include data directly in prompt for analysis 3. Specify Output: Ask for specific calculations or metrics 4. Use Available Packages: Stick to numpy, pandas, matplotlib, scipy 5. Check Outcome: Always verify outcome === 'OUTCOME_OK'
❌ Don't
1. Network Access: Code cannot make HTTP requests 2. File System: No persistent file storage between executions 3. Long Computations: Timeout limits apply (~30 seconds) 4. External Dependencies: Can't install new packages 5. State Persistence: Each execution is isolated (no global state)
---
Limitations
Sandbox Restrictions
- No Network Access: Cannot call external APIs
- No File I/O: Cannot read/write to disk (in-memory only)
- Limited Packages: Only pre-installed packages available
- Execution Timeout: ~30 seconds maximum
- No State: Each execution is independent
Supported Models
✅ Works with:
gemini-2.5-progemini-2.5-flash
❌ Does NOT work with:
gemini-2.5-flash-lite(no code execution support)- Gemini 1.5 models (use Gemini 2.5)
---
Advanced Patterns
Iterative Analysis
const chat = await ai.chats.create({
model: 'gemini-2.5-flash',
config: { tools: [{ codeExecution: {} }] }
});
// Step 1: Initial analysis
let response = await chat.sendMessage('Analyze data: [10, 20, 30, 40, 50]');
// Step 2: Follow-up based on results
response = await chat.sendMessage('Now calculate the variance');
// Step 3: Visualization
response = await chat.sendMessage('Create a histogram of this data');Combining with Function Calling
const weatherFunction = {
name: 'get_current_weather',
description: 'Get weather for a city',
parametersJsonSchema: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city']
}
};
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Get weather for NYC, LA, Chicago. Calculate the average temperature.',
config: {
tools: [
{ functionDeclarations: [weatherFunction] },
{ codeExecution: {} }
]
}
});
// Model will:
// 1. Call get_current_weather for each city
// 2. Generate code to calculate average
// 3. Return resultData Transformation Pipeline
const prompt = `
Transform this data:
Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Pipeline:
1. Filter odd numbers
2. Square each number
3. Calculate sum
4. Return result
Use code to process.
`;
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt,
config: { tools: [{ codeExecution: {} }] }
});---
Optimization Tips
1. Clear Instructions
❌ Vague:
contents: 'Analyze this data'✅ Specific:
contents: 'Calculate mean, median, and standard deviation for: [12, 15, 18, 22, 25]'2. Provide Complete Data
const csvData = `...complete dataset...`;
const prompt = `Analyze this CSV data:\n\n${csvData}\n\nCalculate total revenue.`;3. Request Code Explicitly
contents: 'Generate and run code to calculate the factorial of 20'4. Handle Large Datasets
For large data, consider:
- Sampling (analyze subset)
- Aggregation (group by categories)
- Pagination (process in chunks)
---
Troubleshooting
Code Not Executing
Symptom: Response has text but no executableCode
Causes: 1. Code execution not enabled (tools: [{ codeExecution: {} }]) 2. Model decided code wasn't necessary 3. Using gemini-2.5-flash-lite (doesn't support code execution)
Solution: Be explicit in prompt: "Use code to calculate..."
Timeout Errors
Symptom: OUTCOME_FAILED with timeout message
Causes: Computation too complex or data too large
Solution:
- Simplify algorithm
- Reduce data size
- Use more efficient approach
Import Errors
Symptom: ModuleNotFoundError
Causes: Trying to import unavailable package
Solution: Use only available packages (numpy, pandas, matplotlib, seaborn, scipy)
---
References
- Official Docs: https://ai.google.dev/gemini-api/docs/code-execution
- Templates: See
code-execution.tsfor working examples - Available Packages: See "Available Python Packages" section above
Context Caching Guide
Complete guide to using context caching with Google Gemini API to reduce costs by up to 90%.
---
What is Context Caching?
Context caching allows you to cache frequently used content (system instructions, large documents, videos) and reuse it across multiple requests, significantly reducing token costs and improving latency.
---
How It Works
1. Create a cache with your repeated content (documents, videos, system instructions) 2. Set TTL (time-to-live) for cache expiration 3. Reference the cache in subsequent API calls 4. Pay less - cached tokens cost ~90% less than regular input tokens
---
Benefits
Cost Savings
- Cached input tokens: ~90% cheaper than regular tokens
- Output tokens: Same price (not cached)
- Example: 100K token document cached → ~10K token cost equivalent
Performance
- Reduced latency: Cached content is preprocessed
- Faster responses: No need to reprocess large context
- Consistent results: Same context every time
Use Cases
- Large documents analyzed repeatedly
- Long system instructions used across sessions
- Video/audio files queried multiple times
- Consistent conversation context
---
Cache Creation
Basic Cache (SDK)
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const cache = await ai.caches.create({
model: 'gemini-2.5-flash-001', // Must use explicit version!
config: {
displayName: 'my-cache',
systemInstruction: 'You are a helpful assistant.',
contents: 'Large document content here...',
ttl: '3600s', // 1 hour
}
});Cache with Expiration Time
// Set specific expiration time (timezone-aware)
const expirationTime = new Date(Date.now() + 2 * 60 * 60 * 1000); // 2 hours from now
const cache = await ai.caches.create({
model: 'gemini-2.5-flash-001',
config: {
displayName: 'my-cache',
contents: documentText,
expireTime: expirationTime, // Use expireTime instead of ttl
}
});---
TTL (Time-To-Live) Guidelines
Recommended TTL Values
| Use Case | TTL | Reason |
|---|---|---|
| Quick analysis session | 300s (5 min) | Short-lived tasks |
| Extended conversation | 3600s (1 hour) | Standard session length |
| Daily batch processing | 86400s (24 hours) | Reuse across day |
| Long-term analysis | 604800s (7 days) | Maximum allowed |
TTL vs Expiration Time
TTL (time-to-live):
- Relative duration from cache creation
- Format:
"3600s"(string with 's' suffix) - Easy for session-based caching
Expiration Time:
- Absolute timestamp
- Must be timezone-aware Date object
- Precise control over cache lifetime
---
Using a Cache
Generate Content with Cache (SDK)
// Use cache name as model parameter
const response = await ai.models.generateContent({
model: cache.name, // Use cache.name, not original model name
contents: 'Summarize the document'
});
console.log(response.text);Multiple Queries with Same Cache
const queries = [
'What are the key points?',
'Who are the main characters?',
'What is the conclusion?'
];
for (const query of queries) {
const response = await ai.models.generateContent({
model: cache.name,
contents: query
});
console.log(`Q: ${query}`);
console.log(`A: ${response.text}\n`);
}---
Cache Management
Update Cache TTL
// Extend cache lifetime before it expires
await ai.caches.update({
name: cache.name,
config: {
ttl: '7200s' // Extend to 2 hours
}
});List All Caches
const caches = await ai.caches.list();
caches.forEach(cache => {
console.log(`${cache.displayName}: ${cache.name}`);
console.log(`Expires: ${cache.expireTime}`);
});Delete Cache
// Delete when no longer needed
await ai.caches.delete({ name: cache.name });---
Advanced Use Cases
Caching Video Files
import fs from 'fs';
// 1. Upload video
const videoFile = await ai.files.upload({
file: fs.createReadStream('./video.mp4')
});
// 2. Wait for processing
while (videoFile.state.name === 'PROCESSING') {
await new Promise(resolve => setTimeout(resolve, 2000));
videoFile = await ai.files.get({ name: videoFile.name });
}
// 3. Create cache with video
const cache = await ai.caches.create({
model: 'gemini-2.5-flash-001',
config: {
displayName: 'video-cache',
systemInstruction: 'Analyze this video.',
contents: [videoFile],
ttl: '600s'
}
});
// 4. Query video multiple times
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: 'Who are the main people?'
});Caching with System Instructions
const cache = await ai.caches.create({
model: 'gemini-2.5-flash-001',
config: {
displayName: 'legal-expert-cache',
systemInstruction: `
You are a legal expert specializing in contract law.
Always cite relevant sections when making claims.
Use clear, professional language.
`,
contents: largeContractDocument,
ttl: '3600s'
}
});
// System instruction is part of cached context
const response = await ai.models.generateContent({
model: cache.name,
contents: 'Is this contract enforceable?'
});---
Important Notes
Model Version Requirement
⚠️ You MUST use explicit version suffixes when creating caches:
// ✅ CORRECT
model: 'gemini-2.5-flash-001'
// ❌ WRONG (will fail)
model: 'gemini-2.5-flash'Cache Expiration
- Caches are automatically deleted after TTL expires
- Cannot recover expired caches - must recreate
- Update TTL before expiration to extend lifetime
Cost Calculation
Regular request: 100,000 input tokens = 100K token cost
With caching (after cache creation):
- Cached tokens: 100,000 × 0.1 (90% discount) = 10K equivalent cost
- New tokens: 1,000 × 1.0 = 1K cost
- Total: 11K equivalent (89% savings!)Limitations
- Maximum TTL: 7 days (604800s)
- Cache creation costs same as regular tokens (first time only)
- Subsequent uses get 90% discount
- Only input tokens are cached (output tokens never cached)
---
Best Practices
When to Use Caching
✅ Good Use Cases:
- Large documents queried repeatedly (legal docs, research papers)
- Video/audio files analyzed with different questions
- Long system instructions used across many requests
- Consistent context in multi-turn conversations
❌ Bad Use Cases:
- Single-use content (no benefit)
- Frequently changing content
- Short content (<1000 tokens) - minimal savings
- Content used only once per day (cache might expire)
Optimization Tips
1. Cache Early: Create cache at session start 2. Extend TTL: Update before expiration if still needed 3. Monitor Usage: Track how often cache is reused 4. Clean Up: Delete unused caches to avoid clutter 5. Combine Features: Use caching with code execution, grounding for powerful workflows
Cache Naming
Use descriptive displayName for easy identification:
// ✅ Good names
displayName: 'financial-report-2024-q3'
displayName: 'legal-contract-acme-corp'
displayName: 'video-analysis-project-x'
// ❌ Vague names
displayName: 'cache1'
displayName: 'test'---
Troubleshooting
"Invalid model name" Error
Problem: Using gemini-2.5-flash instead of gemini-2.5-flash-001
Solution: Always use explicit version suffix:
model: 'gemini-2.5-flash-001' // CorrectCache Expired Error
Problem: Trying to use cache after TTL expired
Solution: Check expiration before use or extend TTL proactively:
const cache = await ai.caches.get({ name: cacheName });
if (new Date(cache.expireTime) < new Date()) {
// Cache expired, recreate it
cache = await ai.caches.create({ ... });
}High Costs Despite Caching
Problem: Creating new cache for each request
Solution: Reuse the same cache across multiple requests:
// ❌ Wrong - creates new cache each time
for (const query of queries) {
const cache = await ai.caches.create({ ... }); // Expensive!
const response = await ai.models.generateContent({ model: cache.name, ... });
}
// ✅ Correct - create once, use many times
const cache = await ai.caches.create({ ... }); // Create once
for (const query of queries) {
const response = await ai.models.generateContent({ model: cache.name, ... });
}---
References
- Official Docs: https://ai.google.dev/gemini-api/docs/caching
- Cost Optimization: See "Cost Optimization" in main SKILL.md
- Templates: See
context-caching.tsfor working examples
Function Calling Patterns
Complete guide to implementing function calling (tool use) with Gemini API.
---
Basic Pattern
1. Define function declarations 2. Send request with tools 3. Check if model wants to call functions 4. Execute functions 5. Send results back to model 6. Get final response
---
Function Declaration Schema
{
name: string, // Function name (no spaces)
description: string, // What the function does
parametersJsonSchema: { // Subset of OpenAPI schema
type: 'object',
properties: {
[paramName]: {
type: string, // 'string' | 'number' | 'boolean' | 'array' | 'object'
description: string, // Parameter description
enum?: string[] // Optional: allowed values
}
},
required: string[] // Required parameter names
}
}---
Calling Modes
- AUTO (default): Model decides when to call
- ANY: Force at least one function call
- NONE: Disable function calling
---
Parallel vs Compositional
Parallel: Independent functions run simultaneously Compositional: Sequential dependencies (A → B → C)
Gemini automatically detects which pattern to use.
---
Official Docs
https://ai.google.dev/gemini-api/docs/function-calling
Generation Configuration Reference
Complete reference for all generation parameters.
---
All Parameters
config: {
temperature: number, // 0.0-2.0 (default: 1.0)
topP: number, // 0.0-1.0 (default: 0.95)
topK: number, // 1-100+ (default: 40)
maxOutputTokens: number, // 1-65536
stopSequences: string[], // Stop at these strings
responseMimeType: string, // 'text/plain' | 'application/json'
candidateCount: number, // Usually 1
thinkingConfig: {
thinkingBudget: number // Max thinking tokens
}
}---
Parameter Guidelines
temperature
- 0.0: Deterministic, focused
- 1.0: Balanced (default)
- 2.0: Very creative, random
topP (nucleus sampling)
- 0.95: Default, good balance
- Lower = more focused
topK
- 40: Default
- Higher = more diversity
maxOutputTokens
- Always set this to prevent excessive generation
- Max: 65,536 tokens
---
Use Cases
Factual tasks: temperature=0.0, topP=0.8 Creative tasks: temperature=1.2, topP=0.95 Code generation: temperature=0.3, topP=0.9
---
Official Docs
https://ai.google.dev/gemini-api/docs/models/generative-models#model-parameters
Grounding with Google Search Guide
Complete guide to using grounding with Google Search to connect Gemini models to real-time web information, reducing hallucinations and providing verifiable, up-to-date responses.
---
What is Grounding?
Grounding connects the Gemini model to Google Search, allowing it to:
- Access real-time information beyond training cutoff
- Reduce hallucinations with fact-checked web sources
- Provide citations and source URLs
- Answer questions about current events
- Verify information against the web
---
How It Works
1. Model receives query (e.g., "Who won Euro 2024?") 2. Model determines if current information is needed 3. Performs Google Search automatically 4. Processes search results (web pages, snippets) 5. Incorporates findings into response 6. Provides citations with source URLs
---
Two Grounding APIs
1. Google Search (googleSearch) - Recommended for Gemini 2.5
Simple, automatic grounding:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Who won the euro 2024?',
config: {
tools: [{ googleSearch: {} }]
}
});Features:
- Simple configuration (empty object)
- Automatic search when model needs current info
- Available on all Gemini 2.5 models
- Recommended for new projects
2. Google Search Retrieval (googleSearchRetrieval) - Legacy for Gemini 1.5
Dynamic threshold control:
import { DynamicRetrievalConfigMode } from '@google/genai';
const response = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: 'Who won the euro 2024?',
config: {
tools: [{
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: DynamicRetrievalConfigMode.MODE_DYNAMIC,
dynamicThreshold: 0.7 // Search only if confidence < 70%
}
}
}]
}
});Features:
- Control when searches happen via threshold
- Used with Gemini 1.5 models
- More configuration options
Recommendation: Use googleSearch for Gemini 2.5 models (simpler and newer).
---
Basic Usage
SDK Approach (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: 'What are the latest developments in AI?',
config: {
tools: [{ googleSearch: {} }]
}
});
console.log(response.text);
// Check if grounding was used
if (response.candidates[0].groundingMetadata) {
console.log('✓ Search performed');
console.log('Sources:', response.candidates[0].groundingMetadata.webPages);
} else {
console.log('✓ Answered from model knowledge');
}Fetch Approach (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: 'What are the latest developments in AI?' }] }],
tools: [{ google_search: {} }]
}),
}
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);---
Grounding Metadata
Structure
{
groundingMetadata: {
// Search queries performed
searchQueries: [
{ text: "euro 2024 winner" }
],
// Web pages retrieved
webPages: [
{
url: "https://example.com/euro-2024",
title: "UEFA Euro 2024 Results",
snippet: "Spain won UEFA Euro 2024..."
}
],
// Citations (inline references)
citations: [
{
startIndex: 42,
endIndex: 47,
uri: "https://example.com/euro-2024"
}
],
// Retrieval queries (alternative search terms)
retrievalQueries: [
{ query: "who won euro 2024 final" }
]
}
}Accessing Metadata
if (response.candidates[0].groundingMetadata) {
const metadata = response.candidates[0].groundingMetadata;
// Display sources
console.log('Sources:');
metadata.webPages?.forEach((page, i) => {
console.log(`${i + 1}. ${page.title}`);
console.log(` ${page.url}`);
});
// Display citations
console.log('\nCitations:');
metadata.citations?.forEach((citation) => {
console.log(`Position ${citation.startIndex}-${citation.endIndex}: ${citation.uri}`);
});
}---
When to Use Grounding
✅ Good Use Cases
Current Events:
'What happened in the news today?'
'Who won the latest sports championship?'
'What are the current stock prices?'Recent Developments:
'What are the latest AI breakthroughs?'
'What are recent changes in climate policy?'Fact-Checking:
'Is this claim true: [claim]?'
'What does the latest research say about [topic]?'Real-Time Data:
'What is the current weather in Tokyo?'
'What are today's cryptocurrency prices?'❌ Not Recommended For
General Knowledge:
'What is the capital of France?' // Model knows this
'How does photosynthesis work?' // Stable knowledgeMathematical Calculations:
'What is 15 * 27?' // Use code execution insteadCreative Tasks:
'Write a poem about autumn' // No search neededCode Generation:
'Write a sorting algorithm' // Internal reasoning sufficient---
Chat with Grounding
Multi-Turn Conversations
const chat = await ai.chats.create({
model: 'gemini-2.5-flash',
config: {
tools: [{ googleSearch: {} }]
}
});
// First question
let response = await chat.sendMessage('What are the latest quantum computing developments?');
console.log(response.text);
// Display sources
if (response.candidates[0].groundingMetadata) {
const sources = response.candidates[0].groundingMetadata.webPages || [];
console.log(`\nSources: ${sources.length} web pages`);
sources.forEach(s => console.log(`- ${s.title}: ${s.url}`));
}
// Follow-up question
response = await chat.sendMessage('Which company made the biggest breakthrough?');
console.log('\n' + response.text);---
Combining with Other Features
Grounding + Function Calling
const weatherFunction = {
name: 'get_current_weather',
description: 'Get 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: {} }, // For finding Euro 2024 winner
{ functionDeclarations: [weatherFunction] } // For weather lookup
]
}
});
// Model will:
// 1. Use Google Search to find Euro 2024 winner (Madrid/Spain)
// 2. Call get_current_weather function with the city
// 3. Combine both results in responseGrounding + Code Execution
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Find the current stock prices for AAPL, GOOGL, MSFT and calculate their average',
config: {
tools: [
{ googleSearch: {} }, // For current stock prices
{ codeExecution: {} } // For averaging
]
}
});
// Model will:
// 1. Search for current stock prices
// 2. Generate code to calculate average
// 3. Execute code with the found prices
// 4. Return result with citations---
Checking Grounding Usage
Determine if Search Was Performed
const queries = [
'What is 2+2?', // Should NOT use search
'What happened in the news today?' // Should use search
];
for (const query of queries) {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: query,
config: { tools: [{ googleSearch: {} }] }
});
console.log(`Query: ${query}`);
console.log(`Search used: ${response.candidates[0].groundingMetadata ? 'YES' : 'NO'}`);
console.log();
}Output:
Query: What is 2+2?
Search used: NO
Query: What happened in the news today?
Search used: YES---
Dynamic Retrieval (Gemini 1.5)
Threshold-Based Grounding
const response = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: 'Who won the euro 2024?',
config: {
tools: [{
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: DynamicRetrievalConfigMode.MODE_DYNAMIC,
dynamicThreshold: 0.7 // Search only if confidence < 70%
}
}
}]
}
});
if (!response.candidates[0].groundingMetadata) {
console.log('Model answered from knowledge (confidence >= 70%)');
} else {
console.log('Search performed (confidence < 70%)');
}How It Works:
- Model evaluates confidence in its internal knowledge
- If confidence < threshold → performs search
- If confidence >= threshold → uses internal knowledge
Threshold Values:
0.0: Never search (always use internal knowledge)0.5: Search if moderately uncertain0.7: Search if somewhat uncertain (good default)1.0: Always search
---
Best Practices
✅ Do
1. Check Metadata: Always verify if grounding was used
if (response.candidates[0].groundingMetadata) { ... }2. Display Citations: Show sources to users for transparency
metadata.webPages.forEach(page => {
console.log(`Source: ${page.title} (${page.url})`);
});3. Use Specific Queries: Better search results with clear questions
// ✅ Good: "What are Microsoft's Q3 2024 earnings?"
// ❌ Vague: "Tell me about Microsoft"4. Combine Features: Use with function calling/code execution for powerful workflows
5. Handle Missing Metadata: Not all queries trigger search
const sources = response.candidates[0].groundingMetadata?.webPages || [];❌ Don't
1. Don't Assume Search Always Happens: Model decides when to search 2. Don't Ignore Citations: They're crucial for fact-checking 3. Don't Use for Stable Knowledge: Waste of resources for unchanging facts 4. Don't Expect Perfect Coverage: Not all information is on the web
---
Cost and Performance
Cost Considerations
- Added Latency: Search takes 1-3 seconds typically
- Token Costs: Retrieved content counts as input tokens
- Rate Limits: Subject to API rate limits
Optimization
Use Dynamic Threshold (Gemini 1.5):
dynamicThreshold: 0.7 // Higher = more searches, lower = fewer searchesCache Grounding Results (if appropriate):
const cache = await ai.caches.create({
model: 'gemini-2.5-flash-001',
config: {
displayName: 'grounding-cache',
tools: [{ googleSearch: {} }],
contents: 'Initial query that triggers search...',
ttl: '3600s'
}
});
// Subsequent queries reuse cached grounding results---
Troubleshooting
Grounding Not Working
Symptom: No groundingMetadata in response
Causes: 1. Grounding not enabled: tools: [{ googleSearch: {} }] 2. Model decided search wasn't needed (query answerable from knowledge) 3. Google Cloud project not configured (grounding requires GCP)
Solution:
- Verify
toolsconfiguration - Use queries requiring current information
- Set up Google Cloud project
Poor Search Quality
Symptom: Irrelevant sources or wrong information
Causes:
- Vague query
- Search terms ambiguous
- Recent events not yet indexed
Solution:
- Make queries more specific
- Include context in prompt
- Verify search queries in metadata
Citations Missing
Symptom: groundingMetadata present but no citations
Explanation: Citations are inline references - they may not always be present if model doesn't directly quote sources.
Solution: Check webPages instead for full source list
---
Important Requirements
Google Cloud Project
⚠️ Grounding requires a Google Cloud project, not just an API key.
Setup: 1. Create Google Cloud project 2. Enable Generative Language API 3. Configure billing 4. Use API key from that project
Error if Missing:
Error: Grounding requires Google Cloud project configurationModel Support
✅ Supported:
- All Gemini 2.5 models (
googleSearch) - All Gemini 1.5 models (
googleSearchRetrieval)
❌ Not Supported:
- Gemini 1.0 models
---
Examples
News Summary
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Summarize today's top 3 technology news headlines',
config: { tools: [{ googleSearch: {} }] }
});
console.log(response.text);
metadata.webPages?.forEach((page, i) => {
console.log(`${i + 1}. ${page.title}: ${page.url}`);
});Fact Verification
const claim = "The Earth is flat";
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: `Is this claim true: "${claim}"? Use reliable sources to verify.`,
config: { tools: [{ googleSearch: {} }] }
});
console.log(response.text);Market Research
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'What are the current trends in electric vehicle adoption in 2024?',
config: { tools: [{ googleSearch: {} }] }
});
console.log(response.text);
console.log('\nSources:');
metadata.webPages?.forEach(page => {
console.log(`- ${page.title}`);
});---
References
- Official Docs: https://ai.google.dev/gemini-api/docs/grounding
- Google Search Docs: https://ai.google.dev/gemini-api/docs/google-search
- Templates: See
grounding-search.tsfor working examples - Combined Features: See
combined-advanced.tsfor integration patterns
Gemini Models Guide (2025)
Last Updated: 2025-11-19 (Gemini 3 preview release)
---
Gemini 3 Series (Preview - November 2025)
gemini-3-pro-preview
Model ID: gemini-3-pro-preview
Status: 🆕 Preview release (November 18, 2025)
Context Windows:
- Input: TBD (documentation pending)
- Output: TBD (documentation pending)
Description: Google's newest and most intelligent AI model with state-of-the-art reasoning and multimodal understanding. Outperforms Gemini 2.5 Pro on every major AI benchmark.
Best For:
- Most complex reasoning tasks
- Advanced multimodal analysis (images, videos, PDFs, audio)
- Benchmark-critical applications
- Cutting-edge projects requiring latest capabilities
- Tasks requiring absolute best quality
Features:
- ✅ Enhanced multimodal understanding
- ✅ Function calling
- ✅ Streaming
- ✅ System instructions
- ✅ JSON mode
- TBD Thinking mode (documentation pending)
Knowledge Cutoff: TBD
Pricing: Preview pricing (likely higher than 2.5 Pro)
⚠️ Preview Status: Use for evaluation and testing. Consider gemini-2.5-pro for production-critical decisions until Gemini 3 reaches stable general availability.
New Capabilities:
- Record-breaking benchmark performance
- Enhanced generative UI responses
- Advanced coding capabilities (Google Antigravity integration)
- State-of-the-art multimodal understanding
---
Current Production Models (Gemini 2.5 - Stable)
gemini-2.5-pro
Model ID: gemini-2.5-pro
Context Windows:
- Input: 1,048,576 tokens (NOT 2M!)
- Output: 65,536 tokens
Description: State-of-the-art thinking model capable of reasoning over complex problems in code, math, and STEM.
Best For:
- Complex reasoning tasks
- Advanced code generation and optimization
- Mathematical problem-solving
- Multi-step logical analysis
- STEM applications
Features:
- ✅ Thinking mode (enabled by default)
- ✅ Function calling
- ✅ Multimodal (text, images, video, audio, PDFs)
- ✅ Streaming
- ✅ System instructions
- ✅ JSON mode
Knowledge Cutoff: January 2025
Pricing: Higher cost, use for tasks requiring best quality
---
gemini-2.5-flash
Model ID: gemini-2.5-flash
Context Windows:
- Input: 1,048,576 tokens
- Output: 65,536 tokens
Description: Best price-performance model for large-scale processing, low-latency, and high-volume tasks.
Best For:
- General-purpose AI applications
- High-volume API calls
- Agentic workflows
- Cost-sensitive applications
- Production workloads
Features:
- ✅ Thinking mode (enabled by default)
- ✅ Function calling
- ✅ Multimodal (text, images, video, audio, PDFs)
- ✅ Streaming
- ✅ System instructions
- ✅ JSON mode
Knowledge Cutoff: January 2025
Pricing: Best price-performance ratio
⭐ Recommended: This is the default choice for most applications
---
gemini-2.5-flash-lite
Model ID: gemini-2.5-flash-lite
Context Windows:
- Input: 1,048,576 tokens
- Output: 65,536 tokens
Description: Most cost-efficient and fastest 2.5 model, optimized for high throughput.
Best For:
- High-throughput applications
- Simple text generation
- Cost-critical use cases
- Speed-prioritized workloads
Features:
- ✅ Thinking mode (enabled by default)
- ❌ NO function calling (critical limitation!)
- ✅ Multimodal (text, images, video, audio, PDFs)
- ✅ Streaming
- ✅ System instructions
- ✅ JSON mode
Knowledge Cutoff: January 2025
Pricing: Lowest cost
⚠️ Important: Flash-Lite does NOT support function calling! Use Flash or Pro if you need tool use.
---
Model Comparison Matrix
| Feature | Pro | Flash | Flash-Lite |
|---|---|---|---|
| Thinking Mode | ✅ Default ON | ✅ Default ON | ✅ Default ON |
| Function Calling | ✅ Yes | ✅ Yes | ❌ NO |
| Multimodal | ✅ Full | ✅ Full | ✅ Full |
| Streaming | ✅ Yes | ✅ Yes | ✅ Yes |
| Input Tokens | 1,048,576 | 1,048,576 | 1,048,576 |
| Output Tokens | 65,536 | 65,536 | 65,536 |
| Reasoning Quality | Best | Good | Basic |
| Speed | Moderate | Fast | Fastest |
| Cost | Highest | Medium | Lowest |
---
Previous Generation Models (Still Available)
Gemini 2.0 Flash
Model ID: gemini-2.0-flash
Context: 1M input / 65K output tokens
Status: Previous generation, 2.5 Flash recommended instead
Gemini 1.5 Pro
Model ID: gemini-1.5-pro
Context: 2M input tokens (this is the ONLY model with 2M!)
Status: Older model, 2.5 models recommended
---
Context Window Clarification
⚠️ CRITICAL CORRECTION:
ACCURATE: Gemini 2.5 models support 1,048,576 input tokens (approximately 1 million)
INACCURATE: Claiming Gemini 2.5 has 2M token context window
WHY THIS MATTERS:
- Gemini 1.5 Pro (older model) had 2M tokens
- Gemini 2.5 models (current) have ~1M tokens
- This is a common mistake that causes confusion!
This skill prevents this error by providing accurate information.
---
Model Selection Guide
Use gemini-2.5-pro When:
- ✅ Complex reasoning required (math, logic, STEM)
- ✅ Advanced code generation and optimization
- ✅ Multi-step problem-solving
- ✅ Quality is more important than cost
- ✅ Tasks require maximum capability
Use gemini-2.5-flash When:
- ✅ General-purpose AI applications
- ✅ High-volume production workloads
- ✅ Function calling required
- ✅ Agentic workflows
- ✅ Good balance of cost and quality needed
- ⭐ Recommended default choice
Use gemini-2.5-flash-lite When:
- ✅ Simple text generation only
- ✅ No function calling needed
- ✅ High throughput required
- ✅ Cost is primary concern
- ⚠️ Only if you don't need function calling!
---
Common Mistakes
❌ Mistake 1: Using Wrong Model Name
// WRONG - old model name
model: 'gemini-1.5-pro'
// CORRECT - current model
model: 'gemini-2.5-flash'❌ Mistake 2: Claiming 2M Context for 2.5 Models
// WRONG ASSUMPTION
// "Gemini 2.5 has 2M token context window"
// CORRECT
// Gemini 2.5 has 1,048,576 input tokens
// Only Gemini 1.5 Pro (older) had 2M❌ Mistake 3: Using Flash-Lite for Function Calling
// WRONG - Flash-Lite doesn't support function calling!
model: 'gemini-2.5-flash-lite',
config: {
tools: [{ functionDeclarations: [...] }] // This will FAIL
}
// CORRECT
model: 'gemini-2.5-flash', // or gemini-2.5-pro
config: {
tools: [{ functionDeclarations: [...] }]
}---
Rate Limits (Free vs Paid)
Free Tier
- 15 RPM (requests per minute)
- 1M TPM (tokens per minute)
- 1,500 RPD (requests per day)
Paid Tier
- 360 RPM
- 4M TPM
- Unlimited daily requests
Tip: Monitor your usage and implement rate limiting to stay within quotas.
---
Official Documentation
- Models Overview: https://ai.google.dev/gemini-api/docs/models
- Gemini 2.5 Announcement: https://developers.googleblog.com/en/gemini-2-5-thinking-model-updates/
- Pricing: https://ai.google.dev/pricing
---
Production Tip: Always use gemini-2.5-flash as your default unless you specifically need Pro's advanced reasoning or want to minimize cost with Flash-Lite (and don't need function calling).
Multimodal Guide
Complete guide to using images, video, audio, and PDFs with Gemini API.
---
Supported Formats
Images
- JPEG, PNG, WebP, HEIC, HEIF
- Max size: 20MB
Video
- MP4, MPEG, MOV, AVI, FLV, MPG, WebM, WMV
- Max size: 2GB
- Max length (inline): 2 minutes
Audio
- MP3, WAV, FLAC, AAC, OGG, OPUS
- Max size: 20MB
PDFs
- Max size: 30MB
- Text-based PDFs work best
---
Usage Pattern
contents: [
{
parts: [
{ text: 'Your question' },
{
inlineData: {
data: base64EncodedData,
mimeType: 'image/jpeg' // or video/mp4, audio/mp3, application/pdf
}
}
]
}
]---
Best Practices
- Use specific, detailed prompts
- Combine multiple modalities in one request
- For large files (>2GB), use File API (Phase 2)
---
Official Docs
https://ai.google.dev/gemini-api/docs/vision
SDK Migration Guide
From: @google/generative-ai (DEPRECATED) To: @google/genai (CURRENT)
Deadline: November 30, 2025 (deprecated SDK sunset)
---
Why Migrate?
The @google/generative-ai SDK is deprecated and will stop receiving updates on November 30, 2025.
The new @google/genai SDK:
- ✅ Works with both Gemini API and Vertex AI
- ✅ Supports Gemini 2.0+ features
- ✅ Better TypeScript support
- ✅ Unified API across platforms
- ✅ Active development and updates
---
Migration Steps
1. Update Package
# Remove deprecated SDK
npm uninstall @google/generative-ai
# Install current SDK
npm install @google/genai@1.27.02. Update Imports
Old (DEPRECATED):
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(apiKey);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });New (CURRENT):
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey });
// No need to get model separately3. Update API Calls
Old:
const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();New:
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt
});
const text = response.text;4. Update Streaming
Old:
const result = await model.generateContentStream(prompt);
for await (const chunk of result.stream) {
console.log(chunk.text());
}New:
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: prompt
});
for await (const chunk of response) {
console.log(chunk.text);
}5. Update Chat
Old:
const chat = model.startChat({
history: []
});
const result = await chat.sendMessage(message);
const response = await result.response;
console.log(response.text());New:
const chat = await ai.models.createChat({
model: 'gemini-2.5-flash',
history: []
});
const response = await chat.sendMessage(message);
console.log(response.text);---
Complete Before/After Example
Before (Deprecated SDK)
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
// Generate
const result = await model.generateContent('Hello');
const response = await result.response;
console.log(response.text());
// Stream
const streamResult = await model.generateContentStream('Write a story');
for await (const chunk of streamResult.stream) {
console.log(chunk.text());
}
// Chat
const chat = model.startChat();
const chatResult = await chat.sendMessage('Hi');
const chatResponse = await chatResult.response;
console.log(chatResponse.text());After (Current SDK)
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Generate
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: 'Hello'
});
console.log(response.text);
// Stream
const streamResponse = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: 'Write a story'
});
for await (const chunk of streamResponse) {
console.log(chunk.text);
}
// Chat
const chat = await ai.models.createChat({ model: 'gemini-2.5-flash' });
const chatResponse = await chat.sendMessage('Hi');
console.log(chatResponse.text);---
Key Differences
| Aspect | Old SDK | New SDK |
|---|---|---|
| Package | @google/generative-ai | @google/genai |
| Class | GoogleGenerativeAI | GoogleGenAI |
| Model Init | genAI.getGenerativeModel() | Specify in each call |
| Text Access | response.text() (method) | response.text (property) |
| Stream Iteration | result.stream | Direct iteration |
| Chat Creation | model.startChat() | ai.models.createChat() |
---
Troubleshooting
Error: "Cannot find module '@google/generative-ai'"
Cause: Old import statement after migration
Solution: Update all imports to @google/genai
Error: "Property 'text' does not exist"
Cause: Using response.text() (method) instead of response.text (property)
Solution: Remove parentheses: response.text not response.text()
Error: "generateContent is not a function"
Cause: Trying to call methods on old model object
Solution: Use ai.models.generateContent() directly
---
Automated Migration Script
# Find all files using old SDK
rg "@google/generative-ai" --type ts
# Replace import statements
find . -name "*.ts" -exec sed -i 's/@google\/generative-ai/@google\/genai/g' {} +
# Replace class name
find . -name "*.ts" -exec sed -i 's/GoogleGenerativeAI/GoogleGenAI/g' {} +⚠️ Note: This script handles imports but NOT API changes. Manual review required!
---
Official Resources
- Migration Guide: https://ai.google.dev/gemini-api/docs/migrate-to-genai
- New SDK Docs: https://github.com/googleapis/js-genai
- Deprecated SDK: https://github.com/google-gemini/deprecated-generative-ai-js
---
Deadline Reminder: November 30, 2025 - Deprecated SDK sunset
Streaming Patterns
Complete guide to implementing streaming with Gemini API.
---
SDK Approach (Async Iteration)
const response = await ai.models.generateContentStream({
model: 'gemini-2.5-flash',
contents: 'Write a story'
});
for await (const chunk of response) {
process.stdout.write(chunk.text);
}Pros: Simple, automatic parsing Cons: Requires Node.js or compatible runtime
---
Fetch Approach (SSE Parsing)
const response = await fetch(
'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent',
{ /* ... */ }
);
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.startsWith('data: ')) continue;
const data = JSON.parse(line.slice(6));
const text = data.candidates[0]?.content?.parts[0]?.text;
if (text) process.stdout.write(text);
}
}Pros: Works in any environment Cons: Manual SSE parsing required
---
SSE Format
data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}
data: {"candidates":[{"content":{"parts":[{"text":" world"}]}}]}
data: [DONE]---
Best Practices
- Always use
streamGenerateContentendpoint - Handle incomplete chunks in buffer
- Skip empty lines and
[DONE]markers - Use streaming for better UX on long responses
---
Official Docs
https://ai.google.dev/gemini-api/docs/streaming
Thinking Mode Guide
Complete guide to thinking mode in Gemini 2.5 models.
---
What is Thinking Mode?
Gemini 2.5 models "think" internally before responding, improving accuracy on complex tasks.
Key Points:
- ✅ Always enabled on 2.5 models (cannot disable)
- ✅ Transparent (you don't see the thinking process)
- ✅ Configurable thinking budget
- ✅ Improves reasoning quality
---
Configuration
config: {
thinkingConfig: {
thinkingBudget: 8192 // Max tokens for internal reasoning
}
}---
When to Increase Budget
✅ Complex math/logic problems ✅ Multi-step reasoning ✅ Code optimization ✅ Detailed analysis
---
When Default is Fine
⏺️ Simple questions ⏺️ Creative writing ⏺️ Translation ⏺️ Summarization
---
Model Comparison
- gemini-2.5-pro: Best for complex reasoning
- gemini-2.5-flash: Good balance
- gemini-2.5-flash-lite: Basic thinking
---
Official Docs
https://ai.google.dev/gemini-api/docs/thinking
Top Errors and Solutions
22 common Gemini API errors with solutions (Phase 1 + Phase 2).
---
1. Using Deprecated SDK
Error: Cannot find module '@google/generative-ai'
Cause: Using old SDK after migration
Solution: Install @google/genai instead
---
2. Wrong Context Window Claims
Error: Input exceeds model capacity
Cause: Assuming 2M tokens for Gemini 2.5
Solution: Gemini 2.5 has 1,048,576 input tokens (NOT 2M!)
---
3. Model Not Found
Error: models/gemini-3.0-flash is not found
Cause: Wrong model name
Solution: Use: gemini-2.5-pro, gemini-2.5-flash, or gemini-2.5-flash-lite
---
4. Function Calling on Flash-Lite
Error: Function calling not working
Cause: Flash-Lite doesn't support function calling
Solution: Use gemini-2.5-flash or gemini-2.5-pro
---
5. Invalid API Key (401)
Error: API key not valid
Cause: Missing or wrong GEMINI_API_KEY
Solution: Set environment variable correctly
---
6. Rate Limit Exceeded (429)
Error: Resource has been exhausted
Cause: Too many requests
Solution: Implement exponential backoff
---
7. Streaming Parse Errors
Error: Invalid JSON in SSE stream
Cause: Incomplete chunk parsing
Solution: Use buffer to handle partial chunks
---
8. Multimodal Format Errors
Error: Invalid base64 or MIME type
Cause: Wrong image encoding
Solution: Use correct base64 encoding and MIME type
---
9. Context Length Exceeded
Error: Request payload size exceeds the limit
Cause: Input too large
Solution: Reduce input size (max 1,048,576 tokens)
---
10. Chat Not Working with Fetch
Error: No chat helper available
Cause: Chat helpers are SDK-only
Solution: Manually manage conversation history or use SDK
---
11. Thinking Mode Not Supported
Error: Trying to disable thinking mode
Cause: Thinking mode always enabled on 2.5
Solution: You can only configure budget, not disable
---
12. Parameter Conflicts
Error: Unsupported parameters
Cause: Using wrong config options
Solution: Use only supported parameters (see generation-config.md)
---
13. System Instruction Placement
Error: System instruction not working
Cause: Placed inside contents array
Solution: Place at top level, not in contents
---
14. Token Counting Errors
Error: Unexpected token usage
Cause: Multimodal inputs use more tokens
Solution: Images/video/audio count toward token limit
---
15. Parallel Function Call Errors
Error: Functions not executing in parallel
Cause: Dependencies between functions
Solution: Gemini auto-detects; ensure functions are independent
---
Phase 2 Errors
16. Invalid Model Version for Caching
Error: Invalid model name for caching
Cause: Using gemini-2.5-flash instead of gemini-2.5-flash-001
Solution: Must use explicit version suffix when creating caches
// ✅ Correct
model: 'gemini-2.5-flash-001'
// ❌ Wrong
model: 'gemini-2.5-flash'Source: https://ai.google.dev/gemini-api/docs/caching
---
17. Cache Expired or Not Found
Error: Cache not found or Cache expired
Cause: Trying to use cache after TTL expiration
Solution: Check expiration before use or recreate cache
const cache = await ai.caches.get({ name: cacheName });
if (new Date(cache.expireTime) < new Date()) {
// Recreate cache
cache = await ai.caches.create({ ... });
}---
18. Cannot Update Expired Cache TTL
Error: Cannot update expired cache
Cause: Trying to extend TTL after cache already expired
Solution: Update TTL before expiration or create new cache
// Update TTL before expiration
await ai.caches.update({
name: cache.name,
config: { ttl: '7200s' }
});---
19. Code Execution Timeout
Error: Execution timed out after 30 seconds with OUTCOME_FAILED
Cause: Python code taking too long to execute
Solution: Simplify computation or reduce data size
// Check outcome before using results
if (part.codeExecutionResult?.outcome === 'OUTCOME_FAILED') {
console.error('Execution failed:', part.codeExecutionResult.output);
}Source: https://ai.google.dev/gemini-api/docs/code-execution
---
20. Python Package Not Available
Error: ModuleNotFoundError: No module named 'requests'
Cause: Trying to import package not in sandbox
Solution: Use only available packages (numpy, pandas, matplotlib, seaborn, scipy)
Available Packages:
- Standard library: math, statistics, json, csv, datetime
- Data science: numpy, pandas, scipy
- Visualization: matplotlib, seaborn
---
21. Code Execution on Flash-Lite
Error: Code execution not working
Cause: gemini-2.5-flash-lite doesn't support code execution
Solution: Use gemini-2.5-flash or gemini-2.5-pro
// ✅ Correct
model: 'gemini-2.5-flash' // Supports code execution
// ❌ Wrong
model: 'gemini-2.5-flash-lite' // NO code execution support---
22. Grounding Requires Google Cloud Project
Error: Grounding requires Google Cloud project configuration
Cause: Using API key not associated with GCP project
Solution: Set up Google Cloud project and enable Generative Language API
Steps: 1. Create Google Cloud project 2. Enable Generative Language API 3. Configure billing 4. Use API key from that project
Source: https://ai.google.dev/gemini-api/docs/grounding
---
Quick Debugging Checklist
Phase 1 (Core)
- [ ] Using @google/genai (NOT @google/generative-ai)
- [ ] Model name is gemini-2.5-pro/flash/flash-lite
- [ ] API key is set correctly
- [ ] Input under 1,048,576 tokens
- [ ] Not using Flash-Lite for function calling
- [ ] System instruction at top level
- [ ] Streaming endpoint is streamGenerateContent
- [ ] MIME types are correct for multimodal
Phase 2 (Advanced)
- [ ] Caching: Using explicit model version (e.g., gemini-2.5-flash-001)
- [ ] Caching: Cache not expired (check expireTime)
- [ ] Code Execution: Not using Flash-Lite
- [ ] Code Execution: Using only available Python packages
- [ ] Grounding: Google Cloud project configured
- [ ] Grounding: Checking groundingMetadata for search results
#!/bin/bash
# Check @google/genai package version and warn about deprecated SDK
# Usage: ./scripts/check-versions.sh
echo "🔍 Checking Gemini API SDK versions..."
echo ""
# Check if package.json exists
if [ ! -f "package.json" ]; then
echo "❌ No package.json found in current directory"
exit 1
fi
# Check for deprecated SDK
if grep -q "@google/generative-ai" package.json; then
echo "⚠️ WARNING: DEPRECATED SDK DETECTED!"
echo ""
echo " Package: @google/generative-ai"
echo " Status: DEPRECATED (sunset Nov 30, 2025)"
echo ""
echo " Action required:"
echo " 1. npm uninstall @google/generative-ai"
echo " 2. npm install @google/genai@1.27.0"
echo " 3. Update imports (see sdk-migration-guide.md)"
echo ""
fi
# Check for current SDK
if grep -q "@google/genai" package.json; then
# Get installed version
INSTALLED_VERSION=$(npm list @google/genai --depth=0 2>/dev/null | grep @google/genai | sed 's/.*@//' | sed 's/ .*//')
RECOMMENDED_VERSION="1.27.0"
echo "✅ Current SDK installed: @google/genai"
echo " Installed version: $INSTALLED_VERSION"
echo " Recommended version: $RECOMMENDED_VERSION"
echo ""
# Check if version matches recommendation
if [ "$INSTALLED_VERSION" != "$RECOMMENDED_VERSION" ]; then
echo "ℹ️ Consider updating to recommended version:"
echo " npm install @google/genai@$RECOMMENDED_VERSION"
echo ""
fi
else
echo "❌ @google/genai not found in package.json"
echo ""
echo " Install with:"
echo " npm install @google/genai@1.27.0"
echo ""
fi
# Check Node.js version
NODE_VERSION=$(node -v | sed 's/v//')
REQUIRED_NODE="18.0.0"
echo "Node.js version: $NODE_VERSION"
echo "Required: >= $REQUIRED_NODE"
echo ""
# Summary
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Summary:"
echo ""
if grep -q "@google/generative-ai" package.json; then
echo "❌ Migration needed: Remove deprecated SDK"
elif grep -q "@google/genai" package.json; then
echo "✅ Using current SDK (@google/genai)"
else
echo "❌ Gemini SDK not installed"
fi
echo ""
echo "For migration help, see:"
echo " references/sdk-migration-guide.md"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"