Claude Platform Docs
MessagesClaude로 빌드하기

거부와 폴백

Claude Fable 및 Claude Opus 모델이 분류기 거부를 반환하는 방식과 거부된 요청을 폴백 모델에서 재시도하는 방법.

Claude Fable 5.1, Claude Fable 5, Claude Opus 5에는 요청을 거절할 수 있는 안전 분류기가 포함되어 있습니다. 이 경우 오류가 아닌 stop_reason: "refusal"이 포함된 정상 응답을 받게 됩니다. 응답의 stop_details.category는 정책 영역의 이름을 나타냅니다(거부의 형태 참조). 일반적으로 동일한 요청을 다른 Claude 모델로 보내면 여전히 답변을 얻을 수 있습니다. 이 페이지에서는 거부를 인식하는 방법과 해당 재시도를 설정하는 방법을 보여 줍니다.

이러한 모델 중 하나를 기반으로 구축하면서 거절된 요청이 자동으로 다른 모델로 넘어가도록 하려는 경우 이 페이지를 읽으세요. 응답에서 "refusal"을 확인하고 다음에 무엇을 해야 할지 알고 싶은 경우에도 적용됩니다.

관련 페이지:

Claude API에서 베타로 제공되는 가장 간단한 설정: fallbacks"default"로 설정하면, API가 거절된 요청을 해당 거부 카테고리에 대해 Anthropic이 권장하는 폴백 모델에서 재시도합니다. 권장 폴백이 없는 카테고리의 경우 거부가 그대로 유지됩니다.

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"],
)
print(response.model)

다음 섹션에서는 거부 응답에 포함되는 내용, 서버 측 또는 클라이언트 측 폴백을 사용해야 하는 경우, 그리고 각각의 청구 방식을 다룹니다.

거부의 형태

거부는 stop_reason: "refusal"이 포함된 성공적인 HTTP 200 응답입니다:

{
  "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
  }
}

stop_details 객체는 거절 사유를 설명합니다:

  • category: 분류기를 트리거한 정책 영역의 이름을 나타냅니다.
  • explanation: 사람이 읽을 수 있는 설명입니다. 텍스트는 고정되어 있지 않으므로 파싱하지 말고 표시하세요.
  • recommended_model: fallbacks를 설정한 요청(서버 측 폴백, 베타)에만 존재합니다. API가 폴백 시도를 건너뛴 경우(예: 폴백 모델이 속도 제한에 걸린 경우) 직접 재시도할 모델의 이름을 나타내며, 그 외에는 null입니다. 이는 힌트일 뿐 보장이 아닙니다.
  • 거부가 명명된 카테고리에 매핑되지 않는 경우 categoryexplanation은 모두 null입니다. 이 null은 자리 표시자가 아니라 정상적이고 영구적인 값입니다.
  • refusal 이외의 모든 중지 사유에 대해서는 stop_details 자체가 null입니다.
category의미
"cyber"요청이 악성코드나 익스플로잇 개발과 같은 사이버 피해를 가능하게 할 수 있습니다. 무해한 사이버 보안 작업도 이 카테고리를 트리거할 수 있습니다.
"bio"요청이 위험한 실험실 방법과 같은 생물학적 피해를 가능하게 할 수 있습니다. 유익한 생명과학 작업도 이 카테고리를 트리거할 수 있습니다.
"frontier_llm"요청이 경쟁 AI 모델의 개발을 도울 수 있으며, 이는 Anthropic의 상업 약관에 따라 제한됩니다. 무해한 머신러닝 작업도 이 카테고리를 트리거할 수 있습니다.
"reasoning_extraction"요청이 모델에게 내부 추론을 응답 텍스트에 재현하도록 요구합니다. 대신 구조화된 형태로 추론을 얻으려면 적응형 사고를 사용하세요.
"general_harms"요청이 네 가지 명명된 카테고리 외의 사용 정책 영역에 해당합니다. 무해한 작업도 이 카테고리를 트리거할 수 있습니다.

거부는 출력이 전혀 없는 상태에서 도착할 수도 있고, 부분 출력 이후 스트림 중간에 도착할 수도 있습니다. 어느 경우든 부분 출력은 불완전한 것으로 취급하고 폐기하세요.

폴백 방식 선택

거부된 요청을 다른 모델에서 재시도하는 방법은 세 가지입니다. 적합한 방법은 실행 환경과 필요한 제어 수준에 따라 달라집니다.

