토큰 이해 및 계산


Gemini 및 기타 생성형 AI 모델은 토큰이라는 세분화 수준에서 입력과 출력을 처리합니다.

토큰 정보

토큰은 z와 같은 단일 문자이거나 cat와 같은 전체 단어일 수 있습니다. 긴 단어는 여러 토큰으로 분할됩니다. 모델에서 사용하는 모든 토큰의 집합을 어휘라고 하며 텍스트를 토큰으로 분할하는 프로세스를 토큰화라고 합니다.

Gemini 모델의 경우 토큰은 약 4자(영문 기준)에 해당합니다. 토큰 100개는 영어 단어 약 60~80개에 해당합니다.

결제가 사용 설정된 경우 Gemini API 호출 비용은 입력 및 출력 토큰 수에 따라 부분적으로 결정되므로 토큰 수를 계산하는 방법을 알고 있으면 유용합니다.

토큰 집계

텍스트, 이미지 파일, 기타 텍스트가 아닌 형식을 비롯하여 Gemini API의 모든 입력과 출력은 토큰화됩니다.

다음과 같은 방법으로 토큰을 집계할 수 있습니다.

  • 요청의 입력과 함께 countTokens를 호출합니다.
    입력만의 총 토큰 수를 반환합니다. 입력을 모델에 전송하기 전에 이 호출을 실행하여 요청 크기를 확인할 수 있습니다.

  • generate_content를 호출한 후 response 객체에 usageMetadata 속성을 사용합니다.
    입력과 출력의 총 토큰 수를 반환합니다. totalTokenCount
    또한 입력과 출력의 토큰 수를 별도로 반환합니다. promptTokenCount (입력 토큰) 및 candidatesTokenCount (출력 토큰).

텍스트 토큰 수 집계

텍스트 전용 입력으로 countTokens를 호출하면 입력 전용 (totalTokens)으로 텍스트의 토큰 수가 반환됩니다. generateContent를 호출하여 요청 크기를 확인하기 전에 이 호출을 실행할 수 있습니다.

generateContent을 호출한 다음 response 객체의 usageMetadata 속성을 사용하여 다음을 가져오는 방법도 있습니다.

  • 입력 (promptTokenCount)과 출력 (candidatesTokenCount)의 개별 토큰 수
  • 입력과 출력 모두의 총 토큰 수입니다. (totalTokenCount)
// Make sure to include the following import:
// import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const prompt = "The quick brown fox jumps over the lazy dog.";
const countTokensResponse = await ai.models.countTokens({
  model: "gemini-2.0-flash",
  contents: prompt,
});
console.log(countTokensResponse.totalTokens);

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

멀티턴 (채팅) 토큰 집계

채팅 기록으로 countTokens를 호출하면 채팅의 각 역할 (totalTokens)에서 텍스트의 총 토큰 수가 반환됩니다.

다른 방법은 sendMessage를 호출한 다음 response 객체의 usageMetadata 속성을 사용하여 다음을 가져오는 것입니다.

  • 입력 (promptTokenCount)과 출력 (candidatesTokenCount)의 개별 토큰 수
  • 입력과 출력 모두의 총 토큰 수입니다. (totalTokenCount)

다음 대화의 길이를 파악하려면 countTokens를 호출할 때 대화 기록에 추가해야 합니다.

// Make sure to include the following import:
// import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
// Initial chat history.
const history = [
  { role: "user", parts: [{ text: "Hi my name is Bob" }] },
  { role: "model", parts: [{ text: "Hi Bob!" }] },
];
const chat = ai.chats.create({
  model: "gemini-2.0-flash",
  history: history,
});

