✦ AI Buttons
Runnpm run lesson3View the code →

Lesson 3 · Route it

One prompt that handles every kind of support email gets long, vague and expensive. "If it's about shipping do this, if it's billing do that, unless…" Every email pays for every rule.

Better: sort first, then hand it to a specialist.

email ──► classify (fast model) ──► code picks the specialist ──► next steps (smart model)
                     │
                     └── not sure? ──► a person

Step 1: a cheap sort

const classification = await askJson<Classification>({
  step: "classify",
  model: "fast",
  schema: {
    category: { enum: ["shipping", "damaged", "billing", "returns", "other"] },
    confident: { type: "boolean", description: "false if the email fits two categories or none." },
    reason: { type: "string" },
  },
  // …
});

Classification is a small job. The fast model handles it quickly, at a small fraction of the smart model's price.

Step 2: code decides where it goes

if (!classification.confident || classification.category === "other") {
  return { classification, routedTo: "person", next: null };
}
const specialist = SPECIALISTS[classification.category];

This is the line that makes it a workflow. The model gave an opinion. Your code turned it into a path. Paths are something you can see in the code, test and change.

Notice the confident flag. When the classifier isn't sure, we don't guess: a person gets the ticket, with no AI suggestions to anchor them. Wrong routing is worse than no routing, because the specialist will confidently follow the wrong policy.

Step 3: a specialist with only what it needs

Each specialist gets:

damaged: { policy: "Damaged items", focus: "Get a photo first. Offer replacement or refund. …" },
billing: { policy: "Billing", focus: "Check whether it's a pending authorisation before refunding anything. …" },

Shorter prompts mean fewer tokens, but the bigger win is quality. A model that only sees the billing rules can't mix them up with the returns rules.

The specialist uses the smart model, because its answer is what a person acts on.

Run it

npm run lesson3
broken mug :(
  damaged  Mug arrived cracked; customer wants a replacement.
  1. Reply to Ana and ask for a photo of the crack.
  2. When the photo arrives, send a free replacement mug for order TS-48213.
  3. Let her know she can keep the damaged mug.
     ask for: A photo of the crack

  2 calls · 0.3s · replay, no cost

The pattern, in general

Routing is worth it when:

If every email needs the same handling, skip the router. One good prompt beats two average ones.

Try this