Le firme di pensiero sono rappresentazioni criptate del processo di pensiero interno del modello e vengono utilizzate per preservare il contesto di ragionamento nelle interazioni multi-step.
Quando utilizzi i modelli di ragionamento (come le serie Gemini 3 e 2.5), l'API può
restituire un campo thoughtSignature all'interno delle parti di contenuto
della risposta (ad esempio, le parti text o functionCall).
In generale, se ricevi una firma di pensiero in una risposta del modello, devi restituirla esattamente come l'hai ricevuta quando invii la cronologia della conversazione nel turno successivo.
Quando utilizzi i modelli Gemini 3, devi restituire le firme di pensiero durante la chiamata di funzione, altrimenti riceverai un errore di convalida (codice di stato 4xx).
Ciò include l'utilizzo dell'impostazione del minimal
livello di ragionamento per Gemini 3
Flash.
Come funziona
Il grafico di seguito visualizza il significato di "turno" e "step" in relazione a chiamata di funzione nell'API Gemini. Un "turno" è un singolo scambio completo in una conversazione tra un utente e un modello. Uno "step" è un'azione o un'operazione più granulare eseguita dal modello, spesso come parte di un processo più ampio per completare un turno.

Questo documento si concentra sulla gestione della chiamata di funzione per i modelli Gemini 3. Per le discrepanze con la versione 2.5, consulta la sezione relativa al comportamento del modello.
Gemini 3 restituisce le firme di pensiero per tutte le risposte del modello (risposte dell'API) con una chiamata di funzione. Le firme di pensiero vengono visualizzate nei seguenti casi:
- Quando sono presenti chiamate di funzione parallele, la prima parte della chiamata di funzione restituita dalla risposta del modello avrà una firma di pensiero.
- Quando sono presenti chiamate di funzione sequenziali (multi-step), ogni chiamata di funzione avrà una firma e devi restituire tutte le firme.
- Le risposte del modello senza una chiamata di funzione restituiranno una firma di pensiero all'interno dell'ultima parte restituita dal modello.
La seguente tabella fornisce una visualizzazione delle chiamate di funzione multi-step, combinando le definizioni di turni e step con il concetto di firme introdotto sopra:
Turno |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
1 |
1 |
request1 = user_prompt |
FC1 + signature |
FR1 |
1 |
2 |
request2 = request1 + (FC1 + signature) + FR1 |
FC2 + signature |
FR2 |
1 |
3 |
request3 = request2 + (FC2 + signature) + FR2 |
text_output
|
Nessuno |
Firme nelle parti di chiamata di funzione
Quando Gemini genera un functionCall, si basa su thought_signature per elaborare correttamente l'output dello strumento nel turno successivo.
- Comportamento:
- Chiamata di funzione singola: la parte
functionCallconterrà unthought_signature. - Chiamate di funzione parallele: se il modello genera chiamate di funzione parallele
in una risposta,
thought_signatureviene allegato solo alla primafunctionCallparte. Le partifunctionCallsuccessive nella stessa risposta non conterranno una firma.
- Chiamata di funzione singola: la parte
- Requisito: devi restituire questa firma nella parte esatta in cui l'hai ricevuta quando invii la cronologia della conversazione.
- Convalida: viene applicata una convalida rigorosa per tutte le chiamate di funzione all'interno
del turno corrente . (È richiesto solo il turno corrente; non eseguiamo la convalida nei turni precedenti)
- L'API torna indietro nella cronologia (dal più recente al più vecchio) per trovare il messaggio Utente più recente che contiene contenuti standard (ad esempio,
text) ( che sarebbe l'inizio del turno corrente). Non be unfunctionResponse. - Tutti i turni
functionCalldel modello che si verificano dopo questo messaggio di utilizzo specifico sono considerati parte del turno. - La prima parte
functionCallin ogni step del turno corrente deve includere il relativothought_signature. - Se ometti un
thought_signatureper la prima partefunctionCallin qualsiasi step del turno corrente, la richiesta non andrà a buon fine e verrà restituito un errore 400.
- L'API torna indietro nella cronologia (dal più recente al più vecchio) per trovare il messaggio Utente più recente che contiene contenuti standard (ad esempio,
- Se non vengono restituite le firme corrette, ecco come si verificherà l'errore
- Modelli Gemini 3: se non includi le firme, verrà restituito un errore 400. La formulazione sarà del tipo:
- Nella chiamata di funzione
<Function Call>nel<index of contents array>blocco di contenuti manca unthought_signature. Ad esempio, Nella chiamata di funzioneFC1nel blocco di contenuti1.manca unthought_signature.
- Nella chiamata di funzione
- Modelli Gemini 3: se non includi le firme, verrà restituito un errore 400. La formulazione sarà del tipo:
Esempio di chiamata di funzione sequenziale
Questa sezione mostra un esempio di più chiamate di funzione in cui l'utente pone una domanda complessa che richiede più attività.
Esaminiamo un esempio di chiamata di funzione multi-turno in cui l'utente pone
una domanda complessa che richiede più attività: "Check flight status for AA100 and
book a taxi if delayed".
Turno |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
1 |
1 |
request1="Check flight status for AA100 and book a taxi 2 hours before if delayed." |
FC1 ("check_flight") + signature |
FR1 |
1 |
2 |
request2 = request1 + FC1 ("check_flight") + signature + FR1 |
FC2("book_taxi") + signature |
FR2 |
1 |
3 |
request3 = request2 + FC2 ("book_taxi") + signature + FR2 |
text_output
|
None |
Il seguente codice illustra la sequenza nella tabella sopra riportata.
Turno 1, Step 1 (richiesta utente)
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
}
]
}
],
"tools": [
{
"functionDeclarations": [
{
"name": "check_flight",
"description": "Gets the current status of a flight",
"parameters": {
"type": "object",
"properties": {
"flight": {
"type": "string",
"description": "The flight number to check"
}
},
"required": [
"flight"
]
}
},
{
"name": "book_taxi",
"description": "Book a taxi",
"parameters": {
"type": "object",
"properties": {
"time": {
"type": "string",
"description": "time to book the taxi"
}
},
"required": [
"time"
]
}
}
]
}
]
}
Turno 1, Step 1 (risposta del modello)
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
Turno 1, Step 2 (risposta dell'utente - invio degli output dello strumento) Poiché questo turno dell'utente contiene solo un functionResponse (nessun testo nuovo), siamo ancora nel Turno 1. Dobbiamo
conservare <Signature_A>.
{
"role": "user",
"parts": [
{
"text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
}
]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>" //Required and Validated
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "check_flight",
"response": {
"status": "delayed",
"departure_time": "12 PM"
}
}
}
]
}
Turno 1, Step 2 (modello) Il modello ora decide di prenotare un taxi in base all'output dello strumento precedente.
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "book_taxi",
"args": {
"time": "10 AM"
}
},
"thoughtSignature": "<Signature B>"
}
]
}
}
Turno 1, Step 3 (utente - invio dell'output dello strumento) Per inviare la conferma della prenotazione del taxi, dobbiamo includere le firme per TUTTE le chiamate di funzione in questo loop
(<Signature A> + <Signature B>).
{
"role": "user",
"parts": [
{
"text": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
}
]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>" //Required and Validated
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "check_flight",
"response": {
"status": "delayed",
"departure_time": "12 PM"
}
}
}
]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "book_taxi",
"args": {
"time": "10 AM"
}
},
"thoughtSignature": "<Signature B>" //Required and Validated
}
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "book_taxi",
"response": {
"booking_status": "success"
}
}
}
]
}
}
Esempio di chiamata di funzione parallela
Esaminiamo un esempio di chiamata di funzione parallela in cui l'utente chiede
"Check weather in Paris and London" per vedere dove il modello esegue la convalida.
Turno |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
|---|---|---|---|---|
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature FC2 ("London") |
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output (no FCs) |
None |
Il seguente codice illustra la sequenza nella tabella sopra riportata.
Turno 1, Step 1 (richiesta utente)
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Check the weather in Paris and London."
}
]
}
],
"tools": [
{
"functionDeclarations": [
{
"name": "get_current_temperature",
"description": "Gets the current temperature for a given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco"
}
},
"required": [
"location"
]
}
}
]
}
]
}
Turno 1, Step 1 (risposta del modello)
{
"content": {
"parts": [
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"location": "Paris"
}
},
"thoughtSignature": "<Signature_A>"// INCLUDED on First FC
},
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"location": "London"
}// NO signature on subsequent parallel FCs
}
}
]
}
}
Turno 1, Step 2 (risposta dell'utente - invio degli output dello strumento) Dobbiamo conservare
<Signature_A> nella prima parte esattamente come l'abbiamo ricevuta.
[
{
"role": "user",
"parts": [
{
"text": "Check the weather in Paris and London."
}
]
},
{
"role": "model",
"parts": [
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"city": "Paris"
}
},
"thought_signature": "<Signature_A>" // MUST BE INCLUDED
},
{
"functionCall": {
"name": "get_current_temperature",
"args": {
"city": "London"
}
}
} // NO SIGNATURE FIELD
]
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_current_temperature",
"response": {
"temp": "15C"
}
}
},
{
"functionResponse": {
"name": "get_current_temperature",
"response": {
"temp": "12C"
}
}
}
]
}
]
Firme nelle parti non functionCall
Gemini può anche restituire thought_signatures nella parte finale della risposta nelle parti non relative alla chiamata di funzione.
- Comportamento: la parte di contenuto finale (
text, inlineData…) restituita dal modello può contenere unthought_signature. - Consigli: la restituzione di queste firme è consigliata per garantire che il modello mantenga un ragionamento di alta qualità, soprattutto per le istruzioni complesse o i workflow agentici simulati.
- Convalida: l'API non applica rigorosamente la convalida. Se le ometti, non riceverai un errore di blocco, anche se le prestazioni potrebbero peggiorare.
Ragionamento testuale/nel contesto (nessuna convalida)
Turno 1, Step 1 (risposta del modello)
{
"role": "model",
"parts": [
{
"text": "I need to calculate the risk. Let me think step-by-step...",
"thought_signature": "<Signature_C>" // OPTIONAL (Recommended)
}
]
}
Turno 2, Step 1 (utente)
[
{ "role": "user", "parts": [{ "text": "What is the risk?" }] },
{
"role": "model",
"parts": [
{
"text": "I need to calculate the risk. Let me think step-by-step...",
// If you omit <Signature_C> here, no error will occur.
}
]
},
{ "role": "user", "parts": [{ "text": "Summarize it." }] }
]
Firme per la compatibilità con OpenAI
I seguenti esempi mostrano come gestire le firme di pensiero per un'API di completamento della chat utilizzando la compatibilità con OpenAI.
Esempio di chiamata di funzione sequenziale
Questo è un esempio di più chiamate di funzione in cui l'utente pone una domanda complessa che richiede più attività.
Esaminiamo un esempio di chiamata di funzione multi-turno in cui l'utente chiede Check flight status for AA100 and book a taxi if delayed e puoi vedere cosa succede quando l'utente pone una domanda complessa che richiede più attività.
Turno |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature
|
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output
|
None |
Il seguente codice illustra la sequenza indicata.
Turno 1, Step 1 (richiesta utente)
{
"model": "google/gemini-3.1-pro-preview",
"messages": [
{
"role": "user",
"content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
}
],
"tools": [
{
"type": "function",
"function": {
"name": "check_flight",
"description": "Gets the current status of a flight",
"parameters": {
"type": "object",
"properties": {
"flight": {
"type": "string",
"description": "The flight number to check."
}
},
"required": [
"flight"
]
}
}
},
{
"type": "function",
"function": {
"name": "book_taxi",
"description": "Book a taxi",
"parameters": {
"type": "object",
"properties": {
"time": {
"type": "string",
"description": "time to book the taxi"
}
},
"required": [
"time"
]
}
}
}
]
}
Turno 1, Step 1 (risposta del modello)
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>"
}
},
"function": {
"arguments": "{\"flight\":\"AA100\"}",
"name": "check_flight"
},
"id": "function-call-1",
"type": "function"
}
]
}
Turno 1, Step 2 (risposta dell'utente - invio degli output dello strumento)
Poiché questo turno dell'utente contiene solo un functionResponse (nessun testo nuovo), siamo
ancora nel Turno 1 e dobbiamo conservare <Signature_A>.
"messages": [
{
"role": "user",
"content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
},
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>" //Required and Validated
}
},
"function": {
"arguments": "{\"flight\":\"AA100\"}",
"name": "check_flight"
},
"id": "function-call-1",
"type": "function"
}
]
},
{
"role": "tool",
"name": "check_flight",
"tool_call_id": "function-call-1",
"content": "{\"status\":\"delayed\",\"departure_time\":\"12 PM\"}"
}
]
Turno 1, Step 2 (modello)
Il modello ora decide di prenotare un taxi in base all'output dello strumento precedente.
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature B>"
}
},
"function": {
"arguments": "{\"time\":\"10 AM\"}",
"name": "book_taxi"
},
"id": "function-call-2",
"type": "function"
}
]
}
Turno 1, Step 3 (utente - invio dell'output dello strumento)
Per inviare la conferma della prenotazione del taxi, dobbiamo includere le firme per TUTTE
le chiamate di funzione in questo loop (<Signature A> + <Signature B>).
"messages": [
{
"role": "user",
"content": "Check flight status for AA100 and book a taxi 2 hours before if delayed."
},
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>" //Required and Validated
}
},
"function": {
"arguments": "{\"flight\":\"AA100\"}",
"name": "check_flight"
},
"id": "function-call-1d6a1a61-6f4f-4029-80ce-61586bd86da5",
"type": "function"
}
]
},
{
"role": "tool",
"name": "check_flight",
"tool_call_id": "function-call-1d6a1a61-6f4f-4029-80ce-61586bd86da5",
"content": "{\"status\":\"delayed\",\"departure_time\":\"12 PM\"}"
},
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature B>" //Required and Validated
}
},
"function": {
"arguments": "{\"time\":\"10 AM\"}",
"name": "book_taxi"
},
"id": "function-call-65b325ba-9b40-4003-9535-8c7137b35634",
"type": "function"
}
]
},
{
"role": "tool",
"name": "book_taxi",
"tool_call_id": "function-call-65b325ba-9b40-4003-9535-8c7137b35634",
"content": "{\"booking_status\":\"success\"}"
}
]
Esempio di chiamata di funzione parallela
Esaminiamo un esempio di chiamata di funzione parallela in cui l'utente chiede
"Check weather in Paris and London" e puoi vedere dove il modello esegue la
convalida.
Turno |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + signature
|
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
text_output
|
None |
Ecco il codice per esaminare la sequenza indicata.
Turno 1, Step 1 (richiesta utente)
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Check the weather in Paris and London."
}
]
}
],
"tools": [
{
"functionDeclarations": [
{
"name": "get_current_temperature",
"description": "Gets the current temperature for a given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco"
}
},
"required": [
"location"
]
}
}
]
}
]
}
Turno 1, Step 1 (risposta del modello)
{
"role": "assistant",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>" //Signature returned
}
},
"function": {
"arguments": "{\"location\":\"Paris\"}",
"name": "get_current_temperature"
},
"id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
"type": "function"
},
{
"function": {
"arguments": "{\"location\":\"London\"}",
"name": "get_current_temperature"
},
"id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
"type": "function" // No signature on Parallel FC
}
]
}
Turno 1, Step 2 (risposta dell'utente - invio degli output dello strumento)
Devi conservare <Signature_A> nella prima parte esattamente come l'hai ricevuta.
"messages": [
{
"role": "user",
"content": "Check the weather in Paris and London."
},
{
"role": "assistant",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>" //Required
}
},
"function": {
"arguments": "{\"location\":\"Paris\"}",
"name": "get_current_temperature"
},
"id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
"type": "function"
},
{
"function": { //No Signature
"arguments": "{\"location\":\"London\"}",
"name": "get_current_temperature"
},
"id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
"type": "function"
}
]
},
{
"role":"tool",
"name": "get_current_temperature",
"tool_call_id": "function-call-f3b9ecb3-d55f-4076-98c8-b13e9d1c0e01",
"content": "{\"temp\":\"15C\"}"
},
{
"role":"tool",
"name": "get_current_temperature",
"tool_call_id": "function-call-335673ad-913e-42d1-bbf5-387c8ab80f44",
"content": "{\"temp\":\"12C\"}"
}
]
Domande frequenti
Come faccio a trasferire la cronologia da un modello diverso a Gemini 3 con una parte di chiamata di funzione nel turno e nello step correnti? Devo fornire parti di chiamata di funzione che non sono state generate dall'API e quindi non hanno una firma di pensiero associata ?
Sebbene l'inserimento di blocchi di chiamate di funzione personalizzati nella richiesta sia fortemente sconsigliato, nei casi in cui non è possibile evitarlo, ad esempio fornire informazioni al modello sulle chiamate di funzione e sulle risposte eseguite in modo deterministico dal client o trasferire una traccia da un modello diverso che non include firme di pensiero, puoi impostare le seguenti firme fittizie di
"context_engineering_is_the_way_to_go"o"skip_thought_signature_validator"nel campo della firma di pensiero per saltare la convalida.Sto inviando chiamate di funzione e risposte parallele intercalate e l'API restituisce un errore 400. Perché?
Quando l'API restituisce chiamate di funzione parallele "FC1 + signature, FC2", la risposta dell'utente prevista è "FC1+ signature, FC2, FR1, FR2". Se le hai intercalate come "FC1 + signature, FR1, FC2, FR2", l'API restituirà un errore 400.
Durante lo streaming e il modello non restituisce una chiamata di funzione, non riesco a trovare la firma di pensiero
Durante una risposta del modello che non contiene una chiamata di funzione con una richiesta di streaming, il modello può restituire la firma di pensiero in una parte con una parte di contenuto di testo vuota. È consigliabile analizzare l'intera richiesta finché il modello non restituisce
finish_reason.
Firme di pensiero per modelli diversi
I modelli Gemini 3 e i modelli Gemini 2.5 si comportano in modo diverso con le firme di pensiero nelle chiamate di funzione:
- Se in una risposta sono presenti chiamate di funzione,
- Gemini 3 avrà sempre la firma nella prima parte della chiamata di funzione. È obbligatorio restituire questa parte.
- Gemini 2.5 avrà la firma nella prima parte (indipendentemente dal tipo). La restituzione di questa parte è facoltativa.
- Se in una risposta non sono presenti chiamate di funzione,
- Gemini 3 avrà la firma nell'ultima parte se il modello genera un pensiero.
- Gemini 2.5 non avrà una firma in nessuna parte.
Per maggiori dettagli sul confronto, consulta la pagina Ragionamento per maggiori dettagli sul confronto. Per i modelli di immagini Gemini 3, consulta la sezione relativa al processo di ragionamento della guida alla generazione di immagini.