Сигнатуры мыслей – это зашифрованные представления внутренних мыслительных процессов модели, которые используются для сохранения контекста рассуждений при многоэтапном взаимодействии.
При использовании думающих моделей (например, Gemini 4, 3 и 2.5) API может возвращать поле thoughtSignature в частях контента ответа (например, в частях text или functionCall).
Как правило, если в ответе модели есть подпись мысли, ее нужно передать в следующем запросе в том же виде, в котором она была получена.
При использовании моделей Gemini 4 и Gemini 3 вы должны передавать сигнатуры мыслей во время вызова функции, иначе вы получите ошибку валидации (код статуса 4xx).
Это относится и к случаям, когда для Gemini 3 Flash используется minimal
уровень мышления.
Принцип работы
На изображении ниже показано, что означают термины "ход" и "шаг" в контексте вызова функций в Gemini API. "Реплика" – это один полный обмен сообщениями между пользователем и моделью. "Шаг" – это более детальное действие или операция, выполняемая моделью, часто в рамках более крупного процесса по завершению хода.

В этом документе рассматривается обработка вызовов функций для моделей Gemini 4 и Gemini 3. О расхождениях с версией 2.5 читайте в разделе Поведение модели.
Gemini 4 и Gemini 3 возвращают сигнатуры мыслей для всех ответов модели (ответов от API) с вызовом функции. Подписи мыслей появляются в следующих случаях:
- Если есть параллельные вызовы функций, то первая часть вызова функции, возвращенная ответом модели, будет иметь сигнатуру мысли.
- При последовательном вызове функций (многоэтапном) у каждого вызова будет своя сигнатура, и вы должны передать все сигнатуры обратно.
- Ответы модели без вызова функции будут содержать сигнатуру размышления в последней части, возвращенной моделью.
В таблице ниже показаны многоэтапные вызовы функций, сочетающие определения ходов и шагов с концепцией сигнатур, представленной выше.
Повернуть |
Шаг |
Запрос пользователя |
Ответ модели |
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 возвращается к истории (от нового к старому), чтобы найти последнее сообщение User, содержащее стандартный контент (например,
text), который будет началом текущего хода. Это не будетfunctionResponse.be - Все ответы модели
functionCall, полученные после этого сообщения, считаются частью реплики. - Первая часть
functionCallв каждом шаге текущего хода должна включатьthought_signature. - Если вы опустите
thought_signatureдля первой частиfunctionCallна любом шаге текущего хода, запрос не будет выполнен и появится ошибка 400.
- API возвращается к истории (от нового к старому), чтобы найти последнее сообщение User, содержащее стандартный контент (например,
- Если правильные подписи не возвращаются, вы получите ошибку следующим образом:
- Модели Gemini 3: если не добавить подписи, возникнет ошибка 400. Текст будет выглядеть следующим образом:
- В вызове функции
<Function Call>в блоке контента<index of contents array>отсутствуетthought_signature. Например, В вызове функцииFC1в блоке контента1.отсутствуетthought_signature.
- В вызове функции
- Модели Gemini 3: если не добавить подписи, возникнет ошибка 400. Текст будет выглядеть следующим образом:
Пример последовательного вызова функций
В этом разделе показан пример нескольких вызовов функций, когда пользователь задает сложный вопрос, требующий выполнения нескольких задач.
Рассмотрим пример многоэтапного вызова функций, в котором пользователь задает сложный вопрос, требующий выполнения нескольких задач: "Check flight status for AA100 and
book a taxi if delayed".
Повернуть |
Шаг |
Запрос пользователя |
Ответ модели |
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. Ответ модели
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "check_flight",
"args": {
"flight": "AA100"
}
},
"thoughtSignature": "<Signature A>"
}
]
}
}
Шаг 2 (ответ пользователя – отправка выходных данных инструмента). Поскольку эта реплика пользователя содержит только functionResponse (без нового текста), мы все ещё находимся на первом шаге. Мы должны сохранить <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 ("Париж") + подпись FC2 ("London") |
FR1 |
1 |
2 |
request 2 = request1 + FC1 ("Paris") + signature + FC2 ("London") |
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. Ответ модели
{
"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
В примерах ниже показано, как обрабатывать подписи цепочки рассуждений для Chat Completion API, используя совместимость с OpenAI.
Пример последовательного вызова функций
Это пример вызова нескольких функций, когда пользователь задает сложный вопрос, требующий выполнения нескольких задач.
Давайте рассмотрим пример многоэтапного вызова функции, когда пользователь спрашивает:
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. Запрос пользователя
{
"model": "google/gemini-4-argon",
"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". Вы увидите, как модель выполняет проверку.
Повернуть |
Шаг |
Запрос пользователя |
Ответ модели |
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 4 или Gemini 3 с вызовом функции на текущем шаге? Мне нужно предоставить части вызова функции, которые не были сгенерированы API и поэтому не имеют связанной сигнатуры мысли?
Внедрять в запрос блоки вызова пользовательских функций крайне не рекомендуется. Однако если этого не избежать, например при передаче модели информации о вызовах функций и ответах, которые были детерминированно выполнены клиентом, или при переносе трассировки из другой модели, не включающей сигнатуры рассуждений, вы можете задать в поле сигнатуры рассуждений следующие фиктивные сигнатуры:
"context_engineering_is_the_way_to_go"или"skip_thought_signature_validator", чтобы пропустить проверку.Я отправляю чередующиеся параллельные вызовы функций и ответы, а API возвращает ошибку 400. Что делать?
Если API возвращает параллельные вызовы функций "FC1 + подпись, FC2", ожидаемый ответ пользователя – "FC1 + подпись, FC2, FR1, FR2". Если вы чередуете их, например "FC1 + подпись, FR1, FC2, FR2", API вернет ошибку 400.
При потоковой передаче, когда модель не возвращает вызов функции, я не могу найти подпись размышления
Во время ответа модели, не содержащего FC с запросом на потоковую передачу, модель может вернуть сигнатуру мысли в части с пустым текстовым контентом. Рекомендуется анализировать весь запрос, пока модель не вернет
finish_reason.
Подписи для разных моделей
Модели Gemini 4, Gemini 3 и Gemini 2.5 по-разному работают с подписями размышлений в вызовах функций:
- Если в ответе есть вызовы функций,
- В Gemini 4 и Gemini 3 подпись всегда будет в первой части вызова функции. Возврат этой детали обязателен.
- В Gemini 2.5 подпись будет в первой части (независимо от типа). Возвращать эту деталь необязательно.
- Если в ответе нет вызовов функций,
- В Gemini 4 и Gemini 3 подпись будет в последней части, если модель сгенерирует мысль.
- У Gemini 2.5 нет подписи ни в одной части.
Подробную информацию вы найдете на странице Размышления. Для моделей Gemini 3 Image см. раздел о процессе рассуждения в руководстве Генерирование изображений.