◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/API / SDK
◈ API / SDK/2026-05-30Advanced

Preserving Gemini 3 Thought Signatures So Multi-Turn Function Calling Doesn't Degrade

When you build function calling on Gemini 3 thinking models, reasoning quality often drops from the second turn onward. The cause is usually a dropped thought signature. Here is how to keep it and verify the effect.

Gemini API249function calling4thinking7agents9production140

✦ Premium Article

While building an agent that detects AdMob revenue anomalies with Gemini, I ran into a strange behavior. On the first turn it would correctly call a tool to "fetch the eCPM," but from the second turn onward its judgment turned sloppy. It would call only one tool when two were needed, or forget premises it had clearly established a turn earlier.

I assumed it was a prompt problem and rewrote my system instructions many times. The effect was limited. The real cause was that I was discarding the thought signature that Gemini 3 thinking models return, at the moment I rebuilt the conversation history. It is an easy detail to miss unless you read the docs carefully, yet it has an outsized effect on production agent quality. In this article I share what the signature actually is, how to assemble your contents without losing it, and how to measure the difference, in the exact order I worked through it as an indie developer.

What a thought signature actually carries

Gemini 3 thinking models return an encrypted representation of their internal reasoning in a field called thoughtSignature. It is distinct from any human-readable thinking text, and we cannot decrypt or read its contents. Its job is to hand the model a key so that, on the next request, it can reconstruct "how I was thinking a moment ago."

The crucial point is that the signature comes back attached to the function call part. When the model decides to call a tool, the functionCall part carries, as a signature, the reasoning context for why it chose that tool. When you run the tool and return the result, you must include that signature-bearing part in the history as-is. Otherwise the model starts its next round of reasoning having lost the context of why it called the tool in the first place.

That was exactly the "judgment gets sloppy from turn two" symptom I hit. Drop the signature and the model rethinks from scratch each turn, like amnesia, and worse, it restarts from an incomplete state where only part of the context is missing, so quality actually drops.

Why even SDK users fall into this

You might assume the official SDK handles this automatically. It is true that if you use a chat session in the Python or Node SDK and push the model's returned response.candidates[0].content straight back into history, the signature is preserved. The problem is that most production code is not that simple.

My agent broke because I extracted only the function call arguments into my own intermediate representation, then rebuilt "the function call name and args" to push back into history after running the tool. The moment you decompose a part for implementation conveniences, such as cleaner logs or easier retries, the signature falls off. The signature is neither the arguments nor the function name; it is metadata attached to the part. So any time you hand-build { functionCall: { name, args } } yourself, you lose it.

In other words, "it's the SDK, so I'm safe" is the wrong mental model. The real dividing line is whether you push the model's returned content object back into history without modifying it.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Understand exactly how a missing thought signature lowers tool-selection accuracy on later turns, shown through request JSON diffs
✦Tell apart a REST implementation that loses signatures from one that keeps them, and the trap of assuming the SDK saves you automatically
✦Take away a tuning workflow grounded in before/after logs from an AdMob anomaly-detection agent, cutting wasteful re-thinking
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◈ API / SDK2026-09-22
When Function Calls Turn Into Plain Text, Suspect the Property Names in Your Tool Declarations
A record of chasing MALFORMED_FUNCTION_CALL after output limits and schema conflicts were ruled out, bisecting nine tool declarations down to one property name, and adding a linter that stops bad names before they ship.
◈ API / SDK2026-05-04
Solving Gemini API Cold Starts — Production-Grade Startup Optimization for Cloud Run, Lambda, and Workers
When you put Gemini API on serverless, the first request takes six seconds. This guide breaks down where the time goes and shows concrete startup-optimization patterns for Cloud Run, AWS Lambda, and Cloudflare Workers — with real numbers, runnable code, and cost trade-off advice.
◈ API / SDK2026-04-26
Defending Gemini API Responses with Schema Validation — Never Let Unexpected Formats Reach Production
Gemini's structured output is convenient, but in production the day always comes when an unexpected format slips through. This piece walks through layered Zod/Pydantic validation, repair prompts, and graceful degradation — the defense lines I run on my own apps.