Anthropic API 2026-10-21: temperature는 1.0도 400 반환
목차
API 버전 2026-10-21로 Claude 요청을 보내면 temperature, top_p, top_k를 지정한 요청은 HTTP 400을 반환한다. 기본값도 예외가 아니다. temperature: 1.0도 “temperature: Extra inputs are not permitted” 오류로 실패한다. 이 샘플링 파라미터들은 모델이 다음 token을 선택할 때 무작위성을 얼마나 허용할지 제어한다. API 버전은 anthropic-version 요청 헤더로 지정하며, Messages API가 요청을 검증하고 응답하는 방식을 결정한다. 기존 값은 2023-06-01이다. Anthropic이 10월 21일 함께 출시한 SDK 메이저 버전들(Python 2.0.0, TypeScript 1.0.0 외 5개)은 새 버전을 기본으로 보낸다. 이 SDK들에서는 샘플링 파라미터 자체가 없어졌다. 따라서 400 오류는 HTTP 클라이언트로 직접 요청하거나 추가 본문 필드를 넣는 등 요청 본문을 직접 구성하는 코드에서 발생한다. Claude Sonnet 4.6과 Claude Sonnet 5.5에서 두 API 버전으로 각각 8가지 요청 형태를 테스트했다. Python SDK 두 버전의 동작도 비교하고, Synthorai를 통해 같은 테스트를 반복했다.
TL;DR
2026-10-21에서는 Claude Sonnet 4.6과 Sonnet 5.5 모두temperature,top_p,top_k에 400을 반환한다.temperature: 1.0도 마찬가지다.2026-10-21은 assistant 메시지의document블록과 user 텍스트 블록의citations도 거부한다.- Anthropic Python SDK 2.x는 키를
Authorization: Bearer로 보낸다. 두 헤더가 모두 있으면 API는x-api-key를 사용한다. - Synthorai에서는 어느 SDK를 쓰든 32개 요청이 모두 200을 반환했다. Anthropic API가
2026-10-21에서 거부하는 12개 요청도 포함된다.
API 버전 2026-10-21에서 어떤 요청이 400을 반환하나?
400 오류를 일으키는 변경 사항은 다섯 가지다. 샘플링 파라미터 3개, assistant 메시지에 직접 넣은 document 블록, user 메시지의 텍스트 블록에 붙인 citations다. citations는 텍스트 블록에서 문서의 특정 구절을 가리키는 참조다. 아래 표는 실패하는 6개 케이스와 여전히 성공하는 2개 케이스를 검증한 결과다. 각 케이스를 모델별, 버전별로 한 번씩 Anthropic API에 직접 보냈다. 200은 요청 수락, 400은 invalid_request_error로 요청 거부를 뜻한다.
| 요청 | Sonnet 4.6, 2023-06-01 | Sonnet 4.6, 2026-10-21 | Sonnet 5.5, 2023-06-01 | Sonnet 5.5, 2026-10-21 |
|---|---|---|---|---|
| 샘플링 파라미터 없음 | 200 | 200 | 200 | 200 |
temperature: 1.0 (기본값) | 200 | 400 | 200 | 400 |
temperature: 0.2 | 200 | 400 | 400 | 400 |
top_p: 0.9 | 200 | 400 | 400 | 400 |
top_k: 40 | 200 | 400 | 400 | 400 |
assistant 메시지의 document 블록 | 200 | 400 | 200 | 400 |
user 텍스트 블록의 citations | 200 | 400 | 200 | 400 |
assistant 텍스트 블록의 citations | 200 | 200 | 200 | 200 |
새 버전의 오류 메시지는 다음과 같다.
| 요청 | 2026-10-21의 오류 메시지 |
|---|---|
temperature, top_p, top_k | ”temperature: Extra inputs are not permitted” (파라미터 이름만 달라짐) |
assistant 메시지의 document | ”messages: `document` blocks can’t be placed directly in `assistant` messages; send them in a `user` message. Found at: messages.1.content.0” |
user 텍스트의 citations | ”messages: text blocks in `user` messages can’t have `citations`; remove `citations` from them. Found at: messages.0.content.1” |
Claude Sonnet 5.5는 2023-06-01에서도 기본값이 아닌 샘플링 값을 이미 거부했다. 당시 오류 메시지는 “`temperature` is deprecated for this model.”이었고, temperature: 1.0은 허용했다. 2026-10-21에서는 파라미터 자체가 없어져 기본값도 실패한다. Claude Sonnet 4.6은 이전 버전에서 모든 케이스를 허용했다. Anthropic의 마이그레이션 가이드에 따르면 token 계산과 Message Batch 내 개별 요청에도 같은 규칙이 적용된다. Batch API는 여러 요청을 할인된 비용으로 비동기 실행하는 API다. 가이드에는 2023-06-01의 지원 종료일이 명시되어 있지 않다.
각 400 오류는 어떻게 해결하나?
샘플링 파라미터 3개를 제거하고, 문서를 user 메시지로 옮기고, user로 보내는 텍스트에서 citations를 제거하면 된다. 샘플링 파라미터를 생략하면 temperature 1.0을 포함한 기본값으로 샘플링한다. 2023-06-01에서도 이 파라미터들을 생략하면 같은 방식으로 동작했다. Claude의 이전 응답에 붙은 인용 정보와 문서의 "citations": {"enabled": true}는 계속 허용된다.
Python SDK에서 두 버전 모두에 사용할 수 있는 요청은 다음과 같다.
import anthropic
client = anthropic.Anthropic() # 2.x sends anthropic-version: 2026-10-21
message = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
# no temperature, top_p or top_k: the parameters no longer exist in 2.x
messages=[{"role": "user", "content": "Summarize this memo in one sentence."}],
)
print(message.content[0].text)
Claude Sonnet 4.6처럼 기본값 외의 temperature를 아직 허용하는 모델에서 해당 값이 필요한 요청은 이전 버전을 유지해야 한다. HTTP로 직접 호출한다면 헤더를 명시하면 된다.
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-4-6", "max_tokens": 256, "temperature": 0.2,
"messages": [{"role": "user", "content": "Pick a number from 1 to 100."}]}'
Anthropic SDK에서는 무엇이 바뀌었나?
2026-10-21을 보내는 SDK 메이저 버전은 Python 2.0.0, TypeScript 1.0.0, Go 2.0.0, Java 3.0.0, C# 13.0.0, PHP 1.0.0, Ruby 2.0.0이다. API 버전 외에도 키를 보내는 방식과 클라이언트가 보유할 수 있는 인증 정보 수가 바뀌었다. 라이선스도 MIT에서 Apache 2.0으로 변경됐다. Python SDK 1.17.0(마지막 1.x)과 2.3.0을 설치하고, 받은 요청의 헤더와 본문을 모두 기록하는 로컬 에코 서버로 요청을 보냈다.
| 동작 | Python SDK 1.17.0 | Python SDK 2.3.0 |
|---|---|---|
전송하는 anthropic-version | 2023-06-01 | 2026-10-21 |
| API 키를 담는 헤더 | x-api-key | Authorization: Bearer |
인자로 temperature=0.2 전달 | TypeError, 요청 전송 안 됨 | TypeError, 요청 전송 안 됨 |
extra_body(원시 본문 필드)로 temperature 전달 | 전송됨, API가 처리 여부 결정 | 전송됨, 2026-10-21에서 400 반환 |
extra_headers={"X-Api-Key": ...}에 다른 키 지정 | 클라이언트 키를 대체 | 두 키 모두 전송 |
api_key와 auth_token(API 키 대신 사용하는 bearer token) 동시 지정 | 둘 다 전송 | 클라이언트 생성 시 ValueError |
| Anthropic API에 실제 요청 | 200 | 200 |
Python SDK의 메시지 메서드에서는 1.0.0부터 temperature 인자가 제거됐다. 따라서 Python 사용자는 extra_body(요청 본문에 원시 필드를 추가하는 SDK 옵션)를 쓰거나, 본문을 직접 구성하는 HTTP 클라이언트 및 라이브러리를 쓸 때만 서버 측 400 오류를 만나게 된다. Bearer 헤더는 두 API 버전에서 모두 동작한다. Authorization: Bearer <key>만 보낸 요청도 2023-06-01에서 200을 반환했다. 인증 방식 변경과 API 버전 변경은 따로 배포할 수 있다.
두 헤더를 모두 보내면 어떤 키를 사용하나?
Anthropic API는 두 헤더가 모두 있으면 x-api-key를 사용한다. 두 버전에서 각각 다섯 가지 헤더 조합을 보냈다.
| 요청 헤더 | 두 버전의 상태 코드 |
|---|---|
x-api-key만 전송 | 200 |
Authorization: Bearer만 전송 | 200 |
| 동일한 키로 두 헤더 모두 전송 | 200 |
유효한 x-api-key, 잘못된 Bearer 키 | 200 |
잘못된 x-api-key, 유효한 Bearer 키 | 401 “invalid x-api-key” |
Claude 앞단의 프록시나 게이트웨이는 API와 다른 키를 사용한 요청으로 판단할 수 있다. SDK 2.x에서 extra_headers={"X-Api-Key": other_key}로 두 번째 키를 추가하면 이제 키가 두 개 전송된다. Authorization에는 클라이언트 키가, x-api-key에는 다른 키가 들어간다. Anthropic API는 other_key로 요청을 인증한다. 반면 Authorization만 읽는 프록시는 클라이언트 키를 사용한 요청으로 처리한다. 그 결과 키별 쿼터, 로그, 지출 한도가 엉뚱한 키에 적용될 수 있다. 가이드에서 제시하는 클라이언트 측 해결책은 두 번째 키를 Authorization: Bearer <other_key>로 보내는 것이다. 프록시에서는 두 헤더를 모두 읽고 API와 같은 우선순위(x-api-key 우선)를 적용하거나, 두 헤더의 키가 다른 요청을 거부해야 한다.
temperature를 없애면 무엇을 잃나?
temperature: 0에 의존하던 팀이라도 temperature 제거의 영향은 예상보다 작을 수 있다. 마이그레이션 가이드에 따르면 Claude 4.7 이후 모델은 이미 기본값만 허용하므로 달라지는 것이 없다. Claude Sonnet 4.6처럼 다른 값도 허용하는 모델에서는 출력의 일관성을 높이려고 temperature를 낮췄던 효과가 사라진다. 이를 대체할 설정은 없다. 실제 효과를 측정하기 위해 2023-06-01로 Sonnet 4.6에 설정별 20개 요청을 보냈다. 모든 요청이 서로 다르도록 각 요청 끝에 임의의 요청 ID를 덧붙였다.
| 프롬프트 | temperature: 0 | 기본값 (temperature: 1.0) |
|---|---|---|
| “1부터 100까지 숫자 하나를 골라 줘” | 서로 다른 답변 2개: 47 (19회), 42 (1) | 서로 다른 답변 2개: 47 (17), 42 (3) |
| “커피숍 홍보 문구를 최대 8단어로 써 줘” | 동일한 답변 1개, 20회 | 동일한 답변 1개, 20회 |
이 짧은 답변들에서는 Sonnet 4.6이 기본 temperature에서도 0일 때와 비슷하게 특정 답변에 집중됐다. 따라서 temperature: 0을 제거해도 차이가 작았다. temperature: 0이 결정론적 출력을 보장한 것도 아니다. 20번의 시도에서 서로 다른 숫자 두 개가 나왔다. 설정값보다 프롬프트 텍스트가 출력에 더 큰 영향을 줬다. 요청 ID를 붙이지 않았을 때는 42가 가장 많이 나왔고(temperature: 0에서 20회 중 17회), 붙였을 때는 47이 가장 많았다. 재현 가능한 출력이 필요하다면 코드에서 답변을 비교하거나 캐시해야 한다. 샘플링 파라미터가 이전에도 이를 보장해 주지는 않았다.
Synthorai는 API 버전 2026-10-21을 어떻게 처리하나?
Synthorai는 두 API 버전과 두 SDK의 요청을 모두 받는다. 따라서 SDK 2.x로 업그레이드하거나 anthropic-version: 2026-10-21을 보내도 기존에 동작하던 요청이 실패하지 않는다. 두 모델의 16개 케이스를 두 anthropic-version 값으로 Synthorai를 통해 다시 테스트했다. 32개 요청이 모두 200을 반환했으며, Anthropic API가 2026-10-21에서 거부하는 12개 요청도 포함된다. Python SDK 1.17.0(x-api-key 전송)과 2.3.0(Authorization: Bearer 전송) 모두 base_url="https://synthorai.io"와 동일한 키로 동작했다. extra_body로 보낸 temperature도 마찬가지였다.
Synthorai가 이렇게 처리하는 이유는 네 가지다.
- 같은 모델을 여러 제공 경로로 호출한다. Claude 모델은 Anthropic API, Amazon Bedrock, Google Cloud Vertex AI에서 제공되며, 각 서비스는 서로 다른 버전 문자열을 받는다. Synthorai는 각 서비스가 요구하는 버전을 보내므로 클라이언트의
anthropic-version헤더가 요청 검증 방식을 결정하지 않는다. - 마이그레이션 중에는 여러 클라이언트가 공존한다. 팀은 서비스를 하나씩 업그레이드한다. 그래서 몇 주 동안 같은 계정에서 SDK 1.x로는
2023-06-01을, SDK 2.x로는2026-10-21을 보내게 된다. 둘 다 허용하면 서비스별 일정에 맞춰 전환할 수 있고, 어느 SDK의 인증 헤더를 쓰든 같은 키가 동작한다. - 코드는 그대로 두고 모델을 바꿀 수 있다. Claude Sonnet 4.6에
temperature: 0.2를 지정하던 코드는 모델 이름을 해당 파라미터를 받지 않는 Claude Sonnet 5.5로 바꿔도 계속 실행된다. 모델 전환 때문에 요청이 실패하지 않는다. - 기본값을 명시했다고 요청을 실패시키지 않는다.
temperature: 1.0은 어차피 모델이 사용하는 값이다. 이를 거부하면 출력에는 차이가 없는데 요청만 실패한다.
대신 200 응답이 모든 파라미터가 적용됐다는 뜻은 아니다. Sonnet 5.5는 기본 샘플링 값만 허용한다. Synthorai를 통해 temperature: 0.2를 보내면 요청은 성공하지만 무작위성을 낮출 수는 없다. 출력이 특정 샘플링 값에 의존한다면 실제로 사용하는 프롬프트에서 해당 값을 넣었을 때와 뺐을 때를 비교해야 한다. 위 측정에서는 짧은 답변에 미치는 영향이 작았다.
업그레이드 전에 무엇을 확인해야 하나?
| 사용 방식 | 확인할 항목 | 변경 사항 |
|---|---|---|
| HTTP로 API 직접 호출 | anthropic-version을 설정하는 모든 곳 | 2026-10-21로 전환하기 전에 temperature, top_p, top_k 제거 |
| Python SDK 사용 | extra_body와 샘플링 파라미터를 추가하는 래퍼 | 해당 파라미터 제거, 대체 설정 없음 |
Claude Sonnet 4.6에서 낮은 temperature 필요 | 출력이 실제로 해당 값에 의존하는지 | 해당 요청은 2023-06-01 유지, 또는 측정 후 파라미터 제거 |
| 대화 이력에 문서나 인용 정보 재전송 | document 블록이 있는 assistant 턴, citations가 있는 user 턴 | 문서를 user 메시지로 옮기고 user 측 인용 정보 제거 |
| 프록시나 게이트웨이 운영 | 키를 읽는 헤더 | Authorization과 x-api-key를 모두 읽고 API와 같은 우선순위 적용 |
| Synthorai를 통해 Claude 호출 | 출력이 샘플링 값에 의존하는지 | 업그레이드를 위한 요청 변경 불필요, 샘플링 값을 넣고 뺀 출력 비교 |
자주 묻는 질문
Claude 요청이 “temperature: Extra inputs are not permitted”로 실패하는 이유는?
요청에 사용한 anthropic-version: 2026-10-21에는 temperature 파라미터가 더 이상 없다. 따라서 1.0을 포함해 어떤 값을 넣어도 400을 반환한다. 새 SDK 메이저 버전들은 이 API 버전을 기본으로 보낸다. 파라미터를 제거하거나, 기본값 외의 값을 아직 허용하는 모델에서 그 값이 필요한 요청에 한해 2023-06-01로 고정하면 된다.
anthropic-version 2023-06-01은 지원이 종료되나?
Anthropic은 2023-06-01의 지원 종료일을 발표하지 않았다. 마이그레이션 가이드와 10월 21일 API 릴리스 노트에도 종료일은 없다. 헤더를 명시한 요청은 기존 동작을 유지한다. 따라서 특정 요청만 Claude Sonnet 4.6에서 temperature를 계속 사용하도록 할 수 있다.
Anthropic API는 x-api-key 헤더를 계속 허용하나?
Anthropic API는 두 버전 모두에서 x-api-key와 Authorization: Bearer를 허용한다. SDK가 기본으로 보내는 헤더만 바뀌었다. 두 헤더가 모두 있으면 API는 x-api-key를 사용한다.
함께 읽을 글
- Claude Sonnet 5.5 비용: Sonnet 5와 비교한 모델 비용
- LLM 사고 과정 제어: 최신 Claude 모델에서 지원하는 추론 설정
- OpenCode 침해 사고: API 키 보호: 키 유출 시 피해 범위를 제한하는 방법
- LLM API 요청 한도: 키별 한도를 집계하는 방식