CCDV-F 备考手册 · Claude Certified Developer – Foundations
Chapter 16 · Domain 4(本章 skill 权重合计 2.6%)

调试与错误处理
先判 integration layer 还是 model output,再选恢复策略

TS 4.1 不奖励「看到 exception 就重试」。它考的是从 trace 识别错误类型、隔离失败源头,再把代码/配置/网络问题与 prompt/schema/输出校验问题交给不同修复路径。

一、第一刀:这次调用有没有形成完整 Message

诊断从证据边界开始,而不是从异常栈最末一行开始。先找 HTTP status、SDK exception、SSE event 与最终 Message:请求若在认证、权限、payload、rate limit、网络或服务端处理阶段失败,源头在 integration layer(集成层);API 若已经返回成功的 Message,再看 stop_reason 与 content,才能判断是正常完成、截断、工具交接,还是 model output(模型输出)不满足业务契约。

Trace 证据先归哪一层第一修法
非 2xx、typed SDK exception、没有 MessageIntegration修 request / credential / permission / payload;瞬时错误走 bounded retry
SSE 已是 HTTP 200,但出现 event: error,没有 final message_stopIntegration / stream把 partial response 标为未完成;按 event type 恢复或重试
成功 Message,stop_reason 是 max_tokens / tool_use 等Generation / output path按停止原因继续、执行工具或调整输出预算,不把它伪装成 parser bug
end_turn 且 content 完整,但 schema / business validation 失败Model output contract收紧 prompt / schema,并保留确定性 validation failure branch
P6 先分源头 — JSON.parse() 抛错只说明失败被 parser 看见,不说明根因在 JSON。上游若把 429 吞成空字符串,修的是 integration;上游若给出 end_turn 且正文多了一句 preamble,修的是 output contract。相同 exception 名可以来自两层。

二、错误名决定恢复;stop_reason 决定下一步

API 错误 body 是 JSON:顶层 error 对象含 type 与 message,另有 request_id;每个响应也有唯一 request-id header。把这些字段写进 trace,才能按类型聚合,而不是 string-match 一段会变化的自然语言错误。

HTTP / error type它指向什么恢复动作
400 invalid_request_errorrequest format / content修请求;不要重写业务 prompt 来掩盖无效 payload
401 authentication_error · 402 billing_error · 403 permission_errorcredential / billing / access修配置或授权;模型没有机会生成答案
404 not_found_error · 409 conflict_error · 413 request_too_largeresource / state / bytes核对 ID、先解决冲突、或缩小 payload
429 rate_limit_errorrate limit 或 spend cap遵守 retry-after;无该 header 的 spend-cap 429 不能靠紧密重试恢复
500 api_error · 504 timeout_error · 529 overloaded_errorserver / processing / temporary capacity指数退避;长请求考虑 streaming 或 batch,并保留 request ID

官方 SDK 会对 connection errors、rate limits 与 5xx 等瞬时失败用 exponential backoff 自动重试,默认两次,并在存在时遵守 retry-after。Trace 因此要记录 attempt:否则你会把「SDK 已重试三次总尝试」误读为三位用户各发了一次,或在外层再套无界重试。

stop_reason含义集成层下一步
end_turn自然完成使用 content,但仍做 schema / business validation
max_tokens触到请求或模型输出上限视为截断;提高预算或缩短输出后再校验
stop_sequence命中自定义 stop sequence读 stop_sequence 判断是哪条边界触发
tool_use模型发起一个或多个工具调用执行 client tool,并回传匹配的 tool_result
pause_turnserver-tool loop 触到 iteration limit把 assistant content 带回后续请求继续
refusalClaude 拒绝回应按 refusal 分支处理,不归为 network error
model_context_window_exceededgeneration 触到 context window视为截断并缩减 context / output 预算

三、让 trace 能分堆,而不是只会报一个 “parse_error”

最小可用 trace 至少保留:request_id、attempt、elapsed_ms、HTTP status / SDK exception、最后一个 SSE event、stop_reason、content block types、tool / permission stage,以及独立的 validation result。关键是不要把上游事实覆盖成下游症状:

{"req":"req_A","attempt":2,"http":529,"error":"overloaded_error","message":null}
{"req":"req_B","http":200,"stop_reason":"max_tokens","validation":"truncated_json"}
{"req":"req_C","http":200,"stop_reason":"end_turn","validation":"missing:currency"}
分堆证据该改什么不要改什么
Integrationreq_A:无 Message,529retry / backoff / capacity handlingprompt 与 output schema
Output-side limitreq_B:成功 Message,明确截断max_tokens、response scope、截断校验HTTP retry helper
Model outputreq_C:自然完成但契约不合格prompt / Structured Outputs / validationcredential 与 network timeout

