spring-boottokengoogle-gemini

How to get token usage (prompt/completion tokens) from GenerateContentResponse using google-genai Java SDK v1.23.0? - springboot, github codespace


I am using the com.google.genai:google-genai:1.23.0 Java SDK in a Spring Boot 3 project to call the Gemini API (gemini-1.5-flash).

I can successfully generate content and get the answer text like this:

// This part works perfectly

GenerateContentResponse response = geminiClient.models.generateContent(modelName, finalPrompt, generationConfig);

String answer = response.text();

Now, I want to get the token usage details (prompt tokens, completion/candidates tokens, and total tokens) from the response object to log them.

Based on some documentation and examples, I'm trying to use the usageMetadata() method, but I'm consistently getting compilation errors (cannot find symbol).

Here is the relevant part of my code that is failing:

My Code (AiServiceImpl.java)

import com.google.genai.types.GenerateContentResponse;

// I'm unsure about the correct import for UsageMetadata, I've tried a few things.

// import com.google.genai.types.GenerateContentResponse.UsageMetadata; // This gives a compile error

import com.google.genai.types.GenerateContentResponseUsageMetadata; // This also leads to errors in the method calls



//...



public class AiServiceImpl implements AiService {



    // ... (other code)



    public void someMethod() {

        GenerateContentResponse response = //... call to generateContent

        

        // This is where the first error occurs: "incompatible types"

        // if the method signature for logTokenUsage is wrong.

        logTokenUsage(user, savedHistory, response.usageMetadata().orElse(null));

    }



    private void logTokenUsage(User user, AiHistory history, GenerateContentResponseUsageMetadata usageMetadata) {

        int promptTokens = 0;

        int completionTokens = 0;

        int totalTokens = 0;



        if (usageMetadata != null) {

            // ALL THREE of the following lines cause a "cannot find symbol" error

            promptTokens = usageMetadata.getPromptTokenCount();

            completionTokens = usageMetadata.getCandidatesTokenCount();

            totalTokens = usageMetadata.getTotalTokenCount();

        }



        // ... logic to save token counts to the database

    }

}

The Errors I'm Getting:

When I try to compile, I get these errors, which suggest the method names are wrong:

error: cannot find symbol

symbol: method getPromptTokenCount()

location: variable usageMetadata of type GenerateContentResponseUsageMetadata

error: cannot find symbol

symbol: method getCandidatesTokenCount()

location: variable usageMetadata of type GenerateContentResponseUsageMetadata

error: cannot find symbol

symbol: method getTotalTokenCount()

location: variable usageMetadata of type GenerateContentResponseUsageMetadata

I have tried calling methods without the get prefix (e.g., usageMetadata.promptTokenCount()) which also resulted in compilation errors, related to Optional types.

It seems I'm confused about the exact class name and the correct method names to access the token counts in this specific version of the SDK.

My Question:

What is the correct, canonical way to get the prompt token count, candidates token count, and total token count from a GenerateContentResponse object using the com.google.genai:google-genai:1.23.0 library?

It seems I'm confused about the exact class name and the correct method names to access the token counts in this specific version of the SDK.


Solution

  • The Java class for response usageMetadata is: com.google.genai.types.GenerateContentResponseUsageMetadata

    See SDK Doc.

    The following code works when I tested with Gemini-2.5-flash.

    import com.google.genai.Client;
    import com.google.genai.types.GenerateContentResponse;
    // Import the specific UsageMetadata class to resolve the type.
    import com.google.genai.types.GenerateContentResponseUsageMetadata;
    // Assuming you have these classes
    import com.google.vertex.User;
    import com.google.vertex.AiHistory;
    
    import java.util.Optional;
    
    // @Service
    // public class GeminiTokenCount implements AiService {
    public class GeminiTokenCount {
    
        private final Client geminiClient;
    
        public GeminiTokenCount() {
            // Instantiate the client. The client by default uses the Gemini API. It
            // gets the API key from the environment variable `GOOGLE_API_KEY`.
            Client client = new Client();
            this.geminiClient = client;
        }
    
        public static void main(String[] args) {
            // Create an instance and call the method.
            // Make sure to set the GOOGLE_API_KEY environment variable.
            GeminiTokenCount tokenCounter = new GeminiTokenCount();
            tokenCounter.someMethod(new User(), new AiHistory());
        }
    
        public void someMethod(User user, AiHistory savedHistory) {
            // ... (your code to build finalPrompt and generationConfig) ...
            String modelName = "gemini-2.5-flash"; // Use a valid model name
            String finalPrompt = "What is the difference between a token and a word?";
        
            // The actual API call
            GenerateContentResponse response = this.geminiClient.models.generateContent(modelName,finalPrompt, null);
    
            // Correct way to get the Optional UsageMetadata
            GenerateContentResponseUsageMetadata usageMetadataOptional = response.usageMetadata().orElse(null);
            
            // Pass the Optional to the logging method to handle presence/absence
            logTokenUsage(user, savedHistory, usageMetadataOptional);
        }
    
        /**
         * Logs the token usage from the Gemini API response.
         * @param user The user associated with the request.
         * @param history The history entry to update.
         * @param usageMetadataOptional The Optional UsageMetadata from the response.
         */
        private void logTokenUsage(User user, AiHistory history, GenerateContentResponseUsageMetadata usageMetadata) {
        
            // This block executes if usageMetadata is present
            System.out.println("Usage metadata is present. Logging token counts.");
    
            int promptTokens = usageMetadata.promptTokenCount().orElse(0);
            int thoughtsTokens = usageMetadata.thoughtsTokenCount().orElse(0);
            int totalTokens = usageMetadata.totalTokenCount().orElse(0);
    
            System.out.printf("Prompt Tokens: %d, Thought Tokens: %d, Total Tokens: %d%n",
                    promptTokens, thoughtsTokens, totalTokens);
    
            // ... your logic to save token counts to the database ...
            // history.setPromptTokens(promptTokens);
        }
        
        // Interface for completeness
        public interface AiService {
            void someMethod(User user, AiHistory savedHistory);
        }
    }
    

    Run this code should give you result:

    Usage metadata is present. Logging token counts.
    Prompt Tokens: 11, Thought Tokens: 1243, Total Tokens: 2480
    

    Also, I noticed that you are using Gemini 1.5 which has been deprecated, please update to the latest Gemini models (2.0, 2.5). See this google-cloud-retired-models.