Décodage long

Le décodage long permet à Gemini 4 Argon de générer des réponses au-delà de la limite de sortie d'une requête unique pour les tâches de raisonnement approfondi, jusqu'à la fenêtre de contexte unifiée de 1 million de jetons (1 048 576 jetons partagés entre l'entrée, la réflexion et la sortie).

Le simple fait de modifier l'ID du modèle n'active pas le décodage long. Sans configuration supplémentaire, la sortie s'arrête à 64 000 jetons pour les appels de streaming et à 32 000 jetons pour les appels non streaming. Le moyen le plus rapide d'activer le décodage long consiste à mettre à niveau le SDK Google GenAI et à définir max_output_tokens sur une valeur supérieure à 65 536. Ce guide explique comment fonctionne le décodage long, quand l'utiliser et comment l'activer avec generateContent.

Durée de fonctionnement du décodage

Une seule requête de streaming ou de SDK génère jusqu'à 64 000 jetons, et une requête REST sans streaming génère jusqu'à 32 000 jetons. Lorsqu'une réponse nécessite plus de jetons, le modèle la génère sur plusieurs sauts de requête et de réponse, chacun reprenant là où le saut précédent s'est arrêté.

  • Limite unifiée de jetons d'entrée et de sortie : l'entrée, la réflexion, les appels de fonction et la réponse finale partagent une fenêtre de 1 million de jetons. La sortie peut utiliser jusqu'à 1 048 576 jetons moins vos jetons d'entrée.
  • Une limite pour chaque saut : un saut renvoie jusqu'à 65 536 jetons de sortie. Les requêtes REST sans streaming renvoient jusqu'à 32 768 jetons.
  • Un signal de continuation : si le modèle atteint la limite et qu'il reste des jetons, la réponse se termine par finish_reason: CONTINUATION et un continuation_token.
  • Prochain saut : le client renvoie la même requête avec le jeton. Le modèle reprend là où il s'est arrêté.
  • Un total pour tous les sauts : max_output_tokens définit le nombre total de jetons de réflexion et de sortie pour tous les sauts.
  • Signal d'arrêt : lorsque le modèle utilise tous les max_output_tokens, la réponse se termine par finish_reason: MAX_TOKENS.

Pour les problèmes difficiles, un saut peut dépenser tous ses jetons en réflexion interne et renvoyer un texte vide avec un continuation_token. Ce comportement est normal. La réponse finale sera fournie lors des étapes suivantes.

Limites de sortie par défaut

Sans décodage long, une seule requête s'arrête à ces limites par requête :

  • Requêtes de streaming et requêtes sans streaming via le SDK Google GenAI (generate_content) : 64 000 jetons de sortie par défaut.
  • Appels REST directs sans streaming (generateContent) : 32 000 jetons de sortie par défaut. Si vous définissez max_output_tokens sur une valeur supérieure à 32 768 pour un appel REST non en flux continu sans continuation_token,une erreur 400 est renvoyée.
Comment vous appelez le modèle Limite de sortie sans décodage long Longue décodage au lancement Que faire ?
Dernière version du SDK Google GenAI 64 Ko Oui, le SDK continue pour vous Définissez max_output_tokens.
SDK Google GenAI, ancienne version, sans streaming 64 Ko Non Mettez à niveau le SDK.
REST streamGenerateContent 64 Ko Oui, avec votre propre boucle Écrivez une boucle. Consultez l'option 2.
REST generateContent 32 000 Oui, avec votre propre boucle Écrivez une boucle. Consultez l'option 2.

Quand utiliser le décodage long

La plupart des requêtes se terminent dans la limite d'une seule requête (64 000 jetons pour les appels en streaming et SDK, ou 32 000 jetons pour les appels REST sans streaming). Utilisez le décodage long lorsqu'une réponse nécessite plus de jetons de réflexion et de sortie combinés que ce qu'une seule requête permet. Augmenter max_output_tokens donne au modèle une plus grande marge de manœuvre pour résoudre des problèmes complexes, plutôt que de rallonger les réponses standards.

Charge de travail Utiliser le décodage long ? Pourquoi
Mathématiques, sciences, recherche et preuves formelles complexes Oui Le modèle peut dépenser plus de 64 000 jetons pour explorer et vérifier son raisonnement.
Les tâches de codage et agentiques les plus difficiles Oui Certaines tâches nécessitent plus de 64 000 jetons de réflexion et de code dans une seule réponse. La plupart des tâches de codage et agentiques se terminent en moins de 64 000.
Les outils d'évaluation qui s'arrêtent à la limite de sortie Oui Le décodage long empêche les réponses d'être tronquées lorsque le modèle consacre une requête complète de 64 000 ou 32 000 jetons à la réflexion.
Chat, questions/réponses, synthèse, classification et extraction Non Ces tâches se terminent bien en dessous de 32 000 jetons.
Les requêtes demandant une longueur fixe, comme "rédiger un livre de 700 000 mots" Non Le modèle ne respecte pas les objectifs de longueur.
Agents qui appellent des outils en plusieurs tours courts Non Chaque tour est court. Les sorties volumineuses à chaque tour remplissent rapidement la fenêtre d'entrée et de sortie unifiée de 1 million de jetons.
Requêtes proches de la limite d'entrée de 1 million Non La sortie ne peut utiliser que 1 M moins votre entrée.
Requêtes sensibles à la latence Non Le décodage long peut prendre plusieurs minutes.

Définir un max_output_tokens élevé donne au modèle plus de temps pour réfléchir à des problèmes difficiles, mais le modèle décide toujours de la quantité de texte à écrire. Pour contrôler l'effort de raisonnement du modèle, définissez thinking_level.

Activer le décodage long

Vous pouvez exécuter automatiquement le décodage long avec le SDK GenAI de Google (option 1, recommandée pour la plupart des applications) ou écrire votre propre boucle de continuation (option 2). Les deux options sont compatibles avec la fenêtre de contexte complète d'un million de jetons.

Option 1 : SDK Google GenAI (recommandé) Option 2 : Votre propre boucle de streaming Option 2 : Votre propre boucle non diffusée en streaming
Qui lance chaque saut Le SDK. Vous définissez max_output_tokens. Votre code, à chaque point de contrôle ou après une interruption de flux Votre code, tous les 32 000 jetons
Jetons par requête 64 k par saut 64 000 par flux, avec un point de contrôle tous les 5 000 jetons après 32 000 32 000 par requête
Délai par requête 20 minutes 20 minutes 20 minutes
Stockage Aucun stockage sur le serveur Aucun stockage sur serveur Aucun stockage sur serveur
Application idéale La plupart des applications Les appelants REST et les harnais personnalisés qui diffusent Harnais d'évaluation simples

Le continuation_token chiffré transporte l'état du modèle entre les requêtes. Par conséquent, rien n'est stocké sur le serveur.

Option 1 : Utiliser le SDK Google GenAI (recommandé)

Dans le dernier SDK GenAI de Google, automatic_continuation est activé par défaut pour les appels de streaming et non-streaming. Vous n'avez donc pas besoin de le définir. Lorsque vous définissez max_output_tokens au-dessus de la limite par requête, le SDK exécute automatiquement les sauts de continuation et renvoie une réponse combinée.

  1. Mettez à niveau le SDK.

    Python

    pip install -U "google-genai>=2.30.1"
    

    JavaScript

    npm install "@google/genai@>=2.29.1"
    
  2. Définissez max_output_tokens sur une valeur supérieure à 65 536.

    Python

    from google import genai
    from google.genai import types
    
    client = genai.Client()  # Reads GEMINI_API_KEY
    
    response = client.models.generate_content(
        model="gemini-4-argon",
        contents="Write a complete, rigorous proof of the prime number theorem.",
        config=types.GenerateContentConfig(
            max_output_tokens=262_144,  # Total thinking and output for all hops
            thinking_config=types.ThinkingConfig(thinking_level="high"),
            automatic_continuation=True,  # Default. Shown for clarity.
        ),
    )
    
    print(response.text)
    print("Finish reason:", response.candidates[0].finish_reason)
    print("Prompt size:", response.usage_metadata.initial_prompt_token_count)
    print("Billed tokens:", response.usage_metadata.total_token_count)
    

    JavaScript

    import { GoogleGenAI, ThinkingLevel } from "@google/genai";
    
    const ai = new GoogleGenAI({}); // Reads GEMINI_API_KEY
    
    const response = await ai.models.generateContent({
      model: "gemini-4-argon",
      contents: "Write a complete, rigorous proof of the prime number theorem.",
      config: {
        maxOutputTokens: 262144, // Total thinking and output for all hops
        thinkingConfig: { thinkingLevel: ThinkingLevel.HIGH },
        automaticContinuation: true, // Default. Shown for clarity.
      },
    });
    
    console.log(response.text);
    console.log("Finish reason:", response.candidates?.[0]?.finishReason);
    console.log("Prompt size:", response.usageMetadata?.initialPromptTokenCount);
    console.log("Billed tokens:", response.usageMetadata?.totalTokenCount);
    

Notez les points suivants :

  • Streaming : generate_content_stream (Python) et generateContentStream (JavaScript) continuent également pour vous. Si un flux est interrompu après un point de contrôle, le SDK reprend à partir de ce point de contrôle.
  • Délais avant expiration : les délais avant expiration et les nouvelles tentatives s'appliquent à chaque saut, et non à l'exécution complète.
  • Contrôle manuel : pour exécuter la boucle vous-même, définissez automatic_continuation=False (Python) ou automaticContinuation: false (JavaScript). Suivez ensuite l'option 2.
  • Utilisation : les champs d'utilisation affichent la somme de tous les sauts. Pour connaître la taille de votre requête, lisez initial_prompt_token_count. Consultez Compter les jetons.

Option 2 : Écrire votre propre boucle

Écrivez votre propre boucle si vous appelez REST directement, si vous utilisez un langage sans le dernier SDK ou si vous avez besoin d'un contrôle total. Vous pouvez également vous référer à nos implémentations du SDK Google GenAI en Python et JavaScript/TypeScript.

Suivez les règles ci-dessous :

  1. Envoyez la même requête à chaque saut. Envoyez les contents, system_instruction, tools et generation_config d'origine. Conservez la même valeur pour max_output_tokens.
  2. N'ajoutez pas de résultat partiel à contents. continuation_token contient l'état du modèle, y compris son raisonnement.
  3. N'envoyez que le dernier jeton. Chaque jeton contient toute la progression précédente.
  4. Continuer tant que finish_reason est CONTINUATION. Arrêtez-vous pour toute autre raison de fin.
  5. Joignez les parties après le dernier saut. Combinez les parties de tous les sauts en un seul tour de modèle pour l'historique de la conversation.

Python

from google import genai
from google.genai import types

client = genai.Client()  # Reads GEMINI_API_KEY
PROMPT = "Write a complete, rigorous proof of the prime number theorem."
parts = []
token = None

while True:
    response = client.models.generate_content(
        model="gemini-4-argon",
        contents=PROMPT,  # The original contents on every request
        config=types.GenerateContentConfig(
            max_output_tokens=262_144,  # The same total on every request
            thinking_config=types.ThinkingConfig(thinking_level="high"),
            automatic_continuation=False,  # You run the loop
            continuation_token=token,
        ),
    )
    candidate = response.candidates[0]
    if candidate.content and candidate.content.parts:
        parts.extend(candidate.content.parts)
    token = candidate.continuation_token
    if candidate.finish_reason != types.FinishReason.CONTINUATION or not token:
        break

print("".join(p.text for p in parts if p.text and not p.thought))
print("Finish reason:", candidate.finish_reason)

JavaScript

import { GoogleGenAI, ThinkingLevel } from "@google/genai";

const ai = new GoogleGenAI({}); // Reads GEMINI_API_KEY
const PROMPT = "Write a complete, rigorous proof of the prime number theorem.";
const parts = [];
let token = undefined;
let candidate = undefined;

while (true) {
  const response = await ai.models.generateContent({
    model: "gemini-4-argon",
    contents: PROMPT, // The original contents on every request
    config: {
      maxOutputTokens: 262144, // The same total on every request
      thinkingConfig: { thinkingLevel: ThinkingLevel.HIGH },
      automaticContinuation: false, // You run the loop
      continuationToken: token,
    },
  });
  candidate = response.candidates?.[0];
  if (candidate?.content?.parts) {
    parts.push(...candidate.content.parts);
  }
  token = candidate?.continuationToken;
  if (candidate?.finishReason !== "CONTINUATION" || !token) {
    break;
  }
}

console.log(parts.filter((p) => p.text && !p.thought).map((p) => p.text).join(""));
console.log("Finish reason:", candidate?.finishReason);

REST

# Hop 1: send the request with max_output_tokens.
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-4-argon:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Write a complete, rigorous proof of the prime number theorem."}]}],
    "generationConfig": {
      "maxOutputTokens": 262144,
      "thinkingConfig": {"thinkingLevel": "high"}
    }
  }'

