Bonus Track
Special Topics
Standalone deep-dives, one topic at a time
Special Topic 01
Custom Training
Specialize a small, cheap, local model on your task — a.k.a. fine-tuning. It routes a ticket in milliseconds for a fraction of a cent, with no API call at inference.
The project · support-ticket routing
One task, three methods, one yardstick

Route each customer-support ticket to the team that owns it — across 6 teams, scored on the same 48-ticket gold test set so the numbers are directly comparable.

The six teams (taxonomy.json)
Billing
Invoices, charges, refunds, payment methods, and subscription plans.
Account Access
Signing in and credentials: passwords, resets, SSO, two-factor, locked accounts.
Technical Support
Bugs, errors, crashes, and product features not working as expected.
Sales
Plans, pricing, quotes, demos, trials, and purchasing.
Trust & Safety
Abuse, fraud, spam, harassment, impersonation, and account-security concerns.
Data Privacy
Personal-data requests and handling: export, retention, and what data is stored or shared.
The tool call required Claude to pick a department for every ticket — but it might not be correct.
What makes it hard · hidden house rules

Org-specific conventions deliberately kept out of the team descriptions. Reasoning from definitions alone gets them wrong — you teach these by example.

Ticket looks like…
Obvious guess
Actually routes to
"Upgrade my plan / add seats"
Sales
Billing
"Close / delete my account"
Account Access
Data Privacy
"Charges I didn't make / hacked"
Billing
Trust & Safety
"Can't log in — throws a 500"
Account Access
Technical Support
Primer · what a classifier network does
Three layers, from pixels to a label

The classic example — recognizing a handwritten digit — has the same shape as our ticket router: raw input → learned features → one score per class.

A neural net learning to read handwritten digits.
Input layer one node per pixel
(28×28 = 784)
Hidden layer(s) learn features:
edges, loops, strokes
0
1
7 ✓
8
9
Output layer one score per class
— pick the largest
This is a very simple neural network that "classifies" a simple grayscale pixel-map array as the numbers 0–9. Each node has a weight for each input (W) and an offset (b): output = W·input + b.
Training gradually adjusts every W and b so the outputs match the desired labels — comparing each prediction to the truth and nudging the weights to reduce the error, via the famous backpropagation algorithm.
The progression
From prompting to a trained model

Three ways to solve the same task. Only the method changes; the test set and metric stay fixed.

Stage 0
Zero-shot
Claude sees the team definitions and the ticket — nothing else. The baseline.
Misses the house rules that aren't written down.
1 Claude call / ticket
Stage 1
Few-shot
Same prompt, plus ~21 labeled examples that demonstrate the house rules.
Examples teach where your team boundaries actually sit.
1 Claude call / ticket
Stage 2
Custom-trained
Train a small local classifier on a set of labeled tickets.
No Claude call at inference — embed + matrix multiply.
0 Claude calls / ticket
Why custom training might make sense here
1
It's just a classifier
We only need a label, not language output — a small model is a natural fit.
2
Failure is cheap
A few percent get routed to the wrong place — a human simply reroutes them.
3
Data is easy to get
A few days/weeks of correctly-routed tickets is a training set — and rerouted tickets feed back in to refine it over time.
Example project finetune.zip
Under the hood · custom training
Get labeled data, then train a small model
① Labeled data — (ticket → team) pairs
# production: capture from your resolved-ticket logs.
# this project: a ready-made set ships in the box.
rows = load("data/synthetic_train.jsonl")  # ~240 rows
② Train — embed → logistic regression
X = embed(texts)          # MiniLM, 384-dim, local
clf = LogisticRegression().fit(X, y)
# inference: embed + multiply, no API call
The included training set is for demonstration. It ships with the project so it runs without a production log. In practice you'd train on real labeled examples from production — which carry the true distribution and no model bias.
Run order
python stage0_zeroshot.py # baseline
python stage1_fewshot.py  # + examples
python stage2_finetune.py # train + score
python evaluate.py        # side by side
In the box
taxonomy.json · test.jsonl (48 gold)
seed_examples.jsonl (21 few-shot)
synthetic_train.jsonl (~240 train)
common.py — routing, embeddings
stage0 · stage1 · stage2
evaluate.py — F1 + confusion matrix
The full runnable project is bundled as finetune.zip — set ANTHROPIC_API_KEY and run in order.
The model · a frozen embedder + a trained head
Input
"My card was charged twice"
Feature extractor
Frozen
Embedding model
MiniLM · pretrained, downloaded once. Weights never change.
384-dim vector
What you train
Trained
Logistic-regression head
The only weights that learn — fit on your labeled tickets.
Output
Billing
Training touches only the small head: the embedder is a fixed feature extractor, so gradients update just the classifier on top — fast, cheap, and hard to overfit.
Why train a head at all? It learns which of the 384 dimensions matter for each team — a learned, per-class weighting — rather than treating them all equally like a plain cosine-distance nearest-match.
Special Topic 02
Vision-Language-Action
Moving LLMs into the physical world. An LLM maps text → text; a VLA maps (image + instruction) → robot action — in a closed perception-to-action loop.
See it move
A model, driving a real body

Same idea as an LLM turn — an observation goes in, a prediction comes out — except the prediction is motion, and the next observation is the world's response to it.

A low-cost arm following a spoken-language instruction.
A generalist policy generalizing across tasks and objects.
Under the hood · VLA
A multimodal LLM with an action head

A vision encoder + a language model — the familiar multimodal stack — but the text-generation head is swapped for an action model that emits continuous motor commands.

What the robot gives
Camera frame
what it sees now
Instruction
"transfer the cube"
Robot state
joint positions
VLA · SmolVLA (~450M)
Vision model
Encoder
frame → visual tokens
Language model
Backbone
fuses vision tokens + the instruction
Action model
Action expert
→ action chunk (not words)
14-num vector
Acts on the world
Robot / Sim
MuJoCo steps the arms
↻ the next camera frame becomes the next input — obs → action → step, every control tick
Example project robot.zip
A CPU-only demo: SmolVLA driving the bimanual ALOHA arms in MuJoCo, ~40 lines of loop. It runs end-to-end — but the base checkpoint is trained for a different robot body, so the motion is meaningless. That gap is the lesson about embodiment.