Streaming 更要保留层级:SSE event stream 可能出现 event: error,而正常 flow 以 final message_stop 收口;收到 partial blocks 甚至 HTTP 200 都不能覆盖后续 error event。Claude 4.6 及之后如因 network / timeout 中断,可保存已收 text,再以 user message 携带 partial response 并要求继续;partial tool use 与 thinking block 不能这样恢复。没有 message_stop 的 partial text 不能直接当完整 model output 入库。

Claude Code 的 permission path 也是 integration/control plane 的子层:auto mode classifier 在 permissions system 之后运行;managed permissions.deny 会在 classifier 被咨询前阻断且不可覆盖。Trace 若写着 deny_match=true、classifier_invoked=false、tool_started=false,应修 permission 配置或应用的状态传播,不能靠改 prompt 让被 deny 的动作“更可信”。

P6 + P7 — 先把 failure 按源头分堆,再给每堆自己的 recovery;成功 Message 的 content 仍是待校验数据。若 529 与 schema mismatch 同时存在,正确答案必须同时修 integration 与 model-output contract,不能用一个统一的 “retry everything” 抹平层级。

本章题组

QUESTION 01 · TS 4.1 · AUTHENTICATION TRACE
A production call fails after 74 ms. The trace is {"http":401,"error":{"type":"authentication_error","message":"invalid x-api-key"},"request_id":"req_01K","message":null}. A downstream worker reports “Claude returned no JSON.” What should the team change first?
正确 C401 authentication_error、74 ms、message:null 已把失败定位在 credential/integration 层。先修 key loading,并让错误按错误传播;此时不存在可供 prompt 优化的模型输出。
D2 无关杠杆违反 P6A:few-shot 能影响成功调用后的输出形态,却不能让一个 401 请求进入生成阶段;它作用在错误发生之后的另一层。
D6 半对半错违反 P6B:catch typed error 是对的,伪造成空 JSON 则把 integration failure 再次改名为 output failure,破坏了 trace 的源头边界。
D4 换模型当解法违反 P6D:认证发生在模型生成之前;换模型不会改变 key 的有效性,也不会创造不存在的 Message。
QUESTION 02 · TS 4.1 · OUTPUT CONTRACT
An invoice extractor returns HTTP 200 with stop_reason:"end_turn". Its text is Here is the result:\n{"invoice_id":"I-73","total":91.4}, followed by SyntaxError: Unexpected token 'H' at JSON.parse (worker.ts:88:19). The same preamble appears in 116 of 1,000 successful calls. What is the best fix?
正确 A请求成功并自然结束,失败对象是 text 与 JSON contract 不一致。Structured Outputs 用 output_config.format 约束 schema;集成层仍保留 validation,符合 P7。
D2 无关杠杆违反 P6B:116/1,000 的稳定 preamble 是 output shape,不是 transport 中断;重试 network client 没有修 schema 契约。
D6 半对半错违反 P7C:catch 能防进程崩溃,但把未解析字符串冒充 validated JSON,正好删掉了下游需要的确定性边界。
D4 换模型当解法违反 P6D:trace 已定位为可表达的 output contract;换模型还顺带撤掉 validation,让概率性格式直接进入 billing。
QUESTION 03 · TS 4.1 · MID-STREAM ERROR
A streaming summarizer logs HTTP/1.1 200, two content_block_delta events containing 312 characters, then event:error data:{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}. The socket closes at 8.4 s and no message_stop arrives. How should the application classify and handle this trace?
正确 DSSE 可以在 HTTP 200 之后发 error event;overloaded_error 对应非 streaming 的 529。没有 final message_stop,partial text 不能冒充完整 output,应走 stream recovery。
D6 半对半错违反 P6A:200 只证明 stream 已建立;后续 error event 已否定「完整成功」。把 partial validation failure 记到模型层会污染两层指标。
D2 无关杠杆违反 P6B:overloaded_error 是容量错误,不是 max_tokens;调输出预算没有作用在已命名的失败类型上。
D3 措辞冒充控制违反 P3C:prompt 无法控制 API capacity;后半句还把未收口的 stream 当完成结果,既没有闸门也没有恢复分支。
QUESTION 04 · TS 4.1 · MAX_TOKENS
A non-streaming request returns {"http":200,"stop_reason":"max_tokens","usage":{"output_tokens":96},"content":[{"type":"text","text":"{\"items\":[{\"sku\":\"A1\""}]}. The parser raises JSONDecodeError: Expecting ',' delimiter. Network latency is 640 ms and no SDK exception was raised. What should be changed first?
正确 Bmax_tokens 明示成功调用停在 output-side limit,parser 只是下游观察点。先调 budget 或缩小 response scope,再由 validator 决定是否可用。
D6 半对半错违反 P7A:补括号可能让字符串可解析,却不能证明被截掉的 items 已恢复;它把 syntax repair 冒充 semantic completeness。
D2 无关杠杆违反 P6C:max_tokens 是成功 Message 的停止原因,不是 5xx;把 parser exception 送进 transport retry 分错了层。
D4 换模型当解法违反 P1D:题干给的是 96-token hard ceiling,不是能力不足;换模型并未放宽或缩减输出约束。
QUESTION 05 · TS 4.1 · TOOL LOOP
An order-status endpoint receives HTTP 200 with {"stop_reason":"tool_use","content":[{"type":"tool_use","id":"toolu_72","name":"lookup_order","input":{"id":"O-19"}}]}. The application stores that object as the final customer answer, never invokes lookup_order, and records “model returned no status text.” Where is the failure?
正确 Atool_use 是正式交接信号,不是缺文本。client tool 要由应用执行,再以相同 ID 回传 tool_result;漏掉这段代码才是 integration failure。
D5 错层承载违反 P4B:结构化 tool request 属于应用执行协议,把它降成普通 text 不会触发订单系统,也失去 ID 配对。
D5 错层承载违反 P4C:实时订单状态应来自外部 tool,不该让模型凭 prompt 生成;它把确定性数据访问搬回模型层。
D2 无关杠杆违反 P6D:trace 已显示正常 tool_use,重采样只是在逃避 integration 必须完成的 tool-result 往返。
QUESTION 06 · TS 4.1 · RATE-LIMIT RECOVERY
A worker trace shows 429 rate_limit_error with retry-after: 12. The SDK log records attempt=0 t=0.0s, attempt=1 t=12.1s, and attempt=2 t=36.4s, then raises the typed error; no Message was created. What is the best next step?
正确 C429、typed error、无 Message 是 integration failure。日志还证明 SDK 已按 retry-after 做完默认两次 retry;下一步应显式 backpressure / reschedule 或向上游报错,而不是让 output path 再试。
D2 无关杠杆违反 P6A:max_tokens 管输出上限,不管 rate limit;它没有作用在已命名的 429 源头上。
D6 半对半错违反 P6B:让 worker 不中断听起来稳健,但空字符串会把 integration failure 再包装成 model-output failure,并触发重复请求。
D4 换模型当解法违反 P1D:题干没有证明限额只绑定 model;立即并发回放还与已经观测到的 rate-limit signal 反向。
QUESTION 07 · TS 4.1 · PERMISSION LAYER
A Claude Code automation reports success even though production cleanup did not run. Its trace is {"permission_stage":"managed.permissions.deny","deny_match":true,"classifier_invoked":false,"tool_started":false}, followed by AdapterError: expected tool result, received PermissionDenied. Which diagnosis is most precise?
正确 Dmanaged deny 在 classifier 前阻断且不可覆盖;trace 也明确写着 classifier 未调用、tool 未启动。控制本身按设计工作,bug 是 adapter 把 PermissionDenied 映成 success。
D3 措辞冒充控制违反 P3A:CLAUDE.md 是 guidance,不是能替代 managed deny 的闸门;移除 deny 会破坏题干原有的强制边界。
D2 无关杠杆违反 P6B:exception 来自 adapter 收到 PermissionDenied,不来自一句成功措辞;重写输出没有补上状态传播代码。
D2 无关杠杆违反 P5C:官方层序和 trace 都说明 classifier 根本没运行;调它无法越过更早的 deny。
QUESTION 08 · TS 4.1 · MIXED FAILURE SET
A 10,000-call trace reports 800 failures. Of those, 300 are {"http":529,"error":"overloaded_error","message":null}. The other 500 are HTTP 200 with stop_reason:"end_turn", but validation says required property 'currency' missing. Which remediation plan matches the evidence?
正确 B300 条没有 Message,是 integration/capacity failure;500 条自然完成却少字段,是 model-output contract failure。两堆要分别用 bounded retry 与 schema + validation,正是 P6。
D6 半对半错违反 P6A:retry 对 529 是正当恢复,对稳定的 schema miss 却只是重新采样;一个动作只对了一半。
D6 半对半错违反 P6C:schema 正确修 500 条,但 529 根本没有 content;把无 Message 的失败归到输出层抹掉了 300 条 integration evidence。
D4 换模型当解法违反 P1D:题干已经给出两个不同的直接原因,换模型既不处理 API overload,也不建立字段校验契约。