| name | gemini-best-practices |
| description | Review and fix Gemini API usage against Google's official best practices. Use when modifying src/core/gemini.ts, adding new API calls, or auditing Gemini integration quality. |
| user-invocable | true |
| disable-model-invocation | false |
| paths | ["src/core/gemini.ts","src/core/fileSearch.ts","src/core/tools.ts"] |
Gemini API Best Practices
When reviewing or modifying Gemini API integration code, ensure compliance with Google's official best practices from google-gemini/gemini-skills.
SDK and Package
- Correct SDK:
@google/genai (npm)
- NEVER use deprecated:
@google/generative-ai (old package)
- Prefer environment variables for API keys over hard-coding
Safety Settings
All API calls (generateContent, generateContentStream, chats.create) MUST include safetySettings in the config:
import { HarmCategory, HarmBlockThreshold, type SafetySetting } from "@google/genai";
const DEFAULT_SAFETY_SETTINGS: SafetySetting[] = [
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE },
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE },
{ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE },
{ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE },
];
Response Validation (finishReason)
Always check finishReason on response candidates:
SAFETY - Response blocked by safety filters; inform user to rephrase
RECITATION - Blocked due to potential copyrighted content recitation
MAX_TOKENS - Output truncated; consider informing user
STOP - Normal completion
import { FinishReason } from "@google/genai";
if (candidate.finishReason === FinishReason.SAFETY) {
}
For non-streaming: check response.candidates[0].finishReason before using response.text.
For streaming: check finishReason in chunk candidates.
System Instructions
- Pass via
systemInstruction in config (not as a chat message)
- System instructions are interaction-scoped; re-specify on each chat session creation
Tool / Function Calling
- Pass tools via
config.tools array
- Use proper SDK types (
Tool, FunctionDeclaration) without forced as casts
googleSearch and fileSearch are first-class Tool properties
fileSearch CANNOT be combined with functionDeclarations in the same request
googleSearch CANNOT be combined with functionDeclarations
Streaming
- Use
generateContentStream or chat.sendMessageStream for streaming
- Use SDK Chat (
ai.chats.create()) for automatic thought signature handling
- Process ALL parts in each chunk (text, thought, functionCall can coexist)
Thinking / Reasoning
- Thinking is ON by default for Gemini 2.5+ and 3.x models
thinkingBudget: 0 disables thinking (except models that require it)
- Gemini 3.1 Flash Lite uses
thinkingLevel instead of thinkingBudget
- Gemini 3 Pro / 3.1 Pro require thinking (cannot be disabled)
- Access thought parts via
part.thought boolean on content parts
Model Names
Current models (use these):
gemini-3.1-pro-preview - Flagship, 1M context
gemini-3-flash-preview - Fast, balanced
gemini-3.1-flash-lite-preview - Cost-efficient
gemini-2.5-pro / gemini-2.5-flash - Still available
Deprecated models (NEVER use):
- All
gemini-2.0-*, gemini-1.5-*, gemini-1.0-*, gemini-pro
Type Safety
- Use proper SDK types from
@google/genai instead of as casts
Tool interface supports googleSearch, fileSearch, functionDeclarations, codeExecution, urlContext
- Import enums (
FinishReason, HarmCategory, HarmBlockThreshold) as values, not just types
Checklist for New API Calls