The CCA-Foundations Exam, and How This Book Prepares You

What the Claude Certified Architect – Foundations exam (CCAR-F) actually measures — the five weighted domains, the scenario format, the 720-to-pass bar — and how this book maps to the blueprint, built and verified against a stated, dated package matrix rather than a single pin.

This is an independent study guide for the Claude Certified Architect – Foundations exam. It is not affiliated with, authorized by, or endorsed by Anthropic, and it confers no credential of its own.

Five weighted exam domains lead into six production scenarios and a study route that separates durable architecture from a dated compatibility baseline.

The Claude Certified Architect – Foundations exam (code CCAR-F) covers production systems built with Anthropic’s stack: agents, MCP tools, Claude Code workflows, structured output, and context management. The chapters work through those systems with code that was run rather than recalled. The aim is that you pass because you can build the systems the blueprint describes, not because you can recite it.

Keep the compatibility tables nearby when running the code; they distinguish the releases tested for the book from whatever is installed on your machine.

What the exam is

The format matters, because it shapes how you should study.

  • 60 items, multiple-choice and multiple-response. Each item tells you how many answers to select, so a “select all that apply” will not blindside you.
  • Scenario-based. The exam draws 4 scenarios at random from a bank of 6 (below), and the questions hang off those scenarios. You are not answering trivia; you are reasoning about a described production system.
  • 120 minutes. That is two minutes per item. But the scenario text is shared across several items, so the real budget is closer to this: read a scenario once, carefully, then answer its cluster quickly.
  • Passing score: 720 on a 100–1,000 scale. Your report is pass/fail plus a percent-correct by domain, so a weak domain shows up even if you pass.
  • $125 USD, proctored (online or test center), credential valid 12 months.

One thing to be precise about: 720 is a scaled score, not a percentage. The mapping from raw items to scaled points is Anthropic’s, and it is not published. So do not compute “I need 43 of 60” and study to that number. Use the domain weights to decide where your hours go. Treat every item as one you intend to get right.

Where these numbers come from. Every figure in this section is taken from the Claude Certified Architect – Foundations Exam Guide, version 1.0, effective July 2026, which Anthropic publishes to registered candidates through the Partner Academy and describes itself as “the authoritative reference for candidates preparing to sit the exam”. The guide is dated and says it is subject to change without notice, so treat what follows as a snapshot: read the current guide before you register. Registration runs through the Partner Academy and the exam is delivered by Pearson VUE, online-proctored or at a test centre, with a pass earning a digital badge through Credly. You may reschedule up to 24 hours before your appointment; inside that window the fee is forfeit. The credential lasts 12 months and renews through a free, non-proctored assessment — let it lapse and you sit the full exam again at full price.

Practice reasoning from a scenario’s constraints. For a support agent with four tools and an 80%-resolution target, for example, explain when it should escalate and what evidence the next person will need. Knowing what each tool does is only the starting point.

The blueprint: five weighted domains

The exam is built from five content domains, weighted by how much they matter to competent performance. The percentages are official: they are the published share of scored items from each domain. The item column is not official. It is that share applied to 60 and rounded, which is a planning estimate rather than a promise about any particular sitting:

#DomainWeight (official)≈ items (estimated)
1Agentic Architecture & Orchestration27%16
2Tool Design & MCP Integration18%11
3Claude Code Configuration & Workflows20%12
4Prompt Engineering & Structured Output20%12
5Context Management & Reliability15%9

Domain 1 accounts for over a quarter of the exam, roughly sixteen items. It asks you to reason about details such as what terminates a loop and what a subagent can see. Domains 3 and 4 tie for second. Domain 5 has the smallest weight, but its context and reliability concerns recur across the scenarios.

Read the item column as a time allocator. Sixteen items in Domain 1 against nine in Domain 5 means Domain 1 is worth close to twice the study hours, and that is how this book is proportioned: the heaviest domain opens it and gets the most pages. Adjust for the objectives you find difficult.

The six scenarios

