mcpField
G
google-gemini-api

google-gemini-api

github.com/jezweb开发1.1k467 次安装3 周前更新
代码仓库

关于 google-gemini-api

google-gemini-api 是面向开发者的 Google Gemini API 指南技能,涵盖当前 SDK 与直接调用 API 的方法。内容包括文本和多模态生成、流式响应、函数调用及进阶能力,并说明 SDK 迁移与常见问题。

主要功能

  1. 01Node.js SDK 与 Fetch 调用示例
  2. 02文本生成和流式响应
  3. 03图像、视频、音频及 PDF 输入
  4. 04函数调用与并行调用
  5. 05上下文缓存、代码执行和搜索 grounding
  6. 06SDK 迁移及错误处理指南

适用场景

  1. 01在 Node.js 应用中接入 Gemini
  2. 02在边缘运行时通过 Fetch 调用 API
  3. 03构建处理多模态输入的应用
  4. 04为函数调用和流式输出排查实现问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jezweb/claude-skills --skill google-gemini-api

安装后在 Claude Code 中输入/google-gemini-api确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
references/
code-execution-patterns.md
context-caching-guide.md
function-calling-patterns.md
generation-config.md
grounding-guide.md
models-guide.md
multimodal-guide.md
sdk-migration-guide.md
streaming-patterns.md
thinking-mode-guide.md
top-errors.md
rules/
google-gemini-api.md
scripts/
check-versions.sh
templates/
cloudflare-worker.ts
code-execution.ts
combined-advanced.ts
context-caching.ts
function-calling-basic.ts
function-calling-parallel.ts
grounding-search.ts
multimodal-image.ts
multimodal-video-audio.ts
package.json
streaming-chat.ts
streaming-fetch.ts
text-generation-basic.ts
text-generation-fetch.ts
thinking-mode.ts

详细介绍

Google Gemini API - 完整指南

版本:3.0.0(新增 14 个已知问题) 软件包:@google/[email protected](⚠️ 不是 @google/generative-ai) 最后更新:2026-01-21


⚠️ SDK 迁移重要警告

已弃用的 SDK:@google/generative-ai(将于 2025 年 11 月 30 日停止服务) 当前 SDK:@google/genai v1.27+

如果你看到代码使用 @google/generative-ai,说明它已经过时!

本技能使用当前正确的 SDK,并提供完整的迁移指南。


状态

✅ 阶段 1 已完成:

  • ✅ 文本生成(基础 + 流式)
  • ✅ 多模态输入(图像、视频、音频、PDF)
  • ✅ 函数调用(基础 + 并行执行)
  • ✅ 系统指令与多轮对话
  • ✅ 思考模式配置
  • ✅ 生成参数(temperature、top-p、top-k、停止序列)
  • ✅ Node.js SDK(@google/genai)和 fetch 两种方式

✅ 阶段 2 已完成:

  • ✅ 上下文缓存(基于 TTL 的缓存,可优化成本)
  • ✅ 代码执行(内置 Python 解释器和沙盒)
  • ✅ 使用 Google Search 进行信息锚定(实时网络信息 + 引用)

📦 单独的技能:

  • 嵌入:text-embedding-004 请参阅 google-gemini-embeddings 技能

目录

阶段 1 - 核心功能:

  1. 快速开始
  2. 当前模型(2025)
  3. SDK 与 Fetch 方式
  4. 文本生成
  5. 流式处理
  6. 多模态输入
  7. 函数调用
  8. 系统指令
  9. 多轮对话
  10. 思考模式
  11. 生成配置

阶段 2 - 高级功能: 12. 上下文缓存 13. 代码执行 14. 使用 Google Search 进行信息锚定

常用参考: 15. 避免已知问题 16. 错误处理 17. 速率限制 18. SDK 迁移指南 19. 生产环境最佳实践


快速开始

安装

正确的 SDK:

npm install @google/[email protected]

❌ 错误(已弃用):

npm install @google/generative-ai  # DO NOT USE!
环境设置
export GEMINI_API_KEY="..."

或者创建 .env 文件:

GEMINI_API_KEY=...
首次生成文本(Node.js SDK)
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Explain quantum computing in simple terms'
});

console.log(response.text);
首次生成文本(Fetch - Cloudflare Workers)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [{ parts: [{ text: 'Explain quantum computing in simple terms' }] }]
    }),
  }
);

const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);

当前模型(2025)

Gemini 3 系列(2025 年 12 月)
gemini-3-flash
  • 上下文:1,048,576 个输入 token / 65,536 个输出 token
  • 状态:🆕 正式可用(2025 年 12 月)
  • 说明:Google 速度最快、效率最高的 Gemini 3 模型,适用于生产工作负载
  • 最适用于:高吞吐量应用、低延迟响应、对成本敏感的生产环境
  • 功能:增强的多模态能力、函数调用、流式处理、思考模式
  • 基准测试性能:质量媲美 gemini-2.5-pro,速度和成本与 gemini-2.5-flash 相当
  • 推荐用于:需要兼顾速度与质量的生产用例
gemini-3-pro-preview
  • 上下文:待定(文档尚未完成)
  • 状态:预览版(2025 年 11 月 18 日)
  • 说明:Google 最新、最智能的 AI 模型,具备先进的推理能力
  • 最适用于:最复杂的推理任务、高级多模态理解、对基准测试至关重要的应用
  • 功能:增强的多模态能力(文本、图像、视频、音频、PDF)、函数调用、流式处理
  • 基准测试性能:在所有主要 AI 基准测试中均优于 Gemini 2.5 Pro
  • ⚠️ 预览版模型警告:预览版模型没有 SLA,且可能会在几乎不提前通知的情况下发生变更或弃用。生产环境请使用正式可用(GA)的模型。参见问题 #13
Gemini 2.5 系列(正式可用 - 稳定)
gemini-2.5-pro
  • 上下文:1,048,576 个输入令牌 / 65,536 个输出令牌
  • 描述:用于复杂推理的业界领先思考模型
  • 最适合:代码、数学、STEM、复杂问题解决
  • 功能:思考模式(默认开启)、函数调用、多模态、流式传输
  • 知识截止时间:2025 年 1 月
gemini-2.5-flash
  • 上下文:1,048,576 个输入令牌 / 65,536 个输出令牌
  • 描述:性价比最佳的主力模型
  • 最适合:大规模处理、低延迟、高吞吐量、Agent 式用例
  • 功能:思考模式(默认开启)、函数调用、多模态、流式传输
  • 知识截止时间:2025 年 1 月
gemini-2.5-flash-lite
  • 上下文:1,048,576 个输入令牌 / 65,536 个输出令牌
  • 描述:成本优化、速度最快的 2.5 模型
  • 最适合:高吞吐量、成本敏感型应用
  • 功能:思考模式(默认开启)、函数调用、多模态、流式传输
  • 知识截止时间:2025 年 1 月
模型功能矩阵
功能3-Flash3-Pro (Preview)2.5-Pro2.5-Flash2.5-Flash-Lite
思考模式✅ 默认开启TBD✅ 默认开启✅ 默认开启✅ 默认开启
函数调用✅✅✅✅✅
多模态✅ 增强✅ 增强✅✅✅
流式传输✅✅✅✅✅
系统指令✅✅✅✅✅
上下文窗口1,048,576 输入TBD1,048,576 输入1,048,576 输入1,048,576 输入
输出令牌最多 65,536TBD最多 65,536最多 65,536最多 65,536
状态GAPreviewStableStableStable
⚠️ 上下文窗口修正