상황사용할 방법이유
Claude API, 가장 간단한 설정서버 측 폴백요청 하나, 응답 하나. API가 재시도를 처리합니다.
모든 플랫폼, Anthropic SDK 사용SDK 미들웨어클라이언트에서 한 번 구성합니다. 재시도가 자동으로 이루어집니다.
원시 HTTP 또는 사용자 정의 재시도 로직폴백 크레딧을 사용한 수동 재시도완전한 제어. 폴백 크레딧이 비용을 낮춰 줍니다.

서버 측 폴백과 SDK 미들웨어는 폴백 크레딧을 자동으로 적용합니다. 폴백 크레딧 페이지는 재시도를 직접 구축할 때만 필요합니다.

서버 측 폴백

서버 측 폴백은 단일 API 호출 내에서 거부된 요청을 재시도합니다. 기본 모드에서는 기본 모델이 거절하고 해당 거부 카테고리에 권장 폴백이 있는 경우, API가 해당 카테고리에 대해 Anthropic이 권장하는 모델에서 동일한 요청을 실행합니다. 대신 최대 세 개의 폴백 모델을 직접 지정할 수도 있습니다. 어느 쪽이든 답변한 모델의 이름이 포함된 하나의 응답을 받게 되므로, 사용자는 한 번의 왕복으로 답변을 얻습니다.

요청 보내기

fallbacks 매개변수를 문자열 "default"로 설정하고 server-side-fallback-2026-07-01 베타 헤더를 보내세요. 그러면 API는 요청된 모델의 서버 정의 기본 라우팅을 적용하며, 이는 분류기가 보고하는 거부 카테고리에 따라 권장 폴백 모델을 선택합니다. 따라서 권장 사항이 변경되더라도 모델 목록을 직접 관리할 필요 없이 거부된 요청이 처리됩니다.

기본 라우팅은 사용자가 선택하지 않은 모델에 대해 사전 초과 크기 이미지 거부를 발생시키지 않습니다. "oversized_image": "error"로 표시된 이미지를 리사이즈하게 될 라우팅 대상 모델은 대신 라우팅에서 제외되므로, 표시된 이미지가 리사이즈된 상태로 처리되는 일은 없습니다.

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 항목이 있으면 폴백 모델이 실행된 것입니다.
# stop_reason과 함께 확인하여 폴백이 응답을 제공했는지 검증하세요.
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(
    json.dumps(
        {
            "stop_reason": response.stop_reason,
            "model": response.model,
            "served_by_fallback": served_by_fallback,
        }
    )
)

Anthropic은 모델의 역량에 맞춰 각 모델별로, 그리고 각 정책 카테고리별로 안전장치를 설정합니다. 카테고리에 따라 플래그가 지정된 요청은 역량이 더 낮은 모델로 폴백되거나 거절될 수 있습니다. "default" 모드는 이러한 모델별, 카테고리별 권장 사항을 대신 인코딩하므로, 거부된 요청은 해당 카테고리에 대해 Anthropic이 권장하는 모델에서 재시도됩니다. 폴백은 어느 쪽이든 확인할 수 있습니다. 응답에는 이를 처리한 모델의 이름이 표시되고, fallback 콘텐츠 블록이 핸드오프를 표시합니다.

라우팅은 서버 측에서 적용되며 Models API에 모델별로 게시되지 않습니다. 거부된 요청을 어떤 모델이 처리했는지 확인하려면, 이 페이지의 샘플처럼 응답의 최상위 model 필드를 확인하고 usage.iterations에서 fallback_message 항목을 찾으세요.

안전 분류기 거절만이 폴백을 트리거합니다. 요청된 모델의 속도 제한, 과부하 또는 서버 오류는 그대로 반환됩니다.

폴백 모델 직접 지정

기본 라우팅 대신 fallbacks를 최대 세 개의 모델 목록으로 설정할 수 있습니다. 요청된 모델이 거절하면 API는 동일한 요청에 대해 체인의 다음 모델을 실행합니다. 애플리케이션에서 검증한 모델을 고정하는 경우처럼, 거부된 요청을 정확히 어떤 모델이 처리할지 제어하려는 경우 이 형식을 사용하세요.