Each exam presents four of these six. Reading them now tells you exactly what kind of system the questions assume:

  1. Customer Support Resolution Agent — a Claude Agent SDK agent handling returns, billing disputes, and account issues through MCP tools: get_customer, lookup_order, process_refund, escalate_to_human. It targets 80%+ first-contact resolution while knowing when to escalate. (Domains 1, 2, 5)
  2. Code Generation with Claude Code — Claude Code in a dev workflow: generation, refactoring, debugging, with custom slash commands, CLAUDE.md config, and plan-mode-vs-direct-execution judgment. (Domains 3, 5)
  3. Multi-Agent Research System — a coordinator delegating to specialized subagents (search, analyze, synthesize, report) to produce cited reports. (Domains 1, 2, 5)
  4. Developer Productivity with Claude — an agent exploring unfamiliar codebases with the built-in tools (Read, Write, Bash, Grep, Glob) plus MCP servers. (Domains 2, 3, 1)
  5. Claude Code for CI/CD — Claude Code in a CI/CD pipeline running automated reviews and test generation, designing prompts for actionable feedback with few false positives. (Domains 3, 4)
  6. Structured Data Extraction — extracting from unstructured documents, validating against JSON schemas, handling edge cases. (Domains 4, 5)

Notice the recurring cast: the Agent SDK, MCP tools, Claude Code, and the twin reliability concerns of escalation and structured validation. Master those and you have covered the surface the scenarios draw from.

Notice also what is absent. No scenario is about training, fine-tuning, embeddings, or model internals. Every one of them is about a system you assemble from an API, a set of tools, and some configuration. That is the shape of the whole exam.

What you should already know

This is an architect exam, not an introductory programming one, and it assumes a working engineer. Concretely, the book expects three things of you:

Python, at the level of reading and modifying a script. Every runnable example here is Python. You need dataclasses, dicts, list comprehensions, and type annotations to be unremarkable. claude-agent-sdk 0.2.128 declares Requires-Python: >=3.10; anthropic 0.120.0 declares >=3.9. The book was verified on 3.13.5.

Async Python, at the level of async for. The Agent SDK is async to its core. query() is an async generator, ClaudeSDKClient is an async context manager, and every SDK example in this book sits inside an async def driven by asyncio.run(...). If async, await, and async for are unfamiliar, spend an hour on them before Arc 1. You do not need to know anything about event loops beyond that.

Comfort with a subprocess. The Agent SDK does not talk to the API directly. It spawns the Claude Code command-line tool and speaks JSON to it. You do not have to install that tool separately. The wheel ships a self-contained native binary, so the SDK examples have no Node.js prerequisite. But the SDK’s behavior is partly the CLI’s behavior, a point that matters more than it sounds and that gets its own section below.

No GPU, no vector database, no cloud-provider account. You do need an Anthropic account and a way to pay for tokens. The setup section spells that out before you run anything.

Two packages, two surfaces, and which domain uses which

The examples use two Python packages with different responsibilities. Identify which one a snippet imports before applying its configuration or interpreting its result.

anthropic is the API client. You send messages, you get a Message back, and you decide what happens next. It gives you client.messages.create, the tool-use protocol, stop_reason, structured output via client.messages.parse and tool_choice, token counting via client.messages.count_tokens, and the batches API. It also gives you a middle tier, client.beta.messages.tool_runner, which runs a loop over tools you define.

claude-agent-sdk is the agent harness. It spawns the Claude Code CLI, runs the loop for you, and hands you a stream of typed messages. It gives you query(), ClaudeSDKClient, ClaudeAgentOptions, AgentDefinition for subagents, the ten hook events, permission modes, MCP server wiring, and the session functions.

The useful distinction is who runs the loop. With raw anthropic calls, your application dispatches tools and checks the stop condition; tool_runner manages that cycle within your process. With claude-agent-sdk, the Claude Code subprocess runs it. Most domains involve both packages:

