가이드 목록으로
문제 해결·2026년 9월 23일·6분 분량

‘이 모델은 assistant 메시지 프리필을 지원하지 않습니다’ — 어떤 Claude 모델이 프리필을 중단했으며 무엇으로 대체하는가

messages 배열이 assistant 턴으로 끝나면 Claude 4.6 이상 모델은 이를 프리필로 해석하고 거부합니다. 대화를 user 메시지로 끝낸 다음, 프리필이 수행하던 작업(강제 JSON, 프리앰블 생략, 페르소나 유지, 중단된 답변 재개)을 Anthropic이 문서화한 대체 방식으로 옮기세요.

마지막 검토일: .

messages 배열이 assistant 턴으로 끝나면 Claude 4.6 이상 모델은 이를 프리필로 해석하고 거부합니다. 대화를 user 메시지로 끝낸 다음, 프리필이 수행하던 작업(강제 JSON, 프리앰블 생략, 페르소나 유지, 중단된 답변 재개)을 Anthropic이 문서화한 대체 방식으로 옮기세요.

오류

Anthropic API response (HTTP 400)
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "This model does not support assistant message prefill. The conversation must end with a user message."
  },
  "request_id": "req_..."
}

원인과 해결 방법 한눈에 보기

원인해결 방법
messages의 마지막 항목에 role: "assistant"가 있습니다이는 프리필이며 Claude 4.6 이상 모델은 이를 거부합니다. user 메시지로 끝내세요.
프레임워크가 마지막에 빈 assistant 메시지를 남겼습니다전송 전에 내용이 없는 후행 assistant 메시지를 삭제하세요.
JSON을 강제하기 위해 “{”를 프리필했습니다대신 구조화된 출력(output_config.format)을 사용하세요.
프리앰블을 건너뛰거나, 페르소나를 유지하거나, 중단된 답변을 재개하기 위해 프리필했습니다시스템 프롬프트 지시문, 시스템 프롬프트의 역할 설정 또는 user 턴의 연속 요청을 사용하세요.
메모리 관리자, 에이전트 루프 또는 핸드오프가 마지막에 assistant 턴을 남겼습니다모든 코드 경로에서 처리하지 말고 요청 직전에 마지막 부분을 한 번 정규화하세요.

프리필을 거부하는 Claude 모델(2026년 9월 기준)

Anthropic의 오류 참조 문서는 명확합니다. Claude 4.6 이상 모델은 마지막 assistant 메시지의 프리필을 지원하지 않으며, 이를 수행하는 요청은 정확히 이 400 오류를 반환합니다(https://platform.claude.com/docs/en/api/errors#prefill-not-supported). 모델 이름으로는 Claude Opus 4.6 및 이후의 모든 Opus(Claude Opus 5.5 포함)(https://platform.claude.com/docs/en/models/opus-5-5/migration-guide), Claude Sonnet 4.6 및 Claude Sonnet 5(https://platform.claude.com/docs/en/models/sonnet-5/migration-guide), Claude Fable 5 및 Fable 5.1(https://platform.claude.com/docs/en/models/fable-5-1/migration-guide)이 해당합니다. Claude Haiku 4.5와 Claude Sonnet 4.5 및 Claude Opus 4.5는 여전히 프리필을 허용합니다. 따라서 이 오류는 코드 변경보다 모델 ID 변경과 함께 발생하는 경우가 많습니다. 대화 초반의 assistant 메시지와 few-shot 예시는 영향을 받지 않습니다.

user 턴으로 끝내기 — 한 줄 수정 포함

누군가 의도적으로 프리필을 작성한 경우가 아닌 경우가 많습니다. 스택의 어떤 요소가 마지막에 assistant 메시지를 배치한 것입니다. 공개 보고에 따르면 메시리를 추가하는 메모리 관리자(Strands issue #1694), 아직 끝나지 않았다고 잘못 판단한 턴 이후 다시 요청하는 에이전트 루프(opencode issue #46415), 연속 응답 및 에이전트 핸드오프(LiveKit issue #4907), 마지막에 남은 빈 assistant 메시지(AutoGen PR #7931)에서 발생합니다. 후행 메시지가 비어 있다면 삭제하세요 — 이것이 한 줄 수정입니다. 계속 이어가고 싶은 텍스트가 있다면 Anthropic의 마이그레이션 가이드가 안내하는 연속 방식대로, 답변이 중단된 위치를 인용한 연속 요청을 user 메시지에 넣으세요. 그대로 두어야 하는 문서화된 예외가 하나 있습니다. 웹 검색과 같은 서버 도구의 pause_turn은 일시 중지된 assistant 콘텐츠를 그대로 다시 보내 계속합니다(https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools).

end_on_user.py
from openai import OpenAI

client = OpenAI(base_url="https://api.kunavo.com/v1", api_key="sk-kn-...")

def end_on_user(messages: list[dict]) -> list[dict]:
    """Claude 4.6 and later reject a conversation whose last turn is the assistant's."""
    last = messages[-1] if messages else None
    if not last or last["role"] != "assistant" or last.get("tool_calls"):
        return messages               # tool_calls are owed tool results instead
    content = last.get("content")
    if not content or (isinstance(content, str) and not content.strip()):
        return messages[:-1]          # the one line: drop an empty tail
    tail = content[-200:] if isinstance(content, str) else "..."
    return messages + [{
        "role": "user",
        "content": f"Your previous response was interrupted and ended with {tail!r}. "
                   "Continue from where you left off.",
    }]

messages = [
    {"role": "user", "content": "Explain HTTP caching in three bullets."},
    {"role": "assistant", "content": ""},  # the empty tail a framework left behind
]

resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=end_on_user(messages),
)
print(resp.choices[0].message.content)

프리필이 수행하던 작업을 대체하기

Anthropic의 프롬프팅 가이드는 기존의 각 프리필 사용 사례를 대체 방식에 매핑합니다(https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#migrating-away-from-prefilled-responses). JSON 강제: 응답을 스키마에 제한하는 구조화된 출력은 Claude Haiku 4.5, Sonnet 4.5, Opus 4.5 및 이후 모든 모델에서 사용할 수 있습니다(https://platform.claude.com/docs/en/build-with-claude/structured-outputs). YAML 또는 다른 형식의 경우, 가이드에서는 구조를 요청하고 누락되면 재시도하라고 권장합니다. 분류: 유효한 라벨의 enum을 가진 도구 또는 구조화된 출력. 프리앰블 생략: “프리앰블 없이 직접 응답하세요”와 같은 시스템 프롬프트 지시문. 페르소나 유지: 시스템 프롬프트에서 역할을 설정하고(https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#give-claude-a-role), 프리필된 assistant 메시지 대신 user 턴에 주기적인 알림을 넣으세요. 중단된 답변: 위의 user 턴 연속 방식. 도구 호출 강제는 모든 곳에서 바로 대체할 수 있는 방법이 아닙니다 — Claude Fable 5.1 및 Claude Opus 5.5는 tool_choice any와 tool을 거부하며 자체적인 400 오류를 반환합니다(https://platform.claude.com/docs/en/api/errors#forced-tool-use-not-supported).

structured-output.sh
# Before: messages ended with {"role": "assistant", "content": "{"}
# Kunavo forwards output_config as sent; the reply is constrained to the schema.
curl https://api.kunavo.com/v1/messages \
  -H "x-api-key: sk-kn-..." \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Extract the name and email: John Smith <john@example.com>"}
    ],
    "output_config": {
      "format": {
        "type": "json_schema",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "email": {"type": "string"}
          },
          "required": ["name", "email"],
          "additionalProperties": false
        }
      }
    }
  }'

