Claude Fable 5 폴백이 줄었다 — stop_reason refusal과 server-side fallback 다시 점검하기

mini_knows·2026년 8월 7일

AI 트렌드·이슈

목록 보기
66/120

안녕하세요, 미니지식공간입니다.

Claude Fable 5의 생물학 분류기가 재학습되면서 stop_reason: "refusal"로 떨어지던 요청이 줄었다. 앤트로픽(Anthropic)이 2026년 8월 7일 발표한 내용으로, 폴백(fallback) 처리 코드를 넣어둔 개발자라면 지금이 로그를 다시 볼 시점이다.

먼저 숫자부터

  • 생물학 관련 폴백: 약 85% 감소 (앤트로픽 자사 테스트, 전 제품 합산)
  • 전체 폴백 감소: Claude.ai 약 67%, Cowork 약 55%, Claude Code 약 17%, Claude Platform(API) 약 7%
  • 이중용도(dual-use) 영역(바이러스학·독성학·분자 설계)은 그대로 차단 → Opus 5로 폴백

API를 쓰는 입장에서 눈여겨볼 숫자는 마지막의 7%다. 다른 표면 대비 감소 폭이 작다. API 트래픽에서 생물학 질문 비중이 작기 때문으로 볼 수 있으나 앤트로픽이 이유를 명시하지는 않았다(확인 필요). 결론적으로 폴백 처리 코드를 걷어낼 근거는 되지 않는다.

무엇을 바꿨나 — 모델이 아니라 분류기다

이번 변경은 Fable 5 본 모델을 다시 학습한 것이 아니다. 앤트로픽은 별도로 동작하는 안전 분류기(classifier)의 "헌법(constitution)" — 무엇이 안전장치 대상이고 무엇이 허용인지 규정한 규칙 모음 — 을 다시 작성하고, 그에 맞춘 학습 데이터를 새로 만들어 분류기를 재학습했다고 설명했다. 내부·외부 전문가 피드백을 반영해 무해한 용도를 세밀하게 예외 처리했다는 것이 요지다.

구조적으로는 경계선을 오른쪽으로 밀었다고 보면 된다. 출시 당시 Fable 5는 생물학 질문 대부분을 차단하는 매우 넓은 분류기를 걸고 나왔다. 안전 여유(safety margin) 구간에 "거의 확실히 무해하지만 그래도 막는" 요청이 대거 포함돼 있었고, 이번 업데이트는 그 구간을 좁힌 것이다. 앤트로픽은 여유 구간이 완전히 사라지지는 않는다고 못 박았다.

거부 응답은 에러가 아니다

여기서 개발자가 자주 놓치는 지점이 있다. 분류기가 작동해도 HTTP 200이 온다. 공식 문서 Refusals and fallback 기준 응답 형태는 다음과 같다.

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-fable-5",
  "content": [],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request was declined because it could enable cyber harm."
  },
  "usage": { "input_tokens": 412, "output_tokens": 0 }
}

출처: https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback

stop_details.category가 이번 발표와 직접 연결되는 필드다. 문서가 정의한 카테고리는 아래와 같다.

category의미
cyber악성코드·익스플로잇 등 사이버 위해 가능성. 정상 보안 업무도 걸릴 수 있음
bio위험한 실험 기법 등 생물학 위해 가능성. 유익한 생명과학 작업도 걸릴 수 있음
frontier_llm경쟁 AI 모델 개발 지원 가능성(상업 약관 제한). 일반 ML 작업도 걸릴 수 있음
reasoning_extraction내부 추론을 응답 텍스트로 재현 요청
general_harms유해 판정 영역 관련

이번 8월 7일 업데이트가 좁힌 것이 바로 이 bio 카테고리의 발동 범위다.

한 가지 더. 문서는 stop_details의 category와 explanation이 null일 수 있다고 명시한다. 따라서 분기는 stop_reason == "refusal" 또는 stop_details.type으로 잡아야 하며, 내부 필드나 content로 판단하면 깨진다.

서버 사이드 폴백 붙이기

가장 단순한 방법은 fallbacks="default"다. 거부 카테고리에 대해 앤트로픽이 권장하는 모델로 API가 알아서 재시도한다.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks="default",
    betas=["server-side-fallback-2026-07-01"],
)

# usage.iterations에 fallback_message 항목이 있으면 폴백 모델이 응답한 것
fallback_ran = any(
    iteration.type == "fallback_message"
    for iteration in response.usage.iterations or []
)
served_by_fallback = fallback_ran and response.stop_reason != "refusal"
print(response.model, served_by_fallback)

출처: https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback

모델을 직접 지정하고 싶다면 최대 3개까지 리스트로 넘길 수 있다.

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks=[{"model": "claude-opus-4-8"}],
    betas=["server-side-fallback-2026-07-01"],
)
print(response.model)

베타 헤더 날짜에 주의해야 한다. 문서 기준 "default" 모드는 server-side-fallback-2026-07-01에서만 동작하고, 2026-06-01은 명시 리스트 형태만 받는다. 그 외 값이면 fallbacks 파라미터가 400으로 거부된다. 또한 서버 사이드 폴백은 Claude API 전용 베타이며 Message Batches API, Amazon Bedrock, Google Cloud, Microsoft Foundry에서는 쓸 수 없다.

Bedrock 등 다른 플랫폼이라면 SDK 미들웨어를 쓴다.

from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware

client = Anthropic(
    middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)

state = BetaFallbackState()  # 수락한 모델로 후속 요청을 고정

with state:
    message = client.beta.messages.create(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    )
print(f"served by: {message.model}")

출처: https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback

여전히 남는 제약

앤트로픽은 이번 업데이트 후에도 Fable 5가 이중용도로 판단하는 요청은 Opus 5로 계속 넘긴다고 밝혔다. 언급된 영역은 바이러스학, 독성학, 분자 설계다. 전문 생물학 연구·신약 개발 워크로드는 아직 대상이 아니며, 검증된 연구자를 위한 "신뢰 접근 경로(trusted access pathways)"를 준비 중이라는 것이 회사 입장이다.

같은 안전장치 축의 이전 사건인 Fable 5 재배포와 분류기·세이프티 마진 정리 글도 함께 보면 흐름이 이어진다.

지금 점검할 것

  1. 거부를 별도 지표로 계측한다. HTTP 200이므로 에러율·5xx 기반 모니터링에는 잡히지 않는다. 문서도 거부 1건, 폴백 응답 1건을 각각 이벤트로 남기고 두 카운트 차이에 알림을 걸라고 권한다.
  2. 재시도 경로 전부에 폴백을 건다. 에러 복구 분기, 백그라운드 워커, 서브에이전트 호출 모두 해당한다. fallbacks 파라미터는 툴 실행 내부의 모델 호출로 전파되지 않는다.
  3. 응답 최상위 model 필드를 로그에 남긴다. 요청 모델과 응답 모델이 다를 수 있다.
  4. 같은 모델로 재시도하지 않는다. 대개 또 거부된다.

자주 묻는 질문

Q. 이번 변경으로 API 코드를 수정해야 하나?
아니다. 발표에 API 스펙 변경은 없다. 분류기 동작만 완화된 것이라 기존 코드는 그대로 동작한다. 다만 폴백 처리를 아직 넣지 않았다면 이번 기회에 추가하는 것이 좋다.

Q. 폴백된 요청은 두 번 과금되나?
문서 기준, 출력 전에 발생한 거부는 과금되지 않는다. 스트리밍 중간 거부는 입력 토큰과 이미 전송된 출력 토큰이 정상 요율로 과금된다. 재시도 비용은 fallback credit으로 조정되며, 서버 사이드 폴백과 SDK 미들웨어는 이를 자동 적용한다.

Q. bio 카테고리에 걸렸는지 어떻게 확인하나?
stop_details.category를 보면 된다. 다만 이 필드는 null일 수 있으므로 분기 조건으로는 stop_reason == "refusal"을 쓰고, 카테고리는 로깅·분석 용도로만 읽는 편이 안전하다.

마무리

2026년 8월 7일 앤트로픽의 이번 업데이트는 모델이 아니라 분류기를 손본 변경이다. 생물학 폴백이 약 85% 줄었지만 API 표면의 전체 폴백 감소는 약 7%에 그치고, 이중용도 영역은 그대로 남는다. 폴백은 여전히 정상 동작 경로로 설계해야 한다.

출처

본 글은 공개 자료를 바탕으로 정리했으며, 세부 내용·수치는 원 출처·공식 문서와 대조 확인을 권장합니다.

profile
작지만 알아야 할 모든 것

0개의 댓글