The Gemini 3 and 2.5 series models use a "thinking process" that significantly improves their reasoning and multi-step planning abilities, making them highly effective for complex tasks such as coding, advanced mathematics, and data analysis.
When you use a thinking model, Gemini reasons internally before responding. The Interactions API surfaces this reasoning via thought steps, dedicated steps that appear chronologically alongside function calls, user inputs or model outputs in the steps array.
Every thought step contains two fields:
| Field | Required | Description |
|---|---|---|
signature |
✅ Yes | An encrypted representation of the model's internal reasoning state. Always present, even when the model performs minimal reasoning. |
summary |
❌ No | An array of content (text and/or images) summarizing the reasoning. May be empty depending on the thinking_summaries config, whether the model performed enough reasoning, or the content type (for example, image latents may not have text summaries). |
Interactions with thinking
Initiating an interaction with a thinking model is similar to any other interaction request. Specify one of the models with thinking support in the model field:
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.7-flash",
input="Explain the concept of Occam's Razor and provide a simple, everyday example."
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: "gemini-3.7-flash",
input: "Explain the concept of Occam's Razor and provide a simple, everyday example."
});
console.log(interaction.output_text);
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "gemini-3.7-flash",
"input": "Explain the concept of Occam'\''s Razor and provide a simple example."
}'
Thought summaries
Thought summaries provide insights into the model's internal reasoning process.
By default, only the final output is returned. You can enable thought summaries
with thinking_summaries:
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.7-flash",
input="What is the sum of the first 50 prime numbers?",
generation_config={
"thinking_summaries": "auto"
}
)
for step in interaction.steps:
if step.type == "thought":
print("Thought summary:")
if step.summary:
for content_block in step.summary:
if content_block.type == "text":
print(content_block.text)
print()
elif step.type == "model_output":
for content_block in step.content:
if content_block.type == "text":
print("Answer:")
print(content_block.text)
print()
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: "gemini-3.7-flash",
input: "What is the sum of the first 50 prime numbers?",
generation_config: {
thinking_summaries: "auto"
}
});
for (const step of interaction.steps) {
if (step.type === "thought") {
console.log("Thought summary:");
if (step.summary) {
for (const contentBlock of step.summary) {
if (contentBlock.type === "text") console.log(contentBlock.text);
}
}
} else if (step.type === "model_output") {
for (const contentBlock of step.content) {
if (contentBlock.type === "text") {
console.log("Answer:");
console.log(contentBlock.text);
}
}
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "gemini-3.7-flash",
"input": "What is the sum of the first 50 prime numbers?",
"generation_config": {
"thinking_summaries": "auto"
}
}'
A thought block may contain only a signature with no summary in these cases:
- Simple requests, where the model didn't reason enough to generate a summary
thinking_summaries: "none", where summaries are explicitly disabled- Certain thought content types, such as images, may not have text summaries
Your code should always handle thought blocks where summary is empty or absent.
Streaming with thinking
Use streaming to receive incremental thought summaries during generation. Thought blocks are delivered using Server-Sent Events (SSE) with two distinct delta types:
| Delta type | Contains | When sent |
|---|---|---|
thought_summary |
Text or image summary content | One or more deltas with incremental summary |
thought_signature |
The cryptographic signature | the last delta before step.stop |
Python
from google import genai
client = genai.Client()
prompt = """
Alice, Bob, and Carol each live in a different house on the same street: red, green, and blue.
Alice does not live in the red house.
Bob does not live in the green house.
Carol does not live in the red or green house.
Which house does each person live in?
"""
thoughts = ""
answer = ""
stream = client.interactions.create(
model="gemini-3.7-flash",
input=prompt,
generation_config={
"thinking_summaries": "auto"
},
stream=True
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "thought_summary":
if not thoughts:
print("Thinking...")
summary_text = event.delta.content.text
print(f"[Thought] {summary_text}", end="")
thoughts += summary_text
elif event.delta.type == "text" and event.delta.text:
if not answer:
print("\nAnswer:")
print(event.delta.text, end="")
answer += event.delta.text
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const prompt = `Alice, Bob, and Carol each live in a different house on the same
street: red, green, and blue. Alice does not live in the red house.
Bob does not live in the green house.
Carol does not live in the red or green house.
Which house does each person live in?`;
let thoughts = "";
let answer = "";
const stream = await client.interactions.create({
model: "gemini-3.7-flash",
input: prompt,
generation_config: {
thinking_summaries: "auto"
},
stream: true
});
for await (const event