Comprendi e conteggia i token

Gemini e altri modelli di AI generativa elaborano input e output con una granularità chiamata un token.

Per i modelli Gemini, un token equivale a circa 4 caratteri. 100 token equivalgono a circa 60-80 parole in inglese.

Informazioni sui token

I token possono essere singoli caratteri come z o parole intere come cat. Le parole lunghe vengono suddivise in più token. L'insieme di tutti i token utilizzati dal modello è chiamato vocabolario e il processo di suddivisione del testo in token è chiamato tokenizzazione.

Quando la fatturazione è abilitata, il costo di una chiamata all'API Gemini è determinato in parte dal numero di token di input e output, quindi sapere come contarli può essere utile.

Puoi provare a contare i token nel nostro Colab.

Visualizza su ai.google.dev Prova un notebook Colab Visualizza il notebook su GitHub

Contare i token

Tutti gli input e gli output dell'API Gemini vengono tokenizzati, inclusi testo, file immagine e altre modalità non testuali.

Puoi contare i token nei seguenti modi:

  • Chiama count_tokens con l'input della richiesta.
    In questo modo viene restituito il numero totale di token nell' input solo. Puoi effettuare questa chiamata prima di inviare l'input al modello per verificare le dimensioni delle richieste.

  • Utilizza l'attributo usage_metadata dell'oggetto response dopo aver chiamato generate_content.
    In questo modo viene restituito il numero totale di token sia nell'input sia nell'output: total_token_count.
    Vengono restituiti anche i conteggi dei token di input e output separatamente: prompt_token_count (token di input) e candidates_token_count (token di output).

    Se utilizzi un modello di pensiero, i token utilizzati durante il processo di pensiero vengono restituiti in thoughts_token_count. Se utilizzi la memorizzazione nella cache del contesto, il conteggio dei token memorizzati nella cache sarà in cached_content_token_count.

Contare i token di testo

Se chiami count_tokens con un input di solo testo, viene restituito il conteggio dei token di testo solo nell'input (total_tokens). Puoi effettuare questa chiamata prima di chiamare generate_content per verificare le dimensioni delle richieste.

Un'altra opzione è chiamare generate_content e poi utilizzare l'attributo usage_metadata dell'oggetto response per ottenere quanto segue:

  • I conteggi dei token separati dell'input (prompt_token_count), dei contenuti memorizzati nella cache (cached_content_token_count) e dell'output (candidates_token_count)
  • Il conteggio dei token per il processo di pensiero (thoughts_token_count)
  • Il numero totale di token sia nell'input sia nell'output (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();

Vai

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))
    ```

Contare i token multi-turno (chat)

Se chiami count_tokens con la cronologia chat, viene restituito il conteggio totale dei token del testo di ogni ruolo nella chat (total_tokens).

Un'altra opzione è chiamare send_message e poi utilizzare l'usage_metadata attributo dell'oggetto response per ottenere quanto segue:

  • I conteggi dei token separati dell'input (prompt_token_count), dei contenuti memorizzati nella cache (cached_content_token_count) e dell'output (candidates_token_count)
  • Il conteggio dei token per il processo di pensiero (thoughts_token_count)
  • Il numero totale di token sia nell'input sia nell'output (total_token_count)

Per capire quanto sarà grande il prossimo turno di conversazione, devi aggiungere lo alla cronologia quando chiami 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();

Vai

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)

Contare i token multimodali

Tutti gli input dell'API Gemini vengono tokenizzati, inclusi testo, file immagine e altre modalità non testuali. Tieni presente i seguenti punti chiave di alto livello sulla tokenizzazione dell'input multimodale durante l'elaborazione da parte dell'API Gemini:

  • Gli input immagine con entrambe le dimensioni <=384 pixel vengono conteggiati come 258 token. Le immagini più grandi in una o entrambe le dimensioni vengono ritagliate e scalate in base alle esigenze in riquadri di 768 x 768 pixel, ognuno conteggiato come 258 token.

  • I file audio e video vengono convertiti in token alle seguenti tariffe fisse: video a 263 token al secondo e audio a 32 token al secondo.

Risoluzioni dei contenuti multimediali

I modelli Gemini 3 introducono un controllo granulare dell' elaborazione della visione multimodale con il parametro media_resolution. Il media_resolution parametro determina il numero massimo di token allocati per ogni immagine di input o fotogramma video. Le risoluzioni più elevate migliorano la capacità del modello di leggere il testo fine o identificare piccoli dettagli, ma aumentano l'utilizzo dei token e la latenza.

Per ulteriori dettagli sul parametro e su come può influire sui calcoli dei token, consulta la guida alla risoluzione dei contenuti multimediali.

File immagine

Se chiami count_tokens con un input di testo e immagine, viene restituito il conteggio combinato dei token del testo e dell'immagine in solo nell'input (total_tokens). Puoi effettuare questa chiamata prima di chiamare generate_content per verificare le dimensioni delle richieste. Puoi anche chiamare facoltativamente count_tokens sul testo e sul file separatamente.

Un'altra opzione è chiamare generate_content e poi utilizzare l'attributo usage_metadata dell'oggetto response per ottenere quanto segue:

  • I conteggi dei token separati dell'input (prompt_token_count), dei contenuti memorizzati nella cache (cached_content_token_count) e dell'output (candidates_token_count)
  • Il conteggio dei token per il processo di pensiero (thoughts_token_count)
  • Il numero totale di token sia nell'input sia nell'output (total_token_count)

Esempio che utilizza un'immagine caricata dall'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();

Vai

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))

Esempio che fornisce l'immagine come dati in linea:

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();

Vai

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))

File audio o video

L'audio e il video vengono convertiti in token alle seguenti tariffe fisse:

  • Video: 263 token al secondo
  • Audio: 32 token al secondo

Se chiami count_tokens con un input di testo e video/audio, viene restituito il conteggio combinato dei token del testo e del file video/audio solo nell'input (total_tokens). Puoi effettuare questa chiamata prima di chiamare generate_content per verificare le dimensioni delle richieste. Puoi anche chiamare facoltativamente count_tokens su l testo e sul file separatamente.

Un'altra opzione è chiamare generate_content e poi utilizzare l'attributo usage_metadata dell'oggetto response per ottenere quanto segue:

  • I conteggi dei token separati dell'input (prompt_token_count), dei contenuti memorizzati nella cache (cached_content_token_count) e dell'output (candidates_token_count)
  • Il conteggio dei token per il processo di pensiero (thoughts_token_count)
  • Il numero totale di token sia nell'input sia nell'output (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();

Vai

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))

Finestre contestuali

I modelli disponibili tramite l'API Gemini hanno finestre contestuali che sono misurate in token. La finestra contestuale definisce la quantità di input che puoi fornire e la quantità di output che il modello può generare. Puoi determinare le dimensioni della finestra contestuale chiamando l'endpoint models.get o consultando la documentazione dei modelli.

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();

Vai

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)