Tanda Tangan Pikiran

Tanda tangan pemikiran adalah representasi terenkripsi dari proses pemikiran internal model dan digunakan untuk mempertahankan konteks penalaran di seluruh interaksi multi-giliran. Saat menggunakan model pemikiran (seperti seri Gemini 3 dan 2.5), API dapat menampilkan kolom thoughtSignature dalam bagian konten respons (misalnya, text atau functionCall).

Sebagai aturan umum, jika Anda menerima tanda tangan pemikiran dalam respons model, Anda harus meneruskannya kembali persis seperti yang diterima saat mengirimkan histori percakapan pada giliran berikutnya. Saat menggunakan Gemini 3 Pro, Anda harus meneruskan kembali tanda tangan pemikiran selama panggilan fungsi, atau Anda akan mendapatkan error validasi (kode status 4xx).

Cara kerjanya

Grafik di bawah memvisualisasikan arti "giliran" dan "langkah" sebagaimana berkaitan dengan panggilan fungsi di Gemini API. "Giliran" adalah satu pertukaran lengkap dalam percakapan antara pengguna dan model. "Langkah" adalah tindakan atau operasi yang lebih terperinci yang dilakukan oleh model, sering kali sebagai bagian dari proses yang lebih besar untuk menyelesaikan giliran.

Diagram langkah dan giliran panggilan fungsi

Dokumen ini berfokus pada penanganan panggilan fungsi untuk Gemini 3 Pro. Lihat bagian perilaku model untuk mengetahui perbedaan dengan 2.5.

Gemini 3 Pro menampilkan tanda tangan pemikiran untuk semua respons model (respons dari API) dengan panggilan fungsi. Tanda tangan pikiran muncul dalam kasus berikut:

  • Jika ada panggilan fungsi paralel, bagian panggilan fungsi pertama yang ditampilkan oleh respons model akan memiliki tanda tangan pemikiran.
  • Jika ada panggilan fungsi berurutan (multi-langkah), setiap panggilan fungsi akan memiliki tanda tangan dan Anda harus meneruskan semua tanda tangan kembali.
  • Respons model tanpa panggilan fungsi akan menampilkan tanda tangan pemikiran di dalam bagian terakhir yang ditampilkan oleh model.

Tabel berikut memberikan visualisasi untuk panggilan fungsi multi-langkah, menggabungkan definisi giliran dan langkah dengan konsep tanda tangan yang diperkenalkan di atas:

Putar

Langkah

Permintaan Pengguna

Respons Model

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

(no FCs)

Tidak ada

Tanda tangan di bagian panggilan fungsi

Saat membuat functionCall, Gemini mengandalkan thought_signature untuk memproses output alat dengan benar pada giliran berikutnya.

  • Perilaku:
    • Panggilan Fungsi Tunggal: Bagian functionCall akan berisi thought_signature.
    • Panggilan Fungsi Paralel: Jika model menghasilkan panggilan fungsi paralel dalam respons, thought_signature hanya dilampirkan ke bagian functionCall pertama. Bagian functionCall berikutnya dalam respons yang sama tidak akan berisi tanda tangan.
  • Persyaratan: Anda harus mengembalikan tanda tangan ini di bagian yang sama persis dengan saat tanda tangan tersebut diterima ketika mengirimkan kembali histori percakapan.
  • Validasi: Validasi ketat diterapkan untuk semua panggilan fungsi dalam giliran saat ini . (Hanya giliran saat ini yang diperlukan; kami tidak memvalidasi giliran sebelumnya)
    • API akan kembali ke histori (terbaru hingga terlama) untuk menemukan pesan Pengguna terbaru yang berisi konten standar (misalnya, text) ( yang akan menjadi awal giliran saat ini). Ini be functionResponse.
    • Semua model All functionCall yang terjadi setelah pesan penggunaan spesifik tersebut dianggap sebagai bagian dari giliran.
    • Bagian functionCall pertama di setiap langkah giliran saat ini harus menyertakan thought_signature-nya.
    • Jika Anda menghilangkan thought_signature untuk bagian functionCall pertama di langkah giliran saat ini, permintaan akan gagal dengan error 400.
  • Jika tanda tangan yang tepat tidak ditampilkan, berikut cara Anda akan mengalami error
    • gemini-3-pro-preview: Jika tanda tangan tidak disertakan, akan terjadi error 400. Kata-katanya akan berbentuk:
      • Panggilan fungsi <Function Call> di blok konten <index of contents array> tidak memiliki thought_signature. Misalnya, Panggilan fungsi FC1 di blok konten 1. tidak memiliki thought_signature.

Contoh panggilan fungsi berurutan

Bagian ini menunjukkan contoh beberapa panggilan fungsi saat pengguna mengajukan pertanyaan kompleks yang memerlukan beberapa tugas.

