Le firme del pensiero sono rappresentazioni criptate del processo di pensiero interno del modello e vengono utilizzate per preservare il contesto del ragionamento nelle interazioni multi-turno.
Quando utilizzi modelli di pensiero (come le serie Gemini 3 e 2.5), l'API potrebbe restituire un campo thoughtSignature all'interno delle parti di contenuti della risposta (ad es. text o functionCall).
Come regola generale, se ricevi una firma del pensiero nella risposta di un modello, devi restituirla esattamente come l'hai ricevuta quando invii la cronologia della conversazione nel turno successivo. Quando utilizzi Gemini 3 Pro, devi restituire le firme del pensiero durante la chiamata di funzione, altrimenti riceverai un errore di convalida (codice di stato 4xx).
Come funziona
L'immagine seguente mostra il significato di "turno" e "passaggio" in relazione alla chiamata di funzione nell'API Gemini. Un "turno" è un singolo scambio completo in una conversazione tra un utente e un modello. Un "passo" è un'azione o un'operazione più granulare eseguita dal modello, spesso nell'ambito di un processo più ampio per completare un turno.

Questo documento si concentra sulla gestione della chiamata di funzione per Gemini 3 Pro. Consulta la sezione Comportamento del modello per le discrepanze con la versione 2.5.
Gemini 3 Pro restituisce le firme del pensiero per tutte le risposte del modello (risposte dell'API) con una chiamata di funzione. Le firme dei pensieri vengono visualizzate nei seguenti casi:
- Quando ci sono chiamate di funzioni parallele, la prima parte della chiamata di funzione restituita dalla risposta del modello avrà una firma di pensiero.
- Quando ci sono chiamate di funzioni sequenziali (multistep), 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 funzioni in più passaggi, combinando le definizioni di turni e passaggi con il concetto di firme introdotto sopra:
Svolta |
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 sul 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, il
thought_signatureviene allegato solo alla prima partefunctionCall. Le partifunctionCallsuccessive nella stessa risposta non contengono una firma.
- Chiamata di funzione singola: la parte
- Requisito: devi restituire questa firma esattamente nella parte in cui è stata ricevuta quando invii di nuovo la cronologia della conversazione.
- Convalida: viene applicata una convalida rigorosa a tutte le chiamate di funzione all'interno
del turno corrente . (È richiesto solo il turno attuale; non eseguiamo la convalida
dei turni precedenti)
- L'API esamina la cronologia (dal più recente al meno recente) per trovare il messaggio Utente più recente che contenga contenuti standard (ad es.
text) ( che sarebbe l'inizio del turno corrente). Questa operazione be sarà unfunctionResponse. - Tutti i turni del modello
functionCallche si verificano dopo questo messaggio di utilizzo specifico sono considerati parte del turno. - La prima parte
functionCalldi ogni passaggio del turno corrente deve includere il relativothought_signature. - Se ometti un
thought_signatureper la prima partefunctionCallin qualsiasi passaggio del turno corrente, la richiesta non andrà a buon fine e verrà visualizzato un errore 400.
- L'API esamina la cronologia (dal più recente al meno recente) per trovare il messaggio Utente più recente che contenga contenuti standard (ad es.
- Se non vengono restituite firme corrette, ecco come si verifica l'errore
gemini-3-pro-preview: Se non includi le firme, verrà visualizzato un errore 400. Il testo sarà del tipo:- Nella chiamata alla funzione
<Function Call>nel blocco di contenuti<index of contents array>manca unthought_signature. Ad esempio, la chiamata alla funzioneFC1nel blocco di contenuti1.non includethought_signature.
- Nella chiamata alla funzione
Esempio di chiamata di funzione sequenziale
Questa sezione mostra un esempio di più chiamate di funzioni in cui l'utente pone una domanda complessa che richiede più attività.
Vediamo un esempio di chiamata di funzione a più turni in cui l'utente pone
una domanda complessa che richiede più attività: "Check flight status for AA100 and
book a taxi if delayed".
Svolta |
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 precedente.
Turno 1, passaggio 1 (richiesta dell'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, passaggio 1 (risposta del modello)
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
Turno 1, passaggio 2 (risposta dell'utente - invio degli output dello strumento) Poiché questo turno dell'utente
contiene solo un functionResponse (nessun testo nuovo), siamo ancora al Turno 1. Dobbiamo
preservare <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, passaggio 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, passaggio 3 (utente - output dello strumento di invio) Per inviare la conferma
della prenotazione del taxi, dobbiamo includere le firme per TUTTE le chiamate di funzione in questo ciclo
(<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
Vediamo 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.
Svolta |
Step |
Richiesta utente |
Risposta del modello |
FunctionResponse |
|---|---|---|---|---|
1 |
1 |
request1="Controlla il meteo a Parigi e Londra" |
FC1 ("Parigi") + firma FC2 ("Londra") |
FR1 |
1 |
2 |
richiesta 2 = richiesta 1 + FC1 ("Parigi") + firma + FC2 ("Londra") |
text_output (nessuna FC) |
Nessuno |
Il seguente codice illustra la sequenza nella tabella precedente.
Turno 1, passaggio 1 (richiesta dell'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, passaggio 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, passaggio 2 (risposta dell'utente - invio degli output dello strumento) Dobbiamo conservare
<Signature_A> nella prima parte esattamente come ricevuto.
[
{
"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 in parti non functionCall
Gemini potrebbe anche restituire thought_signatures nella parte finale della risposta
nelle parti non di chiamata di funzione.
- Comportamento: la parte finale dei contenuti (
text, inlineData…) restituita dal modello può contenere unthought_signature. - Consiglio: la restituzione di queste firme è consigliata per garantire che il modello mantenga un ragionamento di alta qualità, soprattutto per istruzioni complesse o workflow con agente simulato.
- Convalida: l'API non applica rigorosamente la convalida. Se li ometti, non riceverai un errore di blocco, anche se il rendimento potrebbe peggiorare.
Testo/Ragionamento nel contesto (nessuna convalida)
Turno 1, passaggio 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, passaggio 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 chiamata di più funzioni in cui l'utente pone una domanda complessa che richiede più attività.
Vediamo un esempio di chiamata di funzione a più turni 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à.
Svolta |
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 esamina la sequenza specificata.
Turno 1, passaggio 1 (richiesta dell'utente)
{
"model": "google/gemini-3-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, passaggio 1 (risposta 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, passaggio 2 (risposta dell'utente - invio degli output dello strumento)
Poiché questo turno dell'utente contiene solo un functionResponse (nessun testo nuovo), siamo ancora al 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, passaggio 2 (modello)
Il modello ora decide di prenotare un taxi in base all'output precedente dello strumento.
{
"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, passaggio 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 ciclo (<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
Vediamo 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.
Svolta |
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 scorrere la sequenza specificata.
Turno 1, passaggio 1 (richiesta dell'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, passaggio 1 (risposta 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, passaggio 2 (risposta dell'utente - invio degli output dello strumento)
Devi conservare <Signature_A> nella prima parte esattamente come l'hai ricevuto.
"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 Pro con una parte di chiamata di funzione nel turno e nel passaggio attuali? Devo fornire parti di chiamate 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 funzioni personalizzate nella richiesta sia fortemente sconsigliato, nei casi in cui non è possibile evitarlo, ad esempio fornire informazioni al modello su chiamate di funzioni e 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.Invio chiamate di funzioni parallele e risposte interleaved e l'API restituisce un errore 400. Perché?
Quando l'API restituisce chiamate di funzioni parallele "FC1 + firma, FC2", la risposta dell'utente prevista è "FC1 + firma, FC2, FR1, FR2". Se sono interlacciati come "FC1 + firma, FR1, FC2, FR2", l'API restituirà un errore 400.
Durante lo streaming e quando il modello non restituisce una chiamata di funzione, non riesco a trovare la firma del pensiero
Durante una risposta del modello che non contiene un FC con una richiesta di streaming, il modello può restituire la firma del pensiero in una parte con un contenuto di testo vuoto. È consigliabile analizzare l'intera richiesta finché il modello non restituisce
finish_reason.
Comportamento della firma del pensiero per serie di modelli
I modelli Gemini 3 Pro e Gemini 2.5 si comportano in modo diverso con le firme del pensiero nelle chiamate di funzione:
- Se in una risposta sono presenti chiamate di funzioni,
- Gemini 3 Pro avrà sempre la firma nella prima parte della chiamata di funzione. La restituzione di questa parte è obbligatoria.
- 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 funzioni,
- Gemini 3 Pro avrà la firma nell'ultima parte se il modello genera un pensiero.
- Gemini 2.5 non avrà una firma in nessuna parte.
Per il comportamento della firma del pensiero dei modelli Gemini 2.5, consulta la pagina Pensiero.