Gemini 3.8 Flash a été lancé le 2 septembre 2026, et Google l'a conçu pour « appeler les outils de manière itérative » : sur une tâche difficile, il effectue un appel, vérifie le résultat, puis en effectue un autre, au lieu de tout deviner d'un seul coup. C'est une bonne nouvelle pour les agents et un nouveau casse-tête pour tous ceux dont la boucle d'outil était configurée pour le 3.7 Flash. Deux détails de l'API sont plus importants que tout le reste. Chaque résultat de fonction doit inclure `call_id` et `name`, et l'API Interactions, et non `generateContent`, est désormais le moyen principal d'exécuter la boucle.
Ce guide décrit le flux complet en deux étapes sur l'API Interactions, présente la forme `generateContent` héritée que vous utilisez probablement encore, explique pourquoi le nouveau modèle consacre plus d'étapes et de jetons aux outils, et se termine par une configuration de test que vous pouvez exécuter tous les jours : simuler le backend de l'outil, enchaîner les deux étapes et vérifier que le `call_id` fait des allers-retours. Si vous avez d'abord besoin d'un aperçu du modèle, commencez par ce qu'est Gemini 3.8 Flash. Les noms de champs ci-dessous proviennent de la documentation sur l'appel de fonction de Google.
Chaque requête ici est du simple HTTP avec JSON, vous pouvez donc la construire et la déboguer dans Apidog avant qu'elle n'entre dans le code de l'application.
Appel de fonction sur Gemini 3.8 Flash en un coup d'œil
| Élément | Gemini 3.8 Flash |
|---|---|
| ID du modèle | gemini-3.8-flash (stable, sans suffixe de préversion) |
| API principale | API Interactions (POST /v1beta/interactions) ; generateContent est hérité mais entièrement pris en charge |
| Déclaration de l'outil | tools: [{"type": "function", "name", "description", "parameters"}] |
| Appel du modèle | Étape function_call avec id, name, arguments |
| Votre réponse | function_result avec call_id + name (les deux requis) plus previous_interaction_id |
| Réflexion | thinking_level low / medium (par défaut) / high ; minimal renvoie une erreur de validation |
| Score d'utilisation des outils | Tau3-Banking 45 %, +12 points par rapport au 3.7 Flash (Artificial Analysis, indépendant) |
| Coût des jetons | ~48k jetons de sortie par tâche sur l'indice AA, +30 % par rapport au 3.7 Flash |
| Prix | 0,75 $ en entrée / 3,75 $ en sortie par 1M jusqu'au 31/12/2026 ; la réflexion est facturée comme sortie |
Étape 1 : déclarer l'outil
Sur l'API Interactions, un outil est un objet plat : un `type` de `function`, un `name`, une `description` que le modèle lit pour décider quand l'appeler, et un schéma JSON sous `parameters`. Gardez la description spécifique. « Rechercher le statut d'expédition actuel d'une commande par son ID » est appelé au bon moment ; « aide-commande » est appelé au hasard.
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Where is order A1029 right now?",
"generation_config": {"thinking_level": "low"},
"tools": [{
"type": "function",
"name": "get_order_status",
"description": "Look up the current shipping status of an order by its ID.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"]
}
}]
}'
Deux choix dans cette requête sont délibérés. `thinking_level` est `low` car une simple recherche n'a pas besoin du `medium` par défaut ; le guide des niveaux de réflexion explique quand l'augmenter. Et il n'y a pas de `temperature`. La recommandation de Google pour Gemini 3 est de le laisser à la valeur par défaut de 1.0, car la réduire peut provoquer des boucles, ce qui est la dernière chose que vous voulez à l'intérieur d'une boucle d'outil.
Étape 2 : lire l'étape `function_call`
L'API Interactions ne répond pas avec un seul message. Elle renvoie l'`id` propre à l'interaction ainsi qu'une liste d'étapes d'exécution : pensées du modèle, appels d'outils, et enfin une étape `model_output` une fois que le modèle a une réponse. Lorsque le modèle décide qu'il a besoin de votre outil, la liste contient une étape `function_call` au lieu d'un `model_output` :
{
"type": "function_call",
"id": "call_8f2d...",
"name": "get_order_status",
"arguments": {"order_id": "A1029"}
}
Trois champs, et vous avez besoin des trois. `id` est le handle que vous renvoyez en tant que `call_id`. `name` vous indique quelle fonction exécuter et doit également être renvoyé. `arguments` est déjà du JSON parsé, alors validez-le selon vos propres règles avant d'exécuter quoi que ce soit ; le modèle remplit la forme que vous avez déclarée, mais il ne sait pas que vos ID de commande ont cinq caractères.
Stockez l'`id` de l'interaction en haut de la réponse en même temps. Il devient `previous_interaction_id` au tour suivant.
Étape 3 : retourner le résultat avec `call_id` et `name`
Exécutez votre fonction, puis envoyez une deuxième requête dont l'`input` est un `function_result`. `call_id` et `name` sont tous deux requis sur Gemini 3.8 Flash. En omettre un des deux fait échouer l'appel, ce qui est l'erreur la plus courante lorsque les équipes migrent des boucles écrites pour des modèles plus anciens.
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"previous_interaction_id": "<interaction id from step 2>",
"input": [{
"type": "function_result",
"name": "get_order_status",
"call_id": "call_8f2d...",
"result": [{"type": "text", "text": "{\"status\":\"in_transit\",\"eta\":\"2026-09-05\"}"}]
}]
}'
`result` est une liste de parties de contenu, et la partie texte contient votre JSON sous forme de chaîne. Parce que `previous_interaction_id` pointe vers l'étape précédente, le serveur détient déjà le prompt original, la déclaration de l'outil et le raisonnement du modèle ; vous n'avez rien à renvoyer de cela. La réponse est une autre liste d'étapes. Si elle se termine par `model_output`, vous avez terminé, et le SDK expose le texte en tant que `interaction.output_text`. Si elle contient un autre `function_call`, retournez à l'étape 2. Cette boucle est tout le modèle.
En Python, le flux est `client.interactions.create(model="gemini-3.8-flash", input=..., ...)` avec les mêmes champs JSON que les arguments nommés, puis un deuxième `create` avec `previous_interaction_id` et la liste `function_result` comme `input`. Le guide pratique de l'API Gemini 3.8 Flash couvre les clés, le streaming et la lecture de l'utilisation des jetons si le point de terminaison est nouveau pour vous.
L'équivalent `generateContent` hérité
La plupart du code Gemini existant appelle toujours `models/gemini-3.8-flash:generateContent`, et Google indique qu'il « reste entièrement pris en charge » sans date de fin de support. Le vocabulaire est différent ; la règle est la même. Les outils sont déclarés sous `functionDeclarations`, le modèle répond avec une partie `functionCall`, et vous répondez avec une partie `functionResponse`. Sur la forme héritée, la partie `functionCall` du modèle contient un `id`, et votre partie `functionResponse` doit renvoyer la même valeur dans son propre champ `id` à côté de `name` et `response`. C'est le même contrat que `call_id` sur l'API Interactions sous un nom de champ différent, et les directives de Google pour Gemini 3 sont explicites sur le fait que l'id et le nom sont tous deux requis.
Deux différences pratiques. Premièrement, `generateContent` est sans état, vous gérez donc vous-même la conversation : l'historique complet des `contents` est renvoyé à chaque étape, y compris la partie `functionCall` du modèle et toutes les signatures de pensée qu'il a renvoyées. Deuxièmement, la réflexion est configurée sous `generationConfig.thinkingConfig.thinkingLevel` au lieu de `generation_config.thinking_level` :
{"generationConfig": {"thinkingConfig": {"thinkingLevel": "low"}}}
Les jetons de réflexion apparaissent sous `usageMetadata.thoughtsTokenCount` dans la réponse et sont facturés comme sortie. Si vous choisissez entre les deux API pour un nouveau projet, choisissez Interactions : l'état côté serveur élimine la catégorie de bugs où un historique renvoyé manque une signature ou un `call_id`.
Pourquoi 3.8 Flash appelle les outils de manière itérative et comment limiter la boucle
Le billet de lancement de Google indique que le modèle « travaille plus dur » : sur des tâches complexes, il « exécute des étapes de raisonnement supplémentaires et appelle les outils de manière itérative », effectuant « des étapes de raisonnement plus petites » et vérifiant son travail en cours de route. Google affirme également qu'il « peut utiliser plus de jetons sur des tâches plus longues et complexes, par conception ». Artificial Analysis a mesuré l'effet : environ 48k jetons de sortie par tâche sur leur indice, +30% par rapport au 3.7 Flash, et un coût par tâche de 0,58 $ en mode `high` contre 0,40 $ pour le 3.7 Flash aux mêmes prix par jeton. Le mode Medium a coûté 0,41 $ et le mode low 0,24 $.
Pour une boucle d'outil, cela signifie plus d'étapes `function_call` par tâche. L'avantage est réel : Tau3-Banking, l'évaluation d'utilisation d'outils d'AA, a augmenté de 12 points pour atteindre 45%. L'inconvénient est qu'une boucle sans plafond fonctionne désormais plus longtemps qu'en août. Quatre contrôles, dans l'ordre où les appliquer :
- Nombre maximal d'étapes dans votre système. Comptez les étapes `function_call` par tâche et arrêtez-vous à une limite que vous choisissez ; 6 à 10 est une fourchette raisonnable pour les recherches, plus élevée pour le codage agentique. Lorsque la limite est atteinte, envoyez une dernière étape sans outils, ou renvoyez une erreur à l'utilisateur. Le modèle ne se limitera pas lui-même.
thinking_levelpar route. `low` pour les recherches et les outils à un seul saut, `medium` (par défaut) pour les travaux en plusieurs étapes, `high` uniquement lorsque la vérification supplémentaire est rentable. N'envoyez pas `minimal` ; 3.8 Flash renvoie une erreur de validation.- Délais d'attente des deux côtés. Un délai d'attente par requête sur l'appel Gemini et un temps réel par tâche sur la boucle. Les exécutions à raisonnement élevé d'AA ont duré en moyenne 2,5 minutes par tâche, 0,8 minute en mode `low`.
- Outils idempotents. Un modèle itératif réessaie. Rendez `get_order_status` sûr à appeler deux fois, et tout ce qui a des effets secondaires (remboursements, envois) nécessite une étape de confirmation.
Si votre budget ne peut pas absorber les étapes supplémentaires, le guide de migration de 3.7 vers 3.8 Flash explique comment conserver le 3.7 Flash, qui reste entièrement pris en charge, derrière un indicateur de configuration.
Signatures de pensée, appels parallèles et sorties structurées
Signatures de pensée. Les modèles Gemini 3 associent des signatures à leur raisonnement. Avec le flux Interactions stocké par défaut, `previous_interaction_id` les gère pour vous. Si vous définissez `store: false` pour une configuration sans état, ou si vous utilisez `generateContent`, vous devez renvoyer les blocs de pensée et les signatures exactement tels que reçus, pour chaque type de partie. Ne les tronquez pas, ne les réorganisez pas et ne les resérialisez pas ; une signature est opaque et toute modification l'invalide. La documentation de l'API Interactions de Google couvre le compromis entre état stocké et sans état.
Appels parallèles. La réponse est une liste, elle peut donc contenir plus d'une étape `function_call` lorsque le modèle souhaite plusieurs recherches indépendantes à la fois. La documentation sur l'appel de fonction de Google confirme que les modèles Gemini 3 renvoient un identifiant unique à chaque appel précisément pour que les résultats puissent revenir dans n'importe quel ordre. Gérez cela en renvoyant un `function_result` par appel dans le même tableau `input`, chacun correspondant à son propre `call_id`. Une correspondance par `name` seul n'est pas suffisante ; deux appels à la même fonction nécessitent deux valeurs `call_id` différentes.
Sorties structurées. 3.8 Flash prend en charge les sorties structurées et l'appel de fonction sur le même modèle. Le schéma clair est celui des outils pour la boucle et un schéma JSON pour la réponse finale, de sorte que le `model_output` qui clôt la boucle est lisible par machine plutôt que sous forme de prose. Les pages de Google sur l'appel de fonction et les sorties structurées documentent la configuration. Ne simulez pas en déclarant un outil factice et en lisant ses `arguments` ; cela échoue au moment où le modèle décide qu'il n'a rien à appeler.
Tout ce qui précède suppose que le modèle atteint votre système via des fonctions déclarées. Google liste également l'utilisation de l'ordinateur (Aperçu) pour 3.8 Flash ; pour savoir quand une API structurée est préférable à un agent piloté par écran, consultez l'utilisation de l'ordinateur vs les API structurées.
Tester la boucle d'outil dans Apidog
Une boucle d'outil peut se briser à trois endroits : la déclaration, l'aller-retour de l'ID et la réponse finale. Vous pouvez couvrir les trois dans Apidog sans toucher à votre vrai backend.
1. Simulez le backend de l'outil. Définissez `GET /orders/{order_id}` comme point de terminaison et activez son serveur de simulation. Donnez-lui un corps de réponse fixe, `{"status": "in_transit", "eta": "2026-09-05"}`, afin que chaque exécution reçoive la même entrée et que tout changement dans la réponse finale du modèle soit dû au modèle, et non à votre base de données. Votre harnais pointe vers l'URL simulée dans l'environnement de test et vers le service réel en production.
2. Enchaînez les deux étapes dans un scénario de test. Stockez `GEMINI_API_KEY` comme variable d'environnement et référencez-la comme `{{GEMINI_API_KEY}}` dans l'en-tête `x-goog-api-key`. Construisez ensuite un scénario en trois étapes :
- Étape A : POST vers `/v1beta/interactions` avec le prompt et la déclaration `get_order_status`. Extrayez l'`id` de l'interaction et l'`id`, le `name` et `arguments.order_id` de l'étape `function_call` dans des variables.
- Étape B : GET le point de terminaison simulé avec `{{order_id}}`. C'est votre étape « exécuter la fonction ».
- Étape C : POST le `function_result` avec `call_id` défini sur `{{call_id}}`, `name` défini sur `{{tool_name}}`, `previous_interaction_id` défini sur `{{interaction_id}}`, et le corps de l'étape B comme partie texte.
3. Affirmez ce qui compte.
- L'étape A renvoie 200 et contient une étape dont le `type` est `function_call` avec `name` égal à `get_order_status`.
- L'`arguments.order_id` extrait est égal à `A1029`, ce qui prouve que le modèle a analysé le prompt et respecté le schéma.
- L'étape C renvoie 200 et se termine par une étape dont le `type` est `model_output` sans deuxième `function_call`, ce qui prouve que le `call_id` et le `name` que vous avez envoyés ont été acceptés et que la boucle s'est fermée en un seul tour.
- Le texte final contient `in_transit`, ce qui prouve que le modèle a utilisé le résultat de l'outil au lieu de sa propre estimation.
- Si vous exécutez le même scénario sur `generateContent`, ajoutez un plafond sur `usageMetadata.thoughtsTokenCount` par `thinking_level`. Cela permet de détecter les augmentations de coûts liées au « travail plus acharné » avant qu'elles n'atteignent votre facture.
Programmez l'exécution quotidienne du scénario. Le comportement du modèle peut dériver lors des mises à jour silencieuses, et une boucle qui se fermait en un tour la semaine dernière peut commencer à en nécessiter deux. Le guide de test d'API d'agents IA approfondit les assertions multi-étapes, et vous pouvez Télécharger Apidog pour construire le scénario sur le niveau gratuit avant de dépenser un centime.
FAQ
Le `call_id` est-il requis sur Gemini 3.8 Flash ? Oui. Sur l'API Interactions, chaque `function_result` nécessite `call_id` et `name` ; sur `generateContent`, chaque `functionResponse` nécessite l'`id` et le `name` de l'appel. Les anciens codes qui n'envoyaient que le nom échouent sur les modèles Gemini 3.
Pourquoi ma boucle d'outil effectue-t-elle plus d'étapes sur 3.8 Flash que sur 3.7 ? Par conception. Google indique que le modèle « appelle les outils de manière itérative » et « peut utiliser plus de jetons sur des tâches plus longues et complexes ». Limitez les étapes dans votre système et baissez le `thinking_level` ; le guide des niveaux de réflexion donne le coût mesuré par niveau.
Puis-je toujours utiliser `generateContent` pour l'appel de fonction ? Oui. Google le qualifie d'hérité mais déclare qu'il « reste entièrement pris en charge » sans date de fin de support. Vous gérez l'historique vous-même, y compris les signatures de pensée, et l'ID d'appel (nommé `id` sur cette API) ainsi que le `name` s'appliquent toujours.
Le `thinking_level` "minimal" fonctionne-t-il avec les outils ? Non. Il renvoie une erreur de validation sur 3.8 Flash. Utilisez `low`.
Combien coûte une tâche riche en outils ? Le prix par jeton est de 0,75 $ en entrée et 3,75 $ en sortie par million de jetons jusqu'au 31 décembre 2026, la réflexion étant facturée comme sortie. Artificial Analysis a mesuré 0,58 $ par tâche en mode `high`, 0,41 $ en mode `medium` et 0,24 $ en mode `low` sur leur indice. Vos tâches seront différentes, alors vérifiez les comptes de jetons et mesurez.
Déployer la boucle avec un plafond
Déclarez l'outil, lisez l'étape `function_call`, et retournez le `function_result` avec `call_id` et `name` sous `previous_interaction_id`. C'est tout le contrat. Ce qui a changé avec Gemini 3.8 Flash, c'est la propension du modèle à boucler, donc le système a besoin d'une limite d'étapes, d'un `thinking_level` par route et d'un délai d'attente avant de passer en production. Simulez le backend, enchaînez les deux étapes, vérifiez que l'ID fait des allers-retours, et planifiez l'exécution. La page Nouveautés de Gemini 3.8 Flash de Google contient les notes de migration ; le guide pilier contient tout le reste sur le modèle.