准确信息(Gemini 2.5):Gemini 2.5 模型支持 1,048,576 个输入令牌(不是 2M!) 已过时:只有上一代 Gemini 1.5 Pro 支持 2M 令牌上下文窗口 GEMINI 3:上下文窗口规格待官方文档公布

常见错误:声称 Gemini 2.5 有 2M 个令牌。事实并非如此。本技能可避免此错误。


SDK 与 Fetch 方案

Node.js SDK (@google/genai)

优点:

  • 支持 TypeScript 类型安全
  • API 更简单(语法更简洁)
  • 内置聊天辅助工具
  • 自动解析流式传输的 SSE
  • 错误处理更完善

缺点:

  • 需要 Node.js 或兼容的运行时
  • 包体积较大
  • 可能无法在所有边缘运行时中使用

**适用场景:**构建 Node.js 应用、Next.js Server Actions/Components,或任何兼容 Node.js 的环境

基于 Fetch(直接 REST API)

优点:

  • 可在任何 JavaScript 环境中使用(Cloudflare Workers、Deno、Bun、浏览器)
  • 依赖项极少
  • 包体积更小
  • 完全掌控请求

缺点:

  • 语法较冗长
  • 需要手动解析流式传输的 SSE
  • 没有内置聊天辅助工具
  • 需要手动处理错误

**适用场景:**部署到 Cloudflare Workers、浏览器客户端或轻量级边缘运行时


文本生成

基本文本生成(SDK)
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Write a haiku about artificial intelligence'
});

console.log(response.text);
基本文本生成(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        {
          parts: [
            { text: 'Write a haiku about artificial intelligence' }
          ]
        }
      ]
    }),
  }
);

const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
响应结构
{
  text: string,                  // Convenience accessor for text content
  candidates: [
    {
      content: {
        parts: [
          { text: string }       // Generated text
        ],
        role: string             // "model"
      },
      finishReason: string,      // "STOP" | "MAX_TOKENS" | "SAFETY" | "OTHER"
      index: number
    }
  ],
  usageMetadata: {
    promptTokenCount: number,
    candidatesTokenCount: number,
    totalTokenCount: number
  }
}

流式传输

使用 SDK 流式传输(异步迭代)
const response = await ai.models.generateContentStream({
  model: 'gemini-2.5-flash',
  contents: 'Write a 200-word story about time travel'
});

for await (const chunk of response) {
  process.stdout.write(chunk.text);
}
使用 Fetch 流式传输(SSE 解析)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [{ parts: [{ text: 'Write a 200-word story about time travel' }] }]
    }),
  }
);

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split('\n');
  buffer = lines.pop() || '';

  for (const line of lines) {
    if (line.trim() === '' || line.startsWith('data: [DONE]')) continue;
    if (!line.startsWith('data: ')) continue;

    try {
      const data = JSON.parse(line.slice(6));
      const text = data.candidates[0]?.content?.parts[0]?.text;
      if (text) {
        process.stdout.write(text);
      }
    } catch (e) {
      // Skip invalid JSON
    }
  }
}

要点:

  • 使用 streamGenerateContent 端点(而不是 generateContent)
  • 解析 Server-Sent Events(SSE)格式:data: {json}\n\n
  • 在缓冲区中处理不完整的数据块
  • 跳过空行和 [DONE] 标记

多模态输入

Gemini 2.5 模型支持在同一请求中输入文本、图像、视频、音频和 PDF。

图像(视觉)
SDK 方案
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

// From file
const imageData = fs.readFileSync('/path/to/image.jpg');
const base64Image = imageData.toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      parts: [
        { text: 'What is in this image?' },
        {
          inlineData: {
            data: base64Image,
            mimeType: 'image/jpeg'
          }
        }
      ]
    }
  ]
});

console.log(response.text);
Fetch 方案
const imageData = fs.readFileSync('/path/to/image.jpg');
const base64Image = imageData.toString('base64');

const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        {
          parts: [
            { text: 'What is in this image?' },
            {
              inlineData: {
                data: base64Image,
                mimeType: 'image/jpeg'
              }
            }
          ]
        }
      ]
    }),
  }
);

const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);

支持的图像格式:

  • JPEG(.jpg、.jpeg)
  • PNG(.png)
  • WebP(.webp)
  • HEIC(.heic)
  • HEIF(.heif)

最大图像大小:每张图像 20MB

视频
// Video must be < 2 minutes for inline data
const videoData = fs.readFileSync('/path/to/video.mp4');
const base64Video = videoData.toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      parts: [
        { text: 'Describe what happens in this video' },
        {
          inlineData: {
            data: base64Video,
            mimeType: 'video/mp4'
          }
        }
      ]
    }
  ]
});

console.log(response.text);

支持的视频格式:

  • MP4(.mp4)
  • MPEG(.mpeg)
  • MOV(.mov)
  • AVI(.avi)
  • FLV(.flv)
  • MPG(.mpg)
  • WebM(.webm)
  • WMV(.wmv)

最长视频时长(内联):2 分钟 最大视频大小:2GB(较大的文件请使用 File API - Phase 2)

音频
const audioData = fs.readFileSync('/path/to/audio.mp3');
const base64Audio = audioData.toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      parts: [
        { text: 'Transcribe and summarize this audio' },
        {
          inlineData: {
            data: base64Audio,
            mimeType: 'audio/mp3'
          }
        }
      ]
    }
  ]
});

console.log(response.text);

支持的音频格式:

  • MP3(.mp3)
  • WAV(.wav)
  • FLAC(.flac)
  • AAC(.aac)
  • OGG(.ogg)
  • OPUS(.opus)

最大音频大小:20MB

PDF
const pdfData = fs.readFileSync('/path/to/document.pdf');
const base64Pdf = pdfData.toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      parts: [
        { text: 'Summarize the key points in this PDF' },
        {
          inlineData: {
            data: base64Pdf,
            mimeType: 'application/pdf'
          }
        }
      ]
    }
  ]
});

console.log(response.text);

最大 PDF 大小:30MB PDF 限制:基于文本的 PDF 效果最佳;扫描图像的准确度可能较低

多种输入

你可以在一个请求中组合多种模态:

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      parts: [
        { text: 'Compare these two images and describe the differences:' },
        { inlineData: { data: base64Image1, mimeType: 'image/jpeg' } },
        { inlineData: { data: base64Image2, mimeType: 'image/jpeg' } }
      ]
    }
  ]
});

函数调用

Gemini 支持函数调用(工具使用),以连接模型与外部 API 和系统。

基本函数调用(SDK)
import { GoogleGenAI, FunctionCallingConfigMode } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

// Define function declarations
const getCurrentWeather = {
  name: 'get_current_weather',
  description: 'Get the current weather for a location',
  parametersJsonSchema: {
    type: 'object',
    properties: {
      location: {
        type: 'string',
        description: 'City name, e.g. San Francisco'
      },
      unit: {
        type: 'string',
        enum: ['celsius', 'fahrenheit']
      }
    },
    required: ['location']
  }
};

// Make request with tools
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What\'s the weather in Tokyo?',
  config: {
    tools: [
      { functionDeclarations: [getCurrentWeather] }
    ]
  }
});

// Check if model wants to call a function
const functionCall = response.candidates[0].content.parts[0].functionCall;

