跳到內容

Google Gemini API

Google Gemini API 是 Google 的原生生成式 AI 協定。如果你的客戶端已經按 Google GenAI SDK 規範開發,把 Base URL 和 API Key 換成 RouteAPI 即可直接使用,不需要改寫請求結構。

Gemini API 使用 URL 路徑包含模型名稱的獨特設計,請求本體用 contents 陣列表達對話,每條訊息的角色是 user 或 model(注意不是 assistant)。回應結構用 candidates 陣列包裝,支援安全過濾和多候選生成。

適用場景:

場景說明
Google GenAI SDKgoogle-generativeai Python / Node.js SDK,改 base_url 即可
Gemini REST 客戶端已經按 Gemini REST API 開發的應用
多模態應用需要原生支援圖片、影片、音訊輸入的場景
Google AI Studio 匯出從 AI Studio 匯出的程式碼可直接遷移

如果你的客戶端只支援 OpenAI 協定,請改用 Chat Completions。RouteAPI 會在內部完成必要的格式適配,但優先選擇客戶端原生支援的協定,相容性最好。

Gemini API 的端點設計與眾不同:模型名稱直接嵌入 URL 路徑。

POST /v1beta/models/{model}:generateContent

完整地址範例:

https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:generateContent

串流端點:

https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:streamGenerateContent

{model} 部分替換為實際模型名稱,如 gemini-1.5-pro、gemini-1.5-flash、gemini-2.0-flash-exp 等。注意冒號前的模型名和冒號後的方法名之間沒有空格。

請求標頭:

Authorization: Bearer sk-your-routeapi-token
Content-Type: application/json

所有協定都使用同一類 RouteAPI Token。請在伺服器端儲存 Token,不要把 Token 暴露到瀏覽器、行動裝置或公開儲存庫中。

欄位類型必填說明
contentsarray是對話內容列表,至少一條
generationConfigobject否生成配置參數
safetySettingsarray否安全過濾設定
systemInstructionobject否系統指令,獨立欄位
toolsarray否函式呼叫工具定義
toolConfigobject否工具呼叫配置

基礎請求範例:

{
"contents": [
{
"role": "user",
"parts": [
{ "text": "請用一句話介紹 RouteAPI" }
]
}
],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 1024
}
}

Gemini API 使用三層巢狀結構:

  1. contents 陣列包含多條訊息
  2. 每條訊息有 role 和 parts 欄位
  3. parts 陣列包含實際內容區塊

關鍵差異:

  • role 只能是 user 或 model(不是 assistant)
  • 內容必須放在 parts 陣列裡,每個元素是一個 part 物件
  • 支援多模態 parts:文字、圖片、影片、音訊可以混合在同一條訊息的 parts 中
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "分析這張圖片" },
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "base64編碼的圖片資料..."
}
}
]
},
{
"role": "model",
"parts": [
{ "text": "這是一張展示..." }
]
}
]
}
參數類型說明
temperaturenumber取樣溫度,取值 0 到 2,預設 1.0
topPnumbernucleus sampling 參數,預設 0.95
topKinteger只從機率最高的 K 個 token 中取樣
maxOutputTokensinteger最大輸出 token 數
stopSequencesarray自訂停止序列,最多 5 個
candidateCountinteger生成候選數量,預設 1
responseMimeTypestring回應格式,如 "application/json"
responseSchemaobjectJSON Schema 約束輸出結構

範例:

{
"generationConfig": {
"temperature": 0.9,
"topP": 0.95,
"topK": 40,
"maxOutputTokens": 2048,
"stopSequences": ["END", "STOP"]
}
}

系統指令是獨立欄位,不放在 contents 裡:

{
"systemInstruction": {
"parts": [
{ "text": "你是一個嚴謹的技術助理,回答保持簡潔。" }
]
},
"contents": [
{
"role": "user",
"parts": [{ "text": "解釋什麼是 API 閘道" }]
}
]
}

控制內容安全過濾級別:

{
"safetySettings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
}
]
}

常見類別:HARM_CATEGORY_HARASSMENT、HARM_CATEGORY_HATE_SPEECH、HARM_CATEGORY_SEXUALLY_EXPLICIT、HARM_CATEGORY_DANGEROUS_CONTENT。

閾值選項:BLOCK_NONE、BLOCK_LOW_AND_ABOVE、BLOCK_MEDIUM_AND_ABOVE、BLOCK_ONLY_HIGH。

Gemini API 原生支援多模態輸入,透過 parts 陣列的不同類型實現。

{ "text": "這是文字內容" }
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQAAAQ..."
}
}

支援的圖片格式:image/jpeg、image/png、image/webp、image/heic、image/heif。

{
"fileData": {
"mimeType": "image/jpeg",
"fileUri": "https://example.com/image.jpg"
}
}
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "gs://bucket-name/video.mp4"
}
}

影片支援:video/mp4、video/mpeg、video/mov 等。 音訊支援:audio/wav、audio/mp3、audio/aac 等。