지정된 폴백 모델은 초과 크기 이미지 검사에 포함됩니다. 이미지 블록에 "oversized_image": "error"를 설정한 요청은 요청된 모델과 지정된 모든 폴백에 대해 사전 검사되며, 그중 하나라도 해당 이미지를 리사이즈하게 되면 거부되고, 거부 시 보고되는 리스케일 대상은 모든 모델에 맞습니다.

강조 표시된 줄이 기본 라우팅 요청과의 유일한 차이점입니다.

client = Anthropic()

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)

fallbacks 목록에는 몇 가지 규칙이 적용됩니다:

  • 항목은 순서대로 시도됩니다. 각 항목은 다른 항목 및 요청된 모델과 서로 달라야 합니다.
  • 각 항목은 요청된 모델의 허용 대상 중 하나여야 합니다. 베타 헤더가 설정된 경우, 해당 목록은 Models API의 모델 항목에 allowed_fallback_models로 게시됩니다.
  • 각 항목은 model을 지정하며, 해당 시도에 대해서만 max_tokens, thinking, output_config, speed를 재정의할 수 있습니다.
  • 요청은 지정된 모든 모델에 대한 직접 요청으로서 유효해야 합니다. 폴백 모델이 요청에서 사용하는 기능을 지원하지 않으면 API는 요청을 사전에 거부합니다.
  • 기본 모드와 마찬가지로 안전 분류기 거절만이 폴백을 트리거합니다. 요청된 모델의 속도 제한, 과부하 또는 서버 오류는 그대로 반환됩니다.
  • 폴백 모델이 속도 제한에 걸리거나 과부하 상태이면 폴백 시도가 이루어지지 않고 대신 직전의 거부가 반환됩니다. 이때 거부의 stop_details.recommended_model은 직접 재시도할 모델의 이름을 나타냅니다. 예상되는 거부량에 맞게 폴백 모델의 속도 제한을 설정하세요. 그렇지 않으면 부하 상황에서 폴백이 거부로 저하됩니다.

응답은 두 모드에서 동일한 형태를 가집니다. 해당 턴을 처리한 모델은 최상위 model 필드에 표시되고, fallback 콘텐츠 블록이 핸드오프를 표시하며, usage.iterations가 각 시도를 기록합니다.

응답에 포함되는 내용

응답은 다른 메시지와 동일하게 보이며, 두 가지가 추가됩니다:

  • 최상위 model 필드는 반환된 메시지를 생성한 모델을 보고하며, 이는 요청된 모델일 수도 폴백일 수도 있습니다.
  • fallback 콘텐츠 블록은 content에서 한 모델의 출력이 다음 모델로 넘어가는 각 지점을 표시합니다: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
    • 거절한 홉이 요청된 모델인 경우 from.model은 사용자가 보낸 모델 문자열을 그대로 반영합니다.
    • to.model은 항상 이어서 처리하는 모델의 확정된 ID입니다.

출력이 전혀 없는 상태에서 거부된 경우 fallback 블록이 첫 번째 콘텐츠 블록입니다. 예를 들어, 기본 라우팅이 거부 카테고리에 대해 Claude Opus 4.8을 선택한 경우:

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4-8",
  "content": [
    {
      "type": "fallback",
      "from": { "model": "claude-fable-5" },
      "to": { "model": "claude-opus-4-8" }
    },
    { "type": "text", "text": "Hi! How can I help you today?" }
  ],
  "stop_reason": "end_turn",
  "stop_details": null,
  "usage": {
    "input_tokens": 412,
    "output_tokens": 264,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0,
    "iterations": [
      {
        "type": "message",
        "model": "claude-fable-5",
        "input_tokens": 535,
        "output_tokens": 0,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      },
      {
        "type": "fallback_message",
        "model": "claude-opus-4-8",
        "input_tokens": 412,
        "output_tokens": 264,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      }
    ]
  }
}

usage.iterations 배열은 모든 시도를 기록합니다. 거절한 모델은 일반 message 항목으로 표시되고, 해당 턴을 처리한 모델은 fallback_message 항목으로 표시됩니다. 체인의 모든 모델이 거절하면 응답은 마지막 모델의 거부가 되며, 이전 각 홉에 대한 message 항목과 마지막에 대한 fallback_message 항목이 포함됩니다.

고정 라우팅은 이후 턴을 폴백 모델로 바로 보낼 수 있습니다. 이러한 턴에는 해당 턴에서 거절한 모델이 없으므로 fallback 콘텐츠 블록이 없습니다. usage.iterationsfallback_message 항목, 요청된 모델에 대한 message 항목의 부재, 그리고 응답의 model 필드로 이를 식별하세요.