if (functionCall) {
  console.log('Function to call:', functionCall.name);
  console.log('Arguments:', functionCall.args);

  // Execute the function (your implementation)
  const weatherData = await fetchWeather(functionCall.args.location);

  // Send function result back to model
  const finalResponse = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: [
      'What\'s the weather in Tokyo?',
      response.candidates[0].content, // Original assistant response with function call
      {
        parts: [
          {
            functionResponse: {
              name: functionCall.name,
              response: weatherData
            }
          }
        ]
      }
    ],
    config: {
      tools: [
        { functionDeclarations: [getCurrentWeather] }
      ]
    }
  });

  console.log(finalResponse.text);
}
函数调用(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        { parts: [{ text: 'What\'s the weather in Tokyo?' }] }
      ],
      tools: [
        {
          functionDeclarations: [
            {
              name: 'get_current_weather',
              description: 'Get the current weather for a location',
              parameters: {
                type: 'object',
                properties: {
                  location: {
                    type: 'string',
                    description: 'City name'
                  }
                },
                required: ['location']
              }
            }
          ]
        }
      ]
    }),
  }
);

const data = await response.json();
const functionCall = data.candidates[0]?.content?.parts[0]?.functionCall;

if (functionCall) {
  // Execute function and send result back (same flow as SDK)
}
并行函数调用

Gemini 可以同时调用多个互相独立的函数:

const tools = [
  {
    functionDeclarations: [
      {
        name: 'get_weather',
        description: 'Get weather for a location',
        parametersJsonSchema: {
          type: 'object',
          properties: {
            location: { type: 'string' }
          },
          required: ['location']
        }
      },
      {
        name: 'get_population',
        description: 'Get population of a city',
        parametersJsonSchema: {
          type: 'object',
          properties: {
            city: { type: 'string' }
          },
          required: ['city']
        }
      }
    ]
  }
];

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What is the weather and population of Tokyo?',
  config: { tools }
});

// Model may return MULTIPLE function calls in parallel
const functionCalls = response.candidates[0].content.parts.filter(
  part => part.functionCall
);

console.log(`Model wants to call ${functionCalls.length} functions in parallel`);
函数调用模式
import { FunctionCallingConfigMode } from '@google/genai';

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What\'s the weather?',
  config: {
    tools: [{ functionDeclarations: [getCurrentWeather] }],
    toolConfig: {
      functionCallingConfig: {
        mode: FunctionCallingConfigMode.ANY, // Force function call
        // mode: FunctionCallingConfigMode.AUTO, // Model decides (default)
        // mode: FunctionCallingConfigMode.NONE, // Never call functions
        allowedFunctionNames: ['get_current_weather'] // Optional: restrict to specific functions
      }
    }
  }
});

模式:

  • AUTO(默认):由模型决定是否调用函数
  • ANY:强制模型至少调用一个函数
  • NONE:对此请求禁用函数调用

系统指令

系统指令用于指导模型行为并设定上下文。它们与对话消息相互独立。

SDK 方式
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  systemInstruction: 'You are a helpful AI assistant that always responds in the style of a pirate. Use nautical terminology and end sentences with "arrr".',
  contents: 'Explain what a database is'
});

console.log(response.text);
// Output: "Ahoy there! A database be like a treasure chest..."
Fetch 方式
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      systemInstruction: {
        parts: [
          { text: 'You are a helpful AI assistant that always responds in the style of a pirate.' }
        ]
      },
      contents: [
        { parts: [{ text: 'Explain what a database is' }] }
      ]
    }),
  }
);

要点:

  • 系统指令不属于 contents 数组
  • 它们在请求的顶层设置一次
  • 在整个对话期间持续生效(使用多轮聊天时)
  • 它们不计作用户或模型消息

多轮聊天

对于包含历史记录的对话,请使用 SDK 的聊天辅助工具,或手动管理对话状态。

SDK 聊天辅助工具(推荐)
const chat = await ai.models.createChat({
  model: 'gemini-2.5-flash',
  systemInstruction: 'You are a helpful coding assistant.',
  history: [] // Start empty or with previous messages
});

// Send first message
const response1 = await chat.sendMessage('What is TypeScript?');
console.log('Assistant:', response1.text);

// Send follow-up (context is automatically maintained)
const response2 = await chat.sendMessage('How do I install it?');
console.log('Assistant:', response2.text);

// Get full chat history
const history = chat.getHistory();
console.log('Full conversation:', history);
手动管理聊天(Fetch)
const conversationHistory = [];

// First turn
const response1 = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        {
          role: 'user',
          parts: [{ text: 'What is TypeScript?' }]
        }
      ]
    }),
  }
);

const data1 = await response1.json();
const assistantReply1 = data1.candidates[0].content.parts[0].text;

// Add to history
conversationHistory.push(
  { role: 'user', parts: [{ text: 'What is TypeScript?' }] },
  { role: 'model', parts: [{ text: assistantReply1 }] }
);

// Second turn (include full history)
const response2 = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        ...conversationHistory,
        { role: 'user', parts: [{ text: 'How do I install it?' }] }
      ]
    }),
  }
);

消息角色:

  • user:用户消息
  • model:助手回复

⚠️ 重要:聊天辅助工具仅限 SDK 使用。使用 fetch 时,你必须手动管理对话历史。


思考模式

Gemini 2.5 模型默认启用思考模式,以提升质量。你可以配置思考预算。

配置思考预算(SDK)
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Solve this complex math problem: ...',
  config: {
    thinkingConfig: {
      thinkingBudget: 8192 // Max tokens for thinking (default: model-dependent)
    }
  }
});
配置思考预算(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [{ parts: [{ text: 'Solve this complex math problem: ...' }] }],
      generationConfig: {
        thinkingConfig: {
          thinkingBudget: 8192
        }
      }
    }),
  }
);
配置思考级别(SDK)- v1.30.0 中新增
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Solve this complex problem: ...',
  config: {
    thinkingConfig: {
      thinkingLevel: 'MEDIUM' // 'LOW' | 'MEDIUM' | 'HIGH'
    }
  }
});

思考级别:

  • LOW:最少的内部推理(速度更快,质量较低)
  • MEDIUM:平衡的推理(默认)
  • HIGH:最大推理深度(速度较慢,质量较高)

要点:

  • Gemini 2.5 模型始终启用思考模式(无法禁用)
  • 更高的思考预算可进行更多内部推理(可能增加延迟)
  • thinkingLevel 比 thinkingBudget 更易于控制(v1.30.0 中新增)
  • 默认预算因模型而异(通常足以应对大多数任务)
  • 仅在非常复杂的推理任务中提高预算/级别

生成配置

使用生成参数自定义模型行为。

所有配置选项(SDK)
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Write a creative story',
  config: {
    temperature: 0.9,           // Randomness (0.0-2.0, default: 1.0)
    topP: 0.95,                 // Nucleus sampling (0.0-1.0)
    topK: 40,                   // Top-k sampling
    maxOutputTokens: 2048,      // Max tokens to generate
    stopSequences: ['END'],     // Stop generation if these appear
    responseMimeType: 'text/plain', // Or 'application/json' for JSON mode
    candidateCount: 1           // Number of response candidates (usually 1)
  }
});
所有配置选项(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [{ parts: [{ text: 'Write a creative story' }] }],
      generationConfig: {
        temperature: 0.9,
        topP: 0.95,
        topK: 40,
        maxOutputTokens: 2048,
        stopSequences: ['END'],
        responseMimeType: 'text/plain',
        candidateCount: 1
      }
    }),
  }
);
参数指南
参数范围默认值用途
temperature0.0-2.01.0值越低越专注,值越高越有创意
topP0.0-1.00.95核采样阈值
topK1-100+40将范围限制在前 K 个词元
maxOutputTokens1-65536模型上限控制回复长度
stopSequences数组无在指定字符串处停止生成

提示:

  • 对于事实类任务:使用较低的 temperature(0.0-0.3)
  • 对于创意类任务:使用较高的 temperature(0.7-1.5)
  • topP 和 topK 都用于控制随机性;二者择一使用(不要同时使用)
  • 始终设置 maxOutputTokens,以防生成过多内容

