Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
There is a clean dividing line that most people learn the hard way: fine-tuning is excellent at shaping behavior — style, tone, output format, following a niche instruction pattern, being concise — and bad at adding knowledge the base model never saw. If you fine-tune a model on 500 facts about your product, it will learn to sound like it knows your product while confidently making facts up, because supervised fine-tuning teaches the shape of answers, not a reliable fact store. Internalizing 'style and format: yes; new facts: no' saves you from the classic disappointment of a fine-tune that talks like an expert and hallucinates like an amateur.
The demo contrasts two training examples — one teaching a format/style the model can generalize, one trying to teach a specific fact — and explains why the first sticks and the second leaks into hallucination.
Use these three in order. Each builds on the one before.
In plain terms, what kinds of problems does fine-tuning fix well, and what does it fail at?
Walk me through why supervised fine-tuning teaches output style and format reliably but is an unreliable way to add new factual knowledge.
Given a model that needs both a strict JSON output format and access to frequently-updated pricing, explain exactly which part to fine-tune and which to leave to retrieval, and why.
# GOOD fine-tuning target: a STYLE/FORMAT the model can generalize.
good = {"messages": [
{"role": "user", "content": "Summarize this ticket."},
{"role": "assistant", "content": "TL;DR: <one line>\nNext step: <one action>"}]}
# The model learns the SHAPE 'TL;DR + Next step' and applies it to any ticket.
# RISKY fine-tuning target: a specific FACT.
risky = {"messages": [
{"role": "user", "content": "What is our refund window?"},
{"role": "assistant", "content": "Our refund window is 30 days."}]}
# The model learns to ANSWER refund questions confidently -- but if the policy
# changes to 14 days, it keeps saying 30. Facts belong in RAG, not the weights.
for name, ex in [("style/format -> learns to generalize", good),
("specific fact -> will go stale / hallucinate", risky)]:
print(name, "::", ex["messages"][-1]["content"][:40])python3 main.py