← 블로그 목록
AI 뉴스약 5분 분량

Claude Sonnet 5.5는 tool_choice 강제를 400으로 막는다, 도구를 부르지 않은 200 응답은 에러 대시보드에 잡히지 않는다

모델 ID보다 먼저 추출 파이프라인의 응답 파서를 고친다

Claude Sonnet 5.5는 tool_choice any·tool 요청을 400 오류로 거부한다. 대안인 auto와 strict 조합은 도구를 건너뛴 200 응답을 허용한다. 모델 ID를 바꾸기 전에 tool_use 없는 응답을 세는 검사를 넣어야 한다.

계약서나 청구서에서 필드를 뽑아 JSON으로 받는 코드는 오래 tool_choice에 기대 왔다. {"type": "tool", "name": "extract_invoice"}를 보내면 응답에는 그 도구 호출이 반드시 들어 있었고, 파서는 호출이 있는지 묻지 않고 입력값을 꺼냈다. 호출이 일어나는 것도, 입력이 스키마를 따르는 것도 API가 맡았다.

Anthropic 9월 28일 발표로 나온 Claude Sonnet 5.5는 Sonnet 5와 같은 가격(입력 100만 토큰당 2달러, 출력 10달러)에 작업당 비용은 자사 테스트에서 최대 30% 낮다. 같은 날 GitHub 9월 28일 changelog는 전역 기본값을 끄지 않은 Copilot Business·Enterprise 조직에 이 모델이 자동으로 켜지도록 순차 배포를 시작했다. Copilot에서는 설정 없이 넘어가는 모델이, API를 직접 부르는 추출 코드에서는 모델 ID 한 줄에서 멈춘다.

5.5 세대는 강제 호출 요청을 받지 않는다

출시와 함께 나온 Sonnet 5.5 마이그레이션 가이드(9월 28일)는 Sonnet 5, 4.6, 4.5와 Haiku 4.5가 받던 tool_choice any와 tool을 Sonnet 5.5가 400으로 거부한다고 적었다. 토큰 카운팅 엔드포인트도 같은 검사를 한다. Opus로 올려도 피하지 못한다. Opus 5.5 변경 사항 문서(9월 22일 출시)도 같은 오류 문구로 강제 호출을 막았고, 남은 값은 auto와 none이다.

Sonnet 5에서 넘어오는 코드라면 thinking: {"type": "disabled"}도 걸린다. 5.5에서는 between_tools로 바꾸고, 이 값은 effort high 이하에서만 받는다. Opus 4.7 전환은 토큰을 다시 재는 문제였지만 이번에는 요청 본문부터 거부된다.

그래도 400은 다루기 쉬운 실패다. 배포 뒤 첫 호출에서 드러나고 에러율 그래프가 바로 튄다.

auto로 고치면 실패가 400에서 200으로 옮겨간다

가이드의 대안은 tool_choice: {"type": "auto"}에 도구마다 strict: true를 붙이는 방식이다. strict는 호출이 일어났을 때 입력이 스키마를 따르게 하고, 모든 객체에 additionalProperties: false를 요구한다. 호출 여부는 보장하지 않는다. 가이드는 모델이 도구 없이 답할 수 있으니 언제 쓰는지 프롬프트에 적으라고 했다. Amazon Bedrock에서는 Sonnet 5.5에 strict 도구도 구조화 출력도 없어서 스키마 검증까지 호출하는 쪽 코드가 한다.

안전 분류기도 같은 모양의 응답을 만든다. Anthropic 거절·폴백 문서(2026년 9월 기준)에 따르면 Sonnet 5.5가 요청을 거절하면 오류 대신 HTTP 200에 stop_reason: "refusal"과 빈 content가 온다. bio, frontier_llm, reasoning_extraction 거절은 출력이 없어도 과금되고, 모든 거절이 속도 제한에 들어간다. 서버 측 폴백(fallbacks: "default", 베타)을 켜면 cyber·frontier_llm 거절은 Sonnet 5가 다시 받아 답하고, 그 JSON을 만든 모델은 response.model에만 남는다.

상태 코드로 세는 에러율은 아래 표의 200 세 줄을 모두 성공으로 집계한다.

응답 모양HTTP코드에서 볼 값
강제 호출 요청400오류 메시지
도구 없이 텍스트로 답함200content에 tool_use 블록 없음
안전 분류기 거절200stop_reason, stop_details.category
폴백 모델이 답함200response.model

가져갈 것

  • tool_choice에 any나 tool을 넣는 호출(토큰 카운팅 포함)을 모두 auto로 바꿨는가?
  • 추출 도구에 strict: true를 붙이고 스키마의 모든 객체에 additionalProperties: false를 넣었는가?
  • Sonnet 5 코드의 thinking: {"type": "disabled"}를 between_tools로 바꾸고 effort를 high 이하로 두었는가?
  • 파서가 content[0] 대신 type이 tool_use인 블록을 찾는가? (응답이 thinking 블록으로 시작할 수 있다)
  • tool_use 누락과 stop_reason: "refusal" 건수를 stop_details.category별로 대시보드에 올리는가?
  • fallbacks: "default"를 켰다면 response.model을 로그에 남겨 Sonnet 5가 만든 JSON을 구분하는가?

안 되는 경우

  • Claude Managed Agents로 돌리는 조직은 가이드상 모델 이름만 바꾸면 된다. 요청 본문을 직접 짜지 않는 팀에는 이 점검이 필요 없다.
  • Anthropic은 auto에서 모델이 도구를 건너뛰는 빈도를 공개하지 않았다. 누락률은 자기 트래픽으로 재야 한다.
  • 서버 측 폴백은 Claude API 전용 베타라 Bedrock·Google Cloud·Message Batches에서는 쓸 수 없다.
  • 작업당 최대 30% 절감은 Anthropic 내부 테스트 수치이고 작업 종류를 밝히지 않았다. 마이그레이션 가이드는 Sonnet 5의 종료 일정도 적지 않았다.

이번 주에 바꿀 것은 모델 ID가 아니라 파서다. tool_choice를 auto로 바꾸는 일은 Sonnet 5에서도 되므로 모델 교체와 떼어 먼저 배포하고, tool_use 누락과 거절 건수를 일주일 모아 기준선을 잡는다. 그다음 claude-sonnet-5-5로 바꾸면 늘어난 실패가 모델 탓인지 설정 탓인지 같은 대시보드에서 가를 수 있다. 사업영역 →

출처

AI뉴스Claude Sonnet 5.5구조화 출력

Contact

이런 교육이 필요하다면

AI·데이터 교육 도입을 검토 중이라면 카카오 오픈채팅으로 편하게 문의하세요.

Newsletter

조녁컴퍼니 뉴스레터

AI 전환과 교육 현장의 기록을 메일로 받아보세요.