# Hop 2: if finishReason is CONTINUATION, send the same request plus the token.
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-4-argon:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Write a complete, rigorous proof of the prime number theorem."}]}],
    "generationConfig": {
      "maxOutputTokens": 262144,
      "thinkingConfig": {"thinkingLevel": "high"}
    },
    "continuationToken": "TOKEN_FROM_HOP_1"
  }'

Un saut entièrement consacré à la réflexion renvoie un text vide avec finishReason: "CONTINUATION". Traitez cela comme une progression normale et demandez le prochain saut :

{
  "candidates": [{
    "content": {"role": "model", "parts": [{"text": ""}]},
    "finishReason": "CONTINUATION",
    "continuationToken": "CiQ4ZmQ3..."
  }],
  "usageMetadata": {
    "promptTokenCount": 142,
    "candidatesTokenCount": 0,
    "thoughtsTokenCount": 32768,
    "totalTokenCount": 32910
  }
}

Les boucles de streaming nécessitent une règle supplémentaire. Après les 32 768 premiers jetons, le flux envoie un jeton de point de contrôle tous les 5 000 jetons. Conserver les nouveaux fragments dans une liste d'attente. Lorsqu'un fragment comporte un continuation_token, déplacez les fragments en attente vers votre sortie validée et enregistrez le jeton. Si le flux est interrompu, supprimez les fragments en attente et reprenez à partir du dernier jeton. Si le flux s'interrompt avant le premier point de contrôle, renvoyez la requête d'origine.