DomainOn anthropicOn claude-agent-sdk
1 · Agentic architecturethe raw loop, stop_reason, tool_runnerquery(), subagents, ResultMessage
2 · Tools & MCPtool schemas, is_error, tool_choiceMCP wiring, built-in tools, permissions
3 · Claude Code configClaudeAgentOptions, settings sources, hooks
4 · Prompt & structured outputmessages.parse, forced tool_choicestructured_output on the result
5 · Context & reliabilitytoken counting, caching, retriesmax_turns, budgets, compaction, sessions

Only Domain 3 sits genuinely on one side, and only because Claude Code configuration is a thing the CLI reads. The rest is the same concept at two altitudes, and an exam item can approach it from either. They are not competitors and the exam does not treat them as alternatives. A scenario that says “a Claude Agent SDK agent handling returns through MCP tools” is asking about the second. A scenario that says “extract from unstructured documents and validate against a JSON schema” is usually asking about the first. Chapter 1 deliberately puts both side by side. The SDK’s loop is the API’s loop with the plumbing hidden, and you cannot reason about the managed version until you have seen the raw one.

The one dependency between them worth knowing on day one: claude-agent-sdk does not import anthropic. Its declared dependencies are anyio, mcp, sniffio, and (below Python 3.11) typing-extensions. The API call happens inside the CLI subprocess, not in your Python process. That is why so much of the SDK’s observable behavior is really the CLI’s behavior.

How this book is organized

The book follows the blueprint, one arc per domain, sized so each chapter treats a coherent slice completely.

  • Arc 1 — Agentic Architecture & Orchestration (the heaviest, three chapters): the agentic loop and what really terminates it; coordinator–subagent orchestration and context isolation; workflows, hooks, and session state.
  • Arc 2 — Tool Design & MCP Integration (two chapters): designing tool interfaces and structured errors; distributing tools and wiring MCP servers, including the built-in tool set and how it is scoped.
  • Arc 3 — Claude Code Configuration & Workflows (three chapters): CLAUDE.md hierarchy and path rules; slash commands and skills; plan mode and CI/CD.
  • Arc 4 — Prompt Engineering & Structured Output (three chapters): precision prompting and few-shot; structured output via tools and JSON schema; batch and multi-pass review.
  • Arc 5 — Context Management & Reliability (three chapters): context management; escalation and error propagation; human review, confidence, and provenance.
  • A closing chapter works all six scenarios end to end, the way the exam frames them.

Each chapter names the exact task-statement objectives it covers, because the exam items are written against those objectives. So you will always know which blueprint line a section is preparing you for.

One thing this book does deliberately: it teaches the anti-patterns the blueprint explicitly flags as wrong, not just the right answers. Domain 1, for instance, calls out two of them. Terminating a loop by parsing the model’s natural-language output. Using an arbitrary iteration cap as the primary stop condition. Those are exactly the plausible-but-wrong options an exam item will offer, and knowing why they are wrong is worth as much as knowing the right design.

Every objective, and where it is taught

The blueprint has a second level below the domains: 30 task statements, seven to five to six across the five domains. They are what the items are actually written against, so they are the useful unit for checking your own readiness. Read down the middle column and mark the ones you could not explain to someone else.