Kunavo를 통해 호출하는 경우

Kunavo는 후행 assistant 턴을 전달할 뿐 수정하지 않습니다. /v1/messages는 사용자의 messages 배열을 변경 없이 업스트림에 전달하고, /v1/chat/completions에서는 변환기가 최종 role: "assistant" 메시지를 Claude 요청의 최종 assistant 턴으로 전달합니다 — 빈 메시지도 포함되므로 직접 삭제해야 합니다. Anthropic은 claude-haiku-4-5를 제외한 우리가 제공하는 모든 claude-* 모델에서 프리필된 최종 턴을 거부합니다. 해당 400 오류는 메시지 텍스트가 그대로 유지된 채 업스트림의 request id와 함께 전달됩니다. /v1/messages에서는 Anthropic 형식으로, Anthropic API와 동일하게 invalid_request_error 유형으로(2026년 9월 24일까지는 api_error였음), /v1/chat/completions에서는 OpenAI 형식으로(type upstream_error, code upstream_400) 전달됩니다. 400 오류는 다른 채널에서 절대 재시도되지 않으며, 실패한 호출은 비용 0으로 기록됩니다. JSON의 경우 프리필 대신 스키마를 보내세요. /v1/messages는 전송한 output_config를 그대로 전달하고, /v1/chat/completions에서는 type json_schema인 response_format을 output_config.format으로 변환합니다. 2026-09-24에는 이 필드가 우리가 제공하는 모든 claude-* 모델에서 응답을 스키마에 제한했습니다. json_object response_format에는 Claude 대응 항목이 없으므로 강제되지 않으며, 최종 턴 프리필과 함께 스키마를 보내면 claude-haiku-4-5를 포함해 자체적으로 400 오류가 발생합니다: “When using output format, pre-filling the `assistant` response is not supported.” 네이티브 엔드포인트와 이를 통과하는 요청 형식은 다음에 문서화되어 있습니다 Messages API 문서.

