חתימות מחשבה הן ייצוגים מוצפנים של תהליך המחשבה הפנימי של המודל, והן משמשות לשמירה על הקשר של הנימוקים לאורך אינטראקציות מרובות.
כשמשתמשים במודלים של חשיבה (כמו סדרת Gemini 3 ו-2.5), יכול להיות שה-API יחזיר שדה thoughtSignature בתוך חלקי התוכן של התגובה (למשל, text או functionCall חלקים).
ככלל, אם אתם מקבלים חתימה של מחשבה בתשובה של מודל, אתם צריכים להעביר אותה בדיוק כמו שהיא כשאתם שולחים את היסטוריית השיחה בתור הבא. כשמשתמשים ב-Gemini 3 Pro, צריך להעביר חתימות של מחשבות במהלך קריאה לפונקציה, אחרת תתקבל שגיאת אימות (קוד סטטוס 4xx).
איך זה עובד
בתרשים שלמטה אפשר לראות את המשמעות של 'תור' ו'שלב' בהקשר של קריאה לפונקציה ב-Gemini API. 'תור' הוא החלפה אחת מלאה בשיחה בין משתמש לבין מודל. 'שלב' הוא פעולה או תהליך מפורטים יותר שהמודל מבצע, לרוב כחלק מתהליך גדול יותר להשלמת תור.

