Repository Public
1The [Gemini 3 and 2.5 series models](https://ai.google.dev/gemini-api/docs/models) use an internal2"thinking process" that significantly improves their reasoning and multi-step3planning abilities, making them highly effective for complex tasks such as4coding, advanced mathematics, and data analysis.56This guide shows you how to work with Gemini's thinking capabilities using the7Gemini API.89## Generating content with thinking1011Initiating a request with a thinking model is similar to any other content12generation request. The key difference lies in specifying one of the13[models with thinking support](https://ai.google.dev/gemini-api/docs/generate-content/thinking#supported-models) in the `model` field, as14demonstrated in the following [text generation](https://ai.google.dev/gemini-api/docs/text-generation#text-input) example:1516### Python1718 from google import genai1920 client = genai.Client()21 prompt = "Explain the concept of Occam's Razor and provide a simple, everyday example."22 response = client.models.generate_content(23 model="gemini-3.8-flash",24 contents=prompt25 )2627 print(response.text)2829### JavaScript3031 import { GoogleGenAI } from "@google/genai";3233 const ai = new GoogleGenAI({});3435 async function main() {36 const prompt = "Explain the concept of Occam's Razor and provide a simple, everyday example.";3738 const response = await ai.models.generateContent({39 model: "gemini-3.8-flash",40 contents: prompt,41 });4243 console.log(response.text);44 }4546 main();4748### Go4950 package main5152 import (53 "context"54 "fmt"55 "log"56 "os"57 "google.golang.org/genai"58 )5960 func main() {61 ctx := context.Background()62 client, err := genai.NewClient(ctx, nil)63 if err != nil {64 log.Fatal(err)65 }6667 prompt := "Explain the concept of Occam's Razor and provide a simple, everyday example."68 model := "gemini-3.8-flash"6970 resp, _ := client.Models.GenerateContent(ctx, model, genai.Text(prompt), nil)7172 fmt.Println(resp.Text())73 }7475### REST7677 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent" \78 -H "x-goog-api-key: $GEMINI_API_KEY" \79 -H 'Content-Type: application/json' \80 -X POST \81 -d '{82 "contents": [83 {84 "parts": [85 {86 "text": "Explain the concept of Occam'\''s Razor and provide a simple, everyday example."87 }88 ]89 }90 ]91 }'92 ```9394## Thought summaries9596Thought summaries are summarized versions of the model's raw thoughts and offer97insights into the model's internal reasoning process. Note that98thinking levels and budgets apply to the model's raw thoughts and not to thought99summaries.100101You can enable thought summaries by setting `includeThoughts` to `true` in your102request configuration. You can then access the summary by iterating through the103`response` parameter's `parts`, and checking the `thought` boolean.104105Here's an example demonstrating how to enable and retrieve thought summaries106without streaming, which returns a single, final thought summary with the107response:108109### Python110111 from google import genai112 from google.genai import types113114 client = genai.Client()115 prompt = "What is the sum of the first 50 prime numbers?"116 response = client.models.generate_content(117 model="gemini-3.8-flash",118 contents=prompt,119 config=types.GenerateContentConfig(120 thinking_config=types.ThinkingConfig(121 include_thoughts=True122 )123 )124 )125126 for part in response.candidates[0].content.parts:127 if not part.text:128 continue129 if part.thought:130 print("Thought summary:")131 print(part.text)132 print()133 else:134 print("Answer:")135 print(part.text)136 print()137138### JavaScript139140 import { GoogleGenAI } from "@google/genai";141142 const ai = new GoogleGenAI({});143144 async function main() {145 const response = await ai.models.generateContent({146 model: "gemini-3.8-flash",147 contents: "What is the sum of the first 50 prime numbers?",148 config: {149 thinkingConfig: {150 includeThoughts: true,151 },152 },153 });154155 for (const part of response.candidates[0].content.parts) {156 if (!part.text) {157 continue;158 }159 else if (part.thought) {160 console.log("Thoughts summary:");161 console.log(part.text);162 }163 else {164 console.log("Answer:");165 console.log(part.text);166 }167 }168 }169170 main();171172### Go173174 package main175176 import (177 "context"178 "fmt"179 "google.golang.org/genai"180 "os"181 )182183 func main() {184 ctx := context.Background()185 client, err := genai.NewClient(ctx, nil)186 if err != nil {187 log.Fatal(err)188 }189190 contents := genai.Text("What is the sum of the first 50 prime numbers?")191 model := "gemini-3.8-flash"192 resp, _ := client.Models.GenerateContent(ctx, model, contents, &genai.GenerateContentConfig{193 ThinkingConfig: &genai.ThinkingConfig{194 IncludeThoughts: true,195 },196 })197198 for _, part := range resp.Candidates[0].Content.Parts {199 if part.Text != "" {200 if part.Thought {201 fmt.Println("Thoughts Summary:")202 fmt.Println(part.Text)203 } else {204 fmt.Println("Answer:")205 fmt.Println(part.Text)206 }207 }208 }209 }210211And here is an example using thinking with streaming, which returns rolling,212incremental summaries during generation:213214### Python215216 from google import genai217 from google.genai import types218219 client = genai.Client()220221 prompt = """222 Alice, Bob, and Carol each live in a different house on the same street: red, green, and blue.223 The person who lives in the red house owns a cat.224 Bob does not live in the green house.225 Carol owns a dog.226 The green house is to the left of the red house.227 Alice does not own a cat.228 Who lives in each house, and what pet do they own?229 """230231 thoughts = ""232 answer = ""233234 for chunk in client.models.generate_content_stream(235 model="gemini-3.8-flash",236 contents=prompt,237 config=types.GenerateContentConfig(238 thinking_config=types.ThinkingConfig(239 include_thoughts=True240 )241 )242 ):243 for part in chunk.candidates[0].content.parts:244 if not part.text:245 continue246 elif part.thought:247 if not thoughts:248 print("Thoughts summary:")249 print(part.text)250 thoughts += part.text251 else:252 if not answer:253 print("Answer:")254 print(part.text)255 answer += part.text256257### JavaScript258259 import { GoogleGenAI } from "@google/genai";260261 const ai = new GoogleGenAI({});262263 const prompt = `Alice, Bob, and Carol each live in a different house on the same264 street: red, green, and blue. The person who lives in the red house owns a cat.265 Bob does not live in the green house. Carol owns a dog. The green house is to266 the left of the red house. Alice does not own a cat. Who lives in each house,267 and what pet do they own?`;268269 let thoughts = "";270 let answer = "";271272 async function main() {273 const response = await ai.models.generateContentStream({274 model: "gemini-3.8-flash",275 contents: prompt,276 config: {277 thinkingConfig: {278 includeThoughts: true,279 },280 },281 });282283 for await (const chunk of response) {284 for (const part of chunk.candidates[0].content.parts) {285 if (!part.text) {286 continue;287 } else if (part.thought) {288 if (!thoughts) {289 console.log("Thoughts summary:");290 }291 console.log(part.text);292 thoughts = thoughts + part.text;293 } else {294 if (!answer) {295 console.log("Answer:");296 }297 console.log(part.text);298 answer = answer + part.text;299 }300 }301 }302 }303304 await main();305306### Go307308 package main309310 import (311 "context"312 "fmt"313 "log"314 "os"315 "google.golang.org/genai"316 )317318 const prompt = `319 Alice, Bob, and Carol each live in a different house on the same street: red, green, and blue.320 The person who lives in the red house owns a cat.321 Bob does not live in the green house.322 Carol owns a dog.323 The green house is to the left of the red house.324 Alice does not own a cat.325 Who lives in each house, and what pet do they own?326 `327328 func main() {329 ctx := context.Background()330 client, err := genai.NewClient(ctx, nil)331 if err != nil {332 log.Fatal(err)333 }334335 contents := genai.Text(prompt)336 model := "gemini-3.8-flash"337338 resp := client.Models.GenerateContentStream(ctx, model, contents, &genai.GenerateContentConfig{339 ThinkingConfig: &genai.ThinkingConfig{340 IncludeThoughts: true,341 },342 })343344 for chunk := range resp {345 for _, part := range chunk.Candidates[0].Content.Parts {346 if len(part.Text) == 0 {347 continue348 }349350 if part.Thought {351 fmt.Printf("Thought: %s\n", part.Text)352 } else {353 fmt.Printf("Answer: %s\n", part.Text)354 }355 }356 }357 }358359## Controlling thinking360361Gemini models engage in dynamic thinking by default, automatically adjusting the362amount of reasoning effort based on the complexity of the user's request.363However, if you have specific latency constraints or require the model to engage364in deeper reasoning than usual, you can optionally use parameters to control365thinking behavior.366367### Thinking levels (Gemini 3)368369The `thinkingLevel` parameter, recommended for Gemini 3 models and onwards,370lets you control reasoning behavior.371372The following table details the `thinkingLevel` settings for each model type:373374| Thinking Level | Gemini 3.8 \& 3.7 Flash | Gemini 3.6 \& 3.5 Flash | Gemini 3.1 Pro | Gemini 3.5 \& 3.1 Flash-Lite | Gemini 3.1 Flash-Lite Image | Gemini 3 Flash | Description |375|---|---|---|---|---|---|---|---|376| **`minimal`** | Not supported (error) | Supported | Not supported | Supported (Default) | Supported (Default) | Supported | Matches the "no thinking" setting for most queries. Note, `minimal` does not guarantee that thinking is off, the model may reason very minimally for complex tasks. |377| **`low`** | Supported | Supported | Supported | Supported | Not Supported | Supported | Minimizes latency and cost. |378| **`medium`** | Supported (Default) | Supported (Default) | Supported | Supported | Not supported | Supported | Balanced thinking for most tasks. |379| **`high`** | Supported (Dynamic) | Supported (Dynamic) | Supported (Default, Dynamic) | Supported (Dynamic) | Supported (Dynamic) | Supported (Default, Dynamic) | Maximizes reasoning depth. The model may take significantly longer to reach a first (non thinking) output token, but the output will be more carefully reasoned. |380381The following example shows how to set the thinking level.382383### Python384385 from google import genai386 from google.genai import types387388 client = genai.Client()389390 response = client.models.generate_content(391 model="gemini-3.8-flash",392 contents="Provide a list of 3 famous physicists and their key contributions",393 config=types.GenerateContentConfig(394 thinking_config=types.ThinkingConfig(thinking_level="low")395 ),396 )397398 print(response.text)399400### JavaScript401402 import { GoogleGenAI, ThinkingLevel } from "@google/genai";403404 const ai = new GoogleGenAI({});405406 async function main() {407 const response = await ai.models.generateContent({408 model: "gemini-3.8-flash",409 contents: "Provide a list of 3 famous physicists and their key contributions",410 config: {411 thinkingConfig: {412 thinkingLevel: ThinkingLevel.LOW,413 },414 },415 });416417 console.log(response.text);418 }419420 main();421422### Go423424 package main425426 import (427 "context"428 "fmt"429 "google.golang.org/genai"430 "os"431 )432433 func main() {434 ctx := context.Background()435 client, err := genai.NewClient(ctx, nil)436 if err != nil {437 log.Fatal(err)438 }439440 thinkingLevelVal := "low"441442 contents := genai.Text("Provide a list of 3 famous physicists and their key contributions")443 model := "gemini-3.8-flash"444 resp, _ := client.Models.GenerateContent(ctx, model, contents, &genai.GenerateContentConfig{445 ThinkingConfig: &genai.ThinkingConfig{446 ThinkingLevel: &thinkingLevelVal,447 },448 })449450 fmt.Println(resp.Text())451 }452453### REST454455 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent" \456 -H "x-goog-api-key: $GEMINI_API_KEY" \457 -H 'Content-Type: application/json' \458 -X POST \459 -d '{460 "contents": [461 {462 "parts": [463 {464 "text": "Provide a list of 3 famous physicists and their key contributions"465 }466 ]467 }468 ],469 "generationConfig": {470 "thinkingConfig": {471 "thinkingLevel": "low"472 }473 }474 }'475476You cannot disable thinking for Gemini 3.1 Pro. Gemini 3 Flash and Flash-Lite477also do not support full thinking-off.478If you don't specify a thinking level, Gemini will use the Gemini 3 models'479default thinking level (e.g., `"high"` for Gemini 3.1 Pro, and `"medium"` for Gemini 3.5 Flash).480481Gemini 2.5 series models don't support `thinkingLevel`; use `thinkingBudget`482instead.483484### Token limits and `max_output_tokens`485486The [`max_output_tokens`](https://ai.google.dev/api/generate-content#v1beta.GenerationConfig)487generation parameter sets the maximum number of tokens a response can generate,488including thought tokens.489490When set, this parameter acts as a hard cutoff enforced by the infrastructure491without changing how the model allocates its thinking budget492(`thinking_level`).493494If the model hits this limit while reasoning, it stops generating with495`finish_reason: MAX_TOKENS` and returns truncated or empty output (while still496billing for any thinking tokens generated). To reduce cost or latency without497truncating responses, lower `thinking_level` (`low` or `medium`) instead of498setting a small `max_output_tokens`.499500### Thinking budgets501502The `thinkingBudget` parameter, introduced with the Gemini 2.5 series, guides503the model on the specific number of thinking tokens to use for reasoning.504505> [!NOTE]506> **Note:** Use the `thinkingLevel` parameter with Gemini 3 models. While `thinkingBudget` is accepted for backwards compatibility, using it with Gemini 3 Pro may result in unexpected performance.507508The following are `thinkingBudget` configuration details for each model type.509You can disable thinking by setting `thinkingBudget` to 0.510Setting the `thinkingBudget` to -1 turns511on **dynamic thinking**, meaning the model will adjust the budget based on the512complexity of the request.513514| Model | Default setting (Thinking budget is not set) | Range | Disable thinking | Turn on dynamic thinking |515|---|---|---|---|---|516| **2.5 Pro** | Dynamic thinking | `128` to `32768` | N/A: Cannot disable thinking | `thinkingBudget = -1` (Default) |517| **2.5 Flash** | Dynamic thinking | `0` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` (Default) |518| **2.5 Flash Preview** | Dynamic thinking | `0` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` (Default) |519| **2.5 Flash Lite** | Model does not think | `512` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` |520| **2.5 Flash Lite Preview** | Model does not think | `512` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` |521| **Robotics-ER 1.6 Preview** | Dynamic thinking | `0` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` (Default) |522| **2.5 Flash Live Native Audio Preview (09-2025)** | Dynamic thinking | `0` to `24576` | `thinkingBudget = 0` | `thinkingBudget = -1` (Default) |523524### Python525526 from google import genai527 from google.genai import types528529 client = genai.Client()530531 response = client.models.generate_content(532 model="gemini-2.5-flash",533 contents="Provide a list of 3 famous physicists and their key contributions",534 config=types.GenerateContentConfig(535 thinking_config=types.ThinkingConfig(thinking_budget=1024)536 # Turn off thinking:537 # thinking_config=types.ThinkingConfig(thinking_budget=0)538 # Turn on dynamic thinking:539 # thinking_config=types.ThinkingConfig(thinking_budget=-1)540 ),541 )542543 print(response.text)544545### JavaScript546547 import { GoogleGenAI } from "@google/genai";548549 const ai = new GoogleGenAI({});550551 async function main() {552 const response = await ai.models.generateContent({553 model: "gemini-2.5-flash",554 contents: "Provide a list of 3 famous physicists and their key contributions",555 config: {556 thinkingConfig: {557 thinkingBudget: 1024,558 // Turn off thinking:559 // thinkingBudget: 0560 // Turn on dynamic thinking:561 // thinkingBudget: -1562 },563 },564 });565566 console.log(response.text);567 }568569 main();570571### Go572573 package main574575 import (576 "context"577 "fmt"578 "google.golang.org/genai"579 "os"580 )581582 func main() {583 ctx := context.Background()584 client, err := genai.NewClient(ctx, nil)585 if err != nil {586 log.Fatal(err)587 }588589 thinkingBudgetVal := int32(1024)590591 contents := genai.Text("Provide a list of 3 famous physicists and their key contributions")592 model := "gemini-2.5-flash"593 resp, _ := client.Models.GenerateContent(ctx, model, contents, &genai.GenerateContentConfig{594 ThinkingConfig: &genai.ThinkingConfig{595 ThinkingBudget: &thinkingBudgetVal,596 // Turn off thinking:597 // ThinkingBudget: int32(0),598 // Turn on dynamic thinking:599 // ThinkingBudget: int32(-1),600 },601 })602603 fmt.Println(resp.Text())604 }605606### REST607608 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \609 -H "x-goog-api-key: $GEMINI_API_KEY" \610 -H 'Content-Type: application/json' \611 -X POST \612 -d '{613 "contents": [614 {615 "parts": [616 {617 "text": "Provide a list of 3 famous physicists and their key contributions"618 }619 ]620 }621 ],622 "generationConfig": {623 "thinkingConfig": {624 "thinkingBudget": 1024625 }626 }627 }'628629Depending on the prompt, the model might overflow or underflow the token budget.630631## Thought signatures632633> [!IMPORTANT]634> **Important:** The [Google GenAI SDK](https://ai.google.dev/gemini-api/docs/libraries) automatically handles the return of thought signatures for you. You only need to [manage thought signatures manually](https://ai.google.dev/gemini-api/docs/function-calling#thought-signatures) if you're modifying conversation history or using the REST API.635636The Gemini API is stateless, so the model treats every API request independently637and doesn't have access to thought context from previous turns in multi-turn638interactions.639640In order to enable maintaining thought context across multi-turn interactions,641Gemini returns thought signatures, which are encrypted representations of the642model's internal thought process.643644- **Gemini 2.5 models** return thought signatures when thinking is enabled and the request includes [function calling](https://ai.google.dev/gemini-api/docs/function-calling#thinking), specifically [function declarations](https://ai.google.dev/gemini-api/docs/function-calling#step-2).645- **Gemini 3 models** may return thought signatures for all types of [parts](https://ai.google.dev/api/caching#Part). We recommend you always pass all signatures back as received, but it's *required* for function calling signatures. Read the [Thought Signatures](https://ai.google.dev/gemini-api/docs/thought-signatures) page to learn more.646647Other usage limitations to consider with function calling include:648649- Signatures are returned from the model within other parts in the response, for example function calling or text parts. [Return the entire response](https://ai.google.dev/gemini-api/docs/function-calling#step-4) with all parts back to the model in subsequent turns.650- Don't concatenate parts with signatures together.651- Don't merge one part with a signature with another part without a signature.652653## Pricing654655> [!NOTE]656> **Note:** **Summaries** are available in the [free and paid tiers](https://ai.google.dev/gemini-api/docs/pricing) of the API. **Thought signatures** will increase the input tokens you are charged when sent back as part of the request.657658When thinking is turned on, response pricing is the sum of output659tokens and thinking tokens. You can get the total number of generated thinking660tokens from the `thoughtsTokenCount` field.661662### Python663664 # ...665 print("Thoughts tokens:", response.usage_metadata.thoughts_token_count)666 print("Output tokens:", response.usage_metadata.candidates_token_count)667668### JavaScript669670 // ...671 console.log(`Thoughts tokens: ${response.usageMetadata.thoughtsTokenCount}`);672 console.log(`Output tokens: ${response.usageMetadata.candidatesTokenCount}`);673674### Go675676 // ...677 fmt.Println("Thoughts tokens:", response.UsageMetadata.ThoughtsTokenCount)678 fmt.Println("Output tokens:", response.UsageMetadata.CandidatesTokenCount)679680Thinking models generate full thoughts to improve the quality of the final681response, and then output [summaries](https://ai.google.dev/gemini-api/docs/generate-content/thinking#summaries) to provide insight into the682thought process. So, pricing is based on the full thought tokens the683model needs to generate to create a summary, despite only the summary being684output from the API.685686> [!NOTE]687> **Note:** Because `max_output_tokens` applies to the combined total of thinking tokens and output tokens, setting a low limit can truncate responses. See [Token limits and `max_output_tokens`](https://ai.google.dev/gemini-api/docs/generate-content/thinking#token-limits) for details.688689You can learn more about tokens in the [Token counting](https://ai.google.dev/gemini-api/docs/tokens)690guide.691692## Best practices693694This section includes some guidance for using thinking models efficiently.695As always, following our [prompting guidance and best practices](https://ai.google.dev/gemini-api/docs/prompting-strategies) will get you the best results.696697### Debugging and steering698699- **Review reasoning**: When you're not getting your expected response from the700 thinking models, it can help to carefully analyze Gemini's thought summaries.701 You can see how it broke down the task and arrived at its conclusion, and use702 that information to correct towards the right results.703704- **Provide Guidance in Reasoning** : If you're hoping for a particularly lengthy705 output, you may want to provide guidance in your prompt to constrain the706 [amount of thinking](https://ai.google.dev/gemini-api/docs/generate-content/thinking#set-budget) the model uses. This lets you reserve more707 of the token output for your response.708709### Task complexity710711- **Easy Tasks (Thinking could be OFF):** For straightforward requests where complex reasoning isn't required, such as fact retrieval or classification, thinking is not required. Examples include:712 - "Where was DeepMind founded?"713 - "Is this email asking for a meeting or just providing information?"714- **Medium Tasks (Default/Some Thinking):** Many common requests benefit from a degree of step-by-step processing or deeper understanding. Gemini can flexibly use thinking capability for tasks like:715 - Analogize photosynthesis and growing up.716 - Compare and contrast electric cars and hybrid cars.717- **Hard Tasks (Maximum Thinking Capability):** For truly complex challenges, such as solving complex math problems or coding tasks, we recommend setting a high thinking budget. These types of tasks require the model to engage its full reasoning and planning capabilities, often involving many internal steps before providing an answer. Examples include:718 - Solve problem 1 in AIME 2025: Find the sum of all integer bases b \> 9 for which 17~b~ is a divisor of 97~b~.719 - Write Python code for a web application that visualizes real-time stock market data, including user authentication. Make it as efficient as possible.720721## Supported models, tools, and capabilities722723Thinking features are supported on all 3 and 2.5 series models.724You can find all model capabilities on the725[model overview](https://ai.google.dev/gemini-api/docs/models) page.726727Thinking models work with all of Gemini's tools and capabilities. This allows728the models to interact with external systems, execute code, or access real-time729information, incorporating the results into their reasoning and final response.730731You can try examples of using tools with thinking models in the732\[Thinking cookbook\]\[Colab\].733734## What's next?735736- Thinking coverage is available in our [OpenAI Compatibility](https://ai.google.dev/gemini-api/docs/openai#thinking) guide.737738\[Colab\]: https://colab.sandbox.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_thinking.ipynb