자주 묻는 질문

어떤 Claude 모델이 assistant 메시지 프리필을 지원하지 않나요?

2026년 9월 기준 Anthropic 문서에 따르면 4.6부터의 모든 Claude 모델입니다. Claude Opus 4.6 및 이후의 모든 Opus, Claude Sonnet 4.6 및 Sonnet 5, Claude Fable 5 및 5.1, Mythos 모델이 해당합니다. Claude Haiku 4.5, Sonnet 4.5 및 Opus 4.5는 여전히 프리필을 허용합니다.

프리필 없이 Claude의 JSON 출력을 강제하려면 어떻게 하나요?

구조화된 출력을 사용하세요. output_config.format에 JSON 스키마를 전달하면 응답이 해당 스키마로 제한됩니다. OpenAI 호환 엔드포인트를 통해서는 type json_schema인 response_format으로 보내세요. Kunavo가 이를 output_config.format으로 변환합니다. Anthropic은 어떤 경우에도 메시지 프리필이 JSON 출력과 호환되지 않는다고 명시합니다.

아무것도 프리필하지 않았는데 왜 이 오류가 발생하나요?

스택의 어떤 요소가 assistant 메시지를 마지막에 남긴 것입니다. 메모리 또는 세션 관리자, 턴 이후 다시 요청하는 에이전트 루프, 에이전트 핸드오프, 또는 아무도 제거하지 않은 빈 assistant 메시지일 수 있습니다. 전송되는 messages 배열을 있는 그대로 기록하세요. 마지막 요소의 role은 "assistant"일 것입니다.

대화에 assistant 메시지를 계속 포함할 수 있나요?

예. 최종 턴만 제한되며, few-shot 예시를 포함한 이전 assistant 메시지는 영향을 받지 않습니다.

OpenAI 호환 엔드포인트를 통해서도 왜 발생하나요?

게이트웨이가 사용자의 최종 role: "assistant" 메시지를 최종 Claude assistant 턴으로 전달하기 때문입니다. 형태만 바뀐 동일한 프리필입니다. Kunavo의 채팅 변환기가 정확히 그렇게 처리하며, 다른 OpenAI 호환 게이트웨이를 통해서도 동일한 메시지가 보고되었습니다(opencode issue #13768). 수정 방법도 같습니다. user 메시지로 끝내세요.

관련 가이드

오류 의미에 대한 자세한 내용은 오류 참조에서 확인할 수 있습니다. 가입 및 인증 가이드를 통해 1분이면 키를 받을 수 있습니다.