Ensemble max_output_tokens

max_output_tokens définit la limite combinée pour le raisonnement et la sortie sur tous les sauts. La diminution de cette valeur n'incite pas le modèle à réfléchir de manière plus concise, mais interrompt la réponse plus tôt.

Votre charge de travail Recommandation : max_output_tokens
Applications existantes avec une limite inférieure à 32 000 Augmentez-la à 32 768.
Codage long et tâches agentiques Commencez à 65 536.
Mathématiques, sciences, recherches et démonstrations complexes Testez des valeurs comprises entre 262 144 et 1 048 576, moins vos jetons d'entrée.

Pour utiliser moins de jetons, réduisez thinking_level. Utilisez high pour les tâches de raisonnement les plus difficiles. Utilisez medium (par défaut) pour la plupart des tâches de codage et d'agent. Utilisez low pour les tâches moins complexes.

Gérer les requêtes de longue durée

Comme Gemini 4 Argon réfléchit plus longtemps que les modèles Gemini 3.x sur les problèmes complexes, vous devez augmenter les délais avant expiration de votre client pour que les requêtes longues ne soient pas déconnectées prématurément.

  • Appels sans streaming : le serveur ferme la connexion au bout de 10 minutes.
  • Appels de streaming : le serveur ferme le flux au bout de 20 minutes.
  • Délais avant expiration du client : définissez le délai avant expiration de la lecture HTTP sur 20 minutes. Un délai avant expiration de trois ou cinq minutes arrête la requête de manière anticipée.