#Task statementTaught in
1.1Design and implement agentic loops for autonomous task executionchapter 1
1.2Orchestrate multi-agent systems with coordinator-subagent patternschapter 2
1.3Configure subagent invocation, context passing, and spawningchapter 2
1.4Implement multi-step workflows with enforcement and handoff patternschapter 3
1.5Apply Agent SDK hooks for tool call interception and data normalizationchapter 3
1.6Design task decomposition strategies for complex workflowschapter 2
1.7Manage session state, resumption, and forkingchapter 3
2.1Design effective tool interfaces with clear descriptions and boundarieschapter 4
2.2Implement structured error responses for MCP toolschapter 4
2.3Distribute tools appropriately across agents and configure tool choicechapter 5
2.4Integrate MCP servers into Claude Code and agent workflowschapter 5
2.5Select and apply built-in tools (Read, Write, Edit, Bash, Grep, Glob) effectivelychapter 5
3.1Configure CLAUDE.md files with appropriate hierarchy, scoping, and modular organizationchapter 6
3.2Create and configure custom slash commands and skillschapter 7
3.3Apply path-specific rules for conditional convention loadingchapter 6
3.4Determine when to use plan mode vs direct executionchapter 8
3.5Apply iterative refinement techniques for progressive improvementchapter 7
3.6Integrate Claude Code into CI/CD pipelineschapter 8
4.1Design prompts with explicit criteria to improve precision and reduce false positiveschapter 9
4.2Apply few-shot prompting to improve output consistency and qualitychapter 9
4.3Enforce structured output using tool use and JSON schemaschapter 10
4.4Implement validation, retry, and feedback loops for extraction qualitychapter 10
4.5Design efficient batch processing strategieschapter 11
4.6Design multi-instance and multi-pass review architectureschapter 11
5.1Manage conversation context to preserve critical information across long interactionschapter 12
5.2Design effective escalation and ambiguity resolution patternschapter 13
5.3Implement error propagation strategies across multi-agent systemschapter 13
5.4Manage context effectively in large codebase explorationchapter 12
5.5Design human review workflows and confidence calibrationchapter 14
5.6Preserve information provenance and handle uncertainty in multi-source synthesischapter 14

Every objective has a chapter. The table establishes coverage; the worked examples and their verification labels show what evidence supports each treatment.

The practice bank is weighted to the domains, not to the task statements. Domain 5 carries six objectives; if you miss items there, the remediation table in the closing chapter points at the three chapters that cover them.

Setting up to follow along

The runnable examples need two packages. You can create a project with uv. These constraints set lower bounds; they do not lock the exact tested versions:

uv init cca-dev && cd cca-dev
uv add 'anthropic>=0.120,<2' 'claude-agent-sdk>=0.2.128'

Run any snippet with uv run python script.py. Confirm what you actually installed before you trust a single output in this book:

import anthropic, claude_agent_sdk, sys
print(sys.version.split()[0])          # 3.13.5
print(anthropic.__version__)           # 0.120.0 and 1.3.0 both verified
print(claude_agent_sdk.__file__)       # .../site-packages/claude_agent_sdk/__init__.py

Or start from the companion repository. Every harness that verified this book, and the contract tests described at the end of this chapter, live at book-companion/ccar-foundations-code. It is filed by chapter: the code behind this one is in chapters/00-the-exam/, chapter 4’s is in chapters/04-tool-interfaces-and-errors/, and the directory names are this book’s own chapter slugs, so there is nothing to look up. Each script’s filename prefix says what it costs to run — api_ needs a key, session_ needs a local Claude Code install, and the contract/ suite needs neither. make venv && make contract runs the API-shape checks against whatever you have installed, and make chapter CH=04 runs one chapter’s worth.

Check authentication and CLI availability before running a model-backed example:

  • An Anthropic account with API access, and a key in the environment. The anthropic client and the Agent SDK both read ANTHROPIC_API_KEY from the environment. A .env file is not loaded automatically. Export it (export ANTHROPIC_API_KEY=sk-ant-…), source an env file, or load it in Python with python-dotenv before the first call. With no key reachable, a call fails with an authentication error rather than hanging.
  • A claude CLI for the Agent SDK, which you probably already have. claude-agent-sdk drives the claude command-line tool under the hood, and the wheel bundles one. So uv add claude-agent-sdk is enough to run every query(), hooks, and sessions example here. Install the standalone CLI (npm install -g @anthropic-ai/claude-code, or the native installer from Anthropic’s docs) when you want an interactive claude session, which Arc 3 does. When both exist the SDK runs the bundled one, and the next section explains why that matters. The plain anthropic examples need no CLI at all.

Three things people reach for that this book does not use. A Claude subscription, Pro or Max, signs you in to the interactive CLI; it is not API access, and the anthropic examples will not run on it. A cloud-provider account — Bedrock or Vertex — is a separate deployment path with its own credentials. And certification access is the exam registration itself, which grants no software.

