Aller au contenu

Guide de Conversion de Protocole

RouteAPI, en tant que passerelle API unifiée, gère automatiquement les conversions entre différents formats de protocole en interne. Lorsque vous appelez un modèle Claude en utilisant le protocole OpenAI, ou appelez un modèle Gemini en utilisant le protocole Claude Messages, RouteAPI gère les différences dans la structure des messages, le mappage des paramètres et le format des réponses, vous n’avez donc pas besoin de vous soucier des détails du protocole sous-jacent.

RouteAPI prend en charge trois points d’entrée de protocole principaux :

  • Protocole compatible OpenAI : /v1/chat/completions, /v1/responses
  • Protocole Claude Messages : /v1/messages
  • Protocole Google Gemini : /v1beta/models/{model}:generateContent

Lorsqu’une requête arrive, RouteAPI identifie le type de protocole en fonction du chemin, détermine l’amont cible en fonction de l’ID du modèle, puis effectue les conversions de format nécessaires entre les deux.

ScénarioConversion ?Description
Protocole OpenAI → Modèles OpenAINonPass-through
Claude Messages → Modèles ClaudeNonPass-through
Protocole OpenAI → Modèles ClaudeOuiOpenAI → Claude Messages
Protocole OpenAI → Modèles GeminiOuiOpenAI → Gemini contents
Claude Messages → Modèles OpenAIOuiClaude Messages → OpenAI
Claude Messages → Modèles GeminiOuiClaude Messages → Gemini

La conversion de protocole est transparente pour les clients. Vous envoyez une requête au format OpenAI et recevez une réponse au format OpenAI, même si Claude ou Gemini est appelé en dessous.

Cependant, la conversion a des limites :

  • Les paramètres non pris en charge par le protocole cible seront ignorés ou utiliseront des valeurs par défaut.
  • Certaines capacités spécifiques au protocole (comme la pensée étendue de Claude, la mise en cache des prompts) peuvent ne pas être entièrement exprimables après conversion.
  • Le processus de conversion introduit une légère latence (généralement moins de 10ms).

Meilleure Pratique : Privilégiez l’utilisation du protocole nativement pris en charge par le modèle cible pour obtenir le support de fonctionnalités le plus complet et les meilleures performances.

OpenAI place le system prompt comme premier message dans le tableau messages :

{
"messages": [
{ "role": "system", "content": "Vous êtes un assistant technique rigoureux." },
{ "role": "user", "content": "Expliquez ce qu'est une passerelle API" }
]
}

Claude place le system prompt dans un champ indépendant de niveau supérieur :

{
"system": "Vous êtes un assistant technique rigoureux.",
"messages": [
{ "role": "user", "content": "Expliquez ce qu'est une passerelle API" }
]
}

Règles de Conversion :

  • OpenAI → Claude : Extraire le premier message role: "system" et le déplacer vers le champ system.
  • Claude → OpenAI : Convertir le contenu du champ system en message role: "system" et l’insérer au début du tableau messages.
OpenAIClaudeGeminiDescription
systemChamp system de niveau supérieursystemInstructionPosition du prompt système différente
useruseruserMessage utilisateur, cohérent
assistantassistantmodelRéponse assistant/modèle, noms différents
tooltool_result dans userfunctionResponse dans userAttribution du résultat d’outil différente

Considérations de Conversion :

  • Claude n’accepte pas deux messages consécutifs avec le même rôle ; la conversion nécessite de fusionner ou d’insérer des messages de remplacement.
  • Le rôle model de Gemini est mappé à assistant lors de la conversion vers OpenAI.
  • Le role: "tool" d’OpenAI est fusionné dans les messages user dans Claude et Gemini.

La structure de message de Gemini s’appelle contents, le rôle de chaque message s’appelle role, et le contenu est dans un tableau parts :

{
"contents": [
{
"role": "user",
"parts": [{ "text": "Expliquez ce qu'est une passerelle API" }]
}
]
}

Règles de Conversion :

  • OpenAI messages ↔ Gemini contents
  • OpenAI content ↔ Gemini parts
  • OpenAI assistant ↔ Gemini model
  • Le system prompt se convertit en champ systemInstruction de niveau supérieur
OpenAIClaudeGeminiDescription
temperaturetemperaturetemperatureClaude max 1, OpenAI max 2, Gemini max 2
top_ptop_ptopPéchantillonnage nucleus, tous supportent
Non supportétop_ktopKOpenAI ne supporte pas, supprimé lors de la conversion
max_tokens / max_completion_tokensmax_tokens (requis)maxOutputTokensClaude nécessite une définition explicite
nNon supportécandidateCountClaude ne supporte pas la génération de plusieurs candidats
stopstop_sequencesstopSequencesNoms de champs différents, sémantique cohérente

