Gemini API (Google)
Use the generative content API (generateContent / chat sessions). Keys only on the server; model ID and system instruction are part of the feature contract.
Stack and scope
| Item |
Role |
| generateContent |
Text / multimodal turns |
| Official SDK |
@google/genai (TS) / google-genai (Python) — or the client already in the repo |
| Streaming |
generateContentStream |
| Tools |
Function calling / code execution / grounding (per product) |
| Auth |
API key (GEMINI_API_KEY / GOOGLE_API_KEY) or ADC on Vertex |
New apps: Google AI API (ai.google.dev) with API key, unless the project is already on Vertex AI — in that case preserve endpoint, project, and ADC/service account auth.
Non-negotiable rules
- API key / credentials only in backend/workers — never in the public frontend.
- Pin model ID in config/env (e.g. family
gemini-2.5-flash / the ID the project standardizes on).
- Timeouts and retries with backoff only on
429 / 5xx / transient network errors.
- Streaming: consume the iterator; cancel upstream if the client aborts.
- Do not log full prompts/responses with PII/secrets.
generateContent
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: process.env.GEMINI_MODEL!,
contents: "Summarize this diff in 3 bullets.",
config: {
systemInstruction: "You are a precise coding assistant.",
temperature: 0.2,
maxOutputTokens: 1024,
},
});
const text = response.text;
contents: string, list of turns (role + parts) or multimodal (text + inline data / file URIs).
- Multi-turn: alternate
user / model (not assistant).
- Read finish/safety: safety blocks may come without useful text — treat as a domain error.
- If the project uses the legacy SDK
@google/generative-ai, preserve that API; do not migrate major without a request.
Chat session
const chat = ai.chats.create({
model: process.env.GEMINI_MODEL!,
config: { systemInstruction: "Be concise." },
});
const reply = await chat.sendMessage({ message: "Hello" });
- Use session when the history is managed by the SDK; otherwise send
contents explicitly (easier to test/persist).
- Persist history in your store if the conversation spans HTTP requests.
Tool / function calling
- Declare function declarations (name, description, parameters JSON Schema).
- If the response brings
functionCall, execute on the server.
- Return
functionResponse in the parts and continue until final text.
- Validate arguments against schema before side effects.
- Least privilege: only tools necessary for the feature.
- Idempotency / human confirmation for destructive actions.
- Limit iterations of the tool↔model loop.
Streaming
const stream = await ai.models.generateContentStream({
model: process.env.GEMINI_MODEL!,
contents: "Hello",
});
for await (const chunk of stream) {
const delta = chunk.text;
if (delta) {
// encaminhar ao client
}
}
- Proxy chunks (SSE) without buffering everything if the UX is stream.
- Handle dropped connections and empty responses due to safety.
Multimodal
- Images/audio/PDF per the model:
inlineData (base64 + mime) or Files API / supported URIs.
- Validate MIME and size on the server before upload.
- Do not assume that every model ID accepts the same set of modalities.
Vertex vs Google AI
|
Google AI (API key) |
Vertex AI |
| Auth |
API key |
ADC / service account |
| Config |
key + model |
project, location, model |
| Usage |
simple prototype/prod |
enterprise, IAM, VPC |
- Do not mix clients/env from the two stacks in the same adapter without a clear layer.
- In GCP, prefer the pattern already adopted by the repo (Secret Manager, workload identity).
Errors and limits
| Situation |
Action |
400 / invalid argument |
Fix request — no blind retry |
401 / 403 |
Key/IAM — no blind retry |
429 |
Backoff + rate limits |
5xx / unavailable |
Limited retry or model fallback |
| Safety block |
Safe message to the user; categorized log |
- Monitor tokens / cost per feature when the API exposes usage metadata.
- Keys and projects separated by environment.
Compatibility
- OpenAI-compatible proxies ≠ native Gemini — see
chatgpt-api / ollama-api if the base URL is /v1/chat/completions.
- Claude/Anthropic is another API —
claude-api; do not reuse payloads blindly.
Anti-patterns
- Gemini API key in the browser bundle
- Function calling loop without a cap
- Retry on safety block or schema error
- Assuming full parity between model IDs (flash vs pro vs vision)
- Mixing Vertex and API key in the same client without intent
Completion criteria
- Key/credentials and model via secure env/config
generateContent or chat with clear system instruction
- Correct and limited tool loop if there are tools
- Cancelable streaming when applicable
- 429/5xx and safety blocks handled; observable usage on critical paths