One thing that does cost money: API calls are billed against your key. Every example that reaches a model spends tokens. The whole book was verified for a few cents on claude-haiku-4-5, which is the model to run these examples on. The introspection snippets, the ones that print a signature or a dataclass field, make no API call and cost nothing.

The version contract, and where it leaks

What was tested, and when

Every runnable example here was executed against a named matrix, not against “the latest”. The examples were first run on the left column and then re-verified, unchanged, on the right:

verified onre-verified on
anthropic0.120.01.3.0
claude-agent-sdk0.2.1280.2.152
Claude Code CLI2.1.248 (PATH), 2.1.220 (bundled)same
Python3.13.53.13.5
modelsclaude-haiku-4-5plus claude-sonnet-5, claude-opus-5 where noted

The right column matters because anthropic crossed a major version between those two runs, and that is where a book about exact fields goes stale. Most of the surface survived: StopReason still has the same seven members, tool_choice the same four variants, ToolParam still carries strict and input_examples, messages.parse and count_tokens still exist, messages.batches still exposes the same six methods, client.max_retries is still 2, the read timeout is still 600 seconds, and the exception classes still carry the same status codes. The structured-output, caching and token-counting examples return the same results on both.

Two things did not survive, and they are the more useful half of the table.

anthropic 1.x removed temperature, top_p and top_k from messages.create. Passing one is now a TypeError from the client rather than an error from the API, and the API still honours the values if you send them through extra_body. So the parameter left the SDK without leaving the platform. Chapter 10 teaches those controls and says so where it teaches them.

claude-agent-sdk 0.2.152 removed the restriction that can_use_tool needs a streaming prompt. On the pinned 0.2.128 a plain string raises ValueError; on 0.2.152 the transport always streams internally and the guard is gone. Chapter 4 shows the error and names the version it belongs to.

Neither breaks an idea in this book. Both break a line of code, and that difference is what the next section is about.

Two consequences for you. Do not read the left column as “the version you must install” — install something in the tested range and check the matrix above. And do not read the right column as a promise about the next release. A tested range is a statement about the past, which is the only kind of statement a printed book can honestly make about a moving platform. Where behavior is model-specific rather than package-specific — extended thinking is the sharp case — the chapter that teaches it carries its own per-model table, because that is where the real variation lives.

The pins are not the whole system

The Python package versions do not fully identify an Agent SDK run. Record the CLI executable and version as well.

The SDK ships its own CLI, and the bundled one wins. The transport resolves the executable in a fixed order. First an explicit ClaudeAgentOptions(cli_path=...), then a binary bundled inside the wheel at claude_agent_sdk/_bundled/claude, then shutil.which("claude"). After that comes a list of well-known install locations: ~/.npm-global/bin, /usr/local/bin, ~/.local/bin, ~/node_modules/.bin, ~/.yarn/bin, ~/.claude/local. On the machine this book was written on, that ordering has a visible consequence:

$ .venv/lib/python3.13/site-packages/claude_agent_sdk/_bundled/claude --version
2.1.220 (Claude Code)

$ claude --version
2.1.248 (Claude Code)

The wheel bundles 2.1.220; the CLI on PATH is 2.1.248. The SDK runs the bundled one, because it is checked first. So your Agent SDK code and your interactive claude session are not necessarily the same program. When SDK behavior disagrees with what you see in the terminal, that is the first thing to check. Pass cli_path explicitly if you need them to match.

Record both before you debug anything, so you know which program produced which output:

import shutil, subprocess, pathlib, claude_agent_sdk

bundled = pathlib.Path(claude_agent_sdk.__file__).parent / "_bundled" / "claude"
for label, exe in (("bundled (the SDK runs this)", bundled if bundled.exists() else None),
                   ("PATH (your terminal runs this)", shutil.which("claude"))):
    if exe is None:
        print(f"{label:32s} -> not present")
        continue
    out = subprocess.run([str(exe), "--version"], capture_output=True, text=True)
    print(f"{label:32s} -> {out.stdout.strip()}")