Mari kita bahas contoh panggilan fungsi multi-giliran saat pengguna mengajukan pertanyaan kompleks yang memerlukan beberapa tugas: "Check flight status for AA100 and book a taxi if delayed".

Putar

Langkah

Permintaan Pengguna

Respons Model

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

(no FCs)

None

Kode berikut menggambarkan urutan dalam tabel di atas.

Giliran 1, Langkah 1 (Permintaan pengguna)

{
  "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"
            ]
          }
        }
      ]
    }
  ]
}

Giliran 1, Langkah 1 (Respons model)

{
"content": {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "check_flight",
              "args": {
                "flight": "AA100"
              }
            },
            "thoughtSignature": "<Signature A>"
          }
        ]
  }
}

Giliran 1, Langkah 2 (Respons pengguna - Mengirim output alat) Karena giliran pengguna ini hanya berisi functionResponse (tanpa teks baru), kita masih berada di Giliran 1. Kita harus melestarikan <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"
                }
              }
            }
        ]
}

Turn 1, Step 2 (Model) Model kini memutuskan untuk memesan taksi berdasarkan output alat sebelumnya.

{
      "content": {
        "role": "model",
        "parts": [
          {
            "functionCall": {
              "name": "book_taxi",
              "args": {
                "time": "10 AM"
              }
            },
            "thoughtSignature": "<Signature B>"
          }
        ]
      }
}

Giliran 1, Langkah 3 (Pengguna - Mengirim output alat) Untuk mengirim konfirmasi pemesanan taksi, kita harus menyertakan tanda tangan untuk SEMUA panggilan fungsi dalam loop ini (<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"
              }
              }
            }
        ]
    }
}

Contoh panggilan fungsi paralel

Mari kita bahas contoh panggilan fungsi paralel saat pengguna meminta "Check weather in Paris and London" untuk melihat tempat model melakukan validasi.

Putar

Langkah

Permintaan Pengguna

Respons Model

FunctionResponse

1

1

request1="Cek cuaca di Paris dan London"

FC1 ("Paris") + tanda tangan

FC2 ("London")

FR1

1

2

request 2 = request1 + FC1 ("Paris") + tanda tangan + FC2 ("London")

text_output

(tanpa FC)

Tidak ada

Kode berikut menggambarkan urutan dalam tabel di atas.

Giliran 1, Langkah 1 (Permintaan pengguna)

{
  "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"
            ]
          }
        }
      ]
    }
  ]
}

Giliran 1, Langkah 1 (Respons model)

{
  "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
        }
      }
    ]
  }
}

Turn 1, Langkah 2 (Respons pengguna - Mengirim output alat) Kita harus mempertahankan <Signature_A> di bagian pertama persis seperti yang diterima.

[
  {
    "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"
          }
        }
      }
    ]
  }
]

Tanda tangan di bagian non-functionCall

Gemini juga dapat menampilkan thought_signatures di bagian akhir respons dalam bagian non-panggilan fungsi.

  • Perilaku: Bagian konten akhir (text, inlineData…) yang ditampilkan oleh model dapat berisi thought_signature.
  • Rekomendasi: Menampilkan tanda tangan ini direkomendasikan untuk memastikan model mempertahankan penalaran berkualitas tinggi, terutama untuk alur kerja agentik yang disimulasikan atau mengikuti petunjuk yang kompleks.
  • Validasi: API tidak secara ketat menerapkan validasi. Anda tidak akan menerima error pemblokiran jika menghapusnya, meskipun performa mungkin menurun.

Teks/Penalaran dalam konteks (Tanpa validasi)

Giliran 1, Langkah 1 (Respons model)

{
  "role": "model",
  "parts": [
    {
      "text": "I need to calculate the risk. Let me think step-by-step...",
      "thought_signature": "<Signature_C>" // OPTIONAL (Recommended)
    }
  ]
}

Turn 2, Langkah 1 (Pengguna)

[
  { "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." }] }
]

Tanda tangan untuk kompatibilitas OpenAI

Contoh berikut menunjukkan cara menangani tanda tangan pemikiran untuk API penyelesaian chat menggunakan kompatibilitas OpenAI.

Contoh panggilan fungsi berurutan

Berikut adalah contoh beberapa panggilan fungsi saat pengguna mengajukan pertanyaan kompleks yang memerlukan beberapa tugas.

Mari kita bahas contoh panggilan fungsi multi-giliran saat pengguna bertanya Check flight status for AA100 and book a taxi if delayed dan Anda dapat melihat apa yang terjadi saat pengguna mengajukan pertanyaan kompleks yang memerlukan beberapa tugas.

Putar

Langkah

Permintaan Pengguna

Respons Model

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

Kode berikut akan memproses urutan yang diberikan.

Giliran 1, Langkah 1 (Permintaan Pengguna)

