CCDV-F tests implementation judgment, not just recall — most of its harder questions hand you two or three mechanisms that all technically work, and ask which one fits the stated constraint. The traps are near-duplicates: a workflow versus an agent, a custom tool versus an MCP server, a retryable error versus a permanent one. Each pair has a real dividing line, and the exam is testing whether you know exactly where it falls.
This guide is independent and unofficial, not affiliated with Anthropic. Every section grounds its comparison in current platform.claude.com, code.claude.com, and modelcontextprotocol.io behavior — verify anything load-bearing before you rely on it, since these surfaces move fast.
Read each section as a decision, not a description. The table shows the axes that separate the options; the "Which one?" callout gives you the single question to ask; the trap warns you off the plausible-but-wrong answer; and the memory hook gives you something durable to carry into the exam.
Workflow vs. Agent
Both get a multi-step task done, so both look correct. The dividing line is who owns control flow. A workflow is your code, orchestrating LLM calls and tools through a predefined path (prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer). An agent hands that control to the model, which dynamically decides which tools to call and when, looping until it judges the task done.
| Dimension | Workflow | Agent |
|---|---|---|
| Purpose | A multi-step task whose path can be fully diagrammed in advance | An open-ended task whose path depends on what's discovered mid-task |
| When to use | You can enumerate the branches and steps before writing code | The number of steps or the branching genuinely can't be pre-specified |
| Cost or risk | Predictable, testable, cheaper — but can't handle genuinely novel paths | Higher latency/cost, compounding-error risk over the loop; needs guardrails and sandboxed testing |
| When NOT to use | Genuinely open-ended exploration where a fixed diagram would miss cases | Any task you could fully diagram in advance — the autonomy is wasted cost |
Synchronous vs. Streaming vs. Message Batches
All three call the same Messages API, so the confusion is real. The choice is about who's waiting and how long the work takes. Synchronous is a single blocking request-response. Streaming returns the same response incrementally over SSE as it's generated. Message Batches processes many requests asynchronously, decoupled from any live connection, with a much higher output-token ceiling (up to 300K in beta, vs. 128K synchronous).
| Dimension | Synchronous | Streaming | Message Batches |
|---|---|---|---|
| Purpose | One request, one response, nothing in between | Same as sync, but the client sees tokens as they're generated | Bulk asynchronous processing of many requests |
| When to use | Short, fast responses where blocking briefly is fine | Anything long-running or user-facing where perceived latency matters — Anthropic explicitly recommends this over sync for long requests | Nightly jobs, evals, backfills — nothing is waiting in real time |
| Cost or risk | Non-streaming requests risk an idle-connection timeout (~10 minutes) on long generations, and can silently fail with a large max_tokens | Requires SSE-handling on the client; no idempotency guarantee any more than sync | Higher token ceiling per request, but results aren't immediate — not for interactive use |
| When NOT to use | A generation likely to run long — you're risking a silent timeout failure | A short, fast, one-shot call where streaming adds client complexity for no benefit | Anything a user is actively waiting on right now |
Custom Tool vs. Built-in Tool vs. Skill vs. MCP Server
All four give Claude a new capability, which is why they're easy to conflate. The differences are who hosts it, how much control you get, and how many consumers reuse it.
| Dimension | Built-in tool | Custom client-side tool | Skill | MCP server |
|---|---|---|---|---|
| Purpose | Anthropic-hosted capability (web_search, code_execution, etc.) | You define the schema and execute it yourself | Packaged, on-demand capability/instructions inside Claude Code specifically | A standardized, reusable integration surface any MCP client can connect to |
| When to use | The exact capability you need already exists and needs no customization | You need full control over execution and data access | Repeatable capability used only within Claude Code sessions | The same tool/resource must be reusable across multiple different AI hosts/apps, not just one Claude Code instance |
| Cost or risk | Least effort, least control — you can't customize behavior | You own hosting, security, and maintenance | Loads into context on demand (not resident like CLAUDE.md) — cheap until invoked | You run/operate a server; protocol overhead pays off through reuse |
| When NOT to use | You need custom logic or data access it doesn't provide | A capability Anthropic already hosts well (reinventing it) | A capability that needs to work outside Claude Code | A single, one-off integration for exactly one consumer — the server is unjustified overhead |
Retryable vs. Permanent Errors — and Why Retrying Isn't Automatically Safe
Every error the Messages API returns falls into exactly one of two buckets, and the exam expects you to sort them without hesitation. But there's a second axis candidates often miss: even a correctly-classified retryable error can cause harm if the original request already had a side effect.
| Dimension | Retryable | Permanent |
|---|---|---|
| Codes | 429, 500, 504, 529, network errors | 400, 401, 402, 403, 404, 409, 413 |
| What it means | A transient condition — rate limit, server hiccup, overload — likely to resolve | The request itself is wrong or unauthorized — retrying it changes nothing |
| Correct response | Exponential backoff, honoring retry-after; SDKs do this by default (~2 retries) | Fix the request (auth, payload, permissions) before sending again — retrying blindly wastes calls |
| The catch | A spend-cap 429 is retryable-shaped but won't resolve until the next billing cycle — no retry-after is given | There's no documented idempotency-key mechanism — retrying a request with a side-effecting tool call can duplicate that side effect |
Direct vs. Indirect Prompt Injection
Both are "prompt injection," which is why candidates conflate them — but the adversary is different, and so is the defense. Direct injection: the end user themselves is trying to manipulate the model. Indirect injection: the user is trusted, but third-party content the app pulls in (a document, a web page, a tool result) carries hidden instructions.
| Dimension | Direct injection | Indirect injection |
|---|---|---|
| Who's the adversary | The end user | Third-party content the app retrieves on the user's behalf |
| Documented mitigations | Harmlessness screens (a cheap classifier checking input), input validation against known patterns, hardened system prompts, throttling repeat offenders | Untrusted content only in tool_result blocks, never in system or plain user text; label its source/type; JSON-encode it; never embed app instructions inside a tool_result |
| Where it shows up | Chatbots, public-facing generation endpoints | RAG pipelines, web-browsing tools, any tool that fetches external content |
| When NOT to apply it | Applying indirect-injection defenses (content labeling) doesn't substitute for direct-injection defenses (input validation) — they cover different attack surfaces |
Claude Agent SDK vs. Managed Agents vs. Raw API Tool-Use
All three let you build an agent, at three different points on the build-vs-host spectrum. Raw API tool-use is the lowest level — you call client.messages.create with tools and build your own harness/loop around it. The Claude Agent SDK packages the full Claude Code harness (built-in tools, agent loop, context management, hooks, subagents, MCP, permissions, session resume/fork) as a callable library — you still deploy and host it yourself. Managed Agents goes further and hosts the sandbox for you as well.
| Dimension | Raw API tool-use | Claude Agent SDK | Managed Agents |
|---|---|---|---|
| Purpose | Full control, build your own harness from scratch | Full Claude Code harness as a library — you deploy it | Anthropic hosts the agent and its sandbox for you |
| When to use | You need a bespoke loop with no built-in tools/harness assumptions | You want Claude Code's built-in tools/hooks/subagents but need to host it yourself (custom infra, on-prem, specific deployment constraints) | You want the least operational overhead and don't need to host anything yourself |
| Cost or risk | You build and maintain the entire harness | You still own hosting/deployment/ops for the harness | Least control over the hosting environment, most convenience |
| Language support | Any language the API supports | Python and TypeScript officially — other languages shell out to the claude CLI | N/A — you're not writing the harness |
Key takeaways
- 01Workflow vs. agent is decided by whether the control flow can be fully diagrammed in advance, not by how many steps a task has.
- 02Choose sync/streaming/Batches by two questions in order: is anything blocked waiting, and could the response take a while to generate?
- 03For a new capability, check built-in tool, then MCP server (multi-host reuse), then Skill (Claude-Code-specific, on-demand), then custom tool, in that order.
- 04Error classification (retryable vs. permanent) and idempotency safety are two separate questions — the API answers the first, your application has to answer the second.
- 05Direct injection (the user) and indirect injection (fetched content) need different, specific mitigations — content labeling doesn't substitute for input validation or vice versa.
- 06Raw tool-use, the Agent SDK, and Managed Agents sit on a build-vs-host spectrum — the Agent SDK is still self-hosted, only Managed Agents removes hosting responsibility.
Common mistakes
Picking the more autonomous, more infrastructure-heavy option because it sounds more capable.
Every comparison above rewards the least complex mechanism that satisfies the stated constraint — treat extra autonomy or infrastructure as a cost to justify, not a default.
Assuming a mitigation for one attack surface (direct injection) covers an adjacent one (indirect injection).
Match the defense to the specific adversary in the scenario — user-typed input vs. fetched third-party content need different documented mitigations.
Treating error-code classification as the whole answer to "is it safe to retry?"
Retryable-vs-permanent tells you whether the API will accept a retry. Whether retrying is safe for your application depends on whether the failed request had a side effect — a separate question the API doesn't answer for you.
Frequently asked
Is this the same content as the domain guides, just condensed?
No — the domain guides teach each topic on its own. This guide is specifically about the pairs and groups of options that look interchangeable on the exam, with the decision rule that separates them.
Which comparison is most likely to show up given the domain weights?
Synchronous vs. streaming vs. Batches and the tool/Skill/MCP decision are the highest-value ones to know cold — they sit inside Applications & Integration (33.1%) and Tools & MCPs (10.6%), two of the three largest domains.
Independent, unofficial study material. Not affiliated with, endorsed by, or authorized by Anthropic. Every example is original and written to teach the public exam objectives — no real exam questions are reproduced. Technical details reflect Claude, the Anthropic API, Claude Code, and MCP as of August 24, 2026; always confirm specifics against current official documentation.
Test yourself
Turn what you just read into answers you can check.