上下文缓存

上下文缓存允许缓存常用内容(例如系统指令、大型文档或视频文件),从而将成本降低最高 90%,并改善延迟。

工作原理
  1. 创建缓存,存入要重复使用的内容
  2. 在后续请求中引用缓存
  3. 节省令牌——缓存令牌的费用低得多
  4. TTL 管理——缓存会在指定时间后过期
优势
  • 节省成本:缓存令牌的费用最高可降低 90%
  • 降低延迟:通过复用已处理的内容,更快地获得响应
  • 上下文一致:在多个请求中使用相同的大型上下文
创建缓存(SDK)
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

// Create a cache for a large document
const documentText = fs.readFileSync('./large-document.txt', 'utf-8');

const cache = await ai.caches.create({
  model: 'gemini-2.5-flash',
  config: {
    displayName: 'large-doc-cache', // Identifier for the cache
    systemInstruction: 'You are an expert at analyzing legal documents.',
    contents: documentText,
    ttl: '3600s', // Cache for 1 hour
  }
});

console.log('Cache created:', cache.name);
console.log('Expires at:', cache.expireTime);
创建缓存(Fetch)
const response = await fetch(
  'https://generativelanguage.googleapis.com/v1beta/cachedContents',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      model: 'models/gemini-2.5-flash',
      displayName: 'large-doc-cache',
      systemInstruction: {
        parts: [{ text: 'You are an expert at analyzing legal documents.' }]
      },
      contents: [
        { parts: [{ text: documentText }] }
      ],
      ttl: '3600s'
    }),
  }
);

const cache = await response.json();
console.log('Cache created:', cache.name);
使用缓存(SDK)
// Generate content using the cache
const response = await ai.models.generateContent({
  model: cache.name, // Use cache name as model
  contents: 'Summarize the key points in the document'
});

console.log(response.text);
使用缓存(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/${cache.name}:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        { parts: [{ text: 'Summarize the key points in the document' }] }
      ]
    }),
  }
);

const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
更新缓存 TTL(SDK)
import { UpdateCachedContentConfig } from '@google/genai';

await ai.caches.update({
  name: cache.name,
  config: {
    ttl: '7200s' // Extend to 2 hours
  }
});
使用过期时间更新缓存(SDK)
// Set specific expiration time (must be timezone-aware)
const in10Minutes = new Date(Date.now() + 10 * 60 * 1000);

await ai.caches.update({
  name: cache.name,
  config: {
    expireTime: in10Minutes
  }
});
列出和删除缓存(SDK)
// List all caches
const caches = await ai.caches.list();
for (const cache of caches) {
  console.log(cache.name, cache.displayName);
}

// Delete a specific cache
await ai.caches.delete({ name: cache.name });
使用视频文件进行缓存
import { GoogleGenAI } from '@google/genai';
import fs from 'fs';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

// Upload video file
const videoFile = await ai.files.upload({
  file: fs.createReadStream('./video.mp4')
});

// Wait for processing
while (videoFile.state.name === 'PROCESSING') {
  await new Promise(resolve => setTimeout(resolve, 2000));
  videoFile = await ai.files.get({ name: videoFile.name });
}

// Create cache with video
const cache = await ai.caches.create({
  model: 'gemini-2.5-flash',
  config: {
    displayName: 'video-analysis-cache',
    systemInstruction: 'You are an expert video analyzer.',
    contents: [videoFile],
    ttl: '300s' // 5 minutes
  }
});

// Use cache for multiple queries
const response1 = await ai.models.generateContent({
  model: cache.name,
  contents: 'What happens in the first minute?'
});

const response2 = await ai.models.generateContent({
  model: cache.name,
  contents: 'Describe the main characters'
});
要点

何时使用缓存:

  • 需要重复使用的大型系统指令
  • 需要多次分析的长文档
  • 使用不同提示词查询的视频/音频文件
  • 在多个对话会话中保持上下文一致

TTL 指南:

  • 短会话:300s(5 分钟)至 3600s(1 小时)
  • 长会话:3600s(1 小时)至 86400s(24 小时)
  • 最长:7 天

节省成本:

  • 缓存的输入令牌:比普通令牌便宜约 90%
  • 输出令牌:价格相同(不缓存)

重要提示:

  • 必须使用明确的模型版本后缀(例如,gemini-2.5-flash-001,不能仅使用 gemini-2.5-flash)
  • 缓存会在 TTL 过期后自动删除
  • 在过期前更新 TTL,以延长缓存的生命周期

代码执行

Gemini 模型可以生成并执行 Python 代码,以解决需要计算、数据分析或可视化的问题。

工作原理
  1. 模型生成可执行的 Python 代码
  2. 代码在安全沙箱中运行
  3. 结果返回给模型
  4. 模型将结果整合到响应中
支持的操作
  • 数学计算
  • 数据分析与统计
  • 文件处理(CSV、JSON 等)
  • 图表生成
  • 算法实现
  • 数据转换
可用的 Python 包

标准库:

  • math、statistics、random、datetime、json、csv、re
  • collections、itertools、functools

数据科学:

  • numpy、pandas、scipy

可视化:

  • matplotlib、seaborn

注意:与完整的 Python 环境相比,可用的软件包有限

基础代码执行(SDK)
import { GoogleGenAI, Tool, ToolCodeExecution } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What is the sum of the first 50 prime numbers? Generate and run code for the calculation.',
  config: {
    tools: [{ codeExecution: {} }]
  }
});

// Parse response parts
for (const part of response.candidates[0].content.parts) {
  if (part.text) {
    console.log('Text:', part.text);
  }
  if (part.executableCode) {
    console.log('Generated Code:', part.executableCode.code);
  }
  if (part.codeExecutionResult) {
    console.log('Execution Output:', part.codeExecutionResult.output);
  }
}
基础代码执行(Fetch)
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      tools: [{ code_execution: {} }],
      contents: [
        {
          parts: [
            { text: 'What is the sum of the first 50 prime numbers? Generate and run code.' }
          ]
        }
      ]
    }),
  }
);

const data = await response.json();

for (const part of data.candidates[0].content.parts) {
  if (part.text) {
    console.log('Text:', part.text);
  }
  if (part.executableCode) {
    console.log('Code:', part.executableCode.code);
  }
  if (part.codeExecutionResult) {
    console.log('Result:', part.codeExecutionResult.output);
  }
}
使用代码执行进行对话(SDK)
const chat = await ai.chats.create({
  model: 'gemini-2.5-flash',
  config: {
    tools: [{ codeExecution: {} }]
  }
});

let response = await chat.sendMessage('I have a math question for you.');
console.log(response.text);

response = await chat.sendMessage(
  'Calculate the Fibonacci sequence up to the 20th number and sum them.'
);

// Model will generate and execute code, then provide answer
for (const part of response.candidates[0].content.parts) {
  if (part.text) console.log(part.text);
  if (part.executableCode) console.log('Code:', part.executableCode.code);
  if (part.codeExecutionResult) console.log('Output:', part.codeExecutionResult.output);
}
数据分析示例
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: `
    Analyze this sales data and calculate:
    1. Total revenue
    2. Average sale price
    3. Best-selling month

    Data (CSV format):
    month,sales,revenue
    Jan,150,45000
    Feb,200,62000
    Mar,175,53000
    Apr,220,68000
  `,
  config: {
    tools: [{ codeExecution: {} }]
  }
});