En Python, définissez le délai avant expiration sur le client en millisecondes :

client = genai.Client(http_options=types.HttpOptions(timeout=1_200_000))  # 20 minutes

Pour les jobs que votre client interroge, l'API Interactions exécute un décodage long sur le serveur. Consultez Exécution en arrière-plan.

Reprendre lorsque le modèle utilise tous les jetons de sortie

Lorsqu'une réponse se termine par MAX_TOKENS, elle inclut toujours un continuation_token. Deux possibilités s'offrent à vous :

  • Continuer : envoyez la même requête avec le jeton et un max_output_tokens plus élevé. La valeur doit être supérieure au nombre de jetons utilisés jusqu'à présent. Sinon, l'API renvoie une erreur 400.
  • Recommencer : envoyez la requête d'origine avec une valeur max_output_tokens plus élevée et sans jeton. Les deux exécutions vous sont facturées.

Compter les jetons

Avec la continuation automatique, usage_metadata indique les totaux pour tous les sauts. Le SDK additionne tous les champs de décompte : prompt_token_count, cached_content_token_count, candidates_token_count, thoughts_token_count et total_token_count.

prompt_token_count additionne les jetons d'entrée de chaque saut. Chaque saut renvoie votre requête et tout ce qui a été généré jusqu'à présent au modèle en tant qu'entrée. Les mêmes jetons sont donc comptabilisés à nouveau à chaque saut ultérieur. Par exemple, avec le SDK Google GenAI, une invite de 1 000 jetons qui produit 200 000 jetons de réflexion et de sortie nécessite quatre sauts :

