1 / 8
↓ / → / space — next · ↑ / ← — back
DINEMAIT · recommendation pipeline
Epic A · Intent Agent

Two weeks of work,
visible in the traces

The Intent Agent went from one big guess to four separate signals. Here's what was added, how it helped the product, and real proof from a live run.

🟢 A1–A4 in production · verified live today
How it worked before

One big call — a trace you couldn't read

One ~600-line prompt guessed the intent and the location together. If the answer looked wrong, the trace couldn't show what broke — the intent, or the location.

IntentAgent · before
# one call, one result
classifyIntent    { intent, location }  // all together
# nearest / fit / best lenses — none
# "best" theme — none
# vague query → 3 separate dead-ends
What we did · A1–A4

Four stages, all in production

A1

Split the classifier

Two separate calls: intent first, then location. Each is tuned and traced on its own.

A2

nearest / fit / best lenses

Three signals: closest, best fit, or top-rated. Ranking now knows what the user really wants.

A3

The "best" theme

Tells "best burger" from "date-night spot". Knows Michelin / James Beard mean top-rated.

A4

Unified fallback

Instead of three dead-ends — one smart clarifying question.

Added to the trace · and what it gives

Every new row is a step you can check

Before — one classification row. Now — five rows, and you can see every one.

+ resolveLocationprompt / response
Location is now a separate step with its own request and answer. You see exactly what the model decided about the location — so a bug is fixed in the right place, with no guessing "intent or location".
+ reconciliation
Joins the two calls into one result. This is where the nearest / fit / best signals and the "best" theme appear.
+ resolveLocationbare-category backstop
A safety check: it catches a fake "location" ("the stadium", "restaurants") and won't search on junk — and it leaves a mark that it fired.
+ location resolution failed
Tells "the location call failed" apart from "it answered, but wrong" — different problems, different fixes.
What this changes

The location is no longer a blind guess

IntentAgent: resolveLocation response · "closest burger place"
{
  "specified_location": null,
  "location_source":    "device",
  "proximity_anchored": true    // ← "closest" makes the search area smaller around the user
}
🔬

Seen on its own

Location has its own request and answer. You can see exactly what the model understood about the location and what it returned.

🎯

Exact tuning

Every location field is on view — proximity_anchored and the rest. We change the behavior in the right place, by one clear field.

🛡

A safety check you can see

Model returned "the stadium" as a place? The check caught it and did not search on a made-up place — and left a mark in the trace.

Now visible · signals inside the trace

The intent became visible

IntentAgent: reconciliation · "best burger in Boston"
{
  intent:             "restaurant_recommendation",
  nearest:            false,      // A2 — proximity
  fit:                true,       // A2 — taste fit
  best:               true,       // A2 — top-rated
  best_theme_family:  "food",     // A3 — which kind of "best"
  best_theme_key:     "burger",   // A3
  best_theme_key_canonical: "burger",
}

Also, at the end, A4 adds a ready follow-up question when the query is too vague to search.

Verified live · DEV run · Jul 22

Real queries, read straight from the traces

Querynearestfitbestbest_theme
"closest burger place"truetruefalse
"closest place with vegan options"truetruefalse
"great pizza near me now"truetruefalse
"best burger in Boston"falsetruetruefood / burger
Outcome · what we got

What it gave the product

🎯

Better results

"Closest burger place" really returns the closest one, not just "burger places". The system understands what the user wants — near / by taste / top-rated — and ranks for it.

🚪

Fewer dead-ends

A vague query no longer loops on "name a city/state". Instead — one simple follow-up question.

🔍

Clear traces, faster fixes

Every decision shows in the trace. Bugs are fixed in the right place, and problems are easier and faster to catch.