Краткий ответ
При выполнении многоэтапного вызова функций (function calling) моделями Gemini 3 и более поздними (gemini-4-argon, gemini-3.8-flash, gemini-3.1-pro-preview и т. д.) возникают два типа ошибок 400, связанных с подписью рассуждений (thoughtSignature), и для них требуются разные решения:
/v1/chat/completions, к вам это не относится: шлюз сам управляет подписями, и стандартных сообщений tool_calls / tool будет вполне достаточно.
Как различить эти две ошибки
Отсутствующая подпись
parts. Это строгое правило, установленное провайдером модели для семейства Gemini 3: каждая часть functionCall в текущей реплике должна содержать свою подпись. При отсутствии подписи запрос завершается ошибкой 400 на любом маршруте, и повторные попытки не помогут.
Недействительная или поврежденная подпись
Почему это происходит
Когда включены tools, модели Gemini 3 прикрепляют зашифрованныйthoughtSignature к той же части, что и каждый functionCall, фиксируя состояние рассуждения на этом шаге. При следующем запросе модели он необходим для продолжения цепочки рассуждений, поэтому провайдер требует отправлять его обратно без изменений.
Отсутствует: клиент пересобрал часть
name и args из functionCall и отбрасывает соседний thoughtSignature; либо чанки при потоковой передаче собираются заново без объединения с подписью.Отсутствует: история была сжата или перезаписана
Недействительна: маршрут изменился в ходе диалога
Недействительна: модель изменилась в ходе диалога
functionCall; у остальных ее обоснованно нет, поэтому не создавайте ее искусственно. При последовательных вызовах (несколько шагов в рамках одной реплики) каждый шаг содержит подпись, и каждую из них необходимо возвращать.Исправление 1: отсутствует подпись, измените способ воспроизведения истории клиентом
Передавайте весь ответ модели обратно дословно
google-genai SDK просто используйте contents.append(response.candidates[0].content); не извлекайте только поле function_call. При отправке прямых REST-запросов реплика модели в contents второго запроса должна выглядеть следующим образом:thoughtSignature и functionCall — это два поля одной и той же части, а не две разные части.Проверьте, не удаляет ли поле фреймворк или middleware
thoughtSignature все еще присутствует. position N в тексте ошибки — это parts[N]; проверяйте сразу там.Не полагайтесь на то, что некоторые модели пропускают такие запросы
Решение 2: недействительная подпись, повторите отправку или начните заново
Повторите отправку один раз без изменений
Все еще 400: удалите подписи из реплик истории и отправьте повторно
thoughtSignature из частей каждой реплики role: "model" в истории, затем отправьте запрос повторно. Вы потеряете контекст рассуждения этих реплик, и качество ответа может незначительно снизиться, но диалог можно будет продолжить. Удаляйте подписи только из реплик истории, но ни в коем случае не из текущей.Либо начните новый диалог
Одна модель, один ключ на диалог
Отсутствие обработки подписи на OpenAI-совместимом эндпоинте
При вызове Gemini через/v1/chat/completions сообщения tool_calls не содержат поля подписи; шлюз сохраняет и восстанавливает его во время преобразования. В наших тестах на gemini-4-argon двухшаговые диалоги успешно работали для всех трёх форматов: одиночный вызов, два параллельных вызова и текст плюс вызов. Просто возвращайте сообщения tool_calls и tool стандартным для OpenAI способом.
/v1/responses, необходимо переключиться на протокол чата, поскольку модели Gemini пока не поддерживают этот эндпоинт. См. Генерация текста Gemini 4 Argon.Часто задаваемые вопросы
Эту ошибку выдает только argon; с flash всегда все было в порядке. argon сломался?
Эту ошибку выдает только argon; с flash всегда все было в порядке. argon сломался?
Можно ли кэшировать подпись и использовать ее повторно в разных диалогах?
Можно ли кэшировать подпись и использовать ее повторно в разных диалогах?
Где находится подпись в потоковом ответе?
Где находится подпись в потоковом ответе?
functionCall, внутри чанка, который ее содержит. При повторной сборке stream объедините это поле вместе с functionCall в итоговый ответ модели, прежде чем возвращать его в историю.Нужны ли подписи и для обычных текстовых реплик?
Нужны ли подписи и для обычных текстовых реплик?
functionCall; отсутствие подписи в текстовой реплике не приводит к ошибке 400, однако ее сохранение помогает непрерывности рассуждения, поэтому в любом случае возвращайте весь ответ дословно.