Conversion de Plage de Température :

Lorsque la temperature d’une requête OpenAI dépasse 1 et que la cible est Claude, RouteAPI la tronque automatiquement à 1 pour éviter le rejet en amont.

OpenAIClaudeGeminiDescription
response_formatNon supportéresponseMimeTypeOpenAI supporte le mode JSON et JSON Schema
frequency_penaltyNon supportéfrequencyPenaltyClaude ne supporte pas les paramètres de pénalité
presence_penaltyNon supportépresencePenaltyClaude ne supporte pas les paramètres de pénalité
streamstreamstreamTous supportent, mais formats d’événements complètement différents
stream_options.include_usageToujours retournéAuto-retourné quand generateContentRequest.stream=trueMéthode de retour des statistiques d’utilisation différente

Comportement de Conversion :

  • frequency_penalty et presence_penalty sont ignorés lors du transfert vers Claude.
  • response_format: { type: "json_object" } est simulé via des appels d’outils lors du transfert vers Claude, ou un prompt de sortie JSON est ajouté au system.
  • n > 1 est réinitialisé à 1 lors du transfert vers Claude, car Claude ne supporte pas la génération de plusieurs candidats.
OpenAIClaudeGeminiDescription
usermetadata.user_idNon supportéPour la détection d’abus
seedNon supportéseedClaude ne supporte pas l’échantillonnage déterministe
logprobs / top_logprobsNon supportéNon supportéSeuls les modèles OpenAI supportent
Non supportéthinkingNon supportéConfiguration de pensée étendue spécifique à Claude
{
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Interroger la météo actuelle d'une ville spécifiée",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "Nom de la ville" }
},
"required": ["city"]
}
}
}
]
}
{
"tools": [
{
"name": "get_weather",
"description": "Interroger la météo actuelle d'une ville spécifiée",
"input_schema": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "Nom de la ville" }
},
"required": ["city"]
}
}
]
}
{
"tools": [
{
"functionDeclarations": [
{
"name": "get_weather",
"description": "Interroger la météo actuelle d'une ville spécifiée",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "Nom de la ville" }
},
"required": ["city"]
}
}
]
}
]
}
OpenAIClaudeGeminiNotes de Conversion
tools[].type: "function"Pas de ce niveauPas de ce niveauSupprimer l’enveloppe type lors de la conversion
tools[].functionAplati dans tools[]Placé dans functionDeclarations[]Structure hiérarchique différente
function.parametersinput_schemaparametersNom de champ Claude différent
OpenAIClaudeGeminiDescription
"auto"{ "type": "auto" }"AUTO"Le modèle décide automatiquement
"none"{ "type": "none" }"NONE"Interdire les appels d’outils
"required"{ "type": "any" }"ANY"Doit appeler un outil
{ "type": "function", "function": { "name": "get_weather" } }{ "type": "tool", "name": "get_weather" }{ "functionCallingConfig": { "allowedFunctionNames": ["get_weather"] } }Forcer un outil spécifique, structure très différente
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "Paris, ensoleillé, 23°C"
}
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Paris, ensoleillé, 23°C"
}
]
}
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_weather",
"response": { "result": "Paris, ensoleillé, 23°C" }
}
}
]
}

Points Clés de Conversion :

  • Le role: "tool" d’OpenAI est fusionné dans les messages user lors de la conversion vers Claude/Gemini.
  • Les noms de champs d’ID d’appel d’outil diffèrent : tool_call_id vs tool_use_id vs identification par nom de fonction Gemini.
  • Claude et Gemini nécessitent tous les résultats d’outils dans le même message user ; OpenAI permet plusieurs messages tool séparés.
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://example.com/image.jpg",
"detail": "high"
}
},
{ "type": "text", "text": "Décrivez cette image" }
]
}
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/image.jpg"
}
},
{ "type": "text", "text": "Décrivez cette image" }
]
}
{
"role": "user",
"parts": [
{
"fileData": {
"mimeType": "image/jpeg",
"fileUri": "https://example.com/image.jpg"
}
},
{ "text": "Décrivez cette image" }
]
}
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
}
}
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "/9j/4AAQSkZJRg..."
}
}
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "/9j/4AAQSkZJRg..."
}
}

