Comprendre et compter les jetons

Gemini et d'autres modèles d'IA générative traitent les entrées et les sorties avec une granularité appelée un jeton.

Pour les modèles Gemini, un jeton équivaut à environ quatre caractères. 100 jetons correspondent à environ 60 à 80 mots en anglais.

À propos des jetons

Les jetons peuvent être des caractères uniques, comme z, ou des mots entiers, comme cat. Les mots longs sont divisés en plusieurs jetons. L'ensemble de tous les jetons utilisés par le modèle est appelé vocabulaire, et le processus de division du texte en jetons est appelé tokenisation.

Lorsque la facturation est activée, le coût d'un appel à l'API Gemini est déterminé en partie par le nombre de jetons d'entrée et de sortie. Il peut donc être utile de savoir comment compter les jetons.

Vous pouvez essayer de compter les jetons dans notre Colab.

Afficher sur ai.google.dev Essayer un notebook Colab Afficher le notebook sur GitHub

Compter les jetons

Toutes les entrées et sorties de l'API Gemini sont tokenisées, y compris le texte, les fichiers image et d'autres modalités non textuelles.

Vous pouvez compter les jetons de différentes manières :

  • Appelez count_tokens avec l'entrée de la requête.
    Cette opération renvoie le nombre total de jetons dans l' entrée uniquement. Vous pouvez effectuer cet appel avant d'envoyer l'entrée au modèle pour vérifier la taille de vos requêtes.

  • Utilisez l'attribut usage_metadata sur l'objet response après avoir appelé generate_content.
    Cette opération renvoie le nombre total de jetons dans l'entrée et la sortie : total_token_count.
    Elle renvoie également le nombre de jetons de l'entrée et de la sortie séparément : prompt_token_count (jetons d'entrée) et candidates_token_count (jetons de sortie).

    Si vous utilisez un modèle de réflexion, le jeton utilisé pendant le processus de réflexion est renvoyé dans thoughts_token_count. Si vous utilisez la mise en cache du contexte, le nombre de jetons mis en cache se trouve dans cached_content_token_count.

Compter les jetons de texte

Si vous appelez count_tokens avec une entrée de texte uniquement, elle renvoie le nombre de jetons de le texte dans l'entrée uniquement (total_tokens). Vous pouvez effectuer cet appel avant d'appeler generate_content pour vérifier la taille de vos requêtes.

Une autre option consiste à appeler generate_content, puis à utiliser l'usage_metadata attribut sur l'objet response pour obtenir les éléments suivants :

  • Le nombre de jetons distincts de l'entrée (prompt_token_count), du contenu mis en cache (cached_content_token_count) et de la sortie (candidates_token_count)
  • Le nombre de jetons pour le processus de réflexion (thoughts_token_count)
  • Le nombre total de jetons dans l'entrée et la sortie (total_token_count)

Python

from google import genai

client = genai.Client()
prompt = "The quick brown fox jumps over the lazy dog."

total_tokens = client.models.count_tokens(
    model="gemini-3-flash-preview", contents=prompt
)
print("total_tokens: ", total_tokens)

response = client.models.generate_content(
    model="gemini-3-flash-preview", contents=prompt
)

print(response.usage_metadata)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});
const prompt = "The quick brown fox jumps over the lazy dog.";

async function main() {
  const countTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: prompt,
  });
  console.log(countTokensResponse.totalTokens);

  const generateResponse = await ai.models.generateContent({
    model: "gemini-3-flash-preview",
    contents: prompt,
  });
  console.log(generateResponse.usageMetadata);
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)

// Convert prompt to a slice of *genai.Content using the helper.
contents := []*genai.Content{
  genai.NewContentFromText(prompt, genai.RoleUser),
}
countResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  return err
}
fmt.Println("total_tokens:", countResp.TotalTokens)

