Aller au contenu

Google Gemini API

L’API Google Gemini est le protocole IA génératif natif de Google. Si votre client est déjà développé selon les spécifications du SDK Google GenAI, il suffit de changer l’URL de base et la clé API vers RouteAPI pour une utilisation directe sans réécrire la structure des requêtes.

L’API Gemini utilise une conception unique où le nom du modèle est intégré dans le chemin URL. Le corps de la requête utilise un tableau contents pour exprimer les conversations, chaque message ayant un rôle user ou model (notez : pas assistant). La structure de réponse utilise un tableau candidates en enveloppe, supportant le filtrage de sécurité et la génération de plusieurs candidats.

Cas d’usage :

ScénarioDescription
SDK Google GenAISDK Python / Node.js google-generativeai, changez seulement base_url
Client REST GeminiApplications déjà développées pour l’API REST Gemini
Applications multimodalesScénarios nécessitant un support natif pour l’entrée d’images, vidéos, audio
Export Google AI StudioLe code exporté depuis AI Studio peut être migré directement

Si votre client ne supporte que le protocole OpenAI, utilisez plutôt Chat Completions. RouteAPI effectuera l’adaptation de format nécessaire en interne, mais privilégier le protocole nativement supporté par votre client garantit la meilleure compatibilité.

La conception des points de terminaison de l’API Gemini est distinctive : le nom du modèle est directement intégré dans le chemin URL.

POST /v1beta/models/{model}:generateContent

Exemple d’adresse complète :

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

Point de terminaison en streaming :

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

Remplacez la partie {model} par le nom réel du modèle, tel que gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash-exp, etc. Notez qu’il n’y a pas d’espace entre le nom du modèle avant les deux-points et le nom de la méthode après.

En-têtes de requête :

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

Tous les protocoles utilisent le même type de jeton RouteAPI. Veuillez enregistrer le jeton côté serveur et ne pas l’exposer aux navigateurs, appareils mobiles ou référentiels publics.

ChampTypeRequisDescription
contentsarrayOuiListe du contenu de conversation, au moins une entrée
generationConfigobjectNonParamètres de configuration de génération
safetySettingsarrayNonParamètres de filtrage de sécurité
systemInstructionobjectNonInstruction système, champ indépendant
toolsarrayNonDéfinitions d’outils d’appel de fonction
toolConfigobjectNonConfiguration d’appel d’outil

Exemple de requête de base :

{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Veuillez présenter RouteAPI en une phrase" }
]
}
],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 1024
}
}

L’API Gemini utilise une structure imbriquée à trois niveaux :

  1. Le tableau contents contient plusieurs messages
  2. Chaque message a des champs role et parts
  3. Le tableau parts contient les blocs de contenu réels

Différences clés :

  • role ne peut être que user ou model (pas assistant)
  • Le contenu doit être placé dans le tableau parts, chaque élément étant un objet part
  • Supporte les parts multimodales : texte, image, vidéo, audio peuvent être mélangés dans les parts du même message
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Analysez cette image" },
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "données d'image encodées en base64..."
}
}
]
},
{
"role": "model",
"parts": [
{ "text": "Ceci est une image montrant..." }
]
}
]
}
ParamètreTypeDescription
temperaturenumberTempérature d’échantillonnage, plage 0 à 2, défaut 1.0
topPnumberParamètre nucleus sampling, défaut 0.95
topKintegerÉchantillonner uniquement parmi les K tokens avec la plus haute probabilité
maxOutputTokensintegerNombre maximum de tokens de sortie
stopSequencesarraySéquences d’arrêt personnalisées, maximum 5
candidateCountintegerNombre de candidats à générer, défaut 1
responseMimeTypestringFormat de réponse, par exemple "application/json"
responseSchemaobjectSchéma JSON pour contraindre la structure de sortie

Exemple :

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

L’instruction système est un champ indépendant, pas dans contents :

{
"systemInstruction": {
"parts": [
{ "text": "Vous êtes un assistant technique rigoureux qui garde les réponses concises." }
]
},
"contents": [
{
"role": "user",
"parts": [{ "text": "Expliquez ce qu'est une passerelle API" }]
}
]
}

Contrôle les niveaux de filtrage de sécurité du contenu :

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

Catégories courantes : HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_HATE_SPEECH, HARM_CATEGORY_SEXUALLY_EXPLICIT, HARM_CATEGORY_DANGEROUS_CONTENT.