Règles de Conversion :

  • L’URI data: d’OpenAI est analysé, media_type extrait du préfixe URI, partie base64 pure passée au protocole cible.
  • Claude nécessite un champ media_type séparé, n’accepte pas l’URI data:.
  • Gemini utilise inlineData au lieu de fileData pour représenter le contenu base64.
  • Le paramètre detail d’OpenAI (low/high) est perdu lors de la conversion ; Claude et Gemini n’ont pas de concept équivalent.
ParamètreProtocole SourceNe Peut Pas Convertir VersRaison
top_kClaude, GeminiOpenAIOpenAI ne supporte pas l’échantillonnage top-k
nOpenAI, GeminiClaudeClaude ne supporte pas la génération de plusieurs candidats
frequency_penalty / presence_penaltyOpenAI, GeminiClaudeClaude n’a pas de paramètres de pénalité
logprobsOpenAIClaude, GeminiSeuls les modèles OpenAI retournent les probabilités logarithmiques
thinkingClaudeOpenAI, GeminiConfiguration de pensée étendue spécifique à Claude
cache_controlClaudeOpenAI, GeminiContrôle de mise en cache de prompt spécifique à Claude
reasoning_effortOpenAIClaude, GeminiParamètre spécifique à la série o1 d’OpenAI
response_format (JSON Schema)OpenAIClaude, GeminiLes contraintes JSON Schema complètes ne sont supportées que par OpenAI

Comment les Paramètres Incompatibles Sont Gérés

Section intitulée « Comment les Paramètres Incompatibles Sont Gérés »

RouteAPI utilise les stratégies suivantes :

  1. Ignorer Silencieusement : Les paramètres non supportés sont supprimés lors de la conversion sans affecter le succès de la requête (ex : detail, logprobs).
  2. Ajustement Automatique : Les valeurs hors limites sont tronquées à la plage légale (ex : temperature > 1 tronqué à 1 lors du transfert vers Claude).
  3. Dégradation Conservatrice : Les fonctionnalités complexes sont simulées avec des méthodes simples (ex : JSON Schema d’OpenAI dégradé en appels d’outils ou contraintes de prompt sur Claude).
  4. Rejeter la Requête : Rarement, si les paramètres essentiels ne peuvent pas être convertis et n’ont pas de valeur par défaut raisonnable, retourner une erreur 400 (ex : protocole Claude manquant max_tokens).

RouteAPI fournit des informations de conversion dans les en-têtes de réponse et les journaux :

X-RouteAPI-Protocol-Conversion: openai-to-claude
X-RouteAPI-Dropped-Params: frequency_penalty,presence_penalty

Si la conversion échoue ou si les paramètres sont en conflit, une réponse d’erreur standard est retournée :

{
"error": {
"message": "Parameter 'max_tokens' is required for Claude models",
"type": "invalid_request_error",
"param": "max_tokens",
"code": "missing_required_parameter"
}
}
  1. Utiliser le Protocole Natif : Utilisez le protocole natif du modèle autant que possible pour éviter les pertes de conversion.
  2. Éviter la Dépendance aux Fonctionnalités Spécifiques au Protocole : Ne dépendez pas de capacités spécifiques à un seul protocole comme logprobs, thinking sauf si vous êtes certain de n’utiliser que les modèles de ce protocole.
  3. Vérifier les En-têtes de Réponse : Faites attention à l’en-tête X-RouteAPI-Dropped-Params pour savoir quels paramètres ont été ignorés.
  4. Tester la Compatibilité Inter-Protocoles : Validez le comportement de la même requête dans différentes combinaisons protocole/modèle dans les environnements de test.
  5. Enregistrer l’ID du Modèle : Enregistrez l’ID du modèle réellement appelé et le type de protocole dans les journaux pour faciliter le dépannage des différences.
ProtocoleChamp input tokenChamp output tokenChamp total token
OpenAIprompt_tokenscompletion_tokenstotal_tokens
Claudeinput_tokensoutput_tokensAucun (calculer vous-même)
GeminipromptTokenCountcandidatesTokenCounttotalTokenCount

Règles de Conversion :

  • Claude → OpenAI : input_tokens → prompt_tokens, output_tokens → completion_tokens, calculer total_tokens = input_tokens + output_tokens.
  • Gemini → OpenAI : promptTokenCount → prompt_tokens, candidatesTokenCount → completion_tokens, totalTokenCount → total_tokens.
  • OpenAI → Claude : prompt_tokens → input_tokens, completion_tokens → output_tokens, supprimer total_tokens.

Les champs de mise en cache de prompt de Claude sont également préservés :