response, err := client.Models.GenerateContent(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", "  ")
if err != nil {
  log.Fatal(err)
}
fmt.Println(string(usageMetadata))
    ```

Compter les jetons multitours (chat)

Si vous appelez count_tokens avec l'historique du chat, elle renvoie le nombre total de jetons du texte de chaque rôle dans le chat (total_tokens).

Une autre option consiste à appeler send_message, puis à utiliser l'usage_metadata attribut sur l'objet response pour obtenir les éléments suivants :

  • Le nombre de jetons distincts de l'entrée (prompt_token_count), du contenu mis en cache (cached_content_token_count) et de la sortie (candidates_token_count)
  • Le nombre de jetons pour le processus de réflexion (thoughts_token_count)
  • Le nombre total de jetons dans l'entrée et la sortie (total_token_count)

Pour comprendre la taille de votre prochain tour de conversation, vous devez l'ajouter à l'historique lorsque vous appelez count_tokens.

Python

from google import genai
from google.genai import types

client = genai.Client()

chat = client.chats.create(
    model="gemini-3-flash-preview",
    history=[
        types.Content(
            role="user", parts=[types.Part(text="Hi my name is Bob")]
        ),
        types.Content(role="model", parts=[types.Part(text="Hi Bob!")]),
    ],
)

print(
    client.models.count_tokens(
        model="gemini-3-flash-preview", contents=chat.get_history()
    )
)

response = chat.send_message(
    message="In one sentence, explain how a computer works to a young child."
)
print(response.usage_metadata)

extra = types.UserContent(
    parts=[
        types.Part(
            text="What is the meaning of life?",
        )
    ]
)
history = [*chat.get_history(), extra]
print(client.models.count_tokens(model="gemini-3-flash-preview", contents=history))

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});

async function main() {
  const history = [
    { role: "user", parts: [{ text: "Hi my name is Bob" }] },
    { role: "model", parts: [{ text: "Hi Bob!" }] },
  ];
  const chat = ai.chats.create({
    model: "gemini-3-flash-preview",
    history: history,
  });

  const countTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: chat.getHistory(),
  });
  console.log(countTokensResponse.totalTokens);

  const chatResponse = await chat.sendMessage({
    message: "In one sentence, explain how a computer works to a young child.",
  });
  console.log(chatResponse.usageMetadata);

  const extraMessage = {
    role: "user",
    parts: [{ text: "What is the meaning of life?" }],
  };
  const combinedHistory = [...chat.getHistory(), extraMessage];
  const combinedCountTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: combinedHistory,
  });
  console.log(
    "Combined history token count:",
    combinedCountTokensResponse.totalTokens,
  );
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)

history := []*genai.Content{
  {Role: genai.RoleUser, Parts: []*genai.Part({Text: "Hi my name is Bob"})},
  {Role: genai.RoleModel, Parts: []*genai.Part({Text: "Hi Bob!"})},
}
chat, err := client.Chats.Create(ctx, "gemini-3-flash-preview", nil, history)
if err != nil {
  log.Fatal(err)
}

firstTokenResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", chat.History(false), nil)
if err != nil {
  log.Fatal(err)
}
fmt.Println(firstTokenResp.TotalTokens)

resp, err := chat.SendMessage(ctx, genai.NewPartFromText("In one sentence, explain how a computer works to a young child."))
if err != nil {
  log.Fatal(err)
}
fmt.Printf("%#v\n", resp.UsageMetadata)

extra := genai.NewContentFromText("What is the meaning of life?", genai.RoleUser)
hist := chat.History(false)
hist = append(hist, extra)

secondTokenResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", hist, nil)
if err != nil {
  log.Fatal(err)
}
fmt.Println(secondTokenResp.TotalTokens)

Compter les jetons multimodaux

Toutes les entrées de l'API Gemini sont tokenisées, y compris le texte, les fichiers image et d'autres modalités non textuelles. Notez les points clés de haut niveau suivants concernant la tokenisation des entrées multimodales lors du traitement par l'API Gemini :

  • Les entrées image dont les deux dimensions sont inférieures ou égales à 384 pixels sont comptabilisées comme 258 jetons. Les images plus grandes dans une ou les deux dimensions sont recadrées et mises à l'échelle selon les besoins en vignettes de 768 x 768 pixels, chacune comptant pour 258 jetons.

  • Les fichiers vidéo et audio sont convertis en jetons aux taux fixes suivants : 263 jetons par seconde pour la vidéo et 32 jetons par seconde pour l'audio.

Résolutions multimédias

Les modèles Gemini 3 introduisent un contrôle précis du traitement de la vision multimodale avec le media_resolution paramètre. Le media_resolution paramètre détermine le nombre maximal de jetons alloués par image d'entrée ou par image vidéo. Les résolutions plus élevées améliorent la capacité du modèle à lire du texte fin ou à identifier de petits détails, mais augmentent l'utilisation des jetons et la latence.

Pour en savoir plus sur le paramètre et son impact sur les calculs de jetons, consultez le guide sur la résolution multimédia.

Fichiers image

Si vous appelez count_tokens avec une entrée texte et image, elle renvoie le nombre combiné de jetons du texte et de l'image dans l'entrée uniquement (total_tokens). Vous pouvez effectuer cet appel avant d'appeler generate_content pour vérifier la taille de vos requêtes. Vous pouvez également appeler count_tokens sur le texte et le fichier séparément.

Une autre option consiste à appeler generate_content, puis à utiliser l'usage_metadata attribut sur l'objet response pour obtenir les éléments suivants :

  • Le nombre de jetons distincts de l'entrée (prompt_token_count), du contenu mis en cache (cached_content_token_count) et de la sortie (candidates_token_count)
  • Le nombre de jetons pour le processus de réflexion (thoughts_token_count)
  • Le nombre total de jetons dans l'entrée et la sortie (total_token_count)

Exemple utilisant une image importée à partir de l'API File :

Python

from google import genai

client = genai.Client()
prompt = "Tell me about this image"
your_image_file = client.files.upload(file=media / "organ.jpg")

print(
    client.models.count_tokens(
        model="gemini-3-flash-preview", contents=[prompt, your_image_file]
    )
)

response = client.models.generate_content(
    model="gemini-3-flash-preview", contents=[prompt, your_image_file]
)
print(response.usage_metadata)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});
const prompt = "Tell me about this image";

async function main() {
  const organ = await ai.files.upload({
    file: path.join(media, "organ.jpg"),
    config: { mimeType: "image/jpeg" },
  });

  const countTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: createUserContent([
      prompt,
      createPartFromUri(organ.uri, organ.mimeType),
    ]),
  });
  console.log(countTokensResponse.totalTokens);

  const generateResponse = await ai.models.generateContent({
    model: "gemini-3-flash-preview",
    contents: createUserContent([
      prompt,
      createPartFromUri(organ.uri, organ.mimeType),
    ]),
  });
  console.log(generateResponse.usageMetadata);
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)

file, err := client.Files.UploadFromPath(
  ctx, 
  filepath.Join(getMedia(), "organ.jpg"), 
  &genai.UploadFileConfig{
    MIMEType : "image/jpeg",
  },
)
if err != nil {
  log.Fatal(err)
}
parts := []*genai.Part{
  genai.NewPartFromText("Tell me about this image"),
  genai.NewPartFromURI(file.URI, file.MIMEType),
}
contents := []*genai.Content{
  genai.NewContentFromParts(parts, genai.RoleUser),
}

tokenResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
fmt.Println("Multimodal image token count:", tokenResp.TotalTokens)

response, err := client.Models.GenerateContent(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", "  ")
if err != nil {
  log.Fatal(err)
}
fmt.Println(string(usageMetadata))

Exemple fournissant l'image en tant que données intégrées :

Python

from google import genai
import PIL.Image

client = genai.Client()
prompt = "Tell me about this image"
your_image_file = PIL.Image.open(media / "organ.jpg")

print(
    client.models.count_tokens(
        model="gemini-3-flash-preview", contents=[prompt, your_image_file]
    )
)

response = client.models.generate_content(
    model="gemini-3-flash-preview", contents=[prompt, your_image_file]
)
print(response.usage_metadata)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});
const prompt = "Tell me about this image";
const imageBuffer = fs.readFileSync(path.join(media, "organ.jpg"));

const imageBase64 = imageBuffer.toString("base64");

const contents = createUserContent([
  prompt,
  createPartFromBase64(imageBase64, "image/jpeg"),
]);

async function main() {
  const countTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: contents,
  });
  console.log(countTokensResponse.totalTokens);

  const generateResponse = await ai.models.generateContent({
    model: "gemini-3-flash-preview",
    contents: contents,
  });
  console.log(generateResponse.usageMetadata);
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)

imageBytes, err := os.ReadFile("organ.jpg")
if err != nil {
    log.Fatalf("Failed to read image file: %v", err)
}
parts := []*genai.Part{
  genai.NewPartFromText("Tell me about this image"),
  {
        InlineData: &genai.Blob{
              MIMEType: "image/jpeg",
              Data:     imageBytes,
        },
  },
}
contents := []*genai.Content{
  genai.NewContentFromParts(parts, genai.RoleUser),
}

tokenResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
fmt.Println("Multimodal image token count:", tokenResp.TotalTokens)

response, err := client.Models.GenerateContent(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", "  ")
if err != nil {
  log.Fatal(err)
}
fmt.Println(string(usageMetadata))

Fichiers audio ou vidéo

L'audio et la vidéo sont convertis en jetons aux taux fixes suivants :

  • Vidéo : 263 jetons par seconde
  • Audio : 32 jetons par seconde

Si vous appelez count_tokens avec une entrée texte et vidéo/audio, elle renvoie le nombre combiné de jetons du texte et du fichier vidéo/audio dans l'entrée uniquement (total_tokens). Vous pouvez effectuer cet appel avant d'appeler generate_content pour vérifier la taille de vos requêtes. Vous pouvez également appeler count_tokens sur le texte et le fichier séparément.

Une autre option consiste à appeler generate_content, puis à utiliser l'usage_metadata attribut sur l'objet response pour obtenir les éléments suivants :

  • Le nombre de jetons distincts de l'entrée (prompt_token_count), du contenu mis en cache (cached_content_token_count) et de la sortie (candidates_token_count)
  • Le nombre de jetons pour le processus de réflexion (thoughts_token_count)
  • Le nombre total de jetons dans l'entrée et la sortie (total_token_count).

Python

from google import genai
import time

client = genai.Client()
prompt = "Tell me about this video"
your_file = client.files.upload(file=media / "Big_Buck_Bunny.mp4")

while not your_file.state or your_file.state.name != "ACTIVE":
    print("Processing video...")
    print("File state:", your_file.state)
    time.sleep(5)
    your_file = client.files.get(name=your_file.name)

print(
    client.models.count_tokens(
        model="gemini-3-flash-preview", contents=[prompt, your_file]
    )
)

response = client.models.generate_content(
    model="gemini-3-flash-preview", contents=[prompt, your_file]
)
print(response.usage_metadata)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});
const prompt = "Tell me about this video";

async function main() {
  let videoFile = await ai.files.upload({
    file: path.join(media, "Big_Buck_Bunny.mp4"),
    config: { mimeType: "video/mp4" },
  });

  while (!videoFile.state || videoFile.state.toString() !== "ACTIVE") {
    console.log("Processing video...");
    console.log("File state: ", videoFile.state);
    await sleep(5000);
    videoFile = await ai.files.get({ name: videoFile.name });
  }

  const countTokensResponse = await ai.models.countTokens({
    model: "gemini-3-flash-preview",
    contents: createUserContent([
      prompt,
      createPartFromUri(videoFile.uri, videoFile.mimeType),
    ]),
  });
  console.log(countTokensResponse.totalTokens);

  const generateResponse = await ai.models.generateContent({
    model: "gemini-3-flash-preview",
    contents: createUserContent([
      prompt,
      createPartFromUri(videoFile.uri, videoFile.mimeType),
    ]),
  });
  console.log(generateResponse.usageMetadata);
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)

file, err := client.Files.UploadFromPath(
  ctx,
  filepath.Join(getMedia(), "Big_Buck_Bunny.mp4"),
  &genai.UploadFileConfig{
    MIMEType : "video/mp4",
  },
)
if err != nil {
  log.Fatal(err)
}

for file.State == genai.FileStateUnspecified || file.State != genai.FileStateActive {
  fmt.Println("Processing video...")
  fmt.Println("File state:", file.State)
  time.Sleep(5 * time.Second)

  file, err = client.Files.Get(ctx, file.Name, nil)
  if err != nil {
    log.Fatal(err)
  }
}

parts := []*genai.Part{
  genai.NewPartFromText("Tell me about this video"),
  genai.NewPartFromURI(file.URI, file.MIMEType),
}
contents := []*genai.Content{
  genai.NewContentFromParts(parts, genai.RoleUser),
}

tokenResp, err := client.Models.CountTokens(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
fmt.Println("Multimodal video/audio token count:", tokenResp.TotalTokens)
response, err := client.Models.GenerateContent(ctx, "gemini-3-flash-preview", contents, nil)
if err != nil {
  log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", "  ")
if err != nil {
  log.Fatal(err)
}
fmt.Println(string(usageMetadata))

Fenêtres de contexte

Les modèles disponibles via l'API Gemini disposent de fenêtres de contexte qui sont mesurées en jetons. La fenêtre de contexte définit la quantité d'entrée que vous pouvez fournir et la quantité de sortie que le modèle peut générer. Vous pouvez déterminer la taille de la fenêtre de contexte en appelant le point de terminaison models.get ou en consultant la documentation des modèles.

Python

from google import genai

client = genai.Client()
model_info = client.models.get(model="gemini-3-flash-preview")
print(f"{model_info.input_token_limit=}")
print(f"{model_info.output_token_limit=}")

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});

async function main() {
  const modelInfo = await ai.models.get({model: 'gemini-3-flash-preview'});
  console.log(modelInfo.inputTokenLimit);
  console.log(modelInfo.outputTokenLimit);
}

await main();

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
  log.Fatal(err)
}
modelInfo, err := client.ModelInfo(ctx, "models/gemini-3-flash-preview")
if err != nil {
  log.Fatal(err)
}
fmt.Println("input token limit:", modelInfo.InputTokenLimit)
fmt.Println("output token limit:", modelInfo.OutputTokenLimit)