Gemini y otros modelos de IA generativa procesan la entrada y la salida con una granularidad llamada un token.
En el caso de los modelos de Gemini, un token equivale a aproximadamente 4 caracteres. 100 tokens equivalen a entre 60 y 80 palabras en inglés.
Acerca de los tokens
Los tokens pueden ser caracteres individuales, como z, o palabras completas, como cat. Las palabras largas
se dividen en varios tokens. El conjunto de todos los tokens que usa el modelo se
denomina vocabulario, y el proceso de dividir el texto en tokens se denomina
tokenización.
Cuando la facturación está habilitada, el costo de una llamada a la API de Gemini se determina, en parte, por la cantidad de tokens de entrada y salida, por lo que puede ser útil saber cómo contarlos.
Puedes probar el recuento de tokens en nuestro Colab.
|
|
Probar un notebook de Colab
|
Ver el notebook en GitHub
|
Cuenta tokens
Toda la entrada y la salida de la API de Gemini se tokenizan, incluido el texto, los archivos de imagen y otras modalidades que no son de texto.
Puedes contar tokens de las siguientes maneras:
Llama a
count_tokenscon la entrada de la solicitud.
Esto muestra la cantidad total de tokens solo en la entrada. Puedes realizar esta llamada antes de enviar la entrada al modelo para verificar el tamaño de tus solicitudes.Usa el atributo
usage_metadataen el objetoresponsedespués de llamar agenerate_content.
Esto muestra la cantidad total de tokens tanto en la entrada como en la salida:total_token_count.
También muestra los recuentos de tokens de la entrada y la salida por separado:prompt_token_count(tokens de entrada) ycandidates_token_count(tokens de salida).Si usas un modelo de pensamiento, el token que se usa durante el proceso de pensamiento se muestra en
thoughts_token_count. Si usas el almacenamiento en caché de contexto, el recuento de tokens almacenados en caché estará encached_content_token_count.
Cuenta tokens de texto
Si llamas a count_tokens con una entrada solo de texto, se muestra el recuento de tokens de
el texto solo en la entrada (total_tokens). Puedes realizar esta llamada antes de
llamar a generate_content para verificar el tamaño de tus solicitudes.
Otra opción es llamar a generate_content y, luego, usar el usage_metadata
atributo en el objeto response para obtener lo siguiente:
- Los recuentos de tokens separados de la entrada (
prompt_token_count), el contenido almacenado en caché (cached_content_token_count) y la salida (candidates_token_count) - El recuento de tokens para el proceso de pensamiento (
thoughts_token_count) La cantidad total de tokens en tanto en la entrada como en la salida (
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))
```
Cuenta tokens de varios turnos (chat)
Si llamas a count_tokens con el historial de chat, se muestra el recuento total de tokens del texto de cada rol en el chat (total_tokens).
Otra opción es llamar a send_message y, luego, usar el atributo usage_metadata
en el objeto response para obtener lo siguiente:
- Los recuentos de tokens separados de la entrada (
prompt_token_count), el contenido almacenado en caché (cached_content_token_count) y la salida (candidates_token_count) - El recuento de tokens para el proceso de pensamiento (
thoughts_token_count) - La cantidad total de tokens en tanto en la entrada como en la salida
(
total_token_count)
Para comprender el tamaño de tu próximo turno conversacional, debes agregar
lo al historial cuando llames a 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)
Cuenta tokens multimodales
Toda la entrada a la API de Gemini se tokeniza, incluido el texto, los archivos de imagen y otras modalidades que no son de texto. Ten en cuenta los siguientes puntos clave de alto nivel sobre la tokenización de la entrada multimodal durante el procesamiento de la API de Gemini:
Las entradas de imágenes con ambas dimensiones <=384 píxeles se cuentan como 258 tokens. Las imágenes más grandes en una o ambas dimensiones se cortan y se ajustan según sea necesario en mosaicos de 768 x 768 píxeles, cada uno contado como 258 tokens.
Los archivos de video y audio se convierten en tokens a las siguientes tasas fijas: video a 263 tokens por segundo y audio a 32 tokens por segundo.
Resoluciones de contenido multimedia
Los modelos de Gemini 3 introducen un control detallado sobre el
procesamiento de visión multimodal con el media_resolution parámetro. El
media_resolution parámetro determina la
cantidad máxima de tokens asignados por imagen de entrada o fotograma de video.
Las resoluciones más altas mejoran la capacidad del modelo para
leer texto fino o identificar detalles pequeños, pero aumentan el uso de tokens y la latencia.
Para obtener más detalles sobre el parámetro y cómo puede afectar los cálculos de tokens, consulta la guía de resolución de contenido multimedia.
Archivos de imagen
Si llamas a count_tokens con una entrada de texto e imagen, se muestra el recuento de tokens combinado
del texto y la imagen en solo en la entrada (total_tokens). Puedes
realizar esta llamada antes de llamar a generate_content para verificar el tamaño de tus
solicitudes. También puedes llamar a count_tokens de forma opcional en el texto y el archivo
por separado.
Otra opción es llamar a generate_content y, luego, usar el usage_metadata
atributo en el objeto response para obtener lo siguiente:
- Los recuentos de tokens separados de la entrada (
prompt_token_count), el contenido almacenado en caché (cached_content_token_count) y la salida (candidates_token_count) - El recuento de tokens para el proceso de pensamiento (
thoughts_token_count) - La cantidad total de tokens en tanto en la entrada como en la salida
(
total_token_count)
Ejemplo que usa una imagen subida desde la API de 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))
Ejemplo que proporciona la imagen como datos intercalados:
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))
Archivos de audio o video
El audio y el video se convierten en tokens a las siguientes tasas fijas:
- Video: 263 tokens por segundo
- Audio: 32 tokens por segundo
Si llamas a count_tokens con una entrada de texto y video o audio, se muestra el
recuento de tokens combinado del texto y el archivo de video o audio solo en la entrada
(total_tokens). Puedes realizar esta llamada antes de llamar a generate_content para
verificar el tamaño de tus solicitudes. También puedes llamar a count_tokens de forma opcional en
el texto y el archivo por separado.
Otra opción es llamar a generate_content y, luego, usar el usage_metadata
atributo en el objeto response para obtener lo siguiente:
- Los recuentos de tokens separados de la entrada (
prompt_token_count), el contenido almacenado en caché (cached_content_token_count) y la salida (candidates_token_count) - El recuento de tokens para el proceso de pensamiento (
thoughts_token_count) La cantidad total de tokens tanto en la entrada como en la salida (
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))
Ventanas de contexto
Los modelos disponibles a través de la API de Gemini tienen ventanas de contexto que se
miden en tokens. La ventana de contexto define la cantidad de entrada que puedes proporcionar
y la cantidad de salida que puede generar el modelo. Puedes determinar el tamaño de la
ventana de contexto llamando al extremo models.get
o consultando la documentación de los modelos.
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)
Probar un notebook de Colab
Ver el notebook en GitHub