What if you could teach a language model a brand new task without changing a single weight? That is in-context learning, and it is the engine behind few-shot prompting.
Intro
Learning Without Learning
Imagine teaching a brand new skill to a model, and not changing a single one of its billions of weights. No gradient descent, no training run, no GPU cluster. You just show it a few examples, right in the prompt, and it gets the idea. That sounds like magic, but it is something you can use today.
- No gradient updates
- No fine-tuning
- Just examples in the prompt
Where We Are
In the last episode we covered prompt patterns and system prompts, which are about telling the model what you want. This episode is about showing the model what you want. We will see what in-context learning is, why researchers still argue about how it works, and how to build a few-shot prompt that is reliable and affordable.
- Last time: prompt patterns
- Today: examples in the prompt
Today's Roadmap
Here is the plan. First the definitions. Then the theory, with honest uncertainty. Then what actually makes examples good or bad, a worked example with similarity based selection, a Python prompt builder, the cost trade-off, and the classic mistakes. We will not cover chain of thought here. That is the next episode.
- Zero, one, few-shot
- Why examples matter
- kNN selection and code
- Cost and mistakes
Zero, One and Few-Shot
Zero-Shot Prompting
Zero-shot means you give the model an instruction and no examples. Classify the sentiment of this review, and here is the review. The model relies entirely on what it picked up in pretraining and instruction tuning. For common tasks this works surprisingly well, and it is always the baseline you should try first.
- Instruction only
- No examples
- Relies on pretraining
One-Shot and Few-Shot
One-shot adds a single worked example before your real input. Few-shot adds several, typically somewhere between two and a few dozen. Each example is an input and the output you want, written in the same format as your final query. The model sees the pattern, and then it continues it for the new input.
- One-shot: one example
- Few-shot: a handful
- Same frozen model
Anatomy of a Few-Shot Prompt
A few-shot prompt has three parts. An instruction, a list of demonstrations, and the final query with the answer left blank. Review colon, text, label colon, positive. Then again, and again. Then the new review, and label colon with nothing after it. The most natural continuation is the label, so the model writes it.
- Instruction
- Demonstrations
- Final query, blank answer
What Is In-Context Learning?
Learning Inside the Forward Pass
In-context learning is the ability of a model to adapt its behavior to a task based only on examples in its input. Compare it with fine-tuning. Fine-tuning changes the weights, and the change is permanent. In-context learning changes nothing in the weights. The adaptation lives in the activations during one forward pass, and it disappears when the prompt does.
- Weights fixed
- Behavior adapts
- Temporary: lasts one prompt
Why It Was Surprising
This was a real surprise when large language models appeared. Pretraining only asks the model to predict the next token. Nobody wrote a loss term for learn a task from three examples. Yet sufficiently large models do exactly that. As in the ML course's lessons on pretraining, the objective is simple, and capabilities fall out of it.
- Trained only to predict next token
- Few-shot ability emerged at scale
Theory One: Task Location
One explanation is task location, sometimes called task recognition. The model already learned many tasks during pretraining. The examples simply tell it which one you mean, and what the output format and label set look like. Under this view, even examples with randomly shuffled labels can still help a lot, because they reveal the task and the format.
- Model already knows many tasks
- Examples pick which one
- Format and label space matter
Theory Two: Implicit Learning
A competing explanation says the model really does learn something new from the examples. Some research shows that transformers can implement simple learning procedures, like fitting a linear function, inside the forward pass, with attention doing the work. Other work suggests that larger models pay more attention to the actual input label mapping. Both views have evidence behind them.
- Forward pass mimics learning
- Attention as an algorithm
- Larger models use labels more
Active Research, Not Settled
So which is right? This is still active research, and it is not settled. The truth is probably a mixture that depends on the model size and the task. Do not repeat either story as proven fact. What matters for engineering is the practical lesson: examples strongly steer the model, and the details of those examples matter.
- Likely a mix of both
- Depends on model and task
- Practical takeaway stays the same
What Makes Examples Work
Example Choice Matters
The first lever is which examples you choose. Examples that look like your real inputs help the most. If your inputs are short customer chats with typos and your examples are polished formal paragraphs, the model sees a mismatch. Studies across tasks have shown that the choice of examples alone can swing accuracy substantially.
- Relevant examples help most
- Cover the real input distribution
- Bad examples can hurt
Order and Recency Bias
The second lever is order. The same examples in a different order can give different predictions. Models often lean on the examples closest to the end of the prompt, which is a form of recency bias. If your last example is negative, the model may lean negative on ambiguous inputs. So test several orderings, and do not place a single label at the end every time.
- Order changes outputs
- Last example weighs heavily
- Shuffle and test
Label Balance
The third lever is label balance. If five of your six examples are positive, the model learns that positive is common, and it will over predict it. This is majority label bias. A safe default is a balanced set of examples. If your real data is heavily skewed, choose that skew on purpose and measure the result, rather than letting it happen by accident.
- Skewed labels skew predictions
- Balance the label counts
- Match real class priors deliberately
Format Is a Signal
The fourth lever is format. Every example should use exactly the same structure, the same delimiters, and the same label words. If one example says positive and another says pos, you are teaching the model that either is fine. Consistent format is also why few-shot prompting is so good at format adherence. The model copies the pattern you give it.
- Consistent delimiters
- Same structure every time
- Clear label vocabulary
How Many Examples?
How many examples do you need? There is no universal number. Typically the first few examples give the biggest gain, then the curve flattens, while your token cost keeps growing in a straight line. Start with three to five good examples, measure, and add more only if the measurements show a real improvement. Hard or ambiguous tasks may benefit from more.
- Gains are biggest early
- Diminishing returns
- Context and cost limits
Worked Example: Choosing Examples
The Task: Support Intent Labels
Let us design examples for a real task. We need to label customer support tickets into three intents: refund, shipping, or account. Here is a tricky ticket. My package never arrived and I want my money back. Is that shipping, or refund? This is exactly the kind of case where example design matters.
- Labels: refund, shipping, account
- Incoming ticket to label
Designing Three Examples
Start with three examples, one for each label, so the set is balanced. Write them in the style of real tickets. Charged twice, please return the extra payment, labeled refund. Tracking has not changed in a week, labeled shipping. Cannot log in after changing my email, labeled account. Now add a borderline case, because borderline cases show the model where the boundary sits.
- One per label
- Realistic wording
- One borderline case
Static Examples Have a Limit
But a fixed set of examples has a limit. Suppose you have a pool of two hundred labeled tickets. Your three fixed examples might be far from the incoming query. A smarter approach is dynamic selection: for each new input, find the labeled examples most similar to it, and put those in the prompt. This is called kNN example selection.
- Same examples for every input
- Pool may be hundreds of labeled items
- Better: choose per query
kNN Selection With Numbers
Here is how it works with numbers. Turn the query and every pool item into vectors. Compute cosine similarity between the query and each item. Say the best matches score zero point nine one, zero point eight four, and zero point seven seven, while an unrelated billing question scores only zero point one two. With k equal to three, we take the top three and drop the rest.
- Embed the query and the pool
- Score by cosine similarity
- Take the top k
Ordering the Chosen Examples
Once selected, order matters. A common choice is to put the most similar example last, right before the query, which uses recency bias in your favor. Also look at the labels of the neighbors. If two are refund and one is shipping, the model sees the real ambiguity of our tricky ticket, and it can decide with relevant evidence in front of it.
- Most similar goes last
- Check label mix of the neighbors
- Fall back if all neighbors agree
Python: Dynamic Prompt Builder
The Builder's Design
Now the code, in plain Python, provider neutral. The builder has four steps. Store a pool of labeled examples. Turn texts into vectors. Pick the top k most similar examples for a query. Then format everything into one prompt string that you send to any LLM API.
- Example pool
- Vectorizer
- Select, format, assemble
Vectorizing the Pool
For a simple version, use TF-IDF from scikit-learn. Fit the vectorizer on the texts in your pool and transform them into a matrix. If you prefer, write a function called embed that takes a string and returns a vector, and leave it as a stub. Later you can swap in a real embedding model from the upcoming embeddings episodes without touching the rest.
- TF-IDF with scikit-learn
- Or an embedding function stub
- Fit on pool texts only
Selecting the Top K
The selection function does this. Transform the query with the same vectorizer. Compute cosine similarity against every row of the pool matrix. Sort the scores from high to low, keep the first k indices, and then reverse that list so the most similar example ends up last. Return the matching example dictionaries.
- Transform the query
- Cosine similarity to all
- argsort, take top k
Assembling the Prompt
Finally the formatter. Start with a one line instruction listing the allowed labels. Loop over the selected examples and append ticket colon text, newline, intent colon label. End with the new ticket and intent colon, left open. Send that string to your model with temperature zero for classification, and parse the first word of the reply.
- Instruction first
- Identical format per example
- End with open label
Cost and Caching
Examples Cost Tokens
Few-shot is not free. Every example is input tokens, and you pay for them on every single request. Suppose each example is sixty tokens and you use eight. That is four hundred eighty tokens added to every call, before your query. At a million calls, that overhead is large, and longer prompts also add latency.
- Every example is input tokens
- Paid on every single call
- Latency grows too
The Prompt Caching Idea
Many providers support prompt caching. If the beginning of your prompt is identical across requests, the system can reuse the work already done for that prefix, typically at lower cost and latency. Details vary by provider, so check yours. The design rule is simple: put static content first, and dynamic content last.
- Reuse a shared prefix
- Cached prefix is cheaper and faster
- Put static content first
Static vs Dynamic Trade-Off
Here is a trade-off. Static examples cache well but are not tailored. Dynamic kNN examples are tailored but change the middle of the prompt, which breaks the cache after that point. A practical hybrid is a small fixed core of examples at the top that can be cached, then two or three retrieved examples, then the query.
- Static examples cache well
- kNN examples improve relevance
- Hybrid: fixed core plus retrieved extras
Real-World Uses and Mistakes
Where Few-Shot Shines
Where does few-shot shine? Classification and labeling, like our intent example. Style transfer, where two or three before and after pairs teach a brand voice better than a paragraph of adjectives. And format adherence, where examples show the exact layout of the output, so downstream code can parse it. Models copy patterns very well.
- Classification and labeling
- Style transfer
- Format adherence
Mistake: Leaking Test Examples
Mistake number one is leaking test examples. If an item you evaluate on also appears in your prompt, even through kNN retrieval from a pool that includes the test set, the model can just copy the answer. Your scores look great and mean nothing. Split your data first, retrieve only from the training pool, and also remove exact duplicates.
- Test items inside the prompt
- Inflated evaluation scores
- Split pool and test set first
Mistake: Unrepresentative Examples
Mistake number two is unrepresentative examples. If you only show clean, easy cases, the model struggles on messy production text. If a rare class never appears in your examples, the model may never predict it. Sample examples from real traffic, include hard and borderline cases, and revisit them as your data drifts.
- Only easy, clean cases
- Missing rare classes
- Mirror production inputs
Mistake: Label Bias and Overfitting to Format
Mistake number three is label bias. Skewed label counts, a repeated label at the end, or a few examples that are simply wrong can all push predictions in the wrong direction. Review your examples by hand, balance them on purpose, shuffle the order across experiments, and always measure on held-out data rather than trusting a single prompt that looked good on three inputs.
- Skewed or wrongly labeled examples
- Wrong labels teach wrong rules
- Always evaluate on held-out data
When to Move Beyond Few-Shot
A final practical note. Start with zero-shot, move to few-shot when you need more control, and consider fine-tuning only if you have lots of labeled data and the prompt gets too long or expensive. We will compare fine-tuning, retrieval, and prompting properly in episode twenty six. For now, few-shot is the cheapest experiment you can run.
- Hundreds of examples available
- Prompt too long or costly
- Consider fine-tuning later
Recap and Next Steps
Recap
Let us recap. Zero-shot has no examples, one-shot has one, few-shot has several. In-context learning adapts behavior with no weight updates, and why it works is still an active research question. Example choice, order, label balance and format all change results. Use kNN selection for relevance, watch your token cost, use caching, and avoid leaks, bias and unrepresentative examples.
- Zero, one, few-shot
- ICL: no weight updates
- Choice, order, balance, format
- kNN selection, cost, mistakes
Next: Reasoning
Examples teach a model what the answer should look like. But some problems need more than a pattern to copy. They need the model to work through steps before it answers. That is the topic of the next episode: chain of thought and reasoning models.
- Examples show what to answer
- Next: how models think before answering