What you’ll be able to do
- Clarify a transformation with 2-3 concrete input/output examples when prose descriptions produce inconsistent results
- Drive implementation with a test suite written first, iterating by sharing test failures
- Use the interview pattern to surface design considerations before implementing in an unfamiliar domain
- Fix edge cases with specific test cases that give example input and expected output
- Send interacting issues together in one detailed message and fix independent issues sequentially
What you need to know
When prose isn’t working, show examples
Some transformations are easy to demonstrate and hard to describe. "Normalize the address fields" can be read several reasonable ways. Does "St." become "Street"? Do unit numbers move to a separate field? What happens to a missing postcode? If Claude gets it right on some runs and differently wrong on others, the description is ambiguous, and making it longer or more emphatic usually doesn't help.
The most effective fix is two or three concrete input/output examples that pin down the expected result:
Input: “Flat 4, 9 Kings Rd, London SW3 4NB” Output: {“line1”: “9 Kings Road”, “unit”: “Flat 4”, “city”: “London”, “postcode”: “SW3 4NB”}
Two examples answer the questions the prose left open: abbreviations are expanded, units go in their own field, and missing values are null rather than guessed. Choose examples that differ along the dimensions where the results were inconsistent. Three near-identical examples teach nothing new.
Test-driven iteration
For behavior you can test, write the test suite first. Cover expected behavior, edge cases, and performance requirements. Then let Claude implement against it and iterate by sharing the test failures. A failing test is a precise, reproducible statement of what's wrong: this input, this expected result, this actual result. It's much more useful than "it's still not quite right."
Test-first also gives the loop a clear end: you're done when the suite passes. Tests written after the implementation tend to describe what the code does rather than what it should do, so they miss the cases the implementation got wrong.
The same idea applies to edge cases on code that already exists. If a migration script mishandles null values, don't report "it doesn't handle nulls well." Give a specific test case: this input row, with discount_code null, should produce this output row, with the column omitted rather than written as the string "null". A specific input with its expected output tells Claude exactly what to change.
The interview pattern
In an unfamiliar domain, the biggest risk is the question nobody asked. Before implementing, have Claude interview you: ask it to list the questions it needs answered and then work through them with you. For a caching layer, that brings up decisions such as:
- How should entries be invalidated: by time, on write, or by event?
- What happens when the cache is unavailable? Fail open to the database, or fail closed?
- Can stale reads be tolerated for this data, and for how long?
These are design decisions, not implementation details. If they're answered by default in the code, they're expensive to change later. The interview pattern raises them at the start, including the ones you wouldn't have thought to mention.
One message or several?
When a round of review turns up several problems, how you send them back matters:
- Interacting issues go in one detailed message. If fixing the retry logic changes how errors reach the logging code, and the logging code also has a bug, the two fixes depend on each other. Fixed separately, the second fix can undo or conflict with the first. Describe all of them together, including how they relate, so Claude can fix them consistently.
- Independent issues go one at a time. A typo in a help string, a missing index on an unrelated table, and an off-by-one in a pagination helper don't affect each other. Fixing them sequentially keeps each change small and easy to verify, and a failure in one doesn't get tangled up with the others.
The deciding question is whether the fixes interact, not how many issues there are.
Key concept
Make the target concrete: input/output examples when prose is ambiguous, a test suite written first with failures fed back, and a specific failing case for each edge case. Interview before unfamiliar work, and group issues by whether their fixes interact.
When a scenario says results are "inconsistent" despite a clear-seeming description, the answer is usually examples. When it says fixes keep breaking each other, the answer is to send the interacting issues together.
Practice scenario
region get the literal string "null", the currency conversion and the new rounding rule disagree (fixing one shifts totals the other depends on), and a log message has a typo.Work it through, then open this
Treat the three differently. For the null handling, give a specific test case: an input row with region null and the exact expected output, ideally added to a test suite that also covers other edge cases. The currency conversion and the rounding rule interact, so describe both in one detailed message that explains how they affect each other and gives example totals. Fixing them one at a time would likely make each fix disturb the other. The typo is independent, so fix it separately whenever convenient. If the developer wasn’t sure how the new schema should treat partially migrated records, starting with the interview pattern would have raised that question before any code was written.
Build exercise — Refine a transformation three ways
Intermediate · 35 min
What you’ll learn
- Seeing how input/output examples change consistency compared with prose alone
- Running a test-first loop driven by shared failures
- Using the interview pattern to surface decisions before implementing
-
Describe a small transformation (for example, normalizing phone numbers) in prose only and run it on ten varied inputs. Then add two or three input/output examples and run it again.
- Why: This shows directly how examples resolve the ambiguity that prose leaves.
- You should see: Inconsistent handling of formats in the prose-only run, and consistent output once the examples cover the differing cases.
-
Write a test suite for the transformation first, covering normal cases, edge cases (empty, null, international formats), and a performance bound. Have Claude implement it, and iterate by pasting only the failing tests.
- Why: Failures are precise feedback, and a passing suite is a clear stopping point.
- You should see: Each iteration reduce the number of failures, ending with the suite green.
-
Before a related feature in an area you know less well (for example, caching the results), ask Claude to interview you with the questions it needs answered before implementing.
- Why: The interview surfaces design decisions such as invalidation and failure modes that would otherwise be decided by default.
- You should see: At least one question you hadn’t considered, answered before any code is written.
Exam traps
Rewriting a prose description more forcefully when examples would remove the ambiguity
If prose is being interpreted inconsistently, two or three concrete input/output examples are the most effective way to show the expected transformation.
Reporting “it doesn’t handle edge cases” instead of giving the failing input and expected output
A specific test case with example input and expected output, for instance for null values, tells Claude exactly what correct looks like.
Asking for the implementation first and writing tests afterwards
Writing tests first, covering behavior, edge cases, and performance, and then iterating on failures gives precise feedback and a clear finish line.
Starting implementation in an unfamiliar domain without first having Claude ask clarifying questions
The interview pattern surfaces considerations such as cache invalidation and failure modes before they’re built in by default.
Fixing interacting issues one at a time, so each fix undoes or conflicts with the last
When fixes interact, put all the issues in one detailed message so they’re resolved together and consistently.
Bundling unrelated, independent issues into one message when sequential fixes would be easier to verify
Independent problems are easier to fix and check one at a time. Batching is for interacting issues.
Sources
- Claude Code Docs
- Anthropic, Claude Certified Architect – Foundations Exam Guide v1.0 (July 2026)