CCAF logo

Domain 3 · Task 3.5

Iterative Refinement Techniques

Apply iterative refinement techniques for progressive improvement.

Iterative refinement is how you drive an agent from a rough result to a correct one. Four techniques cover the exam's scenarios: concrete examples when prose fails, test-driven iteration, the interview pattern for unfamiliar domains, and knowing when to give all issues at once versus sequentially. The through-line is matching the technique to *why* the output is wrong.

Key concept

Inconsistent results from prose → show concrete input/output examples. Fixes that interact → one detailed message. Independent fixes → iterate sequentially. Unfamiliar domain → interview first.

What you need to know

Show examples when prose fails

When results are inconsistent because prose is being interpreted differently each time, concrete input/output examples communicate the transformation better than more words. Provide 2–3 examples of the exact input and the exact desired output. This is the go-to move for the classic scenario "Claude keeps mis-handling an edge case despite my instructions" — instead of rewording the instruction a fourth time, show a specific input and the output you want for it. Examples pin down the transformation that prose leaves ambiguous.

Test-driven iteration and specific cases

Write tests first, then iterate by sharing the failures. Build a suite covering behaviour, edge cases, and performance, run it, and feed the failing cases back so the agent converges on passing them. When a particular edge case is wrong — null values in a migration, say — give a specific test case for exactly that input rather than a general instruction. Concrete failing cases are a precise, low-ambiguity refinement signal, the same principle as showing examples applied to verification.

Interview first; batch interacting fixes

Two more techniques:

  • Interview pattern — in an unfamiliar domain (cache invalidation, failure modes), have the agent surface the considerations and open questions *before* implementing. This flushes out unknowns instead of baking assumptions into code you then have to unwind.
  • All-at-once vs sequential — when several fixes interact (changing one affects the others), give them in one detailed message so the agent can reason about them together. When fixes are independent, iterate sequentially, one round each. Batching interacting problems avoids the agent solving them in a conflicting order; sequencing independent ones keeps each round focused.

Exam traps

The trapThe reality
If Claude keeps mis-handling an edge case, the fix is to reword the instruction more forcefully.Rewording prose that is already being misread rarely helps. Show a concrete input/output example of the correct handling.
Several fixes that affect each other should be applied one at a time to keep each change small.Interacting fixes belong in one detailed message so the agent reasons about them together; sequential rounds risk a conflicting order.
Independent fixes should all be dumped into one giant message for efficiency.Independent problems are best iterated sequentially — one focused round each — since they do not affect one another.
In an unfamiliar domain you should have the agent implement immediately and fix issues afterward.Use the interview pattern first to surface considerations and failure modes before implementing, so assumptions do not get baked in.

Practice scenario

Real questions from the bank that test this topic — the correct answer is highlighted.

Your Claude Code session was paused yesterday after the agent built up significant context across many files. Overnight: a CI pipeline ran an automated dependency upgrade modifying package.json and the lockfile; a teammate's PR was merged renaming a utility function the agent had been using. You want to resume productively.

What's the most robust mechanism to handle the staleness — one that scales to a team where this happens regularly?

AResume the session and let the agent rediscover changes naturally as it re-reads files in the course of its work
BResume the session, then immediately tell the agent which specific things changed (dependency upgrade, function rename) so it can update its mental model
CAlways start a fresh session after any time gap — context built around stale files is fundamentally unreliable
DConfigure a SessionStart hook that detects changes since the session's last activity (via git log since the saved timestamp) and injects a summary of changed files before the agent resumes workCorrect

Why: The question explicitly asks for the most robust mechanism that scales to a team where this happens regularly. An automated SessionStart hook that detects and injects changes since the session's last activity handles every resumption consistently without depending on the user remembering to mention each change. Manual mention (B) works for one user who knows what changed, but doesn't scale — and people forget. Natural rediscovery (A) means the agent may reason on stale content before catching up. Always starting fresh (C) throws away accumulated context unnecessarily. D is the production-grade pattern.

You want a hook that fires when Claude Code's context fills up and is about to be compacted automatically, so you can save the pre-compaction state to a file for later analysis.

Which hook event do you target?

AStop — fires whenever the response stream stops, including before compaction
BPreCompact — fires immediately before context compaction beginsCorrect
CPostToolUse with a counter that triggers at the compaction threshold
DSessionEnd — compaction is treated as an implicit session boundary

Why: PreCompact is the documented hook event that fires immediately before context compaction. Stop (A) fires per-turn-end, not on compaction. PostToolUse counter (C) is a hack that doesn't reliably hit the compaction boundary. SessionEnd (D) fires at session termination, not at compaction (compaction happens mid-session as context fills). Drill: Memorize the full hook event list — PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, PreCompact, SessionStart, SessionEnd, Notification.

Build exercise

Refine a flaky transformation with examples and tests

~40 min
  1. 1
    Give the agent a prose-only spec for a data transformation and run it on several inputs to expose inconsistent handling of an edge case.

    Why: This reproduces the failure mode where prose is interpreted differently each time.

  2. 2
    Replace the vague instruction with 2–3 concrete input/output examples covering the edge case.

    You should see: The transformation becomes consistent because the examples pin down the mapping.

  3. 3
    Write a test suite (behaviour, edge cases, a null-value case) first, run it, and share the failing cases back to the agent.

    Why: Test-driven iteration turns failures into a precise refinement signal.

  4. 4
    Identify two fixes that interact and deliver them in a single detailed message.

    You should see: The agent reasons about them together rather than in a conflicting order.

  5. 5
    For a genuinely unfamiliar sub-problem, run the interview pattern to surface considerations before implementing.

    You should see: Open questions and failure modes come out before any code is written.

Sources

Drill Claude Code Configuration & Workflows

Practice only this domain’s questions, untimed, with instant explanations.