■ stop_reason 으로 분기
표시가 없는 문장은 공식 문서에서 확인한 내용이에요. 다른 표시는 읽는 법
왜 배우나 — 시험이 요구하는 것
시험 목표 1.2 입력부터 피드백까지 구조 설계 · D1 설계 17%Design end-to-end architectures (input → processing → output → feedback loops)
이 개념으로 푸는 판단 (할 수 있어야 하는 것)
- 1.2② 앱은 다음 단계를 무엇으로 아나? — 처리 루프를 무엇으로 제어하나 (stop_reason)
- 5.2② HTTP 200 인데 content 가 비었다 — 어떻게 처리하나? — stop_reason 으로 분기하고 거절을 처리하기
- 4.6③ 5xx 오류율은 0 인데 "답이 비었다" 는 신고가 는다 — 거절(refusal)을 따로 계측하기
- 7.3③ API 오류가 쏟아질 때 무엇부터 보나? — 오류 종류별 대응 (재시도할 것 / 한도를 볼 것 / 오류가 아닌 것)
한눈에
모든 응답에는 stop_reason 이 있다. 이 값은 Claude 가 왜 멈췄는지 알려 준다. 앱은 HTTP 상태가 아니라 이 값으로 다음 걸음을 정한다
- 그대로 쓴다
- 이어 간다
- 재시도한다
- 다른 모델로 폴백한다
stop_reason 은 성공 응답 본문의 일부다. 오류(4xx·5xx)는 요청 처리 실패로 따로 온다
비유 컨테이너 종료 코드(0 정상 · 137 OOM)와 같다. "끝났다" 만 보고 코드를 안 보면 OOM 을 놓친다
ELI5
택배 기사가 문 앞에 쪽지를 붙이고 가는 것과 같아요.
- "배달 끝" 쪽지면 상자를 열면 돼요.
- "도장이 필요해요" 쪽지면 도장을 찍어 돌려줘야 다음 배달이 와요.
- "이 물건은 못 싣습니다" 쪽지가 붙어도 초인종은 똑같이 울려요.
- 그래서 초인종 소리만 듣지 말고 쪽지를 꼭 읽어야 해요.
개념 설명
원리
왜 따로 있나
- 오류(4xx·5xx)는 요청 처리가 실패한 것이다. stop_reason 은 처리는 성공했고, 생성이 왜 멈췄는지를 알려 준다. 둘은 다른 칸이다. 그래서 HTTP 상태만 보면 stop_reason 이 말하는 것을 전부 놓친다.
- 앱이 할 다음 걸음은 네 갈래다.
- 그대로 쓴다
- 이어 간다(tool_use · pause_turn · max_tokens)
- 잘렸다고 표시한다
- 다른 모델로 재시도한다(refusal)
이어가는 세 값의 차이
tool_use: 내 도구를 기다린다. 그래서 내가 tool_result 를 보낸다. 그 메시지에는 tool_result 만 넣는다(뒤에 텍스트를 붙이면 턴이 끝난다).pause_turn: 서버 도구(웹 검색 등) 루프가 반복 한도(기본 10회)에 걸렸다. 받은 assistant 콘텐츠를 그대로 돌려보낸다. 내 도구가 기다리는 중이면 절대 pause_turn 이 아니라 tool_use 가 온다.max_tokens: 내가 준 출력 한도에 걸렸다. 한도를 올리거나 이어서 생성한다.model_context_window_exceeded는 창 자체를 채운 것이다. 잘린 것으로 처리한다.
거절이 까다로운 이유
- 안전 분류기(Fable 5.1 · Fable 5 · Opus 5.5 · Opus 5)가 막으면 HTTP 200,
stop_reason: "refusal", 빈content가 온다. 오류가 아니라서 오류율·5xx 감시가 못 본다. - 같은 모델은 대개 또 거절한다. 다른 모델로 보내면 대개 답이 나온다. 그래서 처방은 폴백이다.
stop_details.category는 분야 이름일 뿐이다. null 이 정상 값일 수 있다. 그래서 분기 기준은stop_reason그 자체다.- 폴백은 "요청의 속성" 이다. 폴백을 안 단 경로(재시도 핸들러 · 백그라운드 워커 · 서브에이전트 호출)에는 폴백이 적용되지 않는다.
핵심 질문 두 개
- 앱은 다음 걸음을 무엇으로 정하나? HTTP 상태인가, stop_reason 인가?
- 거절이 나면 누가 보고, 어디로 다시 보내나?
규칙과 판단
갈림길
① 값별 할 일 [1.2②]
그대로 쓴다
자연 종료다
실행하고 결과를 돌려준다
tool_use 블록마다 tool_result 를 1개 보낸다
그대로 다시 보낸다
서버 도구 루프가 반복 한도(기본 10회)에 걸린 것이다. 받은 assistant 콘텐츠를 그대로 보내 이어 간다
한도를 올리거나 이어서 생성한다
max_tokens 한도에 도달한 것이다. 잘린 답에는 불완전하다는 안내를 붙인다
잘린 것으로 처리한다
모델 컨텍스트 창을 채운 것이다. 불완전하다는 안내를 붙이거나 이어서 생성한다
어느 것인지 읽는다
stop_sequence 필드를 읽는다
다음 물음 — 무엇으로 알아채나?
③④⑤ 거절 처리 [5.2②] [4.6③]
안 보인다
오류율·5xx 기반 감시에는 안 보인다
이것으로 분기하지 않는다
category·explanation 은 null 일 수 있다
대개 또 거절한다
재시도는 다른 모델로 한다
서버 측 fallbacks
한 번 왕복으로 끝난다. 베타다
SDK 미들웨어
클라이언트에 한 번 설정한다
모아서 다시 제출한다
배치에는 서버 측 폴백이 없다
⑤ 폴백 구멍 [5.2②] [7.3③]
안전 분류기 거절만 폴백한다
429·과부하·서버 오류는 그대로 돌아온다
앞 거절을 돌려준다
폴백 모델이 rate limit(속도 제한)·과부하 상태면 폴백하지 않는다. 앞 거절을 돌려준다(recommended_model 힌트)
따로 설정한다
fallbacks 는 도구 실행 안의 모델 호출로 번지지 않는다
모든 요청 경로에 단다
전역 플래그가 아니라 요청마다 단다
흐름
그림 속 이름·금액·시간·토큰 수는 예시예요. 공식 한도·동작은 카드 본문 값이 기준.
장면 글로 보기
칸 : 앱 → 주 모델 → 폴백 모델 → 도구
규칙 (앱) : HTTP 상태가 아니라 stop_reason 으로 다음 걸음을 정한다
질문 : 앱은 무엇을 보고 다음 걸음을 정할까?
① tool_use 루프 ✓
- 시작 : 앱 — 말 : “주문 #1042 어디쯤 왔어요?”
- 요청 : 앱 → 주 모델 — 쪽지 : user: 주문 #1042 어디쯤? / tools: [get_order]
- 멈춤 : 주 모델 → 앱 :
tool_use— 쪽지 : stop_reason: "tool_use" / get_order(1042) - 실행 : 앱 → 도구 : 도구를 실행한다 — 쪽지 : get_order(1042)
- 결과 : 도구 → 앱 — 쪽지 : 상태: "배송 중"
- 이어가기 : 앱 → 주 모델 : tool_result 만 담은 user 메시지 — 쪽지 : tool_result: / 상태: "배송 중"
- 답 : 주 모델 → 앱 :
end_turn이면 끝난다 — 쪽지 : stop_reason: "end_turn" / "지금 배송 중이에요" - 끝 : tool_use 면 실행하고 결과를 넣어 다시 보낸다. end_turn 이면 끝난다
② 거절하면 다른 모델로 ✓
- 시작 : 앱 — 말 : “(고객 문의 한 건)”
- 요청 : 앱 → 주 모델 — 쪽지 : model: Opus 5.5 / messages: 고객 문의
- 멈춤 : 주 모델 → 앱 : HTTP 200 + refusal — 쪽지 : HTTP 200 / stop_reason: "refusal" / content: []
- 재시도 : 앱 → 폴백 모델 : 같은 요청을 다른 모델로 보낸다 — 쪽지 : 같은 messages / → 폴백 모델
- 답 : 폴백 모델 → 앱 — 쪽지 : stop_reason: "end_turn" / content: 답 본문
- 끝 : 폴백 뒤 대화는 폴백 모델에서 이어 간다
③ 200 이니 성공 ≠
- 시작 : 앱 — 말 : “(고객 문의 한 건)”
- 건너뜀 : 폴백 모델
- 요청 : 앱 → 주 모델 — 쪽지 : model: Opus 5.5 / messages: 고객 문의
- 멈춤 : 주 모델 → 앱 : HTTP 200 + refusal — 쪽지 : HTTP 200 / stop_reason: "refusal" / content: []
- 표시 : 앱 : 빈 답을 성공으로 보여 준다 — 쪽지 : 화면: 빈 답 / 5xx 알림: 0건
- 끝 : 오류율·5xx 감시에는 안 보인다
나머지 규칙
-
tool_use 이어가기 : 다음 user 메시지에는 tool_use 블록마다 tool_result 를 1개씩 넣는다. 그 밖에는 아무것도 넣지 않는다. 같은
tools배열을 유지한다 [1.2②]tool_result 뒤에 텍스트를 붙이면 assistant 턴이 끝난다(기다리던 서버 도구가 있으면 400). 더 할 말은 턴이 끝난 뒤 별도 user 메시지로 보낸다
pause_turn 은 클라이언트 tool_use 가 기다리는 응답에는 절대 오지 않는다. 그때는 tool_use 가 온다
에이전트 루프에서는 tool_use 면 실행하고 결과를 넣어 다시 보낸다. end_turn 이면 끝난다 (Skilljar)
-
배치 : 거절 항목은
result.type: "succeeded"와stop_reason: "refusal"로 온다. 배치에는 서버 측 폴백이 없다(fallbacks를 넣으면 항목별 오류가 난다). 그래서 거절 항목만 모아 폴백 모델로 새 배치를 내거나 직접 요청한다. 자세한 것은 ◆ Batch API vs 동기 호출 에 있다 -
과금 : 출력 전 거절은
bio·frontier_llm·reasoning_extraction만 청구한다. 나머지 분류와 null 은 무료다 (2026-09-24 청구 재개 — 시험 뒤 변경). 스트림 중간 거절은 입력과 이미 나온 출력을 청구한다. 거절도 rate limit 에는 센다
규칙 원문 ①③④⑤ (갈림길로 그린 규칙)
-
값 7개와 할 일 [1.2②]
값 뜻 할 일 end_turn 자연 종료 그대로 쓴다 max_tokens max_한도 도달tokens 한도를 올리거나 이어서 생성한다 stop_sequence 내 stop_중 하나가 나왔다sequences stop_로 어느 것인지 본다sequence tool_use 도구 호출 실행하고 결과를 돌려준다 pause_turn 서버 도구 루프 반복 한도(기본 10회) 받은 assistant 콘텐츠를 그대로 다시 보내 이어 간다 refusal거절 stop_를 읽고 폴백 모델로 재시도한다details model_context_ window_ exceeded 모델 컨텍스트 창을 채웠다 잘린 것으로 처리한다 잘린 답(max_tokens · 창 초과)에는 불완전하다는 안내를 붙이거나 이어서 생성한다
스트리밍이면 stop_reason 은
message_start에서는 null 이다.message_delta에서 온다 -
거절은 HTTP 200 과
stop_reason: "refusal"로 온다.content는 비어 있다. 안전 분류기가 있는 모델은 Fable 5.1 · Fable 5 · Opus 5.5 · Opus 5 다 [5.2②]분기는
stop_reason(또는stop_details.type)으로 한다.content나category·explanation으로 분기하지 않는다. 둘 다 null 일 수 있다. null 자체가 정상 값이다. 나중에 채워질 자리표시가 아니다.explanation은 보여 주기만 하고 파싱하지 않는다재시도는 다른 모델로 한다. 같은 모델에 다시 보내면 대개 또 거절한다
스트림 중간에 거절하면 부분 출력은 불완전하다. 그래서 버린다. 폴백 뒤 멀티턴은 폴백 모델에서 이어 간다
-
거절은 따로 계측 : 거절은 오류율·5xx 기반 감시에는 안 보인다. 그래서 거절마다 이벤트를 1개 남긴다. 폴백으로 처리된 응답마다 이벤트를 1개 남긴다. 두 수의 차이에 알림을 건다 [4.6③]
Claude Code 는 거절에
api_error를 띄우지 않는다. 대신claude_code.api_refusal이벤트를 남긴다. 자세한 것은 ■ observability 세 신호 에 있다 -
재시도 세 방법 [5.2②] [7.3③]
상황 방법 Claude API, 가장 간단 서버 측 fallbacks(베타)다. 한 요청에 한 응답이다모든 플랫폼, Anthropic SDK SDK 미들웨어다. 클라이언트에 한 번 설정한다 raw HTTP · 직접 짠 재시도 직접 재시도하고 fallback credit 을 쓴다(프롬프트 캐시 값을 두 번 내지 않는다) "default"모드는 거절 분류별 권장 폴백 모델로 재시도한다. 권장이 없는 분류는 거절을 그대로 돌려준다 (2026-07-24 추가 — 시험 뒤 변경일 수 있다)폴백은 안전 분류기 거절에만 일어난다. 429·과부하·서버 오류는 그대로 돌아온다. 자세한 것은 ■ rate limit 에 있다
폴백 모델이 rate limit·과부하 상태면 폴백하지 않는다. 앞 거절을 돌려준다(
recommended_model힌트)구멍은 네 가지로 막는다
- 모든 요청 경로(재시도 핸들러 · 오류 복구 분기 · 백그라운드 워커)에 폴백을 단다
- 서브에이전트 호출에는 따로 단다
- 전역 플래그가 아니라 요청의 속성으로 단다
- 재시도 예산은 요청 단위로 잡는다
더 깊이 : 판단 규칙 · 상황 변수 (설명)
판단 규칙
| 조건 | 답 | 근거 |
|---|---|---|
| 응답을 받았다 | HTTP 상태가 아니라 stop_ 으로 분기한다 | handling-stop-reasons |
tool_ 다 | 도구를 실행한다. tool_use 블록마다 tool_result 를 1개 보낸다. 그 메시지에는 tool_result 만 넣고, 같은 tools 를 쓴다 | handling-stop-reasons |
pause_ 이다 | 받은 assistant 콘텐츠를 그대로 다시 보내 이어 간다 | handling-stop-reasons |
max_ · model_ 다 | 잘린 것으로 본다. 안내를 붙이거나 이어서 생성한다. max_tokens 는 한도를 올려도 된다 | handling-stop-reasons |
refusal 이다 | stop_ 으로 감지한다. 다른 모델로 재시도한다 | refusals-and-fallback |
| Claude API 에서 거절을 가장 간단히 재시도하려 한다 | 서버 측 fallbacks(베타)를 쓴다 | refusals-and-fallback |
| 여러 플랫폼에서 Anthropic SDK 로 거절을 재시도하려 한다 | SDK 미들웨어를 쓴다 | refusals-and-fallback |
| raw HTTP 로 거절을 재시도하려 한다 | 직접 재시도하고 fallback credit 을 쓴다 | refusals-and-fallback |
| 배치 항목이 거절됐다 | 거절 항목을 모아 폴백 모델로 새 배치를 내거나 직접 요청한다 (배치에는 서버 측 폴백이 없다) | refusals-and-fallback |
| 거절을 감시한다 | 거절 이벤트와 폴백 처리 이벤트를 따로 센다. 그 차이에 알림을 건다 | refusals-and-fallback |
| 스트리밍에서 stop_reason 을 읽는다 | message_ 이벤트에서 읽는다 (message_ 에서는 null) | handling-stop-reasons |
상황 변수
| 변수 | 값 | 답 쪽 | 등급 | 근거 |
|---|---|---|---|---|
| 감시 기준 | HTTP 오류율 · 5xx 만 본다 | 거절을 못 본다. 그래서 stop_reason 분포를 따로 센다 | refusals-and-fallback | |
| 감시 도구 | Claude Code OTel 이다 | 거절은 api_ 가 아니라 claude_ 이벤트로 온다 | monitoring-usage | |
| 실행 모델 | Fable 5.1 · Fable 5 · Opus 5.5 · Opus 5 | 안전 분류기 거절이 올 수 있다. 그래서 폴백이 필수다 | refusals-and-fallback | |
| 실행 모델 | 위 네 모델 밖이다 | 두 문서는 네 모델만 적는다 | 미해결 | 미해결 1 |
| 실행 방식 | 동기 · Claude API | 서버 측 폴백이 가능하다 | refusals-and-fallback | |
| 실행 방식 | Message Batches | 서버 측 폴백이 없다. 거절 항목만 다시 제출한다 | refusals-and-fallback | |
| 호출 구조 | 에이전트 + 서브에이전트 | 서브 호출에 따로 폴백을 단다. 재시도 예산은 요청 단위로 잡는다 | refusals-and-fallback | |
| 폴백 모델 상태 | rate limit(속도 제한) · 과부하 | 폴백을 시도하지 않는다. 앞 거절과 recommended_ 을 돌려준다 | refusals-and-fallback | |
| 실패 종류 | 429 · 529 · 5xx | 폴백 대상이 아니다. 재시도·백오프 쪽이다(■ rate limit) | refusals-and-fallback · errors(529 = 과부하) | |
| 거절 시점 | 스트림 중간 | 부분 출력은 버린다. 입력과 나온 출력을 청구한다 | refusals-and-fallback | |
| 거절 분류 | bio · frontier_ · reasoning_ | 출력 전 거절도 청구한다 | refusals-and-fallback (2026-09-24 재개) |
연습 문제
고객지원 채팅 앱이 Anthropic SDK 로 Opus 5.5 를 부르고, Claude API 말고 다른 클라우드 플랫폼에도 같은 앱을 올린다모든 플랫폼. 어떤 문의에 HTTP 200 인데 stop_reason 이 "refusal" 이고 content 가 빈 응답refusal이 왔다. 담당자는 "같은 요청을 같은 모델로 한 번 더 보내자"고 한다. 어떻게 처리해야 하나?
시험 대비
함정
- "HTTP 상태 코드로 실패·거절을 잡는다" 는 함정이다. 거절은 HTTP 200 이다
- "5xx 알림 임계값을 낮춘다" 는 함정이다. 거절은 5xx 가 아니다. 따로 센다
- "
stop_details.category로 거절을 분기한다" 는 함정이다. category 는 null 일 수 있다.stop_reason으로 분기한다 - "같은 요청을 같은 모델로 재시도한다" 는 함정이다. 대개 또 거절한다. 다른 모델로 보낸다
- "refusal 이면 끝이니 빈 답을 그대로 사용자에게 보낸다" 는 함정이다. 다른 모델로 보내면 대개 답을 얻는다
- stop_reason 을 5개로만 알고 '컨텍스트 창이 가득 차 멈춤' 보기를 버리는 것은 함정이다. 값은 7개다.
model_context_window_exceeded가 있다 - "
pause_turn은 오류이니 새 요청으로 보낸다" 는 함정이다. 받은 assistant 콘텐츠를 그대로 보내 이어 간다 - "폴백을 켜면 429·5xx 도 다른 모델로 간다" 는 함정이다. 폴백은 안전 분류기 거절에만 일어난다
- tool_result 와 같은 메시지에 추가 지시 텍스트를 붙이는 것은 함정이다. 턴이 끝난다. 추가 지시는 별도 user 메시지로 보낸다
신호
"Every Messages API response includes a stop_reason field that tells you why Claude stopped generating."
"Run the tool and return the result."
"Safety classifiers return this stop reason as a normal HTTP 200 response, not an error."
"Re-sending a refused request to the same model usually earns another refusal."
"A refusal is an HTTP 200, so monitoring built on error rates or 5xx responses never sees it."
"Only a safety classifier decline triggers the fallback."
"Check for stop_reason equal to "refusal" directly."
더 깊이 : 뒤집히는 때 · 오답 재료 (설명)
뒤집히는 때
1. "출력 전 거절은 공짜"가 분류 따라 뒤집힘
- 조건 : 2만 5천 토큰 요청이 Fable 5.1 에서 출력 전에 거절됐다.
- 계산 : 분류가
cyber면 $0 이다. 분류가bio면 25,000 × $10 / 1M = $0.25 다. 폴백(Opus 4.8)은 따로 25,000 × $5 / 1M = $0.125 에 출력 값이 더해진다. - 전제 : 캐시가 없다. 가격은 2026-09-28 조회값이다(ko-pricing). 폴백 쪽 출력 토큰은 뺀다.
- 등급 : 계산 (청구 분류는 확인). 2026-09-24 전에는 출력 전 거절이 모두 무료였다(릴리스 노트, 2026-06-02). 그래서 시험(2026-07 기준)은 "출력 전 거절은 과금되지 않는다" 로 물을 가능성이 있다.
- 근거 : refusals-and-fallback · 릴리스 노트
2. 폴백을 켰는데도 거절이 그대로 옴
- 조건 :
fallbacks를 설정했다. 부하가 몰려 폴백 모델이 rate limit 에 걸렸다. - 판단 : 폴백 시도를 건너뛰고 앞 거절을 돌려준다.
stop_details.recommended_model이 직접 재시도할 모델을 힌트로 준다(보장은 아니다). "폴백 켰으니 거절 0" 가정이 깨진다. 그래서 폴백 모델의 rate limit 을 예상 거절량에 맞춰 잡는다. - 근거 : refusals-and-fallback
3. 서브에이전트에서만 빈 답
- 조건 : 메인 호출에는
fallbacks가 있다. 도구 실행 안에서 부르는 서브에이전트 모델 호출에는 없다. - 판단 :
fallbacks는 도구 실행 안의 모델 호출로 번지지 않는다. 그래서 그 호출에 따로 설정한다. 한 턴에 거절이 여러 번(에이전트 + 서브에이전트) 날 수 있다. 그래서 재시도 예산도 요청 단위로 잡는다. - 근거 : refusals-and-fallback
4. max_tokens 로 멈춤 — 한도만 올리면 되나
- 조건 : 분류 답이 중간에 끊겼다. stop_reason 은
max_tokens다. - 판단 : 한도 올리기와 이어서 생성하기가 둘 다 공식 처방이다. 입력 크기를 몰라 최대치를 원하면, 컨텍스트 창 끝까지 쓰게 두고
model_context_window_exceeded로 받는 길도 있다. 비스트리밍 10분 제한과 스트리밍 전환은 이 카드 밖이다(4.5 쪽). - 등급 : (처방) · 업계 일반 (어느 쪽을 먼저 고를지)
- 근거 : handling-stop-reasons
오답 재료
| 오답 | 왜 끌리나 | 왜 틀리나 | 근거 |
|---|---|---|---|
| "HTTP 상태 코드로 실패·거절을 잡는다" | 보통 API 는 실패를 상태 코드로 알린다 | 거절은 HTTP 200 이다. stop_reason 은 성공 응답 본문의 일부다 | handling-stop-reasons |
| "5xx 알림 임계값을 낮춘다" | 빈 답이 장애로 보인다 | 거절은 5xx 가 아니다. 그래서 임계값을 바꿔도 안 잡힌다 | refusals-and-fallback |
| "같은 요청을 같은 모델로 재시도" | 일시 오류처럼 보인다 | 대개 또 거절한다. 다른 모델로 보낸다 | refusals-and-fallback |
| "refusal = 안전 거절로 끝, 빈 답을 사용자에게" | 안전 판단이니 존중해야 할 것 같다 | 다른 모델로 보내면 대개 답을 얻는다. 공식 처방은 폴백이다 | refusals-and-fallback |
"stop_ 를 읽어 분기" | 분야별 처리가 세밀해 보인다 | category·explanation 은 null 일 수 있다. stop_ 으로 분기한다 | refusals-and-fallback |
| '컨텍스트 창이 가득 차 멈춤' 보기를 "그런 값은 없다" 고 버린다 | stop_reason 을 5개로만 외웠다 | 값은 7개다. model_ 가 있다 | handling-stop-reasons |
"pause_ 은 오류이니 처음부터 새 요청" | '멈춤' 이라는 이름 때문이다 | 받은 assistant 콘텐츠를 그대로 보내 이어 간다 | handling-stop-reasons |
| "폴백을 켜면 429·서버 오류도 다른 모델이 받아 준다" | 폴백이 장애 조치로 보인다 | 안전 분류기 거절만 폴백한다. 나머지는 그대로 돌아온다 | refusals-and-fallback |
| "tool_result 와 같은 메시지에 '이제 요약해' 텍스트를 붙인다" | 한 번에 보내면 왕복이 줄어 보인다 | 턴이 끝난다(기다리던 서버 도구가 있으면 400). 턴이 끝난 뒤 별도 user 메시지로 보낸다 | handling-stop-reasons |
| "assistant 문장('완료했습니다')으로 루프 종료 판정" | 사람이 읽기에는 분명하다 | 루프는 stop_reason 으로 판정한다. end_turn 이면 끝난다 | Skilljar p101 486254 |
참고
더 깊이 : CCA-F · 출처 · 상태 · 미해결 (참고)
CCA-F
겹침 (에이전트 루프에서 tool_use 면 한 번 더 돌고 end_turn 이면 끝난다. 완료를 assistant 문장으로 판정하지 않는다). 여기서는 7값 전부의 처리와 거절(HTTP 200)을 설계·감시·폴백 경로 관점에서 묻는다
출처
- 가이드 목표 1.2 공식 시험 가이드 v1.0
- docs handling-stop-reasons
- refusals-and-fallback
- monitoring-usage
- 릴리스 노트
- Skilljar Platform 101 486254
상태
- 시험 뒤 변경 2곳(⑤ `"default"` 모드 · ⑦ 거절 청구 재개)
미해결
- 안전 분류기 거절 문서 두 개는 Fable 5.1 · Fable 5 · Opus 5.5 · Opus 5 만 적는다. 그 밖 모델(Sonnet 등)이
refusal을 내는지는 이 파일들에 없다. 릴리스 노트이 가리키는 streaming refusals 문서는 받지 않았다. fallbacks의"default"모드는 2026-07-24 에 추가됐다(릴리스 노트). 시험 가이드 기준(2026-07)에 들어갔는지 모른다. 그래서 시험은 "다른 모델로 재시도" 원칙만 물을 가능성이 있다(추론).- 목록 5.2② 는 "refusal 이면 stop_details(category·explanation)를 읽고" 였다. 공식은 분기를
stop_reason(또는stop_details.type)으로 하라고 한다. category·explanation 은 null 일 수 있다(refusals-and-fallback). 카드에는 고친 쪽만 적는다. - 목록 1.2② 의 "Part 17 팁이 오답으로 짚은 모양" 과 5.2② 의 "영상 목록 5개" 는 영상 쪽 기록이다. 그래서 원문 대조는 안 했다(영상 파일은 안 봤다).
- handling-stop-reasons 의 코드 예시(항상 확인 · pause_turn 재시도 · 이어서 생성)는 받은 파일에서 코드 블록이 빠져 있다( 뒤가 빈 절이다).