Options de seuil : BLOCK_NONE, BLOCK_LOW_AND_ABOVE, BLOCK_MEDIUM_AND_ABOVE, BLOCK_ONLY_HIGH.

L’API Gemini supporte nativement l’entrée multimodale via différents types dans le tableau parts.

{ "text": "Ceci est du contenu textuel" }
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQAAAQ..."
}
}

Formats d’image supportés : 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"
}
}

Support vidéo : video/mp4, video/mpeg, video/mov, etc. Support audio : audio/wav, audio/mp3, audio/aac, etc.

{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Analysez la relation entre cette vidéo et cette image" },
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "gs://my-bucket/video.mp4"
}
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "base64..."
}
}
]
}
]
}
{
"candidates": [
{
"content": {
"parts": [
{
"text": "RouteAPI est une passerelle API qui unifie la gestion de plusieurs fournisseurs de modèles IA."
}
],
"role": "model"
},
"finishReason": "STOP",
"safetyRatings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"probability": "NEGLIGIBLE"
}
]
}
],
"usageMetadata": {
"promptTokenCount": 12,
"candidatesTokenCount": 18,
"totalTokenCount": 30
}
}
ChampDescription
candidatesTableau de réponses candidates, défaut est un
candidates[].contentContenu généré, même structure que l’élément contents dans la requête
candidates[].content.roleToujours "model"
candidates[].finishReasonRaison de l’achèvement
candidates[].safetyRatingsDétails de notation de sécurité
usageMetadataStatistiques d’utilisation des tokens
ValeurSignification
STOPLe modèle s’est terminé naturellement
MAX_TOKENSLimite maxOutputTokens atteinte
SAFETYBloqué en raison du déclenchement du filtre de sécurité
RECITATIONBloqué en raison de la détection de contenu répétitif
OTHERAutres raisons
ChampDescription
promptTokenCountNombre de tokens d’entrée
candidatesTokenCountNombre de tokens de sortie (somme de tous les candidats)
totalTokenCountNombre total de tokens
cachedContentTokenCountNombre de tokens en cache (si le cache de contexte est utilisé)

Utilisez le point de terminaison streamGenerateContent pour implémenter la réponse en streaming :

POST /v1beta/models/{model}:streamGenerateContent

La réponse en streaming utilise le format SSE (Server-Sent Events), chaque événement étant un objet JSON :