// Count tokens for the current chat history.
const countTokensResponse = await ai.models.countTokens({
  model: "gemini-2.0-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);

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

멀티모달 토큰 집계

텍스트, 이미지 파일, 기타 텍스트가 아닌 형식을 비롯한 Gemini API의 모든 입력은 토큰화됩니다. Gemini API에서 처리하는 동안 멀티모달 입력의 토큰화에 관한 다음과 같은 대략적인 주요 사항에 유의하세요.

  • Gemini 2.0에서는 두 크기가 모두 384픽셀 이하인 이미지 입력이 258개의 토큰으로 집계됩니다. 한 변 또는 양변이 더 큰 이미지는 필요에 따라 잘리고 크기가 조정되어 768x768픽셀의 타일로 변환되며, 각각 258개의 토큰으로 집계됩니다. Gemini 2.0 이전에는 이미지가 고정된 258개의 토큰을 사용했습니다.

  • 동영상 및 오디오 파일은 다음과 같은 고정 비율로 토큰으로 변환됩니다. 동영상은 초당 263개 토큰, 오디오는 초당 32개 토큰입니다.

이미지 파일

텍스트 및 이미지 입력으로 countTokens를 호출하면 입력 전용 (totalTokens)으로 텍스트와 이미지의 결합된 토큰 수를 반환합니다. generateContent를 호출하여 요청 크기를 확인하기 전에 이 호출을 실행할 수 있습니다. 원하는 경우 텍스트와 파일에서 countTokens를 별도로 호출할 수도 있습니다.

generateContent을 호출한 다음 response 객체의 usageMetadata 속성을 사용하여 다음을 가져오는 방법도 있습니다.

  • 입력 (promptTokenCount)과 출력 (candidatesTokenCount)의 개별 토큰 수
  • 입력과 출력 모두의 총 토큰 수입니다. (totalTokenCount)

File API에서 업로드된 이미지를 사용하는 예:

// Make sure to include the following import:
// import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const prompt = "Tell me about this image";
const organ = await ai.files.upload({
  file: path.join(media, "organ.jpg"),
  config: { mimeType: "image/jpeg" },
});

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

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

이미지를 인라인 데이터로 제공하는 예시:

// Make sure to include the following import:
// import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const prompt = "Tell me about this image";
const imageBuffer = fs.readFileSync(path.join(media, "organ.jpg"));

// Convert buffer to base64 string.
const imageBase64 = imageBuffer.toString("base64");

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

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

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

동영상 또는 오디오 파일

오디오와 동영상은 각각 다음과 같은 고정 비율로 토큰으로 변환됩니다.

  • 동영상: 초당 263개 토큰
  • 오디오: 초당 32개 토큰

텍스트 및 동영상/오디오 입력으로 countTokens를 호출하면 입력 전용(totalTokens)으로 텍스트와 동영상/오디오 파일의 결합된 토큰 수를 반환합니다. generateContent를 호출하기 전에 이 호출을 실행하여 요청 크기를 확인할 수 있습니다. 원하는 경우 텍스트와 파일에서 countTokens를 별도로 호출할 수도 있습니다.

generateContent을 호출한 다음 response 객체의 usageMetadata 속성을 사용하여 다음을 가져오는 방법도 있습니다.

  • 입력 (promptTokenCount)과 출력 (candidatesTokenCount)의 개별 토큰 수
  • 입력과 출력 모두의 총 토큰 수입니다. (totalTokenCount)
// Make sure to include the following import:
// import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const prompt = "Tell me about this video";
let videoFile = await ai.files.upload({
  file: path.join(media, "Big_Buck_Bunny.mp4"),
  config: { mimeType: "video/mp4" },
});

// Poll until the video file is completely processed (state becomes ACTIVE).
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-2.0-flash",
  contents: createUserContent([
    prompt,
    createPartFromUri(videoFile.uri, videoFile.mimeType),
  ]),
});
console.log(countTokensResponse.totalTokens);

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

시스템 안내 및 도구

시스템 안내 및 도구도 입력의 총 토큰 수에 포함됩니다.

시스템 안내를 사용하면 systemInstruction 추가를 반영하도록 totalTokens 수가 증가합니다.

함수 호출을 사용하면 tools의 추가를 반영하도록 totalTokens 수가 증가합니다.