{
"usage": {
"prompt_tokens": 120,
"completion_tokens": 45,
"total_tokens": 165,
"cache_creation_input_tokens": 80,
"cache_read_input_tokens": 40
}
}
OpenAIClaudeGeminiSignification
stopend_turnSTOPFin naturelle
lengthmax_tokensMAX_TOKENSLimite de longueur atteinte
tool_callstool_useSTOP (avec functionCall)Demande d’appel d’outil
content_filterPas d’équivalentSAFETYBloqué par filtre de contenu
stopstop_sequenceSTOPSéquence d’arrêt atteinte

Règles de Conversion :

  • Claude end_turn → OpenAI stop
  • Claude max_tokens → OpenAI length
  • Claude tool_use → OpenAI tool_calls
  • Gemini STOP mappé à stop ou tool_calls selon la présence de functionCall
  • Gemini SAFETY → OpenAI content_filter

Toutes les réponses d’erreur de protocole sont converties au format OpenAI (lorsque le client utilise le protocole OpenAI) :

{
"error": {
"message": "Invalid API key",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}

Erreur originale Claude :

{
"type": "error",
"error": {
"type": "authentication_error",
"message": "invalid x-api-key"
}
}

Après conversion au format OpenAI, type est mappé à invalid_request_error, code est défini sur invalid_api_key.

Requête OpenAI Originale :

{
"model": "claude-sonnet-4-5",
"messages": [
{
"role": "system",
"content": "Vous êtes un assistant technique rigoureux, gardez les réponses concises."
},
{
"role": "user",
"content": "Expliquez ce qu'est une passerelle API"
}
],
"temperature": 0.7,
"max_tokens": 150,
"stream": false
}

Requête Claude Convertie :

{
"model": "claude-sonnet-4-5",
"system": "Vous êtes un assistant technique rigoureux, gardez les réponses concises.",
"messages": [
{
"role": "user",
"content": "Expliquez ce qu'est une passerelle API"
}
],
"temperature": 0.7,
"max_tokens": 150,
"stream": false
}

Changements Clés :

  • Message system extrait du tableau messages vers le champ system de niveau supérieur.
  • messages ne contient maintenant que les messages user et assistant.

Exemple 2 : Appel d’Outil Claude → Format OpenAI

Section intitulée « Exemple 2 : Appel d’Outil Claude → Format OpenAI »

Réponse d’Appel d’Outil Claude :

{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-5",
"content": [
{
"type": "text",
"text": "Laissez-moi vérifier la météo de Paris."
},
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "get_weather",
"input": { "city": "Paris" }
}
],
"stop_reason": "tool_use",
"usage": {
"input_tokens": 120,
"output_tokens": 45
}
}

Converti au Format OpenAI :