// Model will generate pandas/numpy code to analyze data
for (const part of response.candidates[0].content.parts) {
  if (part.text) console.log(part.text);
  if (part.executableCode) console.log('Analysis Code:', part.executableCode.code);
  if (part.codeExecutionResult) console.log('Results:', part.codeExecutionResult.output);
}
可视化示例
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Create a bar chart showing the distribution of prime numbers under 100 by their last digit. Generate the chart and describe the pattern.',
  config: {
    tools: [{ codeExecution: {} }]
  }
});

// Model generates matplotlib code, executes it, and describes results
for (const part of response.candidates[0].content.parts) {
  if (part.text) console.log(part.text);
  if (part.executableCode) console.log('Chart Code:', part.executableCode.code);
  if (part.codeExecutionResult) {
    // Note: Chart image data would be in output
    console.log('Execution completed');
  }
}
响应结构
{
  candidates: [
    {
      content: {
        parts: [
          { text: "I'll calculate that for you." },
          {
            executableCode: {
              language: "PYTHON",
              code: "def is_prime(n):\n  if n <= 1:\n    return False\n  ..."
            }
          },
          {
            codeExecutionResult: {
              outcome: "OUTCOME_OK", // or "OUTCOME_FAILED"
              output: "5117\n"
            }
          },
          { text: "The sum of the first 50 prime numbers is 5117." }
        ]
      }
    }
  ]
}
错误处理
for (const part of response.candidates[0].content.parts) {
  if (part.codeExecutionResult) {
    if (part.codeExecutionResult.outcome === 'OUTCOME_FAILED') {
      console.error('Code execution failed:', part.codeExecutionResult.output);
    } else {
      console.log('Success:', part.codeExecutionResult.output);
    }
  }
}
要点

何时使用代码执行:

  • 复杂的数学计算
  • 数据分析与统计
  • 算法实现
  • 文件解析与处理
  • 图表生成
  • 计算问题

限制:

  • 沙箱环境(文件系统访问受限)
  • 可用的 Python 软件包有限
  • 执行超时限制
  • 代码无法访问网络
  • 执行之间不保留状态

最佳实践:

  • 清楚说明所需的计算或分析
  • 明确要求生成代码(“生成并运行代码……”)
  • 检查 outcome 字段是否包含错误
  • 用于确定性计算,而非一般编程

重要提示:

  • 所有 Gemini 2.5 模型(Pro、Flash、Flash-Lite)均可使用
  • 代码在隔离的沙箱中运行,以确保安全
  • 支持 Python 标准库及常用数据科学软件包

使用 Google 搜索进行事实依据 grounding

事实依据 grounding 可将模型连接到实时网络信息,减少幻觉,并提供附带引用的最新、经过事实核查的响应。

工作原理
  1. 模型判断是否需要当前信息
  2. 自动执行 Google 搜索
  3. 处理搜索结果
  4. 将发现的信息整合到回复中
  5. 提供引用和来源 URL
优势
  • 实时信息:获取当前事件和数据
  • 减少幻觉:答案以网络来源为依据
  • 可验证:引用便于核查事实
  • 保持最新:不受模型训练截止时间的限制
信息依据选项
1. Google Search(googleSearch)——推荐用于 Gemini 2.5
const groundingTool = {
  googleSearch: {}
};

功能:

  • 配置简单
  • 需要时自动搜索
  • 适用于所有 Gemini 2.5 模型
2. FileSearch——v1.29.0 新增(预览版)
const fileSearchTool = {
  fileSearch: {
    fileSearchStoreId: 'store-id-here' // Created via FileSearchStore APIs
  }
};

功能:

  • 搜索你自己的文档集合
  • 上传并索引自定义知识库
  • 可作为专有数据的网络搜索替代方案
  • 预览功能(需要设置 FileSearchStore)

注意:有关存储区的创建和管理,请参阅 FileSearch 文档。

3. Google Search Retrieval(googleSearchRetrieval)——旧版(Gemini 1.5)
const retrievalTool = {
  googleSearchRetrieval: {
    dynamicRetrievalConfig: {
      mode: 'MODE_DYNAMIC',
      dynamicThreshold: 0.7 // Only search if confidence < 70%
    }
  }
};

功能:

  • 动态阈值控制
  • 与 Gemini 1.5 模型搭配使用
  • 提供更多配置选项
基本信息依据(SDK)——Gemini 2.5
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Who won the euro 2024?',
  config: {
    tools: [{ googleSearch: {} }]
  }
});

console.log(response.text);

// Check if grounding was used
if (response.candidates[0].groundingMetadata) {
  console.log('Search was performed!');
  console.log('Sources:', response.candidates[0].groundingMetadata);
}
基本信息依据(Fetch)——Gemini 2.5
const response = await fetch(
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': env.GEMINI_API_KEY,
    },
    body: JSON.stringify({
      contents: [
        { parts: [{ text: 'Who won the euro 2024?' }] }
      ],
      tools: [
        { google_search: {} }
      ]
    }),
  }
);

const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);

if (data.candidates[0].groundingMetadata) {
  console.log('Grounding metadata:', data.candidates[0].groundingMetadata);
}
动态检索(SDK)——Gemini 1.5
import { GoogleGenAI, DynamicRetrievalConfigMode } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Who won the euro 2024?',
  config: {
    tools: [
      {
        googleSearchRetrieval: {
          dynamicRetrievalConfig: {
            mode: DynamicRetrievalConfigMode.MODE_DYNAMIC,
            dynamicThreshold: 0.7 // Search only if confidence < 70%
          }
        }
      }
    ]
  }
});

console.log(response.text);

if (!response.candidates[0].groundingMetadata) {
  console.log('Model answered from its own knowledge (high confidence)');
}
信息依据元数据结构
{
  groundingMetadata: {
    searchQueries: [
      { text: "euro 2024 winner" }
    ],
    webPages: [
      {
        url: "https://example.com/euro-2024-results",
        title: "UEFA Euro 2024 Final Results",
        snippet: "Spain won UEFA Euro 2024..."
      }
    ],
    citations: [
      {
        startIndex: 42,
        endIndex: 47,
        uri: "https://example.com/euro-2024-results"
      }
    ],
    retrievalQueries: [
      {
        query: "who won euro 2024 final"
      }
    ]
  }
}
使用信息依据进行聊天(SDK)
const chat = await ai.chats.create({
  model: 'gemini-2.5-flash',
  config: {
    tools: [{ googleSearch: {} }]
  }
});

let response = await chat.sendMessage('What are the latest developments in quantum computing?');
console.log(response.text);

// Check grounding sources
if (response.candidates[0].groundingMetadata) {
  const sources = response.candidates[0].groundingMetadata.webPages || [];
  console.log(`Sources used: ${sources.length}`);
  sources.forEach(source => {
    console.log(`- ${source.title}: ${source.url}`);
  });
}

// Follow-up still has grounding enabled
response = await chat.sendMessage('Which company made the biggest breakthrough?');
console.log(response.text);
将信息依据与函数调用结合使用
const weatherFunction = {
  name: 'get_current_weather',
  description: 'Get current weather for a location',
  parametersJsonSchema: {
    type: 'object',
    properties: {
      location: { type: 'string', description: 'City name' }
    },
    required: ['location']
  }
};

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What is the weather like in the city that won Euro 2024?',
  config: {
    tools: [
      { googleSearch: {} },
      { functionDeclarations: [weatherFunction] }
    ]
  }
});

// Model will:
// 1. Use Google Search to find Euro 2024 winner
// 2. Call get_current_weather function with the city
// 3. Combine both results in response
检查是否使用了信息依据
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'What is 2+2?', // Model knows this without search
  config: {
    tools: [{ googleSearch: {} }]
  }
});

