Gemini 도구 호출 뒤 missing thought_signature 오류가 날 때
Gemini 함수 호출과 병렬 결과에서 서명을 유지하고 네이티브 REST, Python SDK, 호환 API의 필드 차이를 구분합니다.
Gemini 첫 요청은 되지만 함수 호출 뒤 missing thought_signature 오류가 난다면 요청 사이에 저장한 모델 content를 검사하세요. 함수 응답을 추가하기 전에 원래 함수 호출 part와 서명을 그대로 반환해야 합니다. 함수 이름과 인수만 저장하면 다음 턴에 필요한 상태를 잃을 수 있습니다.
이 글은 도구 호출의 후속 요청을 다루며 2026년 9월 14일 확인한 Google의 thought signature 문서를 따릅니다. 모델 세대와 API마다 요구사항이 다릅니다. 서명이 없을 때 모든 Gemini 모델이 같은 HTTP 400을 반환한다고 가정하지 마세요.
실제 인터페이스의 필드 위치 확인하기
오류에는 snake_case가 나오고 네이티브 REST에는 camelCase가 사용될 수 있습니다. generateContent의 네이티브 JSON에서 thoughtSignature는 part 안에서 functionCall과 같은 계층에 있는 필드입니다. Python SDK 객체는 보통 thought_signature를 사용합니다. 호환 엔드포인트는 제공업체 전용 확장에 메타데이터를 담을 수도 있습니다.
| 인터페이스 | 보존해야 할 내용 |
|---|---|
| 네이티브 REST generateContent | thoughtSignature를 포함한 전체 model content와 parts |
| Google Python SDK | thought_signature를 포함한 반환 content 객체 전체 |
| OpenAI 호환 엔드포인트 | 응답 메시지나 도구 호출의 문서화된 제공업체 메타데이터 |
| Interactions 또는 다른 API | 해당 API 자체의 후속 요청·상태 규칙 |
오류의 표기가 다르다는 이유로 필드를 추측한 위치로 옮기지 마세요. 첫 호출 성공은 첫 요청이 수락됐다는 뜻일 뿐입니다. 텍스트 전용 이력 저장소나 어댑터가 필수 상태를 잃는 문제는 후속 요청에서 드러날 수 있습니다.
도구 응답보다 모델 턴을 먼저 유지하기
실제 함수 응답을 담는 다음 user content 전에 모델의 전체 content가 이력에 있어야 합니다. 턴 구성은 Google 함수 호출 안내를 따르세요. 채팅 위젯에서 재구성하지 말고 parts의 원래 순서를 유지합니다.
개념적인 순서는 다음과 같습니다.
user: 원래 작업
model: functionCall과 서명 포함 part를 비롯한 원래 반환 content
user: 실제 결과를 담은 functionResponse
model: 다음 응답
이는 합성 순서이며 실행 가능한 요청이나 실제 API 테스트 기록이 아닙니다. 실제 호출에는 그 작업에 대해 받은 응답을 사용해야 합니다. 서명을 임의 문자열이나 다른 대화의 예시로 바꾸지 마세요.
병렬 호출마다 서명이 필요한 것은 아닙니다
현재 문서화된 Gemini 3 도구 워크플로에서는 각 단계의 첫 function-call part에 필수 서명이 있습니다. 병렬 응답에서도 첫 함수 호출 part가 서명을 가지며 뒤의 호출 part마다 따로 필요하지는 않습니다. 모든 병렬 part에 서명을 요구하는 검증기는 올바른 응답을 거부할 수 있습니다.
서명이 있는 첫 호출과 두 번째 호출을 원래 그룹대로 유지한 뒤 대응 함수 결과를 반환하세요. 같은 병렬 모델 턴에서 온 호출 두 개를 호출1, 결과1, 호출2, 결과2로 재배열하면 안 됩니다. 순차 단계는 다릅니다. 새로운 모델 단계마다 그 단계가 반환한 상태를 보존해야 합니다.
모든 도구를 개별 메시지로 정규화하는 미들웨어에서는 이 차이가 중요합니다. 편리한 공통 표현이 원래 그룹 정보를 없앨 수 있습니다. 요청하는 엔드포인트의 네이티브 순서를 복원할 충분한 정보를 남기세요.
SDK도 앱이 버린 정보까지 보존하지는 못합니다
공식 SDK의 채팅 처리는 전체 응답과 이력을 유지할 때 서명을 관리할 수 있습니다. 앱이 텍스트로 바꾸거나 함수 인수만 추출하거나 축약된 JSON 스키마에 저장하면 그 보장을 앱 전체에 적용할 수 없습니다.
제공업체 응답, 앱이 저장한 이력, 다음 실제 직렬화 요청의 세 객체를 비교하세요. 서명을 가진 part가 사라지거나 바뀌는 첫 경계를 찾습니다. DB 스키마, 메시지 필터, 콜백과 서로 다른 API 사이의 어댑터를 조사하세요.
최소 재현에는 고정 로컬 값을 반환하는 무해한 함수를 사용하고 외부 부작용을 없애세요. 목적은 함수 라운드 하나를 완성하는 것이지 직렬화를 디버깅하며 결제나 배포를 반복하는 것이 아닙니다. 이 글은 특정 제3자 클라이언트 버전이 수정됐다고 주장하지 않습니다.
thinking을 낮추는 것은 범용 해결책이 아닙니다
최소 thinking 설정으로 도구 서명 요구가 사라진다고 가정하지 마세요. 모델과 인터페이스별 thinking 문서를 따릅니다. 생성 설정 변경은 이미 잃은 상태를 복구하는 작업과 다릅니다.
Google은 일부 가져온 실행 이력의 특별 처리를 설명하지만 특별한 우회 표시는 자신이 받은 모델 응답을 잃는 앱의 일반적인 수정 방법이 아닙니다. 이력 보존 경로부터 고치세요. 그렇지 않으면 검증 증상 하나만 숨긴 채 유용한 메타데이터를 계속 버릴 수 있습니다.
서명 누락과 잘못된 함수 응답도 구분해야 합니다. 잘못된 결과 이름, 호출 대응 누락, 유효하지 않은 도구 스키마는 다른 오류를 낼 수 있습니다. HTTP 400만 보고 잘못된 경로를 조사하지 않도록 전체 상태와 오류 본문을 기록하세요.
검사한 범위만큼만 수정 효과를 판단하기
직렬화 수정 뒤 실패했던 경로와 SDK 버전에서 같은 작은 함수 워크플로를 실행하세요. 후속 요청이 수락되고 함수 결과가 답변에 반영되는지 확인합니다. 병렬 함수가 필요하다면 별도 병렬 사례를 추가하세요. 단일 호출 성공으로 병렬 경로까지 검증되지는 않습니다.
검사가 로컬 스키마 검증인지 실제 API 호출인지 기록하세요. 구문 검사만으로 제공업체 수락을 입증할 수 없습니다. 게이트웨이가 관여한다면 해당 동작을 시험하고 복구 원리를 설명할 수 있는 경우에만 클라이언트의 누락 상태를 복구한다고 말해야 합니다.
모델 비용과 접근은 Gemini 3.8 API 안내를 참고하세요. 비슷한 다른 제공업체 오류는 Claude 서명 안내에서 다룹니다. Claude 네이티브 필드를 Gemini 메시지에 그대로 복사할 수는 없습니다.
자주 묻는 질문
병렬 함수 호출마다 서명이 필요한가요?
아닙니다. 문서화된 Gemini 3 병렬 워크플로는 단계의 첫 function-call part에 필수 서명을 둡니다. 반환된 그룹을 그대로 보존하세요.
오류에는 snake_case인데 REST에는 왜 camelCase인가요?
오류 용어와 SDK 속성이 네이티브 REST 필드명과 다를 수 있습니다. 요청을 받는 인터페이스의 스키마를 사용하세요.
제공업체를 바꾸면 해결되나요?
꼭 그렇지는 않습니다. 전송 전에 클라이언트가 필수 상태를 버린다면 목적지만 바꿔도 복구되지 않습니다. 요청 경로부터 확인하세요.
자주 묻는 질문
- 병렬 함수 호출마다 서명이 필요한가요?
- 아닙니다. 문서화된 Gemini 3 병렬 워크플로는 단계의 첫 function-call part에 필수 서명을 둡니다. 반환된 그룹을 그대로 보존하세요.
- 오류에는 snake_case인데 REST에는 왜 camelCase인가요?
- 오류 용어와 SDK 속성이 네이티브 REST 필드명과 다를 수 있습니다. 요청을 받는 인터페이스의 스키마를 사용하세요.
- 제공업체를 바꾸면 해결되나요?
- 꼭 그렇지는 않습니다. 전송 전에 클라이언트가 필수 상태를 버린다면 목적지만 바꿔도 복구되지 않습니다. 요청 경로부터 확인하세요.