{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"object": "chat.completion",
"created": 1726567890,
"model": "claude-sonnet-4-5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Laissez-moi vérifier la météo de Paris.",
"tool_calls": [
{
"id": "toolu_01A09q90qw90lq917835lq9",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 120,
"completion_tokens": 45,
"total_tokens": 165
}
}

Changements Clés :

  • Tableau content divisé : bloc text extrait comme champ content, bloc tool_use converti en tableau tool_calls.
  • Objet tool_use.input sérialisé en chaîne JSON function.arguments.
  • stop_reason: "tool_use" → finish_reason: "tool_calls".
  • input_tokens → prompt_tokens, output_tokens → completion_tokens, ajout de total_tokens.
  • Ajout de champs de niveau supérieur au format OpenAI : object, created, tableau choices.

Réponse Gemini :

{
"candidates": [
{
"content": {
"parts": [
{
"text": "Cette image montre une interface utilisateur moderne avec une barre de navigation, une zone de contenu et une barre latérale."
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 258,
"candidatesTokenCount": 32,
"totalTokenCount": 290
}
}

Converti au Format OpenAI :

{
"id": "chatcmpl-gemini-abc123",
"object": "chat.completion",
"created": 1726567890,
"model": "gemini-2.0-flash-exp",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Cette image montre une interface utilisateur moderne avec une barre de navigation, une zone de contenu et une barre latérale."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 258,
"completion_tokens": 32,
"total_tokens": 290
}
}

Changements Clés :

  • candidates[0].content.parts[0].text → choices[0].message.content.
  • role: "model" → role: "assistant".
  • finishReason: "STOP" → finish_reason: "stop" (converti en minuscules).
  • Noms de champs usageMetadata mappés à la structure usage d’OpenAI.

Sélectionnez le protocole en fonction du type de client et de modèle :

Type de ClientModèle CibleProtocole RecommandéRaison
SDK OpenAIModèles OpenAIOpenAISupport natif, aucune conversion
Claude CodeModèles ClaudeClaude MessagesSupport natif, aucune conversion
LangChain / LiteLLMTout modèleOpenAIMeilleure compatibilité d’écosystème
SDK AnthropicModèles ClaudeClaude MessagesAccès à la pensée étendue, mise en cache de prompt
Client personnaliséTout modèleSelon les besoinsPréférer le protocole natif du modèle cible

2. Éviter les Fonctionnalités Spécifiques au Protocole

Section intitulée « 2. Éviter les Fonctionnalités Spécifiques au Protocole »

Si l’entreprise nécessite un changement de modèle, évitez d’utiliser ces fonctionnalités :

  • Spécifique à OpenAI : logprobs, seed, contraintes JSON Schema complètes, reasoning_effort (série o1)
  • Spécifique à Claude : thinking, cache_control, mcp_servers
  • Spécifique à Gemini : grounding, codeExecution

Ensemble de fonctionnalités universelles (tous supportent) :

  • Conversation de base (messages / contents)
  • Sortie en streaming (stream)
  • Contrôle de température (temperature, noter les différences de plage)
  • Appel d’outils (tools, noter les différences de format)
  • Entrée multimodale (images, noter les différences de format)
  • Séquences d’arrêt (stop / stop_sequences / stopSequences)

Validez ces scénarios dans les environnements de test :

  1. Même protocole, modèles différents : Assurez-vous que le protocole OpenAI appelle correctement les modèles Claude et Gemini.
  2. Protocoles différents, même modèle : Vérifiez la cohérence des résultats lors de l’appel du même modèle Claude via les protocoles Claude Messages et OpenAI.
  3. Aller-retour d’appel d’outil : Testez si la définition, l’invocation et le passage de résultat d’outil sont corrects à travers les protocoles.
  4. Paramètres limites : Testez les cas limites comme temperature: 1.5 (OpenAI valide, Claude nécessite troncature), n: 2 (OpenAI supporte, Claude non).
  5. Gestion des erreurs : Vérifiez que les erreurs en amont sont correctement converties au format de protocole client.

Enregistrez les informations suivantes pour le dépannage des problèmes de conversion de protocole :

{
"request_id": "req_abc123",
"client_protocol": "openai",
"model_id": "claude-sonnet-4-5",
"upstream_protocol": "claude",
"conversion_required": true,
"dropped_params": ["frequency_penalty", "logprobs"],
"adjusted_params": {"temperature": {"original": 1.8, "adjusted": 1.0}},
"latency_ms": 856,
"conversion_overhead_ms": 8
}

Métriques clés :

  • Taux de réussite de conversion : Pourcentage d’erreurs 400 causées par des échecs de conversion de protocole.
  • Latence de conversion : Latence supplémentaire introduite par la conversion de protocole (généralement 5-15ms).
  • Taux de suppression de paramètres : Quels paramètres sont le plus souvent supprimés, s’ils affectent l’entreprise.
  • Taux d’erreur inter-protocoles : Si les appels OpenAI → Claude ont des taux d’erreur plus élevés que OpenAI → OpenAI.

Si vous migrez d’un protocole à un autre :

  1. Phase 1 : Test en double écriture : Les résultats des appels du nouveau protocole ne sont utilisés que pour la comparaison, n’affectent pas l’entreprise.
  2. Phase 2 : Basculement progressif : Petit trafic bascule vers le nouveau protocole, surveiller le taux d’erreur et la qualité de réponse.
  3. Phase 3 : Basculement complet : Basculer tout le trafic après confirmation qu’il n’y a pas d’anomalies.
  4. Phase 4 : Nettoyage de l’ancien code : Supprimer le code d’adaptation de l’ancien protocole.

Chaque phase nécessite une validation :

  • Exactitude fonctionnelle (appel d’outil, multimodal, sortie en streaming)
  • Qualité de réponse (différences de sortie entre différentes combinaisons protocole/modèle)
  • Métriques de performance (latence, utilisation de jetons, coût)
  • Gestion des erreurs (anomalies réseau, limitations de débit, pannes en amont)

La conversion de protocole vous permet de choisir flexiblement les clients et les modèles, mais la meilleure pratique reste de privilégier l’utilisation du protocole natif du modèle cible. Si un appel inter-protocoles est nécessaire, validez soigneusement dans les environnements de test et surveillez les erreurs et les métriques de performance liées à la conversion dans l’environnement de production.