Hop Entrée envoyée au modèle Jetons d'entrée
1 Prompt 1 000
2 Prompt + hop 1 66 536
3 Requête + sauts 1 et 2 132 072
4 Prompt + hops 1 to 3 197 608
Total 397 216

prompt_token_count indique environ 397 000 jetons (avec les entrées de saut répétées automatiquement réduites de 95% par la mise en cache implicite), et total_token_count indique environ 597 000 jetons, même si la taille réelle du contexte n'est que d'environ 201 000 jetons : la requête de 1 000 jetons plus 200 000 jetons de réflexion et de sortie. Une boucle REST sans flux utilise 32 000 sauts. Il faut donc sept sauts pour obtenir le même résultat, et 695 128 jetons d'entrée sont signalés.

Comment vous appelez le modèle Ce que montre usage_metadata Pour le coût Pour la taille du prompt
SDK Google GenAI, continuation automatique (par défaut) Totaux pour tous les tronçons Lisez les champs d'utilisation tels quels. Lisez usage_metadata.initial_prompt_token_count (Python) ou usageMetadata.initialPromptTokenCount (JavaScript).
SDK avec automatic_continuation=False ou REST Un saut par réponse Ajoutez chaque champ aux différents sauts. Lisez prompt_token_count à partir du premier saut.

prompt_token_count et total_token_count correspondent à la somme de chaque saut, et non à la taille de votre contexte. Ne les utilisez pas pour décider quand résumer ou tronquer votre historique des conversations (compression du contexte), ni pour appliquer une limite de contexte. Pour estimer la taille du contexte, ajoutez la taille de votre requête à candidates_token_count et thoughts_token_count.

Mettez à jour votre framework d'agent, votre outil d'évaluation ou votre proxy avant d'exécuter le décodage long :

  • Agents et outils d'évaluation : si votre code compacte le contexte ou arrête une exécution à une limite de jetons, utilisez initial_prompt_token_count (ou le prompt_token_count du premier saut dans REST) au lieu de la somme de prompt_token_count. Les réponses qui se terminent en un seul saut indiquent la même valeur dans les deux champs. Les tests courts ne montrent donc pas le problème.
  • Proxies et passerelles qui appellent REST : chaque réponse REST ne signale que son propre saut. Ajoutez chaque champ entre les sauts pour le coût, et conservez le promptTokenCount du premier saut comme taille de la requête. Sinon, vos utilisateurs verront des chiffres différents de ceux des utilisateurs du SDK pour la même demande.
  • Journaux et réponses sérialisées : le SDK calcule initial_prompt_token_count sur le client. Il ne figure pas dans la réponse REST ni dans la sortie JSON du SDK, comme model_dump(). Enregistrez-la en tant que valeur distincte si vous en avez besoin plus tard.

