GeminiAPI
JoshuaShepherd2026-10-26查看 1832复制 434
使用 Google Gemini API 和 @google/generative-ai SDK 构建、完善和掌握代理。涵盖generateContent、函数调用、Google 搜索基础、多模式输入(文本/图像/音频/视频)、流式传输、上下文缓存以及 Gemini 2.5 和 3.x 模型系列。从 ai.google.dev 获取实时文档。在 Google Gemini 上构建或调试任何内容时使用。
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 4直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景
💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。
SKILL.md18575 chars
---
name: gemini-api
description: Build, refine, and master agents using the Google Gemini API and @google/generative-ai SDK. Covers generateContent, function calling, Google Search grounding, multimodal input (text/image/audio/video), streaming, context caching, and the Gemini 2.5 and 3.x model families. Fetches live docs from ai.google.dev. Use when building or debugging anything on Google Gemini.
user-invocable: true
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch
---
Build or refine a Gemini API agent: $ARGUMENTS
$ARGUMENTS can include:
- What to build (e.g. `multimodal agent`, `grounded chatbot`, `function calling pipeline`, `streaming assistant`)
- A file path to existing code to refine
- A capability to add (e.g. `add Google Search grounding`, `add audio input`, `add video analysis`, `add caching`)
- A model preference (e.g. `--model 2.5-pro`, `--model 2.5-flash`, `--model 2.5-flash-lite`)
- API surface preference (e.g. `--api gemini` for ai.google.dev, `--api vertex` for Vertex AI)
- Empty — scaffold a starter agent with best-practice defaults
---
## Authoritative Sources
Always fetch fresh docs before generating or advising on code. These are the canonical Google sources:
| Resource | URL |
|----------|-----|
| Model overview (current IDs) | `https://ai.google.dev/gemini-api/docs/models` |
| Quickstart | `https://ai.google.dev/gemini-api/docs/quickstart` |
| Function calling guide | `https://ai.google.dev/gemini-api/docs/function-calling` |
| Grounding with Google Search | `https://ai.google.dev/gemini-api/docs/grounding` |
| Multimodal input | `https://ai.google.dev/gemini-api/docs/vision` |
| Audio input | `https://ai.google.dev/gemini-api/docs/audio` |
| Video input | `https://ai.google.dev/gemini-api/docs/video` |
| Context caching | `https://ai.google.dev/gemini-api/docs/caching` |
| Streaming | `https://ai.google.dev/gemini-api/docs/text-generation#streaming` |
| Live API (audio/video realtime) | `https://ai.google.dev/gemini-api/docs/live` |
| Pricing | `https://ai.google.dev/gemini-api/docs/pricing` |
| Vertex AI pricing | `https://cloud.google.com/vertex-ai/generative-ai/pricing` |
**Fetch the model overview and the relevant guide before writing any code.** Gemini model IDs and feature availability evolve rapidly.
---
## Environment Setup
```bash
# Gemini API (ai.google.dev — recommended for prototyping + production)
pnpm add @google/generative-ai
# Vertex AI (Google Cloud — recommended for enterprise/compliance)
pnpm add @google-cloud/vertexai
```
```env
# .env.local — Gemini API
GOOGLE_API_KEY=AIza...
# Vertex AI (alternative)
GOOGLE_CLOUD_PROJECT=my-project-id
GOOGLE_CLOUD_LOCATION=us-central1
```
```typescript
// src/lib/ai/gemini.ts — Gemini API
import { GoogleGenerativeAI } from '@google/generative-ai';
export const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
```
**Current model IDs (verify against live docs before using):**
*Stable / GA — use for production:*
- `gemini-2.5-pro` — complex tasks, long reasoning, $1.25–$2.50/$10–$15 per 1M (tiered by context)
- `gemini-2.5-flash` — balanced production workloads, $0.30/$2.50 per 1M
- `gemini-2.5-flash-lite` — cheapest quality option, $0.10/$0.40 per 1M
*Preview — do not use in production:*
- `gemini-3.1-pro-preview` — next generation, $2–$4/$12–$18 per 1M
- `gemini-3-flash-preview` — fast preview, $0.50/$3.00 per 1M
**Free tier:** All major models — rate-limited, content may improve Google products.
---
## Phase 1 — Load Context
1. Fetch the model overview to confirm current model IDs and capabilities
2. Read any existing code files specified in $ARGUMENTS
3. Determine: Gemini API (simpler, free tier) vs Vertex AI (enterprise, data residency)
4. Identify modalities needed: text-only vs image/audio/video input
5. Read `_docs/ai-intelligence/` for latest pricing snapshot if available
**Decision rule:**
- Prototyping / startup → Gemini API with free tier
- Enterprise / HIPAA / data residency → Vertex AI
- Audio/video input → Gemini API (only provider with native audio + video in text models)
---
## Phase 2 — Core Patterns
### Pattern 1: Basic Text Generation
```typescript
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-flash',
systemInstruction: 'You are a helpful assistant.',
});
const result = await model.generateContent('What is the capital of France?');
console.log(result.response.text());
console.log('Token count:', result.response.usageMetadata);
```
### Pattern 2: Function Calling
```typescript
import {
GoogleGenerativeAI,
FunctionDeclaration,
Tool,
FunctionCallingMode,
} from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const tools: Tool[] = [
{
functionDeclarations: [
{
name: 'get_weather',
description: 'Get current weather for a location.',
parameters: {
type: 'OBJECT',
properties: {
location: {
type: 'STRING',
description: 'City and state, e.g. "Austin, TX"',
},
unit: {
type: 'STRING',
enum: ['celsius', 'fahrenheit'],
description: 'Temperature unit',
},
},
required: ['location'],
},
} satisfies FunctionDeclaration,
],
},
];
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-flash',
tools,
toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.AUTO } },
});
async function runWithTools(userMessage: string) {
const chat = model.startChat();
let result = await chat.sendMessage(userMessage);
while (true) {
const response = result.response;
const calls = response.functionCalls();
if (!calls || calls.length === 0) {
return response.text();
}
// Execute all function calls in parallel
const functionResults = await Promise.all(
calls.map(async (call) => {
const output = await executeTool(call.name, call.args);
return {
functionResponse: {
name: call.name,
response: output,
},
};
})
);
result = await chat.sendMessage(functionResults);
}
}
async function executeTool(
name: string,
args: Record<string, unknown>,
): Promise<Record<string, unknown>> {
if (name === 'get_weather') {
return { temperature: 72, unit: args.unit ?? 'fahrenheit', condition: 'sunny' };
}
throw new Error(`Unknown tool: ${name}`);
}
```
### Pattern 3: Google Search Grounding
Grounds responses in live Google Search results — no RAG pipeline needed for knowledge-current tasks.
```typescript
import { GoogleGenerativeAI, DynamicRetrievalMode } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-flash',
tools: [
{
googleSearchRetrieval: {
dynamicRetrievalConfig: {
mode: DynamicRetrievalMode.MODE_DYNAMIC,
dynamicThreshold: 0.3, // Triggers search when model confidence < 30%
},
},
},
],
});
const result = await model.generateContent(
'What AI models were released in the last 3 months?'
);
// Access grounding metadata (sources used)
const groundingMetadata = result.response.candidates?.[0]?.groundingMetadata;
console.log('Search queries used:', groundingMetadata?.webSearchQueries);
console.log('Sources:', groundingMetadata?.groundingChunks);
console.log('Answer:', result.response.text());
```
**Pricing:** 5,000 free queries/month, then $14/1,000 queries.
### Pattern 4: Multimodal — Image Input
```typescript
import { GoogleGenerativeAI } from '@google/generative-ai';
import fs from 'fs';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
// Inline image (base64)
const imageData = fs.readFileSync('./diagram.png');
const result = await model.generateContent([
{
inlineData: {
mimeType: 'image/png',
data: imageData.toString('base64'),
},
},
'Describe what you see in this diagram and identify any architectural issues.',
]);
console.log(result.response.text());
```
```typescript
// Image from URL (via File API for large files)
import { GoogleAIFileManager } from '@google/generative-ai/server';
const fileManager = new GoogleAIFileManager(process.env.GOOGLE_API_KEY!);
const uploadedFile = await fileManager.uploadFile('./large-diagram.png', {
mimeType: 'image/png',
displayName: 'Architecture Diagram',
});
const result = await model.generateContent([
{ fileData: { mimeType: 'image/png', fileUri: uploadedFile.file.uri } },
'What does this architecture diagram show?',
]);
```
### Pattern 5: Audio Input (Unique to Gemini)
```typescript
import { GoogleGenerativeAI } from '@google/generative-ai';
import { GoogleAIFileManager } from '@google/generative-ai/server';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const fileManager = new GoogleAIFileManager(process.env.GOOGLE_API_KEY!);
// Upload audio file
const audio = await fileManager.uploadFile('./interview.mp3', {
mimeType: 'audio/mpeg',
displayName: 'Interview Recording',
});
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
const result = await model.generateContent([
{ fileData: { mimeType: 'audio/mpeg', fileUri: audio.file.uri } },
'Transcribe this interview and summarize the key points discussed.',
]);
console.log(result.response.text());
```
**Supported audio formats:** MP3, WAV, FLAC, AAC, OGG, OPUS, WEBM.
### Pattern 6: Video Input (Unique to Gemini)
```typescript
// Upload and analyze video
const video = await fileManager.uploadFile('./demo.mp4', {
mimeType: 'video/mp4',
displayName: 'Product Demo',
});
// Wait for processing
let videoFile = await fileManager.getFile(video.file.name);
while (videoFile.state === 'PROCESSING') {
await new Promise(r => setTimeout(r, 5000));
videoFile = await fileManager.getFile(video.file.name);
}
if (videoFile.state !== 'ACTIVE') throw new Error('Video processing failed');
const result = await model.generateContent([
{ fileData: { mimeType: 'video/mp4', fileUri: videoFile.uri } },
'Describe what happens in this video and identify the key moments.',
]);
```
### Pattern 7: Streaming
```typescript
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
const streamResult = await model.generateContentStream('Write a detailed essay about...');
for await (const chunk of streamResult.stream) {
const text = chunk.text();
process.stdout.write(text);
}
const finalResponse = await streamResult.response;
console.log('\nTotal tokens:', finalResponse.usageMetadata?.totalTokenCount);
```
**Next.js streaming (App Router):**
```typescript
// app/api/chat/route.ts
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
export async function POST(req: Request) {
const { messages } = await req.json();
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
const chat = model.startChat({
history: messages.slice(0, -1).map((m: { role: string; content: string }) => ({
role: m.role === 'assistant' ? 'model' : 'user',
parts: [{ text: m.content }],
})),
});
const streamResult = await chat.sendMessageStream(
messages[messages.length - 1].content
);
const encoder = new TextEncoder();
const readable = new ReadableStream({
async start(controller) {
for await (const chunk of streamResult.stream) {
controller.enqueue(encoder.encode(chunk.text()));
}
controller.close();
},
});
return new Response(readable, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
```
### Pattern 8: Multi-Turn Chat
```typescript
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-flash',
systemInstruction: 'You are a helpful coding assistant.',
});
const chat = model.startChat({
history: [
{ role: 'user', parts: [{ text: 'Hello!' }] },
{ role: 'model', parts: [{ text: 'Hi! How can I help you today?' }] },
],
generationConfig: {
maxOutputTokens: 8192,
temperature: 0.7,
},
});
const result1 = await chat.sendMessage('What is TypeScript?');
console.log(result1.response.text());
const result2 = await chat.sendMessage('How does it differ from JavaScript?');
console.log(result2.response.text());
```
### Pattern 9: Context Caching (Large Shared Contexts)
```typescript
import { GoogleAICacheManager } from '@google/generative-ai/server';
const cacheManager = new GoogleAICacheManager(process.env.GOOGLE_API_KEY!);
// Create a cache with large shared content (minimum 32K tokens)
const cache = await cacheManager.create({
model: 'gemini-2.5-flash',
displayName: 'large-document-cache',
systemInstruction: {
role: 'system',
parts: [{ text: 'You are an expert analyst of this document.' }],
},
contents: [
{
role: 'user',
parts: [{ text: largeDocumentContent }], // Must be >= 32K tokens
},
],
ttlSeconds: 3600, // Cache for 1 hour
});
// Use cached model
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const cachedModel = genAI.getGenerativeModelFromCachedContent(cache);
const result = await cachedModel.generateContent('What are the main conclusions?');
```
---
## Phase 3 — Agent Patterns
### Autonomous Function-Loop Agent
```typescript
async function runAgent(
task: string,
toolDeclarations: FunctionDeclaration[],
handlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>>,
maxTurns = 10,
): Promise<string> {
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-pro',
tools: [{ functionDeclarations: toolDeclarations }],
toolConfig: { functionCallingConfig: { mode: FunctionCallingMode.AUTO } },
});
const chat = model.startChat();
let result = await chat.sendMessage(task);
for (let turn = 0; turn < maxTurns; turn++) {
const calls = result.response.functionCalls();
if (!calls || calls.length === 0) {
return result.response.text();
}
const responses = await Promise.all(
calls.map(async (call) => ({
functionResponse: {
name: call.name,
response: await handlers[call.name]?.(call.args) ?? { error: 'Unknown tool' },
},
}))
);
result = await chat.sendMessage(responses);
}
throw new Error('Agent exceeded max turns');
}
```
### Grounded Research Agent
```typescript
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-pro',
tools: [
{ googleSearchRetrieval: { dynamicRetrievalConfig: { mode: DynamicRetrievalMode.MODE_DYNAMIC } } },
{ functionDeclarations: customTools },
],
systemInstruction: 'You are a research agent. Use Google Search for current facts. Use custom tools for internal data.',
});
```
---
## Phase 4 — Error Handling & Rate Limits
```typescript
import { GoogleGenerativeAI, GoogleGenerativeAIError } from '@google/generative-ai';
async function callWithRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error instanceof GoogleGenerativeAIError) {
// Check for rate limit (429) or server error (500+)
const status = (error as { status?: number }).status;
if ((status === 429 || (status && status >= 500)) && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.warn(`Error ${status}. Retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
continue;
}
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
```
**Safety filters:** Gemini returns a `SAFETY` finish reason if content is blocked. Check `result.response.promptFeedback` to diagnose.
```typescript
const result = await model.generateContent(prompt);
if (result.response.promptFeedback?.blockReason) {
console.warn('Blocked:', result.response.promptFeedback.blockReason);
return null;
}
```
---
## Phase 5 — Vertex AI (Enterprise)
```typescript
import { VertexAI } from '@google-cloud/vertexai';
const vertex = new VertexAI({
project: process.env.GOOGLE_CLOUD_PROJECT!,
location: process.env.GOOGLE_CLOUD_LOCATION ?? 'us-central1',
});
const model = vertex.getGenerativeModel({
model: 'gemini-2.5-flash',
});
const result = await model.generateContent({
contents: [{ role: 'user', parts: [{ text: 'Hello!' }] }],
});
console.log(result.response.candidates?.[0]?.content?.parts?.[0]?.text);
```
**When to use Vertex AI:**
- HIPAA / GDPR compliance required
- Data residency requirements (pick specific Google Cloud region)
- Enterprise IAM and audit logging
- Very high volume with committed use discounts
---
## Phase 6 — Cost Reference (verify at ai.google.dev/gemini-api/docs/pricing)
| Model | Input (≤200K) | Input (>200K) | Output | Status |
|-------|--------------|---------------|--------|--------|
| gemini-2.5-flash-lite | $0.10/M | $0.10/M | $0.40/M | GA ✅ |
| gemini-2.5-flash | $0.30/M | $0.30/M | $2.50/M | GA ✅ |
| gemini-2.5-pro | $1.25/M | $2.50/M | $10–$15/M | GA ✅ |
| gemini-3-flash-preview | $0.50/M | — | $3.00/M | Preview ⚠️ |
| gemini-3.1-pro-preview | $2–$4/M | $4/M | $12–$18/M | Preview ⚠️ |
**Free tier:** All stable models available — rate-limited. Suitable for development and low-volume production.
**Google Search grounding:** 5,000 queries/month free, then $14/1,000 queries.
**Context caching:** Storage fee + reduced read price. Minimum 32K tokens to cache.
---
## Output
When building or scaffolding:
1. Fetch the model overview URL to confirm current model IDs
2. Read any existing code files before modifying
3. Use `gemini-2.5-flash` as default (stable, balanced) — upgrade to `gemini-2.5-pro` for complex reasoning
4. Default to Gemini API (simpler); switch to Vertex AI only if compliance requires it
5. Generate TypeScript with strict types — no `any`
6. Include safety filter handling (check `blockReason`)
7. Include error handling with exponential backoff
8. Write files to their appropriate path (e.g. `src/lib/ai/`, `src/agents/`, `src/app/api/`)
Always state which model ID you used, whether it's GA or Preview, and why.