Claude Agent SDK Tutorial: CCDV-F Developer Exam Guide
A practical claude agent sdk tutorial mapped to CCDV-F exam domains: agentic loops, tool use, MCP integration, model selection, and structured output. $125, 53 items.
By Solomon Udoh · AI Architect & Certification Lead

This claude agent sdk tutorial is written for developers preparing for the Claude Certified Developer, Foundations exam (CCDV-F). We cover the Anthropic Python SDK patterns that appear most frequently across the eight CCDV-F domains, with exam-framing throughout. If you have already worked through our Agentic Architecture & Orchestration concepts, this post is the practical complement: code first, theory second.
The CCDV-F exam costs $125, runs 53 items in 120 minutes, and is scored on a 100-to-1000 scale with a passing bar of 720. Unlike the Architect track, it has no scenario bank; every item is written directly against the domain skills. That means the exam rewards breadth across all eight domains, not depth in one.
What does the CCDV-F exam actually test about agents and workflows?
Domain 1 (Agents and Workflows, 14.7%) and Domain 2 (Applications and Integration, 33.1%) together account for nearly half the exam. Domain 1 asks you to distinguish when a deterministic workflow is the right choice versus when a fully autonomous agent is warranted. Domain 2 asks you to choose between synchronous Messages API calls, streaming, and Message Batches for different latency and throughput requirements.
The exam's central judgment call in Domain 1 is this: a deterministic workflow is preferable when steps are fixed, verifiable, and require human escalation points. An autonomous agent is preferable when the task space is open-ended and the model must decide which tools to invoke and in what order. Confusing the two is the most common source of wrong answers in scenario items.
| Characteristic | Deterministic Workflow | Autonomous Agent |
|---|---|---|
| Step sequence | Fixed at design time | Decided at runtime |
| Branching | Explicit if/else in code | Model-driven tool selection |
| Human escalation | Structured handoff points | Requires explicit interrupt design |
| Verifiability | Each step auditable | Requires eval pipeline |
| Best for | Compliance, billing, ETL | Research, open-ended coding tasks |
How do you build a basic agentic loop with the Anthropic SDK?
The agentic loop is the foundation of every agent pattern on the exam. The loop runs until the model returns a stop_reason of "end_turn" rather than "tool_use". Understanding the stop_reason field inspection pattern is essential before writing a single line of agent code.
Here is a minimal, exam-accurate Python implementation:
import anthropicclient = anthropic.Anthropic()tools = [{"name": "get_weather","description": "Returns current weather for a city. Use when the user asks about weather conditions.","input_schema": {"type": "object","properties": {"city": {"type": "string", "description": "City name, e.g. 'London'"}},"required": ["city"]}}]def run_agent(user_message: str) -> str:messages = [{"role": "user", "content": user_message}]while True:response = client.messages.create(model="claude-opus-4-5",max_tokens=1024,tools=tools,messages=messages)# Append assistant turnmessages.append({"role": "assistant", "content": response.content})if response.stop_reason == "end_turn":# Extract final textfor block in response.content:if block.type == "text":return block.textreturn ""if response.stop_reason == "tool_use":tool_results = []for block in response.content:if block.type == "tool_use":result = dispatch_tool(block.name, block.input)tool_results.append({"type": "tool_result","tool_use_id": block.id,"content": result})# Append tool results as user turnmessages.append({"role": "user", "content": tool_results})def dispatch_tool(name: str, inputs: dict) -> str:if name == "get_weather":return f"Weather in {inputs['city']}: 18°C, partly cloudy."return "Tool not found."
Three exam-critical details in this snippet:
- The assistant turn is appended before checking
stop_reason. Skipping this step breaks the conversation history requirement. - Tool results are sent back as a
"user"role message, not an"assistant"message. - The loop terminates on
"end_turn", not on an empty tool list. Terminating early is the agentic loop anti-pattern the exam tests most often.
How do you choose between synchronous calls, streaming, and Message Batches?
Domain 2 (33.1% of the exam) is the heaviest domain and it centres on this decision. The exam presents scenarios with latency, throughput, and cost constraints and asks you to select the right API surface.
| API Surface | Latency | Throughput | Cost | Best scenario |
|---|---|---|---|---|
messages.create (sync) | Low | Low | Standard | Interactive chat, single-turn agents |
messages.stream (streaming) | Low perceived | Low | Standard | Long responses, real-time UI feedback |
messages.batches.create | High (up to 24 h) | Very high | 50% discount | Bulk eval, offline enrichment, nightly jobs |
The Message Batches API is the exam's favourite cost-optimisation lever. When a scenario describes thousands of independent, non-time-sensitive requests, Message Batches is almost always the correct answer. Streaming is correct when the scenario describes a user waiting for a long response and perceived latency matters.
# Message Batches example: submit 3 independent requestsimport anthropicclient = anthropic.Anthropic()batch = client.messages.batches.create(requests=[{"custom_id": "req-001","params": {"model": "claude-haiku-4-5","max_tokens": 256,"messages": [{"role": "user", "content": "Summarise: The quick brown fox."}]}},{"custom_id": "req-002","params": {"model": "claude-haiku-4-5","max_tokens": 256,"messages": [{"role": "user", "content": "Summarise: Lazy dogs sleep well."}]}},{"custom_id": "req-003","params": {"model": "claude-haiku-4-5","max_tokens": 256,"messages": [{"role": "user", "content": "Summarise: Rain falls on rooftops."}]}}])print(batch.id) # Use this to poll for results
Note the custom_id field. The exam tests whether you know that custom_id is how you correlate batch results back to your input records when results arrive out of order.
How do you design tools and integrate MCP servers for the exam?
Domain 8 (Tools and MCPs, 10.6%) and Domain 2 overlap on tool design. The exam's core principle: the model selects tools based on their descriptions, not their names. A vague description causes misrouting; a precise description with scope and constraints prevents it. See our Tool Descriptions as Selection Mechanism concept for the full pattern.
# Poorly described tool -- causes misrouting on the exambad_tool = {"name": "query_db","description": "Query the database.","input_schema": {"type": "object", "properties": {"query": {"type": "string"}}}}# Well-described tool -- exam-correctgood_tool = {"name": "query_orders_db","description": ("Executes a read-only SQL SELECT against the orders database. ""Use ONLY for retrieving order status, history, or line items. ""Do NOT use for customer profile data or inventory queries."),"input_schema": {"type": "object","properties": {"sql": {"type": "string","description": "A valid SELECT statement. No DDL or DML permitted."}},"required": ["sql"]}}
For MCP integration, the exam tests the isError flag pattern. When a tool call fails, the MCP server should return isError: true with structured metadata rather than raising an exception that crashes the agent loop. This keeps the model informed and allows it to retry or escalate gracefully.
{"isError": true,"content": [{"type": "text","text": "OrdersDB connection timeout after 5000ms. Retry after 30s or escalate to on-call."}]}
Tool descriptions are the primary mechanism by which Claude selects among available tools. A description that clearly states what the tool does, when to use it, and when NOT to use it dramatically reduces misrouting in multi-tool agents.
How do you select the right Claude model for CCDV-F scenarios?
Domain 5 (Model Selection and Optimisation, 16.8%) is the third-heaviest domain. The exam presents scenarios with quality, cost, and latency constraints and asks you to justify a model choice. The three axes are always the same: quality, cost, and latency. No single model wins on all three.
| Model | Relative quality | Relative cost | Relative latency | Typical exam scenario |
|---|---|---|---|---|
| claude-haiku-4-5 | Good | Lowest | Fastest | High-volume classification, batch enrichment |
| claude-sonnet-4-5 | High | Mid | Mid | Most production agents, interactive tools |
| claude-opus-4-5 | Highest | Highest | Slowest | Complex reasoning, low-volume high-stakes tasks |
The exam's standard wrong answer is choosing Opus for every scenario because "quality matters". The correct answer weighs all three axes against the scenario's stated constraints. A nightly batch job classifying 50,000 support tickets should use Haiku; a one-off legal document analysis can justify Opus.
How do you handle prompt and context engineering for reliable structured output?
Domain 6 (Prompt and Context Engineering, 11.0%) tests your ability to prevent context bloat, place instructions correctly, and produce reliable structured output. The exam's most-tested principle: instructions placed at the start of the system prompt and reinforced with a JSON schema in the tool definition produce more reliable output than instructions buried mid-conversation.
# Reliable structured output via tool forcingresponse = client.messages.create(model="claude-sonnet-4-5",max_tokens=512,system="You are a data extraction assistant. Always respond using the extract_entity tool.",tools=[{"name": "extract_entity","description": "Extracts a named entity from text.","input_schema": {"type": "object","properties": {"entity_name": {"type": "string"},"entity_type": {"type": "string","enum": ["PERSON", "ORG", "LOCATION", "DATE"]},"confidence": {"type": "number","minimum": 0.0,"maximum": 1.0}},"required": ["entity_name", "entity_type", "confidence"]}}],tool_choice={"type": "tool", "name": "extract_entity"},messages=[{"role": "user", "content": "Anthropic was founded in San Francisco in 2021."}])
Setting tool_choice to a specific tool name forces the model to always call that tool, which is the exam-correct pattern for guaranteed structured output. The Prompt Engineering & Structured Output concept library covers the full decision tree for when to use tool forcing versus XML tags versus JSON mode.
How do you approach security and safety in developer-facing agents?
Domain 7 (Security and Safety, 8.1%) tests prompt-injection defence, data privacy, and safe output handling. The exam's primary principle: never trust tool output as safe input. A tool that returns data from an external source may contain injected instructions. The correct defence is to treat tool results as untrusted data and process them through a separate validation step before passing them back into the model's context.
import redef sanitise_tool_result(raw_result: str) -> str:"""Strip content that looks like injected instructions beforeappending tool results to the conversation."""# Remove patterns that attempt to override system instructionspatterns = [r"ignore (all |previous |above )?instructions",r"you are now",r"<\|system\|>",r"SYSTEM OVERRIDE"]cleaned = raw_resultfor pattern in patterns:cleaned = re.sub(pattern, "[REDACTED]", cleaned, flags=re.IGNORECASE)return cleaned
This is a simplified illustration. The exam does not expect you to write production-grade injection filters; it expects you to know that the threat exists, that tool results are a vector, and that validation before context insertion is the correct architectural response.
Developers should be vigilant about prompt injection attacks -- attempts by malicious content in the environment to hijack Claude's actions.
How does the CCDV-F exam weight map to study time?
With eight domains and fractional weights, prioritising study time is non-trivial. We recommend allocating study hours roughly proportional to domain weight, with a floor of one full session per domain regardless of weight.
| Domain | Weight | Recommended study share |
|---|---|---|
| Domain 2: Applications and Integration | 33.1% | 33% |
| Domain 5: Model Selection and Optimisation | 16.8% | 17% |
| Domain 1: Agents and Workflows | 14.7% | 15% |
| Domain 6: Prompt and Context Engineering | 11.0% | 11% |
| Domain 8: Tools and MCPs | 10.6% | 11% |
| Domain 7: Security and Safety | 8.1% | 8% |
| Domain 3: Claude Code | 3.1% | 3% |
| Domain 4: Eval, Testing and Debugging | 2.6% | 3% |
Domain 4 (Eval, Testing and Debugging, 2.6%) has the lowest weight but is disproportionately useful for debugging wrong answers in practice exams. Knowing how to write a rubric and catch regressions helps you understand why a distractor is wrong, not just why the correct answer is right.
What does the AI Skill Certs platform offer for CCDV-F prep?
Our adaptive engine uses Bayesian Knowledge Tracing with a 0.90 mastery threshold, so it keeps drilling you on weak domains rather than cycling through content you already know. Practice exams mirror the real format: 53 questions, scored 100 to 1000, with 720 as the passing bar.
Archie, our Socratic tutor, will not give you the answer directly. It guides with graduated hints, which is deliberate: the exam rewards judgment, not recall, and passive answer-reading does not build judgment. For the Context Management & Reliability and Tool Design & MCP Integration domains in particular, working through Archie's hints on scenario items is more effective than re-reading documentation.
AI Skill Certs is an independent prep platform. We are not affiliated with, endorsed by, or approved by Anthropic.
Frequently asked questions
What is the passing score for the CCDV-F exam?
How many questions are on the CCDV-F exam and how long is it?
Which CCDV-F domain has the highest exam weight?
Does the Anthropic SDK support streaming responses for agents?
How do I force structured JSON output with the Anthropic SDK?
Is the CCDV-F exam the same as the CCAR-F Architect exam?
People also ask
What is the Anthropic SDK used for?
How do Claude agents handle tool use in a loop?
When should I use Message Batches instead of the synchronous Messages API?
How does MCP integration work with Claude agents?
Which Claude model should I use for a production agent?
About the author
AI Architect & Certification Lead
Solomon Udoh is an AI Architect who designs and ships production agent systems on the Claude API and Claude Code. He built AI Skill Certs' adaptive engine and authored its 174-concept knowledge graph, mapping every Claude Certified Architect - Foundations objective to hands-on, exam-aligned practice.
- Designs production multi-agent systems on the Claude API and Agent SDK
- Author of the AI Skill Certs knowledge graph (174 mapped exam concepts)
- Builds with MCP, Claude Code, structured outputs, and agentic loops daily
- Reviews every concept page against the official Anthropic exam guide
You might also like
Ready to put it into practice?
Study every exam concept with an adaptive tutor.