# bundled (the SDK runs this)      -> 2.1.220 (Claude Code)
# PATH (your terminal runs this)   -> 2.1.248 (Claude Code)

A machine with no standalone install prints not present on the second line and still runs every SDK example in this book. That is the bundled binary earning its 250-odd megabytes: it is a self-contained native executable, not a JavaScript entry point, so the SDK needs no Node.js runtime to spawn it.

Some values in the SDK’s own types are CLI-defined, not SDK-defined. ResultMessage.subtype is annotated str, not a Literal:

import dataclasses
from claude_agent_sdk import ResultMessage
print({f.name: str(f.type) for f in dataclasses.fields(ResultMessage)}["subtype"])
# -> <class 'str'>

By contrast, anthropic’s Message.stop_reason is a closed Literal of seven values. A new one there is a breaking change you would see in your type checker. The SDK’s result subtypes are not protected that way. Both api_error_status and terminal_reason are documented in the SDK source as emitted by particular CLI versions or newer. Treat the subtype strings you will meet in chapter 1 as a contract with the CLI. Check them against the version you are running rather than assuming they are frozen.

The version floor is a log line, not an error. Before spawning, the transport runs claude -v and parses the number. It compares that against a constant in the source, MINIMUM_CLAUDE_CODE_VERSION = "2.0.0". If your CLI is older it emits a logger.warning reading “unsupported in the Agent SDK … Some features may not work correctly”, and then continues anyway. The whole probe is wrapped in except Exception: pass with a two-second timeout. So a CLI that fails to report a version at all produces silence and a normal run. Configure Python logging before you go hunting for a missing feature; the SDK may already have told you. Setting CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK in the environment suppresses the probe entirely.

The subprocess inherits your environment, with two edits. The SDK builds the child environment from os.environ, then sets CLAUDE_CODE_ENTRYPOINT=sdk-py and CLAUDE_AGENT_SDK_VERSION. It also removes CLAUDECODE, so an SDK-spawned CLI does not believe it is nested inside another Claude Code session. Anything you pass as ClaudeAgentOptions(env=...) is layered on top. This inheritance is how ANTHROPIC_API_KEY reaches the CLI at all: you do not hand the SDK a key, you export it, and the subprocess picks it up. It is also why an SDK run can behave differently from a bare script that never touched the environment.

The SDK is a wrapper around an interactive tool, and one more consequence of that will bite as soon as you write a verification harness. The spawned CLI reads the filesystem it is launched in. It will pick up CLAUDE.md, .claude/settings.json, and project MCP configuration from the working directory unless you tell it otherwise. ClaudeAgentOptions(cwd=..., setting_sources=[]) is the isolation switch. setting_sources defaults to None, which means “load everything, matching CLI defaults”. A toy example run inside a real project is not a toy example.

Two names for the same idea, and only one of them is a function

There is a naming collision in the SDK that catches people, and it lands in chapter 3’s sessions section, so meet it here. Resumption is an option field. Forking is both an option and a module-level function, and the two start from different places.

resume is not a function. It is a field on ClaudeAgentOptions, a session id string, documented as “Session ID to resume. Loads the conversation history from the specified session.” You resume by constructing options, not by calling anything.

fork_session is both, and the two do different things:

import inspect
from claude_agent_sdk import fork_session, ClaudeAgentOptions
print(inspect.signature(fork_session))
# (session_id: 'str', directory: 'str | None' = None,
#  up_to_message_id: 'str | None' = None, title: 'str | None' = None)
#     -> 'ForkSessionResult'
print(ClaudeAgentOptions.fork_session)   # False

The option is a boolean that modifies resume. Set both and the resumed session branches to a new id instead of continuing the old one. It forks from the tip of the conversation, because that is where resuming puts you.

The module-level function takes up_to_message_id, which copies the transcript through a chosen message into a new session with fresh UUIDs. Its docstring notes that file-history snapshots are not copied, so the fork starts without undo history.

