Wyjaśnienia dotyczące tokenów i ich zliczania
Gemini i inne modele generatywnej AI przetwarzają dane wejściowe i wyjściowe w jednostkach zwanych tokenami.
W przypadku modeli Gemini token odpowiada około 4 znakom. 100 tokenów to około 60–80 słów w języku angielskim.
Informacje o tokenach
Tokeny mogą być pojedynczymi znakami, np. z, lub całymi słowami, np. cat. Długie słowa
są dzielone na kilka tokenów. Zbiór wszystkich tokenów używanych przez model nazywa się słownikiem, a proces dzielenia tekstu na tokeny to tokenizacja.
Gdy płatności są włączone, koszt wywołania interfejsu Gemini API jest częściowo określany przez liczbę tokenów wejściowych i wyjściowych, więc wiedza o tym, jak je zliczać, może być przydatna.
Możesz wypróbować zliczanie tokenów w naszym Colabie.
Wypróbuj notatnik Colab |
Wyświetl notatnik w GitHubie |
Liczba tokenów
Wszystkie dane wejściowe i wyjściowe interfejsu Gemini API są tokenizowane, w tym tekst, pliki obrazów i inne formaty nietekstowe.
Tokeny możesz zliczać na te sposoby:
Wywołaj funkcję
count_tokens, podając dane wejściowe żądania.
Zwraca łączną liczbę tokenów tylko w danych wejściowych. Możesz wykonać to wywołanie przed wysłaniem danych wejściowych do modelu, aby sprawdzić rozmiar żądań.Użyj atrybutu
usage_metadataw obiekcieresponsepo wywołaniu funkcjigenerate_content.
Zwraca on łączną liczbę tokenów zarówno w danych wejściowych, jak i wyjściowych:total_token_count.
Zwraca też liczbę tokenów w danych wejściowych i wyjściowych osobno:prompt_token_count(tokeny wejściowe) icandidates_token_count(tokeny wyjściowe).Jeśli używasz modelu myślącego, tokeny użyte podczas procesu myślenia są zwracane w
thoughts_token_count. Jeśli używasz pamięci podręcznej kontekstu, liczba tokenów w pamięci podręcznej będzie podana wcached_content_token_count.
Liczba tokenów tekstowych
Jeśli wywołasz funkcję count_tokens z danymi wejściowymi w postaci tekstu, zwróci ona liczbę tokenów tekstu tylko w danych wejściowych (total_tokens). Możesz wywołać tę funkcję przed wywołaniem funkcji generate_content, aby sprawdzić rozmiar żądań.
Inną opcją jest wywołanie generate_content, a następnie użycie atrybutu usage_metadata
w obiekcie response, aby uzyskać te informacje:
- Osobne liczby tokenów wejściowych (
prompt_token_count), treści w pamięci podręcznej (cached_content_token_count) i wyjściowych (candidates_token_count). - Liczba tokenów w procesie myślowym (
thoughts_token_count) Łączna liczba tokenów zarówno wejściowych, jak i wyjściowych (
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.5-flash", contents=prompt
)
print("total_tokens: ", total_tokens)
response = client.models.generate_content(
model="gemini-3.5-flash", 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.5-flash",
contents: prompt,
});
console.log(countTokensResponse.totalTokens);
const generateResponse = await ai.models.generateContent({
model: "gemini-3.5-flash",
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.5-flash", contents, nil)
if err != nil {
return err
}
fmt.Println("total_tokens:", countResp.TotalTokens)
response, err := client.Models.GenerateContent(ctx, "gemini-3.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(usageMetadata))
```
Zliczanie tokenów w czacie wieloetapowym
Jeśli wywołasz count_tokens z historią czatu, zwróci ona łączną liczbę tokenów
tekstu z każdej roli na czacie (total_tokens).
Inną opcją jest wywołanie send_message, a następnie użycie atrybutu usage_metadata
w obiekcie response, aby uzyskać te informacje:
- Osobne liczby tokenów wejściowych (
prompt_token_count), treści w pamięci podręcznej (cached_content_token_count) i wyjściowych (candidates_token_count). - Liczba tokenów w procesie myślowym (
thoughts_token_count) - Łączna liczba tokenów zarówno wejściowych, jak i wyjściowych (
total_token_count)
Aby dowiedzieć się, jak duża będzie kolejna tura rozmowy, musisz dołączyć ją do historii, gdy wywołujesz funkcję count_tokens.
Python
from google import genai
from google.genai import types
client = genai.Client()
chat = client.chats.create(
model="gemini-3.5-flash",
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.5-flash", 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.5-flash", 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.5-flash",
history: history,
});
const countTokensResponse = await ai.models.countTokens({
model: "gemini-3.5-flash",
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.5-flash",
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.5-flash", nil, history)
if err != nil {
log.Fatal(err)
}
firstTokenResp, err := client.Models.CountTokens(ctx, "gemini-3.5-flash", 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.5-flash", hist, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(secondTokenResp.TotalTokens)
Liczba tokenów multimodalnych
Wszystkie dane wejściowe do Gemini API są tokenizowane, w tym tekst, pliki graficzne i inne formaty nietekstowe. Podczas przetwarzania danych wejściowych multimodalnych przez interfejs Gemini API weź pod uwagę te najważniejsze informacje o tokenizacji:
Obrazy wejściowe, których oba wymiary są mniejsze lub równe 384 pikselom, są liczone jako 258 tokenów. Obrazy o większych wymiarach są w razie potrzeby przycinane i skalowane do rozmiaru 768 x 768 pikseli, a każdy z nich jest liczony jako 258 tokenów.
Pliki wideo i audio są konwertowane na tokeny według tych stałych stawek: wideo – 263 tokeny na sekundę, audio – 32 tokeny na sekundę.
Rozdzielczości multimediów
Modele Gemini 3 wprowadzają szczegółową kontrolę nad przetwarzaniem obrazów multimodalnych za pomocą parametru media_resolution. Parametr media_resolution określa maksymalną liczbę tokenów przypisanych do każdego obrazu wejściowego lub klatki wideo.Wyższe rozdzielczości zwiększają zdolność modelu do odczytywania drobnego tekstu lub rozpoznawania małych szczegółów, ale zwiększają zużycie tokenów i opóźnienia.
Więcej informacji o tym parametrze i jego wpływie na obliczenia tokenów znajdziesz w przewodniku dotyczącym rozdzielczości multimediów.
Pliki graficzne
Jeśli wywołasz funkcję count_tokens z tekstem i obrazem, zwróci ona łączną liczbę tokenów tekstu i obrazu tylko w danych wejściowych (total_tokens). Możesz wywołać tę funkcję przed wywołaniem funkcji generate_content, aby sprawdzić rozmiar żądań. Opcjonalnie możesz też wywołać funkcję count_tokens osobno w przypadku tekstu i pliku.
Inną opcją jest wywołanie generate_content, a następnie użycie atrybutu usage_metadata
w obiekcie response, aby uzyskać te informacje:
- Osobne liczby tokenów wejściowych (
prompt_token_count), treści w pamięci podręcznej (cached_content_token_count) i wyjściowych (candidates_token_count). - Liczba tokenów w procesie myślowym (
thoughts_token_count) - Łączna liczba tokenów zarówno wejściowych, jak i wyjściowych (
total_token_count)
Przykład korzystający z przesłanego obrazu z interfejsu File API:
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.5-flash", contents=[prompt, your_image_file]
)
)
response = client.models.generate_content(
model="gemini-3.5-flash", 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.5-flash",
contents: createUserContent([
prompt,
createPartFromUri(organ.uri, organ.mimeType),
]),
});
console.log(countTokensResponse.totalTokens);
const generateResponse = await ai.models.generateContent({
model: "gemini-3.5-flash",
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.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Multimodal image token count:", tokenResp.TotalTokens)
response, err := client.Models.GenerateContent(ctx, "gemini-3.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(usageMetadata))
Przykład, w którym obraz jest podany jako dane w treści:
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.5-flash", contents=[prompt, your_image_file]
)
)
response = client.models.generate_content(
model="gemini-3.5-flash", 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.5-flash",
contents: contents,
});
console.log(countTokensResponse.totalTokens);
const generateResponse = await ai.models.generateContent({
model: "gemini-3.5-flash",
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.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Multimodal image token count:", tokenResp.TotalTokens)
response, err := client.Models.GenerateContent(ctx, "gemini-3.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(usageMetadata))
Pliki wideo lub audio
Dźwięk i wideo są przeliczane na tokeny według tych stałych stawek:
- Film: 263 tokeny na sekundę
- Audio: 32 tokeny na sekundę
Jeśli wywołasz funkcję count_tokens z tekstowym i wideo/audio danymi wejściowymi, zwróci ona łączną liczbę tokenów tekstu i pliku wideo/audio tylko w danych wejściowych (total_tokens). Możesz wywołać tę funkcję przed wywołaniem funkcji generate_content, aby sprawdzić rozmiar żądań. Możesz też opcjonalnie wywołać count_tokens na tekście i pliku osobno.
Inną opcją jest wywołanie generate_content, a następnie użycie atrybutu usage_metadata
w obiekcie response, aby uzyskać te informacje:
- Osobne liczby tokenów wejściowych (
prompt_token_count), treści w pamięci podręcznej (cached_content_token_count) i wyjściowych (candidates_token_count). - Liczba tokenów w procesie myślowym (
thoughts_token_count) Łączna liczba tokenów zarówno wejściowych, jak i wyjściowych (
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.5-flash", contents=[prompt, your_file]
)
)
response = client.models.generate_content(
model="gemini-3.5-flash", 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.5-flash",
contents: createUserContent([
prompt,
createPartFromUri(videoFile.uri, videoFile.mimeType),
]),
});
console.log(countTokensResponse.totalTokens);
const generateResponse = await ai.models.generateContent({
model: "gemini-3.5-flash",
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.5-flash", 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.5-flash", contents, nil)
if err != nil {
log.Fatal(err)
}
usageMetadata, err := json.MarshalIndent(response.UsageMetadata, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(usageMetadata))
Liczba tokenów myśli
Gdy włączysz myślenie, cena odpowiedzi będzie sumą tokenów wyjściowych i tokenów myślenia. Łączną liczbę wygenerowanych tokenów myślenia możesz pobrać z pola thoughtsTokenCount (lub odpowiednika w SDK).
Python
# ...
print("Thoughts tokens:", response.usage_metadata.thoughts_token_count)
print("Output tokens:", response.usage_metadata.candidates_token_count)
JavaScript
// ...
console.log(`Thoughts tokens: ${response.usageMetadata.thoughtsTokenCount}`);
console.log(`Output tokens: ${response.usageMetadata.candidatesTokenCount}`);
Go
// ...
fmt.Println("Thoughts tokens:", response.UsageMetadata.ThoughtsTokenCount)
fmt.Println("Output tokens:", response.UsageMetadata.CandidatesTokenCount)
Modele myślowe generują pełne myśli, aby poprawić jakość ostatecznej odpowiedzi, a następnie wyświetlają podsumowania, aby zapewnić wgląd w proces myślowy. Dlatego interfejs API ustala ceny na podstawie pełnych tokenów myśli, które model generuje w celu utworzenia podsumowania, mimo że interfejs API zwraca tylko podsumowanie.
Więcej informacji o konfigurowaniu myślenia znajdziesz w przewodniku Myślenie Gemini.
Okna kontekstu
Modele dostępne w ramach Gemini API mają okna kontekstu mierzone w tokenach. Okno kontekstu określa, ile danych wejściowych możesz podać i ile danych wyjściowych może wygenerować model. Rozmiar okna kontekstu możesz określić, wywołując models.get punkt końcowy lub sprawdzając dokumentację modeli.
Python
from google import genai
client = genai.Client()
model_info = client.models.get(model="gemini-3.5-flash")
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.5-flash'});
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.5-flash")
if err != nil {
log.Fatal(err)
}
fmt.Println("input token limit:", modelInfo.InputTokenLimit)
fmt.Println("output token limit:", modelInfo.OutputTokenLimit)
Wypróbuj notatnik Colab
Wyświetl notatnik w GitHubie