The Invoice Parser That Wrote Prose
The invoice extractor had one instruction: return one line per line item, fields separated by |. It passed the test invoice and broke on half of production:
prompt: Extract the line items.
Sure! The invoice contains three items:
- 2 × M8 hex bolts at $0.14 each (part BOLT-M8)
- 1 × steel washer, 100-pack at $4.10 (part WSH-100)
- Shipping, $6.00
Every fact in that reply is right and every downstream parser is broken: no pipes, prose wrapped around the quantities, a shipping row mixed in with parts. Rewriting the instruction — "return ONLY pipe-separated lines, no commentary" — fixed some invoices and not others, because a longer rule was still competing with the model's habit of answering in prose.
Two examples ended the argument:
Input: 1 × Widget A @ $3.00
Output: Widget A|1|3.00
Input: 3 × Cable B @ $1.25, plus $5 shipping
Output: Cable B|3|1.25
The second example does two jobs at once: it demonstrates the pipe format, and it shows that shipping lines are dropped. That drop was never stated in the instruction, yet after the examples the model applied it consistently — including on invoices the examples never covered.
An instruction states a rule. An example demonstrates the rule in the exact shape you intend to receive back.
Choosing the Examples That Teach
Four slots fill an example set. Two to five examples is the usual size, and every one has to earn its place:
| Slot | What it teaches | Concrete instance |
|---|---|---|
| Format anchor | The exact shape of the output | Widget A, 1, 3.00 joined by pipes |
| Scope decision | What gets included or dropped | shipping line dropped from the output |
| Edge case | What happens to malformed input | missing price becomes UNKNOWN |
| Tone anchor | How open-ended text is phrased | terse status-page bullet, no greeting |
Assemble the set in code so ordering and labels stay identical across runs:
EXAMPLES = [
("1 × Widget A @ $3.00", "Widget A|1|3.00"),
("3 × Cable B @ $1.25, plus $5 shipping", "Cable B|3|1.25"),
("2 × Gasket, no price listed", "Gasket|2|UNKNOWN"), # the edge case
]
def build_prompt(query: str) -> str:
shots = "\n\n".join(
f"Input: {inp}\nOutput: {out}" for inp, out in EXAMPLES
)
return (
"Extract line items as name|qty|price. Drop non-item lines. "
"Use UNKNOWN when a price is absent.\n\n"
f"{shots}\n\nInput: {query}\nOutput:"
)
Two lines carry the weight. The comprehension renders every pair with identical Input: / Output: labels — inconsistent labels teach the model to imitate punctuation instead of structure. The trailing Input: {query}\nOutput: leaves the completion mid-shape, so the model continues the pattern instead of opening a fresh message with a preamble.
Running it:
Input: 4 × Nut B @ $0.05, handling $2.00
Output: Nut B|4|0.05
Rules for the set itself:
- Include one edge case. A set of clean inputs teaches nothing about ambiguous input, and ambiguous input is where production traffic lives.
- Keep styles uniform. If example two is chatty and example three is terse, the model must guess which pattern to copy — conflicting examples are worse than none.
- Never smuggle instructions into examples. A comment like
# drop shippinginside an Output is a literal string the model may copy, not a rule. State the rule in prose; show its effect in the example.
Placement and Consistency
Position changes how hard the model tries to match you. The reliable order is instructions first, examples second, live query last:
+----------------------------------------------+
| instructions what rules govern this task |
+----------------------------------------------+
| examples 2-5 Input/Output pairs |
+----------------------------------------------+
| live query the actual input, ending with |
| a half-finished Output: |
+----------------------------------------------+
Examples placed before the instructions read as unexplained data — there is no rule for the model to attach them to. Examples placed after the live query arrive too late to shape the response. Because the query sits last, the shape of the final example is still the most recent thing the model saw when generation begins.
Consistency is the other half. One example that ends Thanks! and another that ends nothing teach two patterns, and the model alternates between them; in a log this shows up as "sometimes it works." When an example disagrees with an instruction, the example usually wins — it is concrete, and it sits closer to the output than the prose does.
Placement also decides cost. Every example is re-sent on every request, so a set that grew to twelve pairs is twelve pairs of tokens per call. If you find yourself adding pairs to fix a wording problem, the wording belongs in the instruction instead; Zero-Shot Instruction Writing covers rewriting a request to name inputs, limits, and failure policy rather than demonstrating them.
Test whether the set is doing anything at all. Run the same input twice — once with the pairs, once with the instruction alone:
query = "4 × Nut B @ $0.05, handling $2.00"
with_shots = run(build_prompt(query))
without = run("Extract line items as name|qty|price. "
"Drop non-item lines. Use UNKNOWN when a price is absent.\n\n"
f"Input: {query}\nOutput:")
If both calls return the same parsable row, the instruction already carried the contract and the pairs are re-sent every request for nothing — cut them back to the edge case. If the instruction-only call is the one producing prose, at least one pair is weaker than the rule it is supposed to demonstrate, and replacing that pair beats appending a fifth.
Few-shot steers shape. When the task's difficulty is the reasoning rather than the format, Chain-of-Thought Prompting uses examples of traces instead of examples of outputs, and System Prompt Design keeps the standing rules — scope, refusals — out of the per-request prompt entirely.
Quiz
1. A model returns prose summaries instead of pipe-separated rows despite a clear instruction. What most reliably fixes it?
2. Your example set contains one chatty example and one terse example. What happens next?
3. Where should examples sit relative to the instruction and the live query?
4. What does an edge-case example provide that the same rule in prose does not?
Flashcards
Question
Typical size of an example set
Click to reveal answer
Answer
Two to five high-quality Input/Output pairs; beyond that the pattern usually dilutes and token cost rises per request.
Question
Why an example set should include one edge case
Click to reveal answer
Answer
Clean inputs only teach the happy path. The edge case demonstrates the rule on ambiguous or malformed input that production will send.
Question
Correct placement of examples in a prompt
Click to reveal answer
Answer
Instructions first, examples second, live query last — ending the prompt with a half-finished Output: cue so the model continues the shape.
Question
Effect of conflicting example styles
Click to reveal answer
Answer
The model cannot tell which pattern to imitate, so output alternates between styles across requests and looks randomly broken.
Question
When to prefer an instruction over an example
Click to reveal answer
Answer
When the output space is open-ended and the constraint is a rule rather than a shape — in that case rewrite the instruction instead of adding pairs.
Revision Notes
Key Takeaways
- 1. Two to five examples beat a longer instruction when the problem is output shape
- 2. Every set needs a format anchor, a scope decision, and at least one edge case
- 3. Order is instruction, examples, live query ending in a dangling Output:
- 4. Conflicting example styles are worse than no examples, and examples re-send on every request
Interview Tips
- • Walk through your set slot by slot: which pair demonstrates format, which demonstrates scope, which is the edge case
- • Explain why an example overrides a stated rule — proximity to the output and concreteness
- • Say what you would do when the set grows past five pairs: move wording into the instruction, not more pairs
- • Be ready to contrast few-shot with zero-shot and name the open-ended case where examples hurt
Cheat Sheet
Few-Shot Example Selection — Cheat Sheet
Size: 2–5 pairs. Each pair earns its slot: format anchor, scope decision, edge case, tone anchor.
Order in the prompt
instructions -> examples -> live query ending in "Output:"
Non-obvious lines in the builder
- Identical
Input:/Output:labels on every pair — label drift teaches punctuation, not structure. - Query appended with a dangling
Output:— the model continues the shape instead of starting fresh. - One example with malformed input — the happy path alone leaves ambiguous production traffic unhandled.
Consistency beats quantity. Conflicting styles make the model guess which pattern to imitate; an example that contradicts an instruction usually wins.
Cost: examples are re-sent every request. Fix wording in the instruction, not by adding pairs.
Failure modes: prose despite instructions · shipping/irrelevant rows included · inconsistent row style across requests · examples contradicting the stated rule.
Continue Learning
Before You Start
- No prerequisites listed.