Skip to content
Client Login Start a project
{{ p.cat }} · {{ p.readLabel }}

{{ p.title }}

{{ p.dek }}

{{ p.initials }}
{{ p.author }} · {{ p.authorRole }}{{ p.ameta }}

A recommendation engine can produce an accurate ranking and still leave a customer uncertain about what to choose. The score tells the engineering team how confident the model is. It tells the shopper nothing about what the system noticed, so they cannot judge whether it noticed the right things. The usual response is to add explanations as a layer on top: a sentence generated after the fact, a tooltip, a “why this?” panel. That treats explainability as an interface feature. In practice it is an architectural decision, and the point at which you make it determines whether the explanation can be trusted at all.

Two ways to produce an explanation

There are two places an explanation can come from. It can be generated after the ranking, by a separate component that looks at the result and describes it. Or it can be assembled during the ranking, from the same inputs that produced the score. The two look identical on a product page. They behave very differently in production.

The post-hoc approach is attractive because it is cheap to add. The ranking system stays untouched, and a language model or a template fills in the words. The problem is that the explainer has no access to the decision itself. It sees a product and a context, and it writes something plausible. If the ranking favored a fragrance because the shopper kept returning to warm scent families, but the explainer mentions longevity because longevity appears in the product data, the customer is given a reason that played no part in the decision. Nothing in the system can detect this, because nothing in the system compares the two.

Building the reason with the decision removes that gap. The ranking records which inputs moved each product’s score, and the reason is written from those inputs only. A factor that did not change the ranking cannot appear in the explanation, so the explanation cannot disagree with the decision it describes. The cost is that explainability has to be designed into the ranking pipeline from the start, rather than added once the model is working.

Explanation generated afterwardsReason built with the decision
Source of the wordsA second model describes the ranked resultThe dimensions that moved the score
Can it contradict the ranking?Yes. It describes what it sees, not what happenedNo. A factor that did not move the score cannot appear
LatencyA second call, often a language modelInside the same response
DebuggingTwo systems to reconcileOne record: inputs, score, reason
What changes when the model changesThe explanations may drift silentlyThe reasons change with the decision

How we build reasons at Specicon

Our decision path runs ten engines in a fixed order on every request. For the purpose of explanation, four of their roles matter. The input engine captures behavior, context and any declared intent. The structure engine turns those signals into the dimensions of what we call the User Barcode, a per-session read of what the shopper is responding to rather than a demographic segment. The ranking engine scores the catalog against those dimensions, inside the merchandiser’s constraints, and keeps track of which dimensions moved each product. The output engine takes the dimensions that moved the top match most, writes them as words, and returns the match and its reason together.

On Uquda, the fragrance storefront we built and operate, a typical reason reads warm · evening · luxury. Each word names a dimension that moved the score: the scent family the shopper kept returning to, the occasion they were shopping for, and the price range they browsed. The reason is deliberately short, because the same line has to work on a product card, in an email, next to a support ticket and in the operations console, and it has to mean the same thing in each place.

What the response contains

One call to POST /v1/match returns the decision and its reason in the same payload. There is no second request and no separate explanation service to keep in step with the ranking.

200 OK · POST /v1/match
{
  "sku": "AF-2210",
  "score": 0.93,
  "reason": "warm · evening · luxury"
}

Keeping the reason inside the same response has a practical consequence for latency. Our whole decision path runs in under 20 milliseconds, and the reason adds no round trip to that budget. A post-hoc explainer that calls a language model typically costs hundreds of milliseconds on its own, which is why so many products render the recommendation first and the explanation later, or not at all.

Each reason is also stored with its request. In the Decision Console, a request shows its inputs, the products it ranked and the reason next to each one. That record is what makes a decision auditable: a merchandiser, an engineer or a compliance reviewer can open it and see why it went the way it did, without reconstructing anything.

Where the interface still matters

None of this makes the interface irrelevant. It changes what the interface is responsible for. Once the reason is guaranteed to be true, the design question becomes how to present it so that it is read and believed.

The first choice is placement. The reason has to sit where the eye lands, next to the product name rather than behind a disclosure, because an explanation nobody opens is not doing its job. The second is consistency: a customer who sees one reason on the storefront and a different one in a follow-up email will trust neither. The words themselves, from vocabulary to length to what a reason must never say, follow editorial rules of their own, which we cover in The editorial rules behind a recommendation reason. Both choices depend on the underlying words being reliable.

Trade-offs

Building explanations into the ranking is not free, and it is not always the right call. It constrains the model. A ranking system that cannot attribute its score to named dimensions cannot produce this kind of reason, which rules out some architectures or requires an attribution layer on top of them. It also constrains the vocabulary: a reason built from dimensions can only say what the dimensions can express, so the quality of the explanation depends on how well the dimensions were designed in the first place.

There are products where this trade-off is not worth making. If recommendations are a minor feature, if nobody downstream needs to audit them, or if the catalog is too small for ranking to matter, a post-hoc summary may be adequate. The case for building the reason with the decision is strongest where decisions carry commercial or regulatory weight: high-value purchases, categories where returns are expensive, and any product where a team has to answer the question “why did this customer see this?” after the fact.

What this means for a build decision

If you are evaluating a recommendation system, the question to ask is not whether it offers explanations but where they come from. Ask whether the explanation is derived from the same computation as the ranking, whether a factor can appear in the explanation without having affected the score, and whether the reason is stored with the decision or generated on display. The answers tell you whether the explanations are evidence or decoration.

The reasoning behind an individual decision can be inspected input by input in the Decision Inspector, which runs the same decision path on a worked example.

Open the Decision Inspector

The takeaway

An explanation is only trustworthy if it comes from the same computation as the decision. Build the reason from the inputs that moved the score, return it in the same response, and store it with the request. The interface can then make it visible; it cannot make it true.

New posts, straight to your inbox.

Thanks. We’ll email {{ subEmailShown }} when a new post is out.

{{ subErrorText }}

Unsubscribe at any time.