gemini-agent-dev-support

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Gemini API Development Skill

Gemini API 开发指南

1. Planning Phase (Pre-definition)

1. 规划阶段(预定义)

Before proposing an implementation plan, you must verify and align on these architectural constraints:
  • No Memory: Query Docs MCP
    search_docs
    or refer to
    llms.txt
    for up-to-date SDK specifications.
  • SDK Import: Strictly use
    @google/genai
    (JS/TS) or
    google-genai
    (Python). Never import legacy SDKs.
  • Origin: Web apps must run on a local dev server (e.g.
    localhost
    ). Absolutely no
    file://
    execution.
  • Credentials Policy: Keep API keys and credentials on the server-side/backend proxy. Never expose keys in client-side code.
  • Time Grounding: Plan must include dynamic system instruction time injection.
  • No Mocking: Non-functional elements must be disabled or hidden. No static stub response in production code paths.

在提出实现方案前,必须确认并遵循以下架构约束:
  • 无记忆依赖:查询Docs MCP的
    search_docs
    接口,或参考
    llms.txt
    获取最新的SDK规范。
  • SDK导入要求:严格使用
    @google/genai
    (JS/TS)或
    google-genai
    (Python),禁止导入旧版SDK。
  • 运行源限制:Web应用必须运行在本地开发服务器(如
    localhost
    )上,绝对禁止通过
    file://
    协议执行。
  • 凭证管理策略:API密钥和凭证必须存储在服务器端/后端代理中,严禁在客户端代码中暴露密钥。
  • 时间关联:规划中必须包含动态系统指令时间注入逻辑。
  • 禁止模拟数据:非功能性元素必须禁用或隐藏,生产代码路径中不得使用静态桩响应。

2. Coding & Debugging Phase (Standard Patterns)

2. 编码与调试阶段(标准模式)

Always use these clean code patterns without adding comments in generated production code:
在生成生产代码时,必须遵循以下简洁代码模式,且不得添加注释:

A. IME & Send Event

A. 输入法与发送事件

javascript
input.addEventListener('keydown', (e) => {
  if (e.key === 'Enter') {
    if (e.isComposing || e.keyCode === 229) return;
    if (!e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  }
});
  • Clear
    input.value
    immediately after sending.
  • Disable input element and send button during
    loading === true
    .
  • Prevent sending if
    input.value.trim() === ""
    .
  • Voice Input: Implement actual microphone permission requests, UI state indicators (listening, error, retry), and text input fallback. Never use a silent mic icon placeholder.
javascript
input.addEventListener('keydown', (e) => {
  if (e.key === 'Enter') {
    if (e.isComposing || e.keyCode === 229) return;
    if (!e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  }
});
  • 发送后立即清空
    input.value
  • loading === true
    时,禁用输入框和发送按钮。
  • input.value.trim() === ""
    ,禁止发送请求。
  • 语音输入:需实现实际的麦克风权限请求、UI状态指示器(正在聆听、错误、重试)以及文本输入降级方案,禁止使用无功能的麦克风图标占位符。

B. Model Selection & Time Awareness

B. 模型选择与时间感知

javascript
new GoogleGenAI({}).models.list();
javascript
const systemInstruction = `Current local time: ${new Date().toLocaleString()}`;
javascript
// API Key Validation (verify by listing models via SDK)
async function validateApiKey(apiKey) {
  try {
    const ai = new GoogleGenAI({ apiKey });
    await ai.models.list();
    return true;
  } catch {
    return false;
  }
}
javascript
new GoogleGenAI({}).models.list();
javascript
const systemInstruction = `Current local time: ${new Date().toLocaleString()}`;
javascript
// API Key Validation (verify by listing models via SDK)
async function validateApiKey(apiKey) {
  try {
    const ai = new GoogleGenAI({ apiKey });
    await ai.models.list();
    return true;
  } catch {
    return false;
  }
}

C. Tool Combination (Gemini 2.x vs 3.x)

C. 工具组合(Gemini 2.x 与 3.x)

javascript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});

function adaptGenerateContent(options) {
  // call tools seperately
  // call official tools seperately
}

function withOfficial(options) {
  // append official tools
}