במאמר הזה אנחנו מתמקדים בטיפול בקריאות לפונקציות ב-Gemini 3 Pro. בקטע התנהגות המודל מוסבר על אי-התאמות בגרסה 2.5.
Gemini 3 Pro מחזיר חתימות של תהליכי חשיבה לכל התשובות של המודל (תשובות מ-API) עם קריאה לפונקציה. חתימות מחשבה מופיעות במקרים הבאים:
- כשמתבצעות קריאות לפונקציות מקבילות, לחלק הראשון של הקריאה לפונקציה שמוחזר בתגובת המודל תהיה חתימת מחשבה.
- כשמבצעים כמה קריאות לפונקציה ברצף (multi-step), לכל קריאה לפונקציה יש חתימה, ואתם צריכים להעביר את כל החתימות בחזרה.
- תשובות של מודלים ללא קריאה לפונקציה יחזירו חתימת מחשבה בחלק האחרון שהוחזר על ידי המודל.
בטבלה הבאה מוצגת ויזואליזציה של קריאות לפונקציות מרובות שלבים, שמשלבת את ההגדרות של תורות ושלבים עם המושג של חתימות שהוצג למעלה:
Turn |
שלב |
בקשת משתמש |
תשובת המודל |
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
|
ללא |
חתימות בחלקים של קריאה לפונקציה
כש-Gemini יוצר functionCall, הוא מסתמך על thought_signature כדי לעבד את הפלט של הכלי בצורה נכונה בתור הבא.
- התנהגות:
- קריאה יחידה לפונקציה: החלק
functionCallיכילthought_signature. - קריאות מקבילות לפונקציות: אם המודל יוצר קריאות מקבילות לפונקציות בתגובה, החלק
thought_signatureמצורף רק לחלק הראשוןfunctionCall. חלקים הבאים של אותה תגובה לא יכילו חתימה.functionCall
- קריאה יחידה לפונקציה: החלק
- דרישה: חובה להחזיר את החתימה הזו בדיוק בחלק שבו היא התקבלה כששולחים בחזרה את היסטוריית השיחה.
- אימות: מתבצע אימות קפדני לכל הקריאות לפונקציות במהלך התור הנוכחי . (נדרש רק התור הנוכחי, אנחנו לא מאמתים תורות קודמים)
- ה-API מחפש בהיסטוריה (מהחדש לישן) את ההודעה האחרונה של המשתמש שמכילה תוכן רגיל (למשל,
text) ( שזו תהיה תחילת התור הנוכחי). הפעולה הזו לא befunctionResponse. - כל התורות של מודל All
functionCallשמתרחשות אחרי הודעת השימוש הספציפית הזו נחשבות לחלק מהתור. - החלק הראשון
functionCallבכל שלב של התור הנוכחי חייב לכלול אתthought_signatureשלו. - אם לא תציינו
thought_signatureעבור החלק הראשוןfunctionCallבכל שלב של התור הנוכחי, הבקשה תיכשל ותוחזר שגיאה 400.
- ה-API מחפש בהיסטוריה (מהחדש לישן) את ההודעה האחרונה של המשתמש שמכילה תוכן רגיל (למשל,
- אם לא מוחזרות חתימות תקינות, כך תופיע השגיאה
-
gemini-3-pro-preview: אם לא תכללו חתימות, תקבלו שגיאת 400. הניסוח יהיה מהצורה:- בקריאה לפונקציה
<Function Call>בחסימת התוכן<index of contents array>חסרthought_signature. לדוגמה, חסרthought_signatureב-1.content block שלFC1Function call.
- בקריאה לפונקציה
-
דוגמה להפעלת פונקציות רציפה
בקטע הזה מוצגת דוגמה לכמה קריאות לפונקציה, שבהן המשתמש שואל שאלה מורכבת שדורשת כמה משימות.
בואו נראה דוגמה לשימוש בפונקציות בשיחה מרובת תורות, שבה המשתמש שואל שאלה מורכבת שדורשת כמה משימות: "Check flight status for AA100 and
book a taxi if delayed".
Turn |
שלב |
בקשת משתמש |
תשובת המודל |
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 |
הקוד הבא מדגים את הרצף בטבלה שלמעלה.
תור 1, שלב 1 (בקשת משתמש)
{
"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"
]
}
}
]
}
]
}
תור 1, שלב 1 (תשובה לדוגמה)
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
תור 1, שלב 2 (תגובת המשתמש – שליחת פלט של כלי) מכיוון שהתור הזה של המשתמש
מכיל רק functionResponse (ללא טקסט חדש), אנחנו עדיין בתור 1. אנחנו חייבים לשמור על <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"
}
}
}
]
}
תור 1, שלב 2 (מודל) המודל מחליט להזמין מונית על סמך הפלט הקודם של הכלי.
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "book_taxi",
"args": {
"time": "10 AM"
}
},
"thoughtSignature": "<Signature B>"
}
]
}
}
תור 1, שלב 3 (משתמש – שליחת פלט הכלי) כדי לשלוח את אישור הזמנת המונית, צריך לכלול חתימות לכל הקריאות לפונקציות בלולאה הזו (<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"
}
}
}
]
}
}
דוגמה לקריאה לפונקציה במקביל
בואו נראה דוגמה של קריאה לפונקציות במקביל, שבה המשתמש מבקש מ-"Check weather in Paris and London" לראות איפה המודל מבצע אימות.
Turn |
שלב |
בקשת משתמש |
תשובת המודל |
FunctionResponse |
|---|---|---|---|---|
1 |
1 |
request1="Check the weather in Paris and London" |
FC1 ("Paris") + חתימה FC2 ("London") |
FR1 |
1 |
2 |
בקשה 2 = בקשה 1 + FC1 ("פריז") + חתימה + FC2 ("לונדון") |
text_output (אין כרטיסי מועדון) |
ללא |
הקוד הבא מדגים את הרצף בטבלה שלמעלה.
תור 1, שלב 1 (בקשת משתמש)
{
"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"
]
}
}
]
}
]
}
תור 1, שלב 1 (תשובה לדוגמה)
{
"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
}
}
]
}
}
תור 1, שלב 2 (תגובת המשתמש – שליחת תוצאות של כלי) אנחנו צריכים לשמור על
<Signature_A> בחלק הראשון בדיוק כמו שקיבלנו.
[
{
"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"
}
}
}
]
}
]
חתימות בחלקים שאינם functionCall
יכול להיות ש-Gemini יחזיר גם thought_signatures בחלק האחרון של התשובה בחלקים שלא קשורים לקריאה לפונקציה.
- התנהגות: החלק האחרון של התוכן (
text, inlineData…) שמוחזר על ידי המודל עשוי להכילthought_signature. - המלצה: מומלץ להחזיר את החתימות האלה כדי לוודא שהמודל ישמור על יכולת ניתוח באיכות גבוהה, במיוחד כשמדובר בהוראות מורכבות או בתהליכי עבודה מבוססי-סוכן מדומה.
- אימות: ממשק ה-API לא אוכף אימות באופן מחמיר. אם לא תכללו אותם, לא תקבלו שגיאת חסימה, אבל יכול להיות שהביצועים ייפגעו.
טקסט/הסקה בהקשר (ללא אימות)
תור 1, שלב 1 (תשובה לדוגמה)
{
"role": "model",
"parts": [
{
"text": "I need to calculate the risk. Let me think step-by-step...",
"thought_signature": "<Signature_C>" // OPTIONAL (Recommended)
}
]
}
תור 2, שלב 1 (משתמש)
[
{ "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." }] }
]
חתימות לתאימות ל-OpenAI
בדוגמה הבאה מוצג אופן הטיפול בחתימות של מחשבות ב-API להשלמת צ'אט באמצעות תאימות ל-OpenAI.
דוגמה להפעלת פונקציות רציפה
זו דוגמה לקריאה לכמה פונקציות, שבה המשתמש שואל שאלה מורכבת שדורשת כמה משימות.
בדוגמה הבאה נראה שימוש בפונקציות עם כמה תפניות שיחה. המשתמש שואל Check flight status for AA100 and book a taxi if delayed ואפשר לראות מה קורה כשהמשתמש שואל שאלה מורכבת שדורשת כמה משימות.
Turn |
שלב |
בקשת משתמש |
תשובת המודל |
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 |
הקוד הבא מתאר את הרצף הנתון.
תור 1, שלב 1 (בקשת משתמש)
{
"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"
]
}
}
}
]
}
תור 1, שלב 1 (תגובה של מודל)
{
"role": "model",
"tool_calls": [
{
"extra_content": {
"google": {
"thought_signature": "<Signature A>"
}
},
"function": {
"arguments": "{\"flight\":\"AA100\"}",
"name": "check_flight"
},
"id": "function-call-1",
"type": "function"
}
]
}
תור 1, שלב 2 (תגובת משתמש – שליחת פלט של כלי)
מכיוון שהתור הזה של המשתמש מכיל רק functionResponse (ללא טקסט חדש), אנחנו עדיין בתור 1 וחייבים לשמור על <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\"}"
}
]
תור 1, שלב 2 (מודל)
עכשיו המודל מחליט להזמין מונית על סמך הפלט הקודם של הכלי.
{
"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"
}
]
}
תור 1, שלב 3 (משתמש – שליחת פלט של כלי)
כדי לשלוח את אישור הזמנת המונית, אנחנו צריכים לכלול חתימות לכל קריאות הפונקציה בלולאה הזו (<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\"}"
}
]
דוגמה לקריאה לפונקציה במקביל
בואו נראה דוגמה של קריאה לפונקציות במקביל, שבה המשתמש שואל "Check weather in Paris and London" ואפשר לראות איפה המודל מבצע אימות.
Turn |
שלב |
בקשת משתמש |
תשובת המודל |
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 |
הנה הקוד להרצת הרצף הנתון.
תור 1, שלב 1 (בקשת משתמש)
{
"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"
]
}
}
]
}
]
}
תור 1, שלב 1 (תגובה של מודל)
{
"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
}
]
}
תור 1, שלב 2 (תגובת משתמש – שליחת פלט של כלי)
צריך לשמור את <Signature_A> בחלק הראשון בדיוק כפי שהוא.
"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\"}"
}
]
שאלות נפוצות
איך מעבירים היסטוריה ממודל אחר ל-Gemini 3 Pro עם חלק של קריאה לפונקציה בתור ובשלב הנוכחיים? צריך לספק חלקים של בקשות להפעלת פונקציות שלא נוצרו על ידי ה-API ולכן לא משויכת להם חתימת מחשבה?
לא מומלץ להוסיף בלוקים של בקשות להפעלת פונקציות מותאמות אישית לבקשה, אבל במקרים שבהם אי אפשר להימנע מכך, למשל כשמספקים למודל מידע על בקשות להפעלת פונקציות ותגובות שהלקוח ביצע באופן דטרמיניסטי, או כשמעבירים מעקב ממודל אחר שלא כולל חתימות מחשבה, אפשר להגדיר את החתימות הבאות של placeholder
"context_engineering_is_the_way_to_go"או"skip_thought_signature_validator"בשדה של חתימת המחשבה כדי לדלג על האימות.אני שולח קריאות לפונקציות מקבילות ותשובות משולבות, וה-API מחזיר 400. למה?
כשה-API מחזיר קריאות מקבילות לפונקציות FC1 + signature, FC2, התגובה הצפויה מהמשתמש היא FC1+ signature, FC2, FR1, FR2. אם הם משולבים כמו 'FC1 + signature, FR1, FC2, FR2', ה-API יחזיר שגיאה 400.
בסטרימינג, אם המודל לא מחזיר קריאה לפונקציה, אי אפשר למצוא את חתימת המחשבה
במהלך תגובה של מודל שלא מכילה FC עם בקשת סטרימינג, יכול להיות שהמודל יחזיר את חתימת המחשבה בחלק עם תוכן טקסט ריק. מומלץ לנתח את כל הבקשה עד שהמודל מחזיר את התו
finish_reason.
התנהגות חתימת המחשבה לפי סדרת מודלים
ההתנהגות של מודלים Gemini 3 Pro ו-Gemini 2.5 שונה כשמשתמשים בחתימות מחשבה בקריאות לפונקציות:
- אם יש קריאות לפונקציות בתשובה,
- החתימה תמיד תופיע בחלק הראשון של קריאת הפונקציה ב-Gemini 3 Pro. חובה להחזיר את החלק הזה.
- החתימה תופיע בחלק הראשון של Gemini 2.5 (בלי קשר לסוג). לא חייבים להחזיר את החלק הזה.
- אם אין קריאות לפונקציות בתשובה,
- אם המודל יוצר מחשבה, החתימה של Gemini 3 Pro תופיע בחלק האחרון.
- ל-Gemini 2.5 לא תהיה חתימה באף חלק.
מידע על התנהגות חתימת המחשבה של מודלים של Gemini 2.5 זמין בדף חשיבה.