The rest of the module-level session surface is real too, and all of it is importable in this version: list_sessions, get_session_messages, delete_session, rename_session, tag_session, list_subagents, get_subagent_messages. There are also SessionStore and InMemorySessionStore, for keeping transcripts somewhere other than the filesystem. Chapter 3 uses them.

How the code in this book is verified

Not every claim about a moving platform can be verified the same way, so this book uses four labels rather than one blanket assurance. Every technical statement in these chapters is one of them, and the chapter says which.

The tested range is anthropic 0.120.0 through 1.3.0 and claude-agent-sdk 0.2.128 through 0.2.152, on Python 3.13.5, with the Claude Code CLI at 2.1.248 on PATH and 2.1.220 bundled in the wheel.

  • Live-tested. Executed against a live model on that matrix, using claude-haiku-4-5: the agentic loop, including the stop_reason sequence in chapter 1; a PreToolUse hook firing and denying; subagent delegation through the Agent tool; session resume versus fork; a tool returning an error and the agent’s response to it; forced tool_choice extraction.
  • Introspected. Read out of the installed packages at runtime — a signature, a dataclass field, a default, a docstring, a Literal’s members. Authoritative about structure, silent about behavior. Most of the API detail in these chapters is this, and the snippet that prints it is usually shown.
  • Source-read. Quoted from package source, or from strings inside the bundled CLI binary. Accurate about what the code says, which is not proof of what a running system does. The subagent limits and the CLI’s own delegation guidance in chapter 2 are the clearest cases.
  • Described. Architecture, judgment, and exam strategy, with no artifact to run. The domain weights, the study advice, and the design arguments are this.

The rule that follows: nothing is presented as measured unless it was measured. Where a chapter describes behavior it did not execute, it says so in its own text rather than in a footnote. Where a result is model-dependent rather than an API contract, the chapter claims the direction and not the magnitude. Few-shot prompting took format adherence from 0 of 4 to 4 of 4 in one measurement, and that multiplier belongs to the model, not to the technique.

And the checks run without you. The introspected claims are the ones that rot first, so they are also a test suite: book-companion/ccar-foundations-code asserts the shapes this chapter and the next fifteen print — the seven stop_reason members, the four tool_choice variants, max_retries defaulting to 2, the 600-second read timeout, every status code in the error taxonomy, the ten hook events, the thirteen AgentDefinition fields — against three releases of anthropic on every push and again once a week. It currently passes on 1.4.0, which is later than anything this book was able to test. When it goes red, a sentence in here has stopped being true, and the failing test names the chapter that carries it. That is a better guarantee than a version number in a preface, because it has a date on it that keeps moving.

One test in that suite is deliberately conditional, and it is the seam described above: anthropic 1.x removed the sampling parameters from the typed signature, so the assertion flips on the major version rather than claiming one behaviour for both.

When using an example, check which of those labels its evidence carries. A docstring is a promise a package makes about itself: a great deal better than memory, and a great deal worse than a run.

Final thoughts

What to carry forward.

  • Five weighted domains; Domain 1 is the heaviest at over a quarter of the items. The pass mark of 720 is a scaled score, not a percentage.
  • Two Python surfaces: with anthropic you own the loop; with claude-agent-sdk a Claude Code subprocess owns it. Every domain touches both.
  • A tested range is a statement about the past. Check the compatibility matrix, and record the CLI version as well as the packages, because the SDK ships and prefers its bundled CLI.
  • resume is an option field, not a function. fork_session is both: the option branches from the tip, the function branches from a chosen message.
  • Evidence labels: a live run outranks package introspection, which outranks a source reading.

Choose one of the six scenarios and explain the design before opening its worked answer. Identify who owns the loop, what tools are available, and what happens when required evidence is missing. If you cannot yet justify one of those decisions, use the objective table to find the chapter that develops it.

Next: the agentic loop — what actually drives an agent’s iterations, what terminates them, and the anti-patterns the blueprint wants you to recognize on sight.

Comments