async function callGemini(modelName, userInput, tools = [], enableSearch = false) {
  const options = {
    model: modelName,
    contents: userInput,
    config: { tools }
  }
  return checkAllowToolCombine(modelName) ?
    await adaptGenerateContent(options) :
    await ai.model.generateContent(options);
}
  • Tool Grounding: Update
    systemInstruction
    dynamically. If search is disabled, append:
    "Tool google_search is disabled. Do not attempt to call it."
javascript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});

function adaptGenerateContent(options) {
  // call tools seperately
  // call official tools seperately
}

function withOfficial(options) {
  // append official tools
}

async function callGemini(modelName, userInput, tools = [], enableSearch = false) {
  const options = {
    model: modelName,
    contents: userInput,
    config: { tools }
  }
  return checkAllowToolCombine(modelName) ?
    await adaptGenerateContent(options) :
    await ai.model.generateContent(options);
}
  • 工具关联:动态更新
    systemInstruction
    。若搜索功能禁用,需追加内容:
    "Tool google_search is disabled. Do not attempt to call it."

D. Tool Error Handling

D. 工具错误处理

json
{
  "functionResponse": {
    "name": "unknown_or_failed_tool",
    "response": {
      "error": "Error message for model auto-correction."
    }
  }
}
  • Never throw directly on tool execution error or unknown tool name. Return the structured error JSON above.
json
{
  "functionResponse": {
    "name": "unknown_or_failed_tool",
    "response": {
      "error": "Error message for model auto-correction."
    }
  }
}
  • 工具执行错误或遇到未知工具名称时,不得直接抛出异常,需返回上述结构化错误JSON。

E. History Schema

E. 历史记录 Schema

  • No plural
    functionCalls
    field in history object. Map each single
    functionCall
    to its corresponding
    functionResponse
    .
  • Preserve
    thought
    ,
    signature
    (within interactions context), and server-side tool context in the dialog loop.
  • 历史记录对象中不得使用复数形式的
    functionCalls
    字段,需将每个
    functionCall
    映射到对应的
    functionResponse
  • 在对话循环中保留
    thought
    signature
    (交互上下文内)以及服务器端工具上下文。

F. Error Handling & Safe Rendering

F. 错误处理与安全渲染

json
{
  "error": {
    "code": "API_LIMIT_EXCEEDED",
    "message": "Friendly error summary in Traditional Chinese.",
    "details": {
      "status": 429,
      "reason": "rate_limit_exceeded",
      "debug_info": "Debug stack trace without API keys."
    }
  }
}
javascript
import { marked } from 'marked';
import DOMPurify from 'dompurify';

const safetyHtml = DOMPurify.sanitize(marked.parse(markdown));

json
{
  "error": {
    "code": "API_LIMIT_EXCEEDED",
    "message": "Friendly error summary in Traditional Chinese.",
    "details": {
      "status": 429,
      "reason": "rate_limit_exceeded",
      "debug_info": "Debug stack trace without API keys."
    }
  }
}
javascript
import { marked } from 'marked';
import DOMPurify from 'dompurify';

const safetyHtml = DOMPurify.sanitize(marked.parse(markdown));

Output Format

输出格式

Verification Log

验证日志

  • Docs MCP / Skill Query Link: [e.g. search_docs query]
  • Models: [e.g. gemini-2.5-flash]
  • Docs MCP / 技能查询链接:[例如 search_docs 查询]
  • 模型:[例如 gemini-2.5-flash]

Checklist

检查清单

IDItemResultEvidence
S1SDK / ToolingPASS / FAIL / N/A[code line or test screenshot link]
ID结果证据
S1SDK / 工具链PASS / FAIL / N/A[代码行或测试截图链接]

Code Changes

代码变更

  • [file path]
    : [description of change]
  • [文件路径]
    :[变更描述]

Smoke Test Output

冒烟测试输出

text
[test execution logs]
text
[test execution logs]

Remaining Risks

剩余风险

  • [untested features, proxies, or "None"]
  • [未测试功能、代理,或“无”]

Recurrence Protection

重复问题防护

  • [Describe protection mechanism: Rule / Hook / Test / Skill / "Not Needed" with reason]
  • [描述防护机制:规则 / 钩子 / 测试 / 技能 / “无需防护”并说明原因]