{
  "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"
          ]
        }
      }
    }
  ]
}

Giliran 1, Langkah 1 (Respons Model)

{
      "role": "model",
        "tool_calls": [
          {
            "extra_content": {
              "google": {
                "thought_signature": "<Signature A>"
              }
            },
            "function": {
              "arguments": "{\"flight\":\"AA100\"}",
              "name": "check_flight"
            },
            "id": "function-call-1",
            "type": "function"
          }
        ]
    }

Turn 1, Step 2 (Respons Pengguna - Mengirim Output Alat)

Karena giliran pengguna ini hanya berisi functionResponse (tidak ada teks baru), kita masih berada di Giliran 1 dan harus mempertahankan <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\"}"                 
    }
  ]

Turn 1, Step 2 (Model)

Model kini memutuskan untuk memesan taksi berdasarkan output alat sebelumnya.

{
"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"
          }
       ]
}

Turn 1, Langkah 3 (Pengguna - Mengirim Output Alat)

Untuk mengirim konfirmasi pemesanan taksi, kita harus menyertakan tanda tangan untuk SEMUA panggilan fungsi dalam loop ini (<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\"}"
    }
  ]

Contoh panggilan fungsi paralel

Mari kita pelajari contoh panggilan fungsi paralel saat pengguna bertanya "Check weather in Paris and London" dan Anda dapat melihat tempat model melakukan validasi.

Putar

Langkah

Permintaan Pengguna

Respons Model

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

Berikut adalah kode untuk menelusuri urutan yang diberikan.

Giliran 1, Langkah 1 (Permintaan Pengguna)

{
  "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"
            ]
          }
        }
      ]
    }
  ]
}

Giliran 1, Langkah 1 (Respons Model)

{
"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
          }
        ]
}

Turn 1, Step 2 (Respons Pengguna - Mengirim Output Alat)

Anda harus mempertahankan <Signature_A> di bagian pertama persis seperti yang diterima.

"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\"}"
    }
  ]

FAQ

  1. Bagaimana cara mentransfer histori dari model lain ke Gemini 3 Pro dengan bagian panggilan fungsi dalam giliran dan langkah saat ini? Saya perlu memberikan bagian panggilan fungsi yang tidak dibuat oleh API dan oleh karena itu tidak memiliki tanda tangan pemikiran terkait?

    Meskipun sangat tidak disarankan untuk menyisipkan blok panggilan fungsi kustom ke dalam permintaan, dalam kasus yang tidak dapat dihindari, misalnya memberikan informasi ke model tentang panggilan fungsi dan respons yang dieksekusi secara deterministik oleh klien, atau mentransfer rekaman aktivitas dari model lain yang tidak menyertakan tanda tangan pemikiran, Anda dapat menetapkan tanda tangan tiruan berikut, yaitu "context_engineering_is_the_way_to_go" atau "skip_thought_signature_validator", di kolom tanda tangan pemikiran untuk melewati validasi.

  2. Saya mengirim kembali panggilan dan respons fungsi paralel yang disisipkan dan API menampilkan 400. Mengapa demikian?

    Jika API menampilkan panggilan fungsi paralel "FC1 + tanda tangan, FC2", respons pengguna yang diharapkan adalah "FC1+ tanda tangan, FC2, FR1, FR2". Jika Anda menyisipkannya sebagai "FC1 + tanda tangan, FR1, FC2, FR2", API akan menampilkan error 400.

  3. Saat streaming dan model tidak menampilkan panggilan fungsi, saya tidak dapat menemukan tanda tangan pemikiran

    Selama respons model tidak berisi FC dengan permintaan streaming, model dapat menampilkan tanda tangan pemikiran di bagian dengan bagian konten teks kosong. Sebaiknya parsing seluruh permintaan hingga finish_reason ditampilkan oleh model.

Perilaku tanda tangan pemikiran menurut seri model

Model Gemini 3 Pro dan Gemini 2.5 berperilaku berbeda dengan tanda tangan pemikiran dalam panggilan fungsi:

  • Jika ada panggilan fungsi dalam respons,
    • Gemini 3 Pro akan selalu memiliki tanda tangan di bagian panggilan fungsi pertama. Bagian tersebut wajib ditampilkan.
    • Gemini 2.5 akan memiliki tanda tangan di bagian pertama (terlepas dari jenisnya). Bagian tersebut opsional untuk ditampilkan.
  • Jika tidak ada panggilan fungsi dalam respons,
    • Gemini 3 Pro akan memiliki tanda tangan di bagian terakhir jika model menghasilkan pemikiran.
    • Gemini 2.5 tidak akan memiliki tanda tangan di bagian mana pun.

Untuk perilaku tanda tangan pemikiran model Gemini 2.5, lihat halaman Pemikiran.