data: {"candidates":[{"content":{"parts":[{"text":"RouteAPI"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":1,"totalTokenCount":13}}
data: {"candidates":[{"content":{"parts":[{"text":" est une"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":3,"totalTokenCount":15}}
data: {"candidates":[{"content":{"parts":[{"text":" passerelle API"}],"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}}

Caractéristiques du streaming :

  • Chaque chunk est un objet JSON complet contenant la structure candidates complète
  • finishReason est une chaîne vide pour continuer, a une valeur pour indiquer l’achèvement
  • Le dernier chunk contient les safetyRatings complets et les usageMetadata finaux
  • La réponse en streaming n’a pas de marqueur [DONE] explicite, s’appuie sur finishReason pour déterminer l’achèvement

L’API Gemini supporte l’appel de fonction pour permettre au modèle d’appeler des outils externes.

{
"tools": [
{
"functionDeclarations": [
{
"name": "get_weather",
"description": "Interroger la météo actuelle pour une ville spécifiée. Utilisez le nom complet de la ville.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Nom de la ville, par exemple Paris"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
}
}
]
}
]
}

Le modèle retourne une demande d’appel de fonction :

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

Retourner les résultats d’exécution de fonction comme nouveau message user :

{
"contents": [
{
"role": "user",
"parts": [{ "text": "Quel temps fait-il à Paris maintenant ?" }]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": { "city": "Paris", "unit": "celsius" }
}
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_weather",
"response": {
"content": "Paris, ensoleillé, température 23 degrés Celsius, humidité 45%."
}
}
}
]
}
]
}
ÉlémentGemini APIOpenAI Chat Completions
Format de point de terminaison/v1beta/models/{model}:generateContent/v1/chat/completions
Spécification du modèleDans le chemin URLChamp model du corps de requête
Champ tableau de conversationcontentsmessages
Structure de messagerole + tableau partsrole + chaîne/tableau content
Noms de rôlesuser / modeluser / assistant / system
Instruction systèmeObjet systemInstructionrole: "system" dans messages
Enveloppe de réponseTableau candidatesTableau choices
Emplacement du contenu de réponsecandidates[0].content.parts[0].textchoices[0].message.content
Champ raison d’achèvementfinishReasonfinish_reason
Champ statistiques d’utilisationusageMetadatausage
Gemini APIOpenAI Chat CompletionsNotes
generationConfig.temperaturetemperatureGemini max 2, OpenAI aussi 2
generationConfig.topPtop_pStyle de nommage différent
generationConfig.topKPas d’équivalentOpenAI ne supporte pas
generationConfig.maxOutputTokensmax_tokens / max_completion_tokensNom de champ différent
generationConfig.stopSequencesstopNom différent
generationConfig.candidateCountnMême sémantique
generationConfig.responseMimeTyperesponse_format.typeMéthode de contrôle différente
generationConfig.responseSchemaresponse_format.json_schemaHiérarchie différente
safetySettingsPas d’équivalentOpenAI utilise l’API de modération de contenu
tools[].functionDeclarationstools[].functionNiveau d’enveloppe différent
toolConfigtool_choiceNom de champ et structure différents

Lors de la migration d’OpenAI vers l’API Gemini, vérifiez dans l’ordre suivant :

  1. Déplacer le nom du modèle vers le chemin URL : /v1beta/models/gemini-1.5-pro:generateContent
  2. Renommer messages en contents, changer la structure de chaque message en role + tableau parts
  3. Changer tous les rôles assistant en model
  4. Changer le champ content en tableau parts, envelopper le contenu textuel comme { "text": "..." }
  5. Déplacer le prompt système du tableau messages vers l’objet systemInstruction
  6. Envelopper les paramètres de génération dans l’objet generationConfig et ajuster les noms de champs (par exemple maxOutputTokens, stopSequences)
  7. Modifier l’analyse de réponse pour extraire le contenu de candidates[0].content.parts[0].text
  8. Changer le point de terminaison de streaming en streamGenerateContent, chaque chunk est un JSON complet
  9. Changer la définition d’outil en enveloppe functionDeclarations, champ de paramètre en parameters
GeminiOpenAIClaude
useruseruser
modelassistantassistant
Pas de rôle indépendantsystemPas de rôle indépendant
Pas de rôle indépendanttoolPas de rôle indépendant

Gemini et Claude élèvent tous deux l’instruction système en champ de niveau supérieur, ne la traitant pas comme un rôle de message.

Utilisant le SDK Python Google GenAI, changez seulement client_options :

import os
import google.generativeai as genai
from google.api_core.client_options import ClientOptions
# Configurer le point de terminaison 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(
"Veuillez présenter RouteAPI en une phrase",
generation_config={
"temperature": 0.7,
"max_output_tokens": 1024
}
)
print(response.text)
print(f"Tokens d'entrée : {response.usage_metadata.prompt_token_count}")
print(f"Tokens de sortie : {response.usage_metadata.candidates_token_count}")
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(
["Quels contrôles d'interface utilisateur sont dans cette image ?", image],
generation_config={"max_output_tokens": 2048}
)
print(response.text)
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(
"Expliquez étape par étape ce qu'est une passerelle API",
stream=True
)
for chunk in response:
print(chunk.text, end="", flush=True)
print()
  • Le support réel des paramètres dépend du modèle sélectionné et des capacités du service en amont. Certaines fonctionnalités avancées (comme le cache de contexte, l’exécution de code) doivent d’abord être vérifiées dans un environnement de test.
  • Les paramètres facultatifs explicitement passés comme 0 ou false sont traités comme des valeurs définies par l’utilisateur, pas comme des valeurs par défaut à ignorer.
  • Les environnements de production doivent fixer les ID de modèle et ne pas dépendre d’alias temporaires ou de noms d’affichage.
  • Enregistrez l’ID du modèle, le code de statut et l’utilisation des tokens pour chaque requête pour faciliter le dépannage des anomalies de latence et de coût.
  • Lors de l’utilisation de fileUri avec le protocole gs://, assurez-vous que le fichier est accessible en amont, ou utilisez inlineData pour la transmission directe.
  • Le format de réponse d’erreur peut différer d’OpenAI/Claude, voir Gestion des erreurs.