# 제미나이 "Requests ending with a model turn" 400 오류 원인과 해결

> Gemini 3.6 Flash 이후 모델과 Gemini 4 Argon은 마지막 턴이 model인 요청에 400을 돌려줍니다. 마지막을 user 턴으로 바꾸면 풀리고, 재시도로는 풀리지 않습니다.

- URL: https://blog.laozhang.ai/ko/posts/gemini-requests-ending-with-model-turn-not-supported
- Published: 2026-10-29
- Updated: 2026-10-29
- Author: LaoZhang AI Team (https://blog.laozhang.ai/ko/about)
- Topic: API 가이드
- Tags: 제미나이 API, Gemini 4 Argon, 400 오류, countTokens, Gemini CLI, SillyTavern

---
제미나이 API가 `400 INVALID_ARGUMENT`와 함께 `Requests ending with a model turn are not supported.`를 돌려줬다면, 보낸 요청의 `contents`에서 마지막으로 남은 비어 있지 않은 턴의 role이 `model`이라는 뜻입니다. model 턴은 모델이 쓴 응답 자리의 메시지로, OpenAI 형식의 `assistant` 메시지에 해당합니다. Google은 [Gemini 3.6 변경 사항 문서](https://ai.google.dev/gemini-api/docs/whats-new-gemini-3.6)에서 Gemini 3.6 Flash와 Gemini 3.5 Flash-Lite부터 이후 출시되는 모든 모델이 이런 요청을 거부한다고 밝혔고, 2026년 10월 29일 기준 Gemini 3.7·3.8 Flash와 Gemini 4 Argon도 이 범위에 들어갑니다. 3.5 Flash에서 되던 요청이 모델만 바꾸자 400이 되는 이유가 이것입니다.

고칠 대상은 요청의 마지막 턴입니다. 응답 앞부분을 미리 채워 둔 model 턴(프리필)은 지우고 그 지시를 `systemInstruction`이나 JSON schema 기반 구조화된 출력으로 옮깁니다. 저장된 모델 응답에서 멈춘 대화 기록이라면 새 user 턴을 붙여 보내고, 도구 호출 흐름이라면 모델의 `functionCall` 다음에 `functionResponse`를 담은 user 턴이 오게 합니다. 요청 형태가 원인이기 때문에 같은 요청을 다시 보내면 같은 400이 나옵니다. SillyTavern 같은 롤플레이 앱이나 Gemini CLI, opencode가 요청을 대신 만든다면 프리필·이어쓰기 설정을 끄거나 도구를 업데이트하는 쪽이 해결책입니다.

화면의 마지막 메시지가 내 입력이라고 해서 실제로 전송된 요청이 user 턴으로 끝난다는 보장은 없습니다. 2026년 10월 29일 한 API 중계 서비스를 거쳐 `gemini-4-argon`에 보낸 요청에서도, 모델 응답으로 끝나는 대화 기록은 400을 받았고 같은 기록에 user 턴 하나를 더하자 200이 왔습니다. 오류 문장 뒤에 `unless the last part is a function response`가 붙은 변형도 같은 규칙에서 나온 메시지입니다.

## model 턴으로 끝나는 요청을 거부하는 모델과 오류 문장 변형

Google 문서의 기준은 한 줄입니다. 요청에서 마지막으로 비어 있지 않은 턴이 model 턴이면 API가 400을 돌려줍니다. 문서가 직접 든 예시는 `user`로 번역을 요청한 뒤 `model` 턴에 `Translation:`을 미리 넣어 둔 요청으로, 응답 형식을 강제하려고 흔히 쓰던 프리필이 정확히 이 형태입니다. 이 규칙은 2026년 10월 13일에 마지막으로 갱신된 Gemini 3.6 변경 사항 문서의 "API 변경 사항" 절에 있고, 같은 절에서 `temperature`·`top_p`·`top_k` 폐지도 함께 안내합니다.

Gemini 4 Argon만의 문제는 아닙니다. Argon 전용 안내인 [Gemini 4 Argon 변경 사항 페이지](https://ai.google.dev/gemini-api/docs/generate-content/latest-model)에는 프리필 이야기가 없지만, 3.6 문서가 "이후 모든 Gemini 모델"에 적용된다고 적었으므로 Argon도 같은 규칙을 따릅니다. 반대로 3.5 Flash는 이 규칙 밖입니다. 2026년 7월 22일 LINUX DO의 한 사용자는 같은 기능이 3.5 Flash에서는 아직 되고 3.6 Flash에서 막혔다고 보고했고, arca.live AI 채팅 채널에도 같은 날 "잼삼육(Gemini 3.6 Flash)으로 쓰는데 삼오에선 안 뜨던 게 뜸"이라는 글이 올라왔습니다. 3.5 Flash보다 더 오래된 모델에서도 거부된다는 근거는 없습니다.

오류 문장은 경로에 따라 조금씩 다르게 보이지만 뜻은 같습니다.

| 화면에 보이는 문장 | 주로 보이는 곳 |
|---|---|
| `Requests ending with a model turn are not supported.` + `"status":"INVALID_ARGUMENT"` | 제미나이 API·Vertex AI를 SDK나 REST로 직접 호출할 때, 대부분의 GitHub 이슈 |
| `Requests ending with a model turn are not supported unless the last part is a function response.` | Google AI Studio 키를 쓰는 프록시와 롤플레이 앱, Google Issue Tracker 537423583 |
| `[original: beyond::dependency::INVALID_ARGUMENT] Requests ending with a model turn …` | AI Studio 내부 오류 형식이 그대로 전달될 때 |
| `PROXY ERROR 400: {...}`, OpenRouter의 `Provider returned error` | 중간 서비스가 Google 응답을 감쌀 때. OpenRouter는 원문을 `error.metadata.raw`에 넣습니다 |

## 내 경우는 어느 쪽인가: 계기별 증상과 해결

어느 경우인지는 전송 직전에 직렬화된 `contents`(OpenAI 형식이면 변환을 마친 `messages`)의 마지막 원소를 보면 가릴 수 있습니다. 증상이 첫 요청부터인지, 몇 턴 뒤나 도구 실행 직후부터인지가 단서가 됩니다. 아래 표의 계기는 Google 문서와 2026년 7~10월 GitHub·커뮤니티 보고에서 실제로 확인된 것들입니다.

![프리필, 저장된 모델 응답, 결과 없는 functionCall, 이미지가 든 도구 결과가 각각 contents 끝에 남기는 턴과 해결 방법](https://blog.laozhang.ai/posts/ko/gemini-requests-ending-with-model-turn-not-supported/img/model-turn-triggers.webp)

| 계기 | 이런 증상 | 해결 |
|---|---|---|
| 프리필: model 턴에 응답 앞부분이나 도구 사용을 미리 넣음 | 모델을 바꾼 뒤 첫 요청부터 매번 400 | model 턴을 지우고 지시는 `systemInstruction`이나 JSON schema로 |
| 이어쓰기·응답 시작 문구 같은 앱 설정 | 특정 프리셋이나 "이어서" 동작에서만 400 | 해당 설정을 끄고 새 채팅에서 user 메시지로 끝나는지 확인 |
| 응답을 저장한 직후의 기록을 그대로 다시 보냄(되감기, 중단, 끼어들기 뒤) | 몇 턴 뒤부터 400, 새 메시지를 입력하면 풀림 | 끝에 남은 model 턴을 정리하거나 새 user 턴을 붙여 전송 |
| 도구가 기록 끝에 assistant 메시지를 덧붙임 | 에이전트가 단계 한도 근처에서 멈춤 | 도구 업데이트, 그 문구는 시스템 프롬프트나 user 턴으로 |
| 모델의 `functionCall`이 마지막이고 결과가 아직 없음 | 도구 실행 전에 다음 요청이 나감 | `functionResponse`를 담은 user 턴을 붙인 뒤 전송 |
| 한 user 턴에서 `functionResponse` 뒤에 텍스트를 붙임(Vertex AI 보고) | 도구 결과 직후 사용자 메시지에서만 400 | `functionResponse`를 턴의 마지막에 두거나 텍스트를 별도 user 턴으로 |
| 도구 결과에 이미지가 들어감 | 이미지 파일을 읽은 직후 단계마다 400, 텍스트 결과는 정상 | 도구 결과는 텍스트로, 이미지는 다음 user 메시지로 |
| model로 끝나는 기록에 `countTokens` 호출 | 답변은 오는데 토큰 수 표시가 0이거나 오류 로그 | 마지막 user 턴까지만 세거나 `usageMetadata` 사용 |

`functionCall`이 든 model 턴을 기록에 다시 넣을 때는 모델이 돌려준 내용을 그대로 보내야 합니다. Google은 Argon 문서에서 여러 턴과 함수 호출 요청에 사고 서명(thought signature)까지 포함한 전체 기록을 넘기라고 안내하는데, 이 서명을 지우거나 직접 만들어 넣으면 `Function call is missing a thought_signature` 같은 다른 400으로 바뀔 뿐입니다. 대화 기록 순서가 뒤섞이는 버그도 같은 오류를 냅니다. Kilo Code와 opencode에서는 시계가 뒤로 가면서 단계 저장 순서가 틀어져 model 턴이 마지막에 남은 사례가 2026년 10월 14일 보고됐습니다.

## gemini-4-argon 요청 형태별 결과: 2026년 10월 29일 테스트

2026년 10월 29일 03:00~03:05(UTC)에 laozhang.ai의 제미나이 네이티브 `generateContent` 경로로 `gemini-4-argon`에 요청을 보내, 마지막 턴만 바꾸면 결과가 어떻게 달라지는지 확인했습니다. SDK 없이 REST로 보냈고 `thinkingLevel`은 `low`로 고정했으며, 한 요청에서 변수 하나만 바꿨습니다. 200은 응답의 `modelVersion`이 `gemini-4-argon`인 경우만 결과로 셌습니다.

*안내: [laozhang.ai는 이 블로그 운영팀의 자사 서비스입니다](https://blog.laozhang.ai/ko/about#laozhang). 그 가격은 독립적인 비교가 아니라 자사 제시 가격입니다.*

| 보낸 `contents` (오른쪽 끝이 마지막 턴) | 결과 |
|---|---|
| `[user]` | 200 |
| `[user, model "Rain"]` 프리필 | 400 `Requests ending with a model turn are not supported.` (03:13에 다시 보내도 같음) |
| `[user, model, user, model]` 응답을 저장한 직후의 기록 | 400 (같은 문장) |
| 위 기록에서 마지막 model 턴을 빼고 새 user 턴으로 끝낸 `[user, model, user]` | 200 |
| `[user]` + 도구 선언 | 200, `functionCall` 반환 |
| `[user, model(functionCall)]` 도구 결과 없음 | 400 (같은 문장) |
| `[user, model(functionCall), user(functionResponse)]` | 200 |
| `[user, model(functionCall), user(functionResponse, 텍스트)]` | 200 |

같은 대화 기록이 마지막 model 턴 하나 때문에 400과 200으로 갈린다는 점이 핵심입니다. 마지막 행은 경로에 따라 결과가 다릅니다. 이 경로에서는 `functionResponse` 뒤에 텍스트를 붙인 user 턴이 200이었지만, 2026년 10월 18일 Vertex AI에서 Argon을 시험한 [senpi 이슈 #3633](https://github.com/code-yeongyu/senpi/issues/3633)에서는 같은 형태가 400이었습니다. 어느 한쪽 결과를 모든 경로에 적용할 수는 없고, 두 곳 모두에서 200이었던 형태는 `functionResponse`만 담은 user 턴입니다.

표본은 작습니다. 경로 한 곳에서 하루 동안 형태마다 한 번씩(프리필은 두 번) 보낸 결과입니다. 400 응답에는 `modelVersion`이 없어서 Argon의 거부라고 보는 근거는 요청한 모델 ID와 Google 문서의 규칙입니다. 오류 본문 형식도 경로를 따라 바뀌어, 이 경로는 `{"error":{"message":"…","type":"upstream_error","code":400}}`로 감싸 보냈고 Google 원래 응답에는 `"status":"INVALID_ARGUMENT"`가 들어갑니다. 아래에서 다루는 프리필 대체 방법(`systemInstruction`, JSON schema)과 `[텍스트, functionResponse]` 순서, 텍스트를 별도 user 턴으로 나누는 방법은 이 표에 없으며 Google 문서와 Vertex AI 사용자 보고를 근거로 합니다.

## 코드에서 고치는 방법: 마지막 턴을 user로 끝내기

수정은 전송 직전의 요청을 기록하는 데서 시작합니다. SDK나 프레임워크가 OpenAI 형식 메시지를 제미나이 형식으로 바꿔 보낸다면, 내 코드의 `messages`가 아니라 변환된 `contents`의 마지막 턴을 봐야 합니다. 마지막이 `model`이면 아래 네 가지 중 해당하는 방법으로 바꿉니다.

### 프리필은 systemInstruction이나 JSON schema로 옮기기

Google은 서두 문장을 없애거나 JSON 형식을 강제하려고 model 턴을 프리필하던 앱이라면 시스템 지시(`system_instruction`)나 구조화된 출력을 대신 쓰라고 권합니다. 막히는 요청과 바꾼 요청은 다음과 같습니다.

```json
{
  "contents": [
    { "role": "user", "parts": [{ "text": "Write one short sentence about rain." }] },
    { "role": "model", "parts": [{ "text": "Rain" }] }
  ]
}
```

```json
{
  "systemInstruction": { "parts": [{ "text": "Begin every answer with the word 'Rain'." }] },
  "contents": [
    { "role": "user", "parts": [{ "text": "Write one short sentence about rain." }] }
  ]
}
```

형식이 반드시 맞아야 한다면 지시문보다 JSON schema가 맞습니다. [제미나이 API 구조화된 출력 가이드](https://ai.google.dev/gemini-api/docs/generate-content/structured-output)대로 `generationConfig`에 MIME 타입과 스키마를 넣으면 요청은 user 턴으로 끝나고, 출력은 지정한 구조를 따릅니다.

```json
{
  "contents": [
    { "role": "user", "parts": [{ "text": "Give a city name and its country." }] }
  ],
  "generationConfig": {
    "responseMimeType": "application/json",
    "responseJsonSchema": {
      "type": "object",
      "properties": { "city": { "type": "string" }, "country": { "type": "string" } },
      "required": ["city", "country"]
    }
  }
}
```

### 대화 기록이 저장된 모델 응답으로 끝날 때

응답이 끝나자마자 기록을 저장하는 앱은 다음 요청에서 그 기록을 그대로 보내기 쉽습니다. 되감기, 스트림 중단, 음성 에이전트의 끼어들기 뒤에도 잘린 model 턴이 기록 끝에 남습니다. 사용자가 새 메시지를 보낼 때 그 메시지를 user 턴으로 붙여 전송하고, 이어쓰기가 목적이라면 그 지시도 user 턴으로 보냅니다.

```python
def ensure_user_last(contents, follow_up="이어서 계속 써 주세요."):
    # 마지막 턴이 model이면 새 user 턴을 붙여 보냅니다
    if contents and contents[-1]["role"] == "model":
        contents = contents + [{"role": "user", "parts": [{"text": follow_up}]}]
    return contents
```

Gemini 4 Argon에서 긴 답이 잘려 이어 받으려고 프리필을 쓰던 경우라면, Argon은 프리필 대신 `finishReason: CONTINUATION`과 토큰으로 이어 줍니다. 그 방법은 [Gemini 4 Argon API finish_reason: CONTINUATION·빈 응답 대처](https://blog.laozhang.ai/ko/posts/gemini-4-argon-api-finish-reason)에 정리돼 있습니다.

### 도구 호출 흐름: functionCall 다음에는 functionResponse

모델이 `functionCall`을 돌려주면 그 model 턴을 받은 그대로 기록에 넣고, 바로 뒤에 `functionResponse`를 담은 user 턴을 붙인 뒤에 다음 요청을 보냅니다. `thoughtSignature`는 모델이 준 값을 바꾸지 않습니다.

```json
{
  "contents": [
    { "role": "user", "parts": [{ "text": "What is the temperature in Paris right now? Use the tool." }] },
    { "role": "model", "parts": [{
      "thoughtSignature": "모델이 돌려준 값 그대로",
      "functionCall": { "name": "get_weather", "args": { "city": "Paris" }, "id": "call_74181" }
    }] },
    { "role": "user", "parts": [{
      "functionResponse": { "name": "get_weather", "response": { "temperature_c": 14 }, "id": "call_74181" }
    }] }
  ]
}
```

Vertex AI에서는 한 user 턴 안에서 `functionResponse` 뒤에 사용자 텍스트가 오는 형태가 막힙니다. [senpi 이슈 #3633](https://github.com/code-yeongyu/senpi/issues/3633)의 2026년 10월 18일 측정에서는 `[functionResponse]`와 `[텍스트, functionResponse]`가 200, `[functionResponse, 텍스트]`만 400이었습니다. 10월 28일 재현(Argon, LiteLLM 1.101.0 경유 Google Cloud Express)에서도 `functionResponse` 뒤에 텍스트가 오는 user 턴은 400, 뒤의 텍스트만 빼면 200, 둘을 별도 user 턴으로 나누면 200이었습니다. 같은 패턴이 [langchain-google 이슈 #1995](https://github.com/langchain-ai/langchain-google/issues/1995)와 [CC Switch 이슈 #8988](https://github.com/farion1231/cc-switch/issues/8988), [9router 이슈 #4802](https://github.com/decolua/9router/issues/4802)에서도 보고됐고, epam의 Vertex 어댑터는 10월 28일 텍스트를 함수 응답 안으로 넣는 방식으로 고쳤습니다.

도구 결과에 이미지가 들어갈 때도 같은 오류가 납니다. OpenRouter의 `google/gemini-4-argon`을 쓴 [Hermes Agent 이슈 #139313](https://github.com/NousResearch/hermes-agent/issues/139313)에서는 텍스트와 이미지가 함께 든 도구 결과가 마지막이면 400, 텍스트만 든 도구 결과는 200이었고, 도구 결과는 텍스트로 두고 이미지를 다음 user 메시지에 실으면 200이었습니다.

![functionCall 다음 functionResponse 턴을 두는 기본 순서, Vertex AI에서 텍스트를 별도 user 턴으로 나누는 방법, 이미지를 다음 user 메시지로 옮기는 방법](https://blog.laozhang.ai/posts/ko/gemini-requests-ending-with-model-turn-not-supported/img/tool-call-turn-order.webp)

이 400은 재시도 목록에서 빼야 합니다. [제미나이 API 문제 해결 문서](https://ai.google.dev/gemini-api/docs/troubleshooting)는 429·408·5xx 같은 일시적 오류만 재시도하고 400 같은 클라이언트 오류는 재시도하지 말라고 하며, senpi 메인테이너도 2026년 10월 20일 이 오류를 쿨다운이나 다른 모델로의 전환 계기가 아닌 요청 오류로 분류해야 한다고 적었습니다. [LiveKit Agents 이슈 #2108](https://github.com/livekit/agents-js/issues/2108)에서는 끼어들기 뒤의 400을 반복 재시도하다 음성 에이전트가 말을 멈췄습니다.

## Gemini 4 Argon에서 countTokens가 400을 돌려줄 때

`countTokens`의 400도 같은 규칙으로 보는 보고가 있습니다. Obsidian 플러그인 Gemini Scribe의 메인테이너 allenhutchison은 2026년 10월 27일 [obsidian-gemini 이슈 #1708](https://github.com/allenhutchison/obsidian-gemini/issues/1708)에, 채팅 모델을 `gemini-4-argon`으로 두자 새 세션 첫 턴에서 `models.countTokens`가 `Requests ending wi…are not supported.`라는 잘린 메시지와 함께 400을 냈고, 같은 흐름이 `gemini-flash-latest`에서는 실패하지 않았다고 적었습니다. 보고자가 검증 전이라고 밝힌 가설은 응답을 저장한 직후의 세션 기록이 model 턴으로 끝나고, Argon이 그런 `contents`의 `countTokens`를 거부한다는 것입니다. 2026년 10월 29일 기준 이슈는 열려 있으며, 위 `generateContent` 테스트 결과는 이 가설과 일치하지만 증명은 아닙니다.

이 보고에서 오류는 앱을 멈추지 않았습니다. 대신 직전 응답의 `promptTokenCount`로 대체하는데, 새 세션에는 그 값이 없어 토큰 표시와 컨텍스트 압축 기준이 0으로 계산됐습니다. 보고자가 제안한 수정은 마지막 user 턴까지만 세거나 user 턴을 붙여 세는 것입니다.

```python
from google import genai

client = genai.Client()

def count_until_last_user(contents, model="gemini-4-argon"):
    # 마지막 user 턴까지만 잘라서 셉니다
    last_user = max(i for i, t in enumerate(contents) if t["role"] == "user")
    result = client.models.count_tokens(model=model, contents=contents[: last_user + 1])
    return result.total_tokens
```

호출 수 걱정은 크지 않습니다. 2026년 10월 27일 갱신된 [Firebase AI Logic 토큰 계산 문서](https://firebase.google.com/docs/ai-logic/count-tokens)에 따르면 `countTokens`는 무료이고 한도는 분당 3,000회이며, 지원 모델 목록 첫 줄이 `gemini-4-argon`입니다. 입력 토큰 수에는 시스템 지시와 도구 선언도 들어갑니다. 생성 요청을 이미 보냈다면 응답의 `usageMetadata.promptTokenCount`가 그 요청의 입력 토큰 수를 추가 비용 없이 알려 줍니다.

중계 서비스를 거친다면 오류 문장부터 확인합니다. 2026년 10월 29일 위 테스트 경로의 `:countTokens`는 마지막 턴이 user든 model이든 `400 {"error":{"message":"unsupported action: countTokens","type":"invalid_request_error"}}`를 돌려줬습니다. 중계 서비스가 이 기능을 넘겨주지 않아서 생긴 400이라 model 턴 문제와는 고치는 곳이 다릅니다.

## SillyTavern·Gemini CLI·opencode에서 뜰 때: 도구별 상태

롤플레이 앱에서는 요청을 내가 직접 조립하지 않기 때문에 프리셋과 앱 설정을 먼저 봐야 합니다. arca.live AI 채팅 채널에는 2026년 7월 21일 "컵케익에 ai studio쓰는데 삼육플하니까 이렇게 뜸[Gemini Error 400]", 8월 14일 포켓리스에서 3.7 Flash(잼삼칠플) 모델 프리셋을 설정하다 이 오류를 물어본 글이 올라왔습니다. 어시스턴트 프리필, 이어쓰기, 응답 시작 문구처럼 모델 자리에 텍스트를 넣는 설정이 켜져 있으면 화면에는 내 메시지가 마지막이어도 전송된 요청은 model 턴으로 끝날 수 있습니다. 새 채팅을 열어 실제 user 메시지로 끝나는 짧은 요청이 되는지 보고, 그런 설정을 하나씩 다시 켜면서 어느 것이 400을 만드는지 찾습니다. r/SillyTavernAI에도 프롬프트 끝의 model 턴을 지우자 3.6 Flash에서 오류가 사라졌다는 답이 있습니다.

개발 도구와 라이브러리는 2026년 10월 29일 기준 상태가 저마다 다릅니다.

| 도구 | 보고된 계기 | 2026년 10월 29일 기준 상태와 대처 |
|---|---|---|
| SillyTavern 등 롤플레이 앱 (AI Studio 키·프록시) | 프리셋의 프리필·이어쓰기, 프롬프트 후처리 | 앱 설정 문제. 해당 설정을 끄고 새 채팅에서 확인 |
| Gemini CLI | `/rewind`나 중단된 스트림 뒤([#29530](https://github.com/google-gemini/gemini-cli/issues/29530)), png를 `ReadFile`로 읽은 뒤([#29574](https://github.com/google-gemini/gemini-cli/issues/29574)), 빠른 Ctrl-C(#29588) | 수정 PR #29612(10월 7일)와 #29728(10월 13일)이 10월 20일 공개된 v0.65.0에 들어감. v0.65.0 이상으로 업데이트 |
| opencode | 단계 한도 문구 `MAX_STEPS_PROMPT`를 assistant 메시지로 덧붙임(#45359, `steps`를 설정한 서브에이전트), OpenRouter에서 png를 읽은 뒤(#55694) | 수정 버전 미확인, 미해결. 새 프롬프트를 입력하면 세션이 이어짐 |
| Zoo Code·Kilo Code | Zoo Code 3.72.0 Vertex AI 공급자가 도구 사용 프리필 model 턴을 넣음([#1052](https://github.com/Zoo-Code-Org/Zoo-Code/issues/1052)), Kilo Code 단계 저장 순서 오류([#15073](https://github.com/Kilo-Org/kilocode/issues/15073)) | 미해결 |
| LangChain (`langchain-google-vertexai`) | 도구 결과와 다음 사람 메시지를 한 user 턴으로 합침(#1995) | 미해결 |
| LiteLLM | Vertex AI Gemini 3.7 Flash에서 텍스트만 있는 assistant 메시지로 끝나는 기록([#38537](https://github.com/BerriAI/litellm/issues/38537)) | 미해결. 호출 전에 `messages` 끝을 user로 |
| OpenRouter 기반 에이전트 (Hermes 등) | 이미지가 든 도구 결과가 마지막(#139313) | 미해결. 원문은 `error.metadata.raw`, 이미지는 다음 user 메시지로 |
| instructor | 구조화된 출력의 재요청(reask)이 model 턴으로 끝남([#2631](https://github.com/567-labs/instructor/issues/2631)) | 미해결 |

Gemini CLI의 v0.65.0은 GitHub에서 두 수정 커밋이 그 태그에 포함된 것을 근거로 한 판단이라, v0.64.x에 따로 반영됐는지는 알 수 없습니다. npm으로 설치했다면 업데이트 방법은 [Gemini CLI 설치 방법: 2026년 전체 플랫폼 설정과 개인 로그인 종료](https://blog.laozhang.ai/ko/posts/gemini-cli-install)를 참고하세요. opencode 메인테이너는 해당 문구를 시스템 프롬프트로 옮기겠다고 답했지만 9월 15일 1.18.31에서도 재현됐다는 댓글이 달렸고, 10월 14일의 후속 PR은 병합 여부가 공개되지 않았습니다.

## model 턴 400 오류에 관한 다른 질문

### "role system is not supported" 오류와 같은 건가요?

다릅니다. 그 오류는 모델이 `system` 역할 메시지 자체를 받지 않을 때 나오며, 대처는 [시스템 지시를 깨지 않고 API 400 role 미지원 오류를 고치는 방법](https://blog.laozhang.ai/ko/posts/api-400-role-system-is-not-supported-on-this-model)에서 다룹니다.

### Gemini 3.5 Flash로 돌아가면 프리필을 계속 쓸 수 있나요?

2026년 7월 22일 LINUX DO 보고에서는 3.5 Flash에서 프리필이 아직 됐습니다. 다만 Google은 3.6 Flash 이후 출시되는 모든 모델에 이 규칙을 적용한다고 했으므로, 모델을 되돌리는 것은 프리필을 `systemInstruction`이나 JSON schema로 옮기기 전까지의 임시 방편입니다.

### 같은 Gemini 4 Argon 요청에서 다른 400이 나오면?

문장이 다르면 원인도 다릅니다. `Function call is missing a thought_signature`는 `functionCall` 턴의 사고 서명이 빠졌다는 뜻이고, Google의 Argon 변경 사항 페이지는 명시적 캐싱(`cachedContents`)이 Argon에서 지원되지 않아 오류를 낸다고 적고 있습니다. Vertex AI에서 Argon에 대해 보고된 "Thinking budget is not supported" 400도 별개의 오류입니다.

## 참고 자료

이 글이 링크한 외부 페이지를 본문에 나온 순서대로 정리했습니다. 마지막 업데이트: 2026-10-29.

- [Gemini 3.6 변경 사항 문서](https://ai.google.dev/gemini-api/docs/whats-new-gemini-3.6) (ai.google.dev)
- [Gemini 4 Argon 변경 사항 페이지](https://ai.google.dev/gemini-api/docs/generate-content/latest-model) (ai.google.dev)
- [senpi 이슈 #3633](https://github.com/code-yeongyu/senpi/issues/3633) (github.com)
- [제미나이 API 구조화된 출력 가이드](https://ai.google.dev/gemini-api/docs/generate-content/structured-output) (ai.google.dev)
- [langchain-google 이슈 #1995](https://github.com/langchain-ai/langchain-google/issues/1995) (github.com)
- [CC Switch 이슈 #8988](https://github.com/farion1231/cc-switch/issues/8988) (github.com)
- [9router 이슈 #4802](https://github.com/decolua/9router/issues/4802) (github.com)
- [Hermes Agent 이슈 #139313](https://github.com/NousResearch/hermes-agent/issues/139313) (github.com)
- [제미나이 API 문제 해결 문서](https://ai.google.dev/gemini-api/docs/troubleshooting) (ai.google.dev)
- [LiveKit Agents 이슈 #2108](https://github.com/livekit/agents-js/issues/2108) (github.com)
- [obsidian-gemini 이슈 #1708](https://github.com/allenhutchison/obsidian-gemini/issues/1708) (github.com)
- [Firebase AI Logic 토큰 계산 문서](https://firebase.google.com/docs/ai-logic/count-tokens) (firebase.google.com)
- [#29530](https://github.com/google-gemini/gemini-cli/issues/29530) (github.com)
- [#29574](https://github.com/google-gemini/gemini-cli/issues/29574) (github.com)
- [#1052](https://github.com/Zoo-Code-Org/Zoo-Code/issues/1052) (github.com)
- [#15073](https://github.com/Kilo-Org/kilocode/issues/15073) (github.com)
- [#38537](https://github.com/BerriAI/litellm/issues/38537) (github.com)
- [#2631](https://github.com/567-labs/instructor/issues/2631) (github.com)