대화 이어가기

다음 턴에서는 어시스턴트 콘텐츠를 받은 그대로 다시 보내세요. 출력 중간 폴백 이후에는 content에 거절한 모델이 핸드오프 전에 생성한 블록 유형이 포함될 수 있습니다. 다음 표는 턴을 다시 보낼 때 어떤 것을 유지하고 어떤 것을 제거해야 하는지 다룹니다.

블록 유형다음 턴에서
fallback나타난 위치 그대로 유지하세요. API는 이 위치를 사용하여 주변의 사고 블록을 검증하므로, 경계 양쪽의 사고 블록을 다시 보내는 요청에서 이 블록이 누락되거나 이동되면 거부됩니다.
text유지.
마지막 fallback 블록 이후의 모든 블록유지.
마지막 fallback 블록 이전의 thinking, redacted_thinking 또는 connector_text제거.
마지막 fallback 블록 이전의 클라이언트 측 tool_use제거.
마지막 fallback 블록 이전의 server_tool_use결과와 쌍을 이루는 경우 유지. 일치하는 결과가 없으면 제거.

스트리밍

스트리밍 요청에서는 재시도가 동일한 스트림에서 이루어지며, 이미 받은 내용은 무효화되지 않습니다. 보이는 내용은 거절이 언제 발생하는지에 따라 달라집니다.

출력이 전혀 없는 상태에서 거절이 발생한 경우:

  • message_start는 폴백 모델의 이름을 나타내며, fallback 블록이 첫 번째 콘텐츠 블록입니다.
  • message_start는 폴백 시도가 시작될 때까지 기다리므로, 첫 바이트까지의 시간에 거절된 시도가 포함됩니다.

출력 중간에 거절이 발생한 경우:

  • 열려 있는 콘텐츠 블록이 닫히고, fallback 블록(델타가 없는 일반 content_block_startcontent_block_stop 쌍)이 경계를 표시합니다.
  • 폴백 모델은 부분 출력에서 이어서 진행합니다. 부분 출력의 text 블록만 폴백 모델에 컨텍스트로 전달됩니다. 다른 블록 유형은 content에 남아 있습니다.
  • message_start는 이미 요청된 모델의 이름을 나타냈으므로, 처리한 모델은 fallback 블록의 to.model과 최종 message_deltausage.iterations에 있는 fallback_message 항목에서 읽으세요.

비스트리밍 응답

비스트리밍 요청에서는 출력 중간 거절이 다르게 동작합니다. 응답은 거절된 모델의 부분 출력을 생략하고, 폴백 모델이 처음부터 답변합니다. 결과는 출력이 전혀 없는 상태에서의 거절처럼 보이며 fallback 블록이 맨 앞에 옵니다. 거절된 시도와 그 출력 토큰은 여전히 usage.iterations에 표시됩니다.

청구 및 속도 제한

출력을 생성하기 전에 거절한 시도는 청구되지 않습니다. 해당 토큰은 usage.iterations 항목에 보고되지만 청구되지 않습니다. 응답 도중에 거절한 시도를 포함하여 출력을 생성한 모든 시도는 이를 실행한 모델의 요율로 별도 청구됩니다. usage.iterations 배열은 청구 내역에 대한 시도별 기록입니다. 최상위 usage 수치는 반환된 메시지를 생성한 시도만 설명합니다. 서로 다른 모델의 토큰은 하나의 필드로 합산되지 않습니다.

거절한 시도를 포함하여 실행된 모든 시도는 해당 모델 자체의 속도 제한에 반영됩니다.

고정 라우팅

대화가 폴백된 후 API는 어떤 모델이 이를 처리했는지 기록합니다. 해당 대화에 대해 fallbacks를 포함하는 이후 요청은 요청된 모델을 실행하지 않고 해당 폴백 모델로 바로 전달됩니다. 이를 통해 매 턴마다 예측 가능하게 다시 거절될 시도에 대한 비용 지불을 피할 수 있습니다.

라우팅 결정의 몇 가지 속성:

  • 약 1시간 동안 유지되며 조직 범위로 한정됩니다.
  • 대화 접두부의 콘텐츠 해시와 이를 처리한 모델로 저장됩니다. 메시지 콘텐츠 자체는 저장되지 않습니다.
  • 최선 노력(best-effort) 방식이므로, 코드는 언제든지 요청된 모델이 다시 시도되는 경우를 처리해야 합니다.