Si vous diffusez en streaming dans votre propre boucle, usage_metadata est cumulatif dans chaque flux. Ne conservez que la dernière valeur de chaque flux, puis ajoutez les valeurs entre les sauts.

Comprendre la facturation

Vous payez pour chaque jeton de chaque saut, y compris les sauts qui ne contiennent que de la réflexion.

  • Mise en cache de la remise : la mise en cache implicite réduit de 95 % les entrées répétées à chaque saut. L'entrée mise en cache coûte 0,10 $ par million de jetons au lieu de 2 $ pendant la période de lancement.
  • Expiration du cache : le cache expire au bout de 15 à 20 minutes d'inactivité. Une longue pause entre les sauts permet de recharger à nouveau le débit d'entrée complet.
  • Hops sans streaming ayant échoué : vous ne payez que lorsqu'une réponse est complète. Une requête ayant échoué ou ayant été abandonnée coûte 0 $.
  • Flux abandonnés : un flux abandonné avant 32 000 jetons coûte 0 $. Ensuite, vous payez jusqu'au dernier jeton de point de contrôle, car vous pouvez reprendre à partir de celui-ci.

Dépannage

Problème constaté Cause et solution
La sortie s'arrête à 64 000 ou 32 000 avec CONTINUATION Le modèle dispose encore de jetons, mais rien n'a continué la requête. Mettez à niveau le SDK ou ajoutez une boucle.
La sortie s'arrête à 64 000 ou 32 000 avec MAX_TOKENS max_output_tokens n'est pas défini ou est trop faible. Définissez-la sur une valeur supérieure à 65 536.
Texte vide avec MAX_TOKENS Le modèle a utilisé tous les jetons pour le raisonnement. Lever max_output_tokens ou baisser thinking_level.
400 : "Le jeton de continuation a déjà utilisé des jetons de sortie..." max_output_tokens n'est pas supérieur aux jetons utilisés jusqu'à présent. Augmentez-le.
Erreur pour thinking_level: "minimal" ou pour thinking_budget avec thinking_level Gemini 4 Argon n'est pas compatible avec minimal. Utilisez low, medium ou high. Définissez thinking_level ou thinking_budget, mais pas les deux.
Avertissement pour thinking_budget, temperature, top_p ou top_k Gemini 4 Argon ignore ou mappe ces champs. Utilisez thinking_level et supprimez les paramètres d'échantillonnage.
La requête se termine au bout de trois ou cinq minutes Le délai avant expiration du client est trop court. Réglez-le sur 20 minutes.
La compaction du contexte commence trop tôt Le harnais lit l'entrée additionnée. Lisez plutôt initial_prompt_token_count.

Limites

  • Point de terminaison de compatibilité OpenAI : le décodage long n'est pas disponible. La sortie s'arrête à la limite par requête.
  • Anciens SDK : les versions inférieures aux versions minimales indiquées dans la remarque ne continuent pas automatiquement.
  • Longueur : le modèle ne respecte pas les objectifs de longueur de jeton ou de nombre de mots.

Checklist

  • Mettez à niveau le SDK Google GenAI vers la version minimale.
  • Définissez max_output_tokens sur une valeur supérieure à 65 536.
  • Utilisez thinking_level (low, medium ou high), et non thinking_budget.
  • Définissez les délais d'expiration de lecture HTTP sur 20 minutes.
  • Utilisez initial_prompt_token_count pour la taille et la compaction du contexte.
  • Exécutez une requête à titre de test avant une évaluation à grande échelle.

Étapes suivantes