{
"contents": [
{
"role": "user",
"parts": [
{ "text": "分析這段影片和這張圖片的關聯性" },
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "gs://my-bucket/video.mp4"
}
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "base64..."
}
}
]
}
]
}
{
"candidates": [
{
"content": {
"parts": [
{
"text": "RouteAPI 是一個統一管理多家 AI 模型供應商的 API 閘道。"
}
],
"role": "model"
},
"finishReason": "STOP",
"safetyRatings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"probability": "NEGLIGIBLE"
}
]
}
],
"usageMetadata": {
"promptTokenCount": 12,
"candidatesTokenCount": 18,
"totalTokenCount": 30
}
}
欄位說明
candidates候選回應陣列,預設只有一個
candidates[].content生成的內容,結構與請求中的 contents 元素相同
candidates[].content.role始終是 "model"
candidates[].finishReason結束原因
candidates[].safetyRatings安全評級詳情
usageMetadatatoken 用量統計
值含義
STOP模型自然結束
MAX_TOKENS達到 maxOutputTokens 上限
SAFETY觸發安全過濾被阻止
RECITATION偵測到內容重複被阻止
OTHER其他原因
欄位說明
promptTokenCount輸入 token 數
candidatesTokenCount輸出 token 數(所有候選的總和)
totalTokenCount總 token 數
cachedContentTokenCount快取命中 token 數(如果使用了情境快取)

使用 streamGenerateContent 端點實現串流回應:

POST /v1beta/models/{model}:streamGenerateContent

串流回應使用 SSE(Server-Sent Events)格式,每個事件是一個 JSON 物件:

data: {"candidates":[{"content":{"parts":[{"text":"RouteAPI"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":1,"totalTokenCount":13}}
data: {"candidates":[{"content":{"parts":[{"text":" 是一個"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":3,"totalTokenCount":15}}
data: {"candidates":[{"content":{"parts":[{"text":"統一管理"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":5,"totalTokenCount":17}}
data: {"candidates":[{"content":{"parts":[{"text":""}],"role":"model"},"finishReason":"STOP","safetyRatings":[{"category":"HARM_CATEGORY_HARASSMENT","probability":"NEGLIGIBLE"}]}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":18,"totalTokenCount":30}}

串流特點:

  • 每個 chunk 都是完整的 JSON 物件,包含完整的 candidates 結構
  • finishReason 為空字串表示繼續,有值表示結束
  • 最後一個 chunk 包含完整的 safetyRatings 和最終的 usageMetadata
  • 串流回應沒有顯式的 [DONE] 標記,靠 finishReason 判斷結束

Gemini API 支援函式呼叫,用於讓模型呼叫外部工具。

{
"tools": [
{
"functionDeclarations": [
{
"name": "get_weather",
"description": "查詢指定城市的當前天氣。城市名使用中文全稱。",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名,如 北京"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
}
}
]
}
]
}

模型傳回函式呼叫請求:

{
"candidates": [
{
"content": {
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": {
"city": "北京",
"unit": "celsius"
}
}
}
],
"role": "model"
},
"finishReason": "STOP"
}
]
}

把函式執行結果作為新的 user 訊息回傳:

{
"contents": [
{
"role": "user",
"parts": [{ "text": "北京現在天氣怎麼樣?" }]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": { "city": "北京", "unit": "celsius" }
}
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_weather",
"response": {
"content": "北京,晴,氣溫 23 攝氏度,濕度 45%。"
}
}
}
]
}
]
}
項目Gemini APIOpenAI Chat Completions
端點格式/v1beta/models/{model}:generateContent/v1/chat/completions
模型指定URL 路徑中請求本體 model 欄位
對話陣列欄位contentsmessages
訊息結構role + parts 陣列role + content 字串/陣列
角色名稱user / modeluser / assistant / system
系統指令systemInstruction 物件messages 中 role: "system"
回應包裝candidates 陣列choices 陣列
回應內容位置candidates[0].content.parts[0].textchoices[0].message.content
結束原因欄位finishReasonfinish_reason
用量統計欄位usageMetadatausage
Gemini APIOpenAI Chat Completions備註
generationConfig.temperaturetemperatureGemini 上限 2,OpenAI 也是 2
generationConfig.topPtop_p命名風格不同
generationConfig.topK無對應OpenAI 不支援
generationConfig.maxOutputTokensmax_tokens / max_completion_tokens欄位名不同
generationConfig.stopSequencesstop名稱不同
generationConfig.candidateCountn語義相同
generationConfig.responseMimeTyperesponse_format.type控制方式不同
generationConfig.responseSchemaresponse_format.json_schema層級不同
safetySettings無對應OpenAI 使用內容審核 API
tools[].functionDeclarationstools[].function包裝層級不同
toolConfigtool_choice欄位名和結構不同

從 OpenAI 遷移到 Gemini API 時,按以下順序檢查:

  1. 模型名稱移到 URL 路徑:/v1beta/models/gemini-1.5-pro:generateContent
  2. messages 改名為 contents,每條訊息的結構改為 role + parts 陣列
  3. 所有 assistant 角色改為 model
  4. content 欄位改為 parts 陣列,文字內容包裝為 { "text": "..." }
  5. 系統提示詞從 messages 陣列移到 systemInstruction 物件
  6. 生成參數包裝到 generationConfig 物件中,並調整欄位名(如 maxOutputTokens、stopSequences)
  7. 回應解析改為從 candidates[0].content.parts[0].text 提取內容
  8. 串流端點改為 streamGenerateContent,每個 chunk 是完整 JSON
  9. 工具定義改為 functionDeclarations 包裝,參數欄位改為 parameters
GeminiOpenAIClaude
useruseruser
modelassistantassistant
無獨立角色system無獨立角色
無獨立角色tool無獨立角色

Gemini 和 Claude 都把系統指令提到頂層欄位,不作為訊息角色。

Terminal window
curl https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:generateContent \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{ "text": "請用一句話介紹 RouteAPI" }
]
}
],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 1024
}
}'

使用 Google GenAI Python SDK,只需改 client_options:

import os
import google.generativeai as genai
from google.api_core.client_options import ClientOptions
# 設定 RouteAPI 端點
genai.configure(
api_key=os.environ["ROUTEAPI_KEY"],
transport="rest",
client_options=ClientOptions(
api_endpoint="https://api.routeapi.ai/v1beta"
)
)
model = genai.GenerativeModel("gemini-1.5-pro")
response = model.generate_content(
"請用一句話介紹 RouteAPI",
generation_config={
"temperature": 0.7,
"max_output_tokens": 1024
}
)
print(response.text)
print(f"輸入 tokens: {response.usage_metadata.prompt_token_count}")
print(f"輸出 tokens: {response.usage_metadata.candidates_token_count}")
Terminal window
# 將圖片轉為 base64
IMAGE_BASE64=$(base64 -w 0 screenshot.jpg)
curl https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:generateContent \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{ "text": "這張圖裡有哪些介面控制項?" },
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "'"$IMAGE_BASE64"'"
}
}
]
}
],
"generationConfig": {
"maxOutputTokens": 2048
}
}'
import os
import google.generativeai as genai
from google.api_core.client_options import ClientOptions
from PIL import Image
genai.configure(
api_key=os.environ["ROUTEAPI_KEY"],
transport="rest",
client_options=ClientOptions(
api_endpoint="https://api.routeapi.ai/v1beta"
)
)
model = genai.GenerativeModel("gemini-1.5-pro")
image = Image.open("screenshot.jpg")
response = model.generate_content(
["這張圖裡有哪些介面控制項?", image],
generation_config={"max_output_tokens": 2048}
)
print(response.text)
Terminal window
curl https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:streamGenerateContent \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{ "text": "逐步解釋什麼是 API 閘道" }
]
}
]
}'
import os
import google.generativeai as genai
from google.api_core.client_options import ClientOptions
genai.configure(
api_key=os.environ["ROUTEAPI_KEY"],
transport="rest",
client_options=ClientOptions(
api_endpoint="https://api.routeapi.ai/v1beta"
)
)
model = genai.GenerativeModel("gemini-1.5-pro")
response = model.generate_content(
"逐步解釋什麼是 API 閘道",
stream=True
)
for chunk in response:
print(chunk.text, end="", flush=True)
print()
import os
import google.generativeai as genai
from google.api_core.client_options import ClientOptions
genai.configure(
api_key=os.environ["ROUTEAPI_KEY"],
transport="rest",
client_options=ClientOptions(
api_endpoint="https://api.routeapi.ai/v1beta"
)
)
# 定義工具
get_weather_declaration = {
"name": "get_weather",
"description": "查詢指定城市的當前天氣。城市名使用中文全稱。",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名,如 北京"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
}
}
model = genai.GenerativeModel(
"gemini-1.5-pro",
tools=[get_weather_declaration]
)
chat = model.start_chat()
# 第一輪:使用者提問
response = chat.send_message("北京現在天氣怎麼樣?")
# 檢查是否有函式呼叫
if response.candidates[0].content.parts[0].function_call:
function_call = response.candidates[0].content.parts[0].function_call
# 模擬函式執行
if function_call.name == "get_weather":
city = function_call.args["city"]
weather_result = f"{city},晴,氣溫 23 攝氏度,濕度 45%。"
# 第二輪:回傳函式結果
response = chat.send_message(
genai.protos.Content(
parts=[
genai.protos.Part(
function_response=genai.protos.FunctionResponse(
name="get_weather",
response={"content": weather_result}
)
)
]
)
)
print(response.text)
  • 參數的實際支援程度取決於所選模型和上游服務能力,部分進階功能(如情境快取、程式碼執行)建議先在測試環境驗證。
  • 明確傳入 0 或 false 的可選參數會被視為使用者顯式設定,不會當作預設值丟棄。
  • 生產環境建議固定模型 ID,不要依賴臨時別名或顯示名稱。
  • 記錄每次請求的模型 ID、狀態碼和 token 用量,便於排查延遲與成本異常。
  • fileUri 使用 gs:// 協定時需要確保檔案可被上游存取,或使用 inlineData 直接傳輸。
  • 錯誤回應格式可能與 OpenAI/Claude 不同,詳見 錯誤處理。