고정 라우팅은 스트리밍 및 비스트리밍 요청 모두에 적용됩니다. 스트리밍 요청에서는 스트림이 열리기 전에 라우팅 결정이 이루어지므로, message_start 이벤트의 model 필드에 이미 폴백 모델의 ID가 포함됩니다.

SDK 미들웨어를 사용한 클라이언트 측 폴백

모든 Anthropic SDK에는 거부 폴백 미들웨어가 포함되어 있습니다. 폴백 모델 목록과 함께 클라이언트에서 한 번 구성하면 됩니다. 그러면 client.beta.messages를 통한 호출은 모든 플랫폼에서 거부된 요청을 자동으로 재시도합니다. 미들웨어는 또한 처리하는 모든 요청에 fallback-credit-2026-07-01 베타 헤더를 보내므로, 요청별 설정 없이 재시도 가격이 재산정됩니다.

설정하기

미들웨어를 클라이언트 생성자에 전달하고, 대화의 요청 전반에 걸쳐 하나의 BetaFallbackState 인스턴스를 공유하세요.

from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware

# 거부 시 미들웨어는 나열된 폴백 모델로 재시도하고
# 처리하는 모든 요청에 fallback-credit 베타 헤더를 자동으로 전송합니다.
client = Anthropic(
    middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)

state = BetaFallbackState()  # pins follow-ups to the model that accepted

# 스트리밍: 거부 시 미들웨어는 폴백 모델로 재시도하고
# 해당 이벤트를 열려 있는 스트림에 이어 붙입니다.
with (
    state,
    client.beta.messages.stream(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    ) as stream,
):
    for text in stream.text_stream:
        print(text, end="", flush=True)
    final_message = stream.get_final_message()
print(f"\nserved by: {final_message.model}")

# 비스트리밍: 상태를 재사용하면 대화가 고정된 상태로 유지됩니다.
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}")

동작 방식

  • 재시도는 폴백 목록을 순서대로 진행합니다. 폴백 모델 자체가 거부하면 요청을 다음 항목으로 넘깁니다.
  • 목록의 모든 모델이 거절하면 미들웨어는 오류를 발생시키지 않고 최종 거부(마지막 모델의 거부 응답)를 반환합니다.
  • Claude Fable 5.1 또는 Claude Fable 5의 사고 블록은 변경 없이 통과됩니다. 각 재시도는 원래 요청 본문을 다시 보내며, 미들웨어가 이후 요청에서 대화 기록에서 제거하는 유일한 블록은 자신이 추가한 fallback 경계 블록입니다. 폴백 모델은 Claude Fable 5.1 블록을 읽을 수 없으며, 이 블록은 해당 모델 또는 더 새로운 모델에 대해서만 보존되므로 API가 이를 제거합니다.
  • 미들웨어를 통해 처리된 응답에는 서버 측 폴백 응답과 마찬가지로 각 모델 경계에 fallback 콘텐츠 블록이 포함됩니다. 미들웨어는 이후 요청에서 해당 블록을 대신 관리합니다.
  • 수락한 모델은 BetaFallbackState에 기록되므로, 상태를 공유하는 후속 요청은 거부한 모델에 다시 묻지 않고 해당 모델에 고정됩니다.

재시도 직접 작성하기

원시 HTTP를 사용하거나 사용자 정의 재시도 로직을 사용하는 경우, 미들웨어가 래핑하는 패턴을 구현하세요:

  1. 거부 감지

    응답에서 stop_reason: "refusal"을 확인하세요.

  2. 폴백 모델에서 다시 보내기

    model을 Claude Opus 4.8과 같은 폴백 모델로 설정하여 동일한 요청을 보내세요. Claude Fable 5.1 또는 Claude Fable 5가 거절한 요청은 일반적으로 다른 모델이 처리할 수 있습니다. 대화 기록을 처리하는 방법은 폴백 크레딧을 사용하는지 여부에 따라 달라집니다:

    • 크레딧을 사용하지 않는 경우: 이전의 thinkingredacted_thinking 블록을 그대로 두거나 입력 토큰을 절약하기 위해 제거할 수 있습니다. 어느 쪽이든 폴백 모델은 이를 사용할 수 없습니다. Claude Fable 5 블록은 무시하며, Claude Fable 5.1 블록은 해당 모델 또는 더 새로운 모델에 대해서만 보존되므로 API가 이를 제거합니다.
    • 크레딧을 사용하는 경우: 사용에는 정확한 일치가 필요하므로 본문을 변경 없이 보내세요. 크레딧 사용 시 서버가 이전 모델의 사고 블록을 처리하므로 제거하지 마세요(거부된 요청과 일치해야 하는 필드 참조).
  3. 폴백 모델 유지

    멀티턴 대화의 경우 다시 전환하지 말고 후속 턴에서도 폴백 모델을 계속 사용하세요.

