Four named techniques, each fitting a different failure mode:
- Concrete input/output examples — the most effective way to communicate an expected transformation when prose is interpreted inconsistently across attempts. Two or three example pairs beat yet another rewrite of the description.
- Test-driven iteration — write the test suite first (expected behavior, edge cases, performance requirements), then iterate by sharing specific failures rather than vague "it's not right yet" feedback.
- The interview pattern — have Claude ask clarifying questions before implementing, which surfaces considerations you hadn't anticipated (cache invalidation, failure modes) — especially valuable in an unfamiliar domain where you might not know what to specify upfront.
- Batching vs. sequencing — provide all known issues in a single message when the fixes interact with each other; fix sequentially, one at a time, when the problems are genuinely independent. Most people get this backwards by default.
The discriminator: for inconsistent output, show rather than describe. A general instruction to "handle nulls" leaves the behavior underspecified in a way a concrete test case (specific input, specific expected output) doesn't. For fix ordering specifically, ask whether the problems interact — that answer, not a general preference for batching or sequencing, decides which approach fits.
A quick-recall version of the same four techniques:
| Technique | Use When |
|---|---|
| Concrete examples | Output is inconsistent run to run |
| Test-driven iteration | Edge cases are known and enumerable upfront |
| Interview pattern | The domain is unfamiliar — unknown unknowns are likely |
| Batching | The issues found interact with each other |
| Sequencing | The issues found are genuinely independent |