if (!response.candidates[0].groundingMetadata) {
  console.log('Model answered from its own knowledge (no search needed)');
} else {
  console.log('Search was performed');
}
要点

何时使用信息依据:

  • 当前事件和新闻
  • 实时数据(股价、体育比分、天气)
  • 事实核查与验证
  • 关于近期进展的问题
  • 超出模型训练截止时间的信息

何时不应使用:

  • 常识问题
  • 数学计算
  • 代码生成
  • 创意写作
  • 仅需内部推理的任务

成本考量:

  • 信息依据会增加延迟(搜索需要时间)
  • 检索内容会产生额外的令牌成本
  • 使用 dynamicThreshold 控制何时进行搜索(Gemini 1.5)

重要说明:

  • 信息依据需要 Google Cloud 项目(仅有 API 密钥不够)
  • 搜索结果的质量取决于查询措辞
  • 引用可能无法涵盖回复中的所有事实
  • 系统会根据置信度自动执行搜索

Gemini 2.5 与 1.5:

  • Gemini 2.5:使用 googleSearch(简单,推荐)
  • Gemini 1.5:使用带有 dynamicThreshold 的 googleSearchRetrieval

最佳实践:

  • 始终检查 groundingMetadata,确认是否使用了搜索
  • 向用户展示引用,确保透明度
  • 使用具体、措辞清晰的问题,以获得更好的搜索结果
  • 与函数调用结合,构建混合工作流

预防已知问题

此技能可预防已记录的 14 个问题:

问题 #1:流式传输时多字节字符损坏

错误:使用非英文文本流式传输回复时,出现乱码或 � 符号 来源:GitHub 问题 #764 原因:TextDecoder 在未启用 {stream: true} 选项的情况下将数据块转换为字符串。跨数据块拆分的多字节 UTF-8 字符(中文、日文、韩文、表情符号)会生成无效字符串。

预防措施:

// The SDK already fixes this, but if implementing custom streaming:
const decoder = new TextDecoder();
const { value } = await reader.read();
const text = decoder.decode(value, { stream: true }); // ← stream: true required

受影响对象:所有使用多字节字符的非英语语言 状态:已在 SDK 中修复,但仍为自定义实现提供相关说明


问题 #2:不支持 Safety Settings 方法参数

错误:“Gemini API 不支持 method 参数” 来源:GitHub Issue #810 原因:safetySettings 中的 method 参数仅适用于 Vertex AI Gemini API,不适用于 Gemini Developer API 或 Google AI Studio。SDK 允许传入该参数,但不会进行验证。

预防措施:

// ❌ WRONG - Fails with Gemini Developer API:
config: {
  safetySettings: [{
    category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
    threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
    method: HarmBlockMethod.SEVERITY // Not supported!
  }]
}

// ✅ CORRECT - Omit 'method' for Gemini Developer API:
config: {
  safetySettings: [{
    category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
    threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE
    // No 'method' field
  }]
}

受影响对象:Gemini Developer API 和 Google AI Studio 用户 状态:已知限制;如果需要使用 method 参数,请使用 Vertex AI


问题 #3:Safety Settings 的阈值因模型而异

错误:尽管设置了严格的 Safety Settings,内容仍然通过;或者 safetyRatings 显示 NEGLIGIBLE,但输出为空 来源:GitHub Issue #872 原因:不同模型的拦截阈值不同。gemini-2.5-flash 的拦截比 gemini-2.0-flash 更严格。此外,只有在输入内容被拦截时才会显示 promptFeedback;如果模型生成的是拒绝消息,safetyRatings 可能会显示 NEGLIGIBLE。

预防措施:

// Check BOTH promptFeedback AND empty response:
if (response.candidates[0].finishReason === 'SAFETY' ||
    !response.text || response.text.trim() === '') {
  console.log('Content blocked or refused');
}

// Be aware: Different models have different thresholds
// gemini-2.5-flash: Lower threshold (stricter blocking)
// gemini-2.0-flash: Higher threshold (more permissive)

受影响对象:所有使用 Safety Settings 的模型 状态:已知行为;模型阈值因模型而异是预期设计


问题 #4:FunctionCallingConfigMode.ANY 导致无限循环

错误:模型不断循环调用工具,始终不返回文本响应 来源:GitHub Issue #908 原因:将 FunctionCallingConfigMode.ANY 与自动函数调用(CallableTool)一起使用时,模型会在每轮中被强制至少调用一个工具,因此实际上无法停止,直到达到最大调用次数限制才会结束循环。

预防措施:

// ❌ WRONG - Loops forever:
config: {
  toolConfig: {
    functionCallingConfig: {
      mode: FunctionCallingConfigMode.ANY // Forces tool calls forever
    }
  }
}

// ✅ CORRECT - Use AUTO mode (model decides):
config: {
  toolConfig: {
    functionCallingConfig: {
      mode: FunctionCallingConfigMode.AUTO // Model can choose to answer directly
    }
  }
}

// Or use manual function calling (check for functionCall, execute, send back)

受影响对象:使用 CallableTool 的自动函数调用 状态:已知限制;请使用 AUTO 模式或手动函数调用


问题 #5:结构化输出无法保留转义反斜杠(Gemini 3)

错误:结构化输出导致 JSON.parse 失败,或包含反斜杠的键不正确 来源:GitHub Issue #1226 原因:当使用 responseMimeType: "application/json",且架构键包含转义反斜杠(例如,键 \a 写作 \\a)时,模型输出不会保留 JSON 转义字符。输出中只会有一个反斜杠,从而导致 JSON 无效。

预防措施:

// Avoid using backslashes in JSON schema keys
// Or manually post-process if required:
let jsonText = response.text;
// Add custom escaping logic if needed

受影响对象:结构化输出中键包含反斜杠的 Gemini 3 模型 状态:已知问题,需要使用变通方案


问题 #6:通过 S3 签名 URL 传入的大型 PDF 报错“Document has no pages”

错误:ApiError: {"error":{"code":400,"message":"The document has no pages.","status":"INVALID_ARGUMENT"}} 来源:GitHub Issue #1259 原因:通过 AWS S3 签名 URL 获取的较大 PDF(例如 20MB)在通过 fileData.fileUri 传入时会失败。API 无法从签名 URL 获取或处理 PDF。

预防措施:

// ❌ WRONG - Fails with large PDFs from S3:
contents: [{
  parts: [{
    fileData: {
      fileUri: 'https://bucket.s3.region.amazonaws.com/file.pdf?X-Amz-Algorithm=...'
    }
  }]
}]

// ✅ CORRECT - Fetch and encode to base64:
const pdfResponse = await fetch(signedUrl);
const pdfBuffer = await pdfResponse.arrayBuffer();
const base64Pdf = Buffer.from(pdfBuffer).toString('base64');

contents: [{
  parts: [{
    inlineData: {
      data: base64Pdf,
      mimeType: 'application/pdf'
    }
  }]
}]

受影响对象:来自外部签名 URL 的 PDF 文件 状态:已知限制;请改用 base64 内联数据


问题 #7:在 Gemini 3 模型上使用已上传的视频时出现 404 NOT_FOUND

错误:在 Gemini 3 模型上使用已上传的视频文件时出现 404 NOT_FOUND 来源:GitHub Issue #1220 原因:部分 Gemini 3 模型(gemini-3-flash-preview、gemini-3-pro-preview)不支持免费层级,或即使是付费账户也只能有限使用。上传视频文件时会出现 404。

预防措施:

// ❌ WRONG - 404 error with Gemini 3:
const response = await ai.models.generateContent({
  model: 'gemini-3-pro-preview', // 404 error
  contents: [{
    parts: [
      { text: 'Describe this video' },
      { fileData: { fileUri: videoFile.uri }}
    ]
  }]
});

// ✅ CORRECT - Use Gemini 2.5 for video understanding:
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash', // Works
  contents: [{
    parts: [
      { text: 'Describe this video' },
      { fileData: { fileUri: videoFile.uri }}
    ]
  }]
});

受影响对象:使用视频上传功能的 Gemini 3 预览模型 状态:已知限制;视频处理请使用 Gemini 2.5 模型


问题 #8:配额未超限,但批处理 API 返回 429

错误:使用批处理 API 时出现 429 RESOURCE_EXHAUSTED,即使未超出文档所述的配额 来源:GitHub 问题 #1264 原因:批处理 API 可能会根据服务器负载动态限制速率,或受到静态配额之外未公开的限制。

预防措施:

// Implement exponential backoff for Batch API:
async function batchWithRetry(request, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await ai.batches.create(request);
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

受影响对象:付费层级的批处理 API 用户 状态:正在调查,请使用重试逻辑


问题 #9:上下文缓存仅适用于 Gemini 1.5 模型

错误:使用 Gemini 2.0、2.5 或 3.0 模型创建缓存时出现 404 NOT FOUND 来源:GitHub 问题 #339 原因:上下文缓存仅支持 Gemini 1.5 Pro 和 Gemini 1.5 Flash 模型。文档示例错误地展示了 Gemini 2.0 及更高版本的模型。

预防措施:

// ❌ WRONG - 404 error:
const cache = await ai.caches.create({
  model: 'gemini-2.5-flash', // Not supported
  config: { /* ... */ }
});

// ✅ CORRECT - Use Gemini 1.5 with explicit version:
const cache = await ai.caches.create({
  model: 'gemini-1.5-flash-001', // Explicit version required
  config: { /* ... */ }
});

受影响对象:所有尝试使用上下文缓存的 Gemini 2.x 和 3.x 用户 状态:已知限制,仅 Gemini 1.5 模型支持缓存


问题 #10:结构化输出偶尔会返回反引号,导致 JSON.parse 错误

错误:解析 JSON 响应时出现 SyntaxError: Unexpected token ''**来源**:[GitHub 问题 #976](https://github.com/googleapis/js-genai/issues/976) **原因**:使用responseMimeType: "application/json"时,响应偶尔会包含包裹 JSON 的 Markdown 代码围栏反引号(`` ```json\n{...}\n``` ``),导致JSON.parse()` 出错。

预防措施:

// Strip markdown code fences before parsing:
let jsonText = response.text.trim();

if (jsonText.startsWith('```json')) {
  jsonText = jsonText.replace(/^```json\n/, '').replace(/\n```$/, '');
} else if (jsonText.startsWith('```')) {
  jsonText = jsonText.replace(/^```\n/, '').replace(/\n```$/, '');
}

const data = JSON.parse(jsonText);

受影响对象:所有使用 responseMimeType: "application/json" 进行结构化输出的模型 状态:已知的间歇性问题,需要使用变通方案


问题 #11:Gemini 3 的温度低于 1.0 时会导致循环或推理能力下降

错误:在复杂任务中出现无限循环或推理质量下降 来源:官方故障排除文档 原因:Gemini 3 模型针对温度 1.0 进行了优化。将温度降低到 1.0 以下,可能会导致循环行为,或降低复杂数学和推理任务的性能。

预防措施:

// ❌ WRONG - May cause issues with Gemini 3:
const response = await ai.models.generateContent({
  model: 'gemini-3-flash',
  contents: 'Solve this complex math problem: ...',
  config: {
    temperature: 0.3 // May cause looping/degradation
  }
});

// ✅ CORRECT - Keep default temperature:
const response = await ai.models.generateContent({
  model: 'gemini-3-flash',
  contents: 'Solve this complex math problem: ...',
  config: {
    temperature: 1.0 // Recommended for Gemini 3
  }
});
// Or omit temperature config entirely (uses default 1.0)

受影响对象:Gemini 3 系列模型 状态:官方建议将温度保持在 1.0


问题 #12:2025 年 12 月免费层级的速率限制大幅降低

错误:2025 年 12 月 6 日之后突然出现 429 RESOURCE_EXHAUSTED 错误 来源:LaoZhang AI 博客 | HowToGeek 原因:Google 将免费层级的速率限制降低了 80%–90%,但未进行广泛公告,让开发者措手不及。

变更:

  • Gemini 2.5 Pro:每日请求量减少 80%(100 RPD,原为约 250)
  • Gemini 2.5 Flash:每日约 20 次请求(原为约 250),减少 90%
  • 免费层级现已不适合用于生产环境

预防措施:

// For production, upgrade to paid tier:
// https://ai.google.dev/pricing

// For free tier, implement aggressive rate limiting:
const rateLimiter = {
  requests: 0,
  resetTime: Date.now() + 24 * 60 * 60 * 1000,
  async checkLimit() {
    if (Date.now() > this.resetTime) {
      this.requests = 0;
      this.resetTime = Date.now() + 24 * 60 * 60 * 1000;
    }
    if (this.requests >= 20) {
      throw new Error('Daily limit reached');
    }
    this.requests++;
  }
};

await rateLimiter.checkLimit();
const response = await ai.models.generateContent({/* ... */});

受影响对象:免费层级用户(2025 年 12 月 6 日起) 状态:永久性变更,生产环境请升级到付费层级


问题 #13:预览模型没有 SLA,且可能在没有警告的情况下发生变更

错误:出现意外的行为变化、弃用或服务中断 来源:Arsturn 博客 | 官方文档 原因:预览版和实验性模型(例如 gemini-2.5-flash-preview、gemini-3-pro-preview)没有服务等级协议(SLA),本身也不稳定。Google 可能会在几乎不提前通知的情况下更改或弃用这些模型。

预防措施:

// ❌ WRONG - Using preview models in production:
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash-preview', // No SLA!
  contents: 'Production traffic'
});

// ✅ CORRECT - Use GA (generally available) models:
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash', // Stable, with SLA
  contents: 'Production traffic'
});

// Or use specific version numbers for stability:
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash-001', // Pinned version
  contents: 'Production traffic'
});

受影响对象:在生产环境中使用预览版或实验性模型的用户 状态:已知限制,生产环境请使用 GA 模型


问题 #14:API 密钥泄漏后自动封禁(安全增强)

错误:意外将密钥提交到 GitHub 后出现“Invalid API key” 来源:AI Free API Blog | 官方故障排除指南 原因:Google 会主动扫描公开暴露的 API 密钥(例如 GitHub 仓库中的密钥),并出于安全考虑自动阻止这些密钥访问 Gemini API。

预防措施:

// Best practices:
// 1. Use .env files (never commit)
// 2. Use environment variables in production
// 3. Rotate keys if exposed
// 4. Use .gitignore:

// .gitignore
.env
.env.local
*.key

受影响用户:意外将 API 密钥提交到公开仓库的用户 状态:安全功能;如果密钥已暴露,请轮换密钥


错误处理

常见错误
1. API 密钥无效(401)
{
  error: {
    code: 401,
    message: 'API key not valid. Please pass a valid API key.',
    status: 'UNAUTHENTICATED'
  }
}

解决方案:确认已正确设置 GEMINI_API_KEY 环境变量。

2. 超出速率限制(429)
{
  error: {
    code: 429,
    message: 'Resource has been exhausted (e.g. check quota).',
    status: 'RESOURCE_EXHAUSTED'
  }
}

解决方案:实施指数退避重试策略。

3. 未找到模型(404)
{
  error: {
    code: 404,
    message: 'models/gemini-3.0-flash is not found',
    status: 'NOT_FOUND'
  }
}

解决方案:使用正确的模型名称:gemini-2.5-pro、gemini-2.5-flash、gemini-2.5-flash-lite

4. 超出上下文长度(400)
{
  error: {
    code: 400,
    message: 'Request payload size exceeds the limit',
    status: 'INVALID_ARGUMENT'
  }
}

解决方案:缩减输入大小。Gemini 2.5 模型最多支持 1,048,576 个输入令牌。

指数退避模式
async function generateWithRetry(request, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await ai.models.generateContent(request);
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

速率限制

⚠️ 2025 年 12 月更新——免费层级大幅缩减

重要:Google 于 2025 年 12 月 6—7 日将免费层级限制降低了 80%—90%,但未进行广泛公告。免费层级现在主要用于原型开发。

来源:LaoZhang AI | HowToGeek

免费层级(Gemini API)——当前限制

速率限制因模型而异:

Gemini 2.5 Pro:

  • 每分钟请求数:5 RPM
  • 每分钟令牌数:125,000 TPM
  • 每日请求数:100 RPD(2025 年 12 月前约为 250)——减少了 80%

Gemini 2.5 Flash:

  • 每分钟请求数:10 RPM
  • 每分钟令牌数:250,000 TPM
  • 每日请求数:约 20 RPD(2025 年 12 月前约为 250)——减少了 90%

Gemini 2.5 Flash-Lite:

  • 每分钟请求数:15 RPM
  • 每分钟令牌数:250,000 TPM
  • 每日请求数:1,000 RPD(未变)
付费层级(Tier 1)

需要将结算账号关联到 Google Cloud 项目。

Gemini 2.5 Pro:

  • 每分钟请求数:150 RPM
  • 每分钟令牌数:2,000,000 TPM
  • 每日请求数:10,000 RPD

Gemini 2.5 Flash:

  • 每分钟请求数:1,000 RPM
  • 每分钟令牌数:1,000,000 TPM
  • 每日请求数:10,000 RPD

Gemini 2.5 Flash-Lite:

  • 每分钟请求数:4,000 RPM
  • 每分钟令牌数:4,000,000 TPM
  • 每日请求数:未指定
更高层级(Tier 2 和 Tier 3)

Tier 2(需要消费 $250 以上并等待 30 天):

  • 可获得更高的限制

Tier 3(需要消费 $1,000 以上并等待 30 天):

  • 可获得最高限制

提示:


SDK 迁移指南

从 @google/generative-ai 迁移到 @google/genai
1. 更新软件包
# Remove deprecated SDK
npm uninstall @google/generative-ai

# Install current SDK
npm install @google/[email protected]
2. 更新导入语句

旧版(已弃用):

import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(apiKey);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });

新版(当前):

import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey });
// Use ai.models.generateContent() directly
3. 更新 API 调用

旧版:

const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();

新版:

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: prompt
});
const text = response.text;
4. 更新流式传输

旧版:

const result = await model.generateContentStream(prompt);
for await (const chunk of result.stream) {
  console.log(chunk.text());
}

新版:

const response = await ai.models.generateContentStream({
  model: 'gemini-2.5-flash',
  contents: prompt
});
for await (const chunk of response) {
  console.log(chunk.text);
}
5. 更新聊天功能

旧版:

const chat = model.startChat();
const result = await chat.sendMessage(message);
const response = await result.response;

新版:

const chat = await ai.models.createChat({ model: 'gemini-2.5-flash' });
const response = await chat.sendMessage(message);
// response.text is directly available

生产环境最佳实践

1. 始终要做

✅ 使用 @google/genai(不要使用 @google/generative-ai) ✅ 设置 maxOutputTokens,防止生成过多内容 ✅ 实现速率限制处理,使用指数退避 ✅ 使用环境变量存储 API 密钥(绝不硬编码) ✅ 在发送到 API 之前验证输入(节省成本) ✅ 对较长的响应使用流式传输,改善用户体验 ✅ 根据需求选择合适的模型(复杂推理选 Pro,兼顾平衡选 Flash,追求速度选 Flash-Lite) ✅ 使用 try-catch 妥善处理错误 ✅ 监控令牌用量,控制成本 ✅ 使用正确的模型名称:gemini-2.5-pro/flash/flash-lite

2. 绝不要做

❌ 绝不要使用 @google/generative-ai(已弃用!) ❌ 绝不要在代码中硬编码 API 密钥 ❌ 绝不要声称 Gemini 2.5 的上下文长度为 2M(其输入令牌数为 1,048,576) ❌ 绝不要在客户端代码中暴露 API 密钥 ❌ 绝不要跳过错误处理(务必使用 try-catch) ❌ 绝不要使用通用速率限制(不同模型的限制各不相同,请查阅官方文档) ❌ 未经用户同意,绝不要发送 PII ❌ 未经验证,绝不要信任用户输入 ❌ 绝不要忽略速率限制(否则会收到 429 错误) ❌ 绝不要使用旧模型名称,例如 gemini-1.5-pro(请使用 2.5 系列模型)

3. 安全性
  • API 密钥存储:使用环境变量或密钥管理器
  • 仅限服务端:绝不要在浏览器 JavaScript 中暴露 API 密钥
  • 输入验证:在调用 API 之前清理所有用户输入
  • 速率限制:自行实现速率限制,以防止滥用
  • 错误消息:不要在错误日志中暴露 API 密钥或敏感数据
4. 成本优化
  • 选择合适的模型:大多数任务使用 Flash,仅在需要时使用 Pro
  • 设置令牌限制:使用 maxOutputTokens 控制成本
  • 批量请求:高效处理多个项目
  • 缓存结果:适时存储响应
  • 监控用量:在 Google Cloud Console 中跟踪令牌消耗
5. 性能
  • 使用流式传输:降低较长响应的感知延迟
  • 并行请求:对相互独立的调用使用 Promise.all()
  • 边缘部署:部署到 Cloudflare Workers,以降低延迟
  • 连接池:尽可能重用 HTTP 连接

快速参考

安装
npm install @google/[email protected]
环境
export GEMINI_API_KEY="..."
模型(2025-2026)
  • gemini-3-flash (1,048,576 输入 / 65,536 输出) - 全新,速度与质量兼顾的最佳选择
  • gemini-2.5-pro (1,048,576 输入 / 65,536 输出) - 复杂推理的最佳选择
  • gemini-2.5-flash (1,048,576 输入 / 65,536 输出) - 久经验证的性价比平衡之选
  • gemini-2.5-flash-lite (1,048,576 输入 / 65,536 输出) - 速度最快、成本效益最高
基本生成
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Your prompt here'
});
console.log(response.text);
流式传输
const response = await ai.models.generateContentStream({...});
for await (const chunk of response) {
  console.log(chunk.text);
}
多模态
contents: [
  {
    parts: [
      { text: 'What is this?' },
      { inlineData: { data: base64Image, mimeType: 'image/jpeg' } }
    ]
  }
]
函数调用
config: {
  tools: [{ functionDeclarations: [...] }]
}

最后更新:2026-01-21 生产环境验证:已使用 @google/[email protected] 测试所有功能 阶段:第 2 阶段已完成 ✅(所有核心功能和高级功能) 已知问题:已记录并避免 14 个错误 变更:新增“已知问题预防”部分,其中包含 14 项基于社区调研的发现,涵盖训练数据截止日期之后的时期(2025 年 5 月至 2026 年 1 月)

评论

支持 Markdown