수동 재시도는 폴백 모델의 프롬프트 캐시를 처음부터 작성하므로 기존 캐시를 읽는 것보다 비용이 더 듭니다. 폴백 크레딧은 해당 비용을 환급해 주므로, 직접 구축하는 모든 재시도에서 이를 사용하세요.

Message Batches에서의 거부

Message Batch에서 거부된 요청은 stop_reason: "refusal"과 함께 result.type: "succeeded"로 반환됩니다. 배치 결과는 동기 응답과 동일한 stop_details 객체를 포함하므로, stop_reason 또는 stop_details.type을 통해 거부를 감지할 수 있습니다. 한 가지 차이점: 배치 거부는 폴백 크레딧을 발행하지 않으므로, 배치 결과의 stop_details에는 fallback_credit_token이 포함되지 않습니다.

서버 측 폴백은 배치에서 사용할 수 없습니다(fallbacks를 포함하는 배치 요청은 항목별 오류 결과를 생성합니다). 거부된 배치 항목을 재시도하려면:

  1. 결과에서 거부된 항목을 수집합니다.
  2. 멀티턴 기록에서 Claude Fable 5.1 또는 Claude Fable 5 사고 블록을 제거합니다.
  3. 새 배치 또는 직접 요청으로 폴백 모델에 다시 제출합니다.

흔한 실수

  • 다른 모델에서 재시도하세요. 거부된 요청을 동일한 모델에 다시 보내면 대개 또 거부됩니다. 재시도는 폴백 모델을 대상으로 하세요.
  • 재시도 예산은 턴이나 세션 단위가 아닌 요청 단위로 책정하세요. 단일 턴에서 여러 거부가 발생할 수 있습니다(예: 에이전트와 그 하위 에이전트).
  • 모든 요청 경로에 폴백을 구성하세요. 재시도 핸들러, 오류 복구 분기, 백그라운드 워커 모두에 필요합니다. 폴백 없이 요청을 재발행하는 핸들러는 정확히 가장 필요할 가능성이 높은 요청에서 보호를 잃게 됩니다.
  • 하위 에이전트 호출에 자체 폴백을 부여하세요. fallbacks 매개변수는 도구 실행 내부에서 이루어지는 모델 호출로 전파되지 않습니다.
  • 폴백을 주변 상태가 아닌 요청의 속성으로 만드세요. 공유 플래그, 캐시된 구성 값 또는 전역 토글은 동기화가 어긋나 요청을 조용히 보호되지 않은 상태로 둘 수 있습니다. 폴백이 활성화되어 있는지 확인할 수 없다면 켜져 있다고 가정하지 말고 구성하세요.
  • 거부를 독자적인 신호로 계측하세요. 거부는 HTTP 200이므로 오류율이나 5xx 응답을 기반으로 구축된 모니터링은 이를 감지하지 못합니다. 거부마다 하나의 이벤트를, 폴백으로 처리된 응답마다 하나의 이벤트를 발생시키고(usage.iterationsfallback_message 항목이 후자를 표시합니다), 두 수치 간의 차이에 대해 알림을 설정하세요.
  • content나 내부 stop_details 필드가 아닌 stop_reason 또는 stop_details.type으로 분기하세요. stop_details 객체는 거부 시 항상 존재하지만, categoryexplanation 필드는 null일 수 있습니다. stop_reason"refusal"과 같은지 직접 확인하세요.

다음 단계

재시도를 직접 구축할 때 프롬프트 캐시 비용을 두 번 지불하지 않도록 하세요.

모든 stop_reason 값과 처리 방법.

거부 폴백 헬퍼를 포함한 SDK 미들웨어의 작동 방식.

기존 애플리케이션을 Claude Fable 5.1로 이전하세요.

Was this page helpful?