Skip to main content
Intelliger
A retrieval and evaluation blueprint

AI Search for Ecommerce: Retrieval, Live State and Evaluation

Build ecommerce AI search that combines hybrid retrieval with authoritative price, inventory and delivery checks, then evaluate the complete path.

Search engineer evaluating ecommerce headphone results against a checklist and physical product
Intelliger
12 min read

AI search for ecommerce should retrieve broadly from stable catalog facts, validate narrowly against live commerce state and rank only eligible variants. The language model can interpret intent and explain tradeoffs. It should not invent price, infer inventory or override compatibility rules. Evaluate the final answer and its evidence, not just vector recall.

This guide is for relevance engineers and commerce architects building search for shopping agents or conversational storefronts. It gives you a typed pipeline, a failure model and a test fixture that can be reproduced after an index, prompt, embedding or reranker change.

It sits within Intelliger's broader agentic commerce architecture guide, where retrieval is one stage in a governed commerce journey.

Define the search contract first

"AI search" often names several unrelated features. Here it means a system that converts natural-language shopping intent into verifiable product candidates. Four components have different jobs:

  • Intent extraction produces typed constraints, preferences and unresolved questions.
  • Retrieval finds a high-recall pool using structured, lexical and semantic signals.
  • Live-state resolution obtains current offer facts from authoritative services.
  • Ranking and presentation orders eligible items and exposes supporting evidence.

The indexed corpus should contain stable descriptive facts: product identity, variant attributes, specifications, compatibility relationships, category and content provenance. Price, inventory, promotion eligibility, delivery estimate and transaction state are volatile. Fetch them at runtime, with explicit timestamps and expiry.

This separation matches the direction of current commerce protocols. Google's Universal Commerce Protocol models product discovery as a capability and supports API, A2A and MCP bindings rather than reducing discovery to scraped pages (Google UCP engineering overview). OpenAI describes feeds as catalog representation while warning that shopping research can still make mistakes about current price and availability (OpenAI shopping research).

Use a typed state model

Treat a search request as a state machine, not one model call:

received -> clarified -> retrieved -> state_checked -> eligible -> ranked -> presented

Any stage may terminate with a named result: needs_clarification, no_match, state_unavailable, policy_denied or partial_results. A named state is easier to recover from than fluent but unsupported prose.

type HardConstraint = {
  field: string;
  op: 'eq' | 'in' | 'gte' | 'lte' | 'compatible';
  value: string | number | boolean | string[];
};

interface SearchRequest {
  requestId: string;
  query: string;
  category?: string;
  hard: HardConstraint[];
  preferences: Array<{ field: string; value: unknown; weight: number }>;
  context: { country: string; postalCode?: string; currency: string };
  requestedAt: string;
}

interface RetrievedVariant {
  variantId: string;
  lexicalScore: number;
  semanticScore: number;
  structuredMatch: boolean;
  stableFacts: Record<string, unknown>;
  sourceVersion: string;
}

interface CheckedVariant extends RetrievedVariant {
  live: {
    priceMinor: number;
    currency: string;
    purchasable: boolean;
    inventoryState: 'available' | 'unavailable' | 'unknown';
    observedAt: string;
    expiresAt: string;
  };
  failedConstraints: string[];
}

The unknown inventory state is intentional. Timeouts, permission failures and incomplete regional data are not proof of unavailability, but they are also not permission to promise stock.

Retrieve with complementary signals

Lexical retrieval remains valuable. It handles model numbers, materials, standards and exact phrases that embeddings can blur. Semantic retrieval helps with needs such as "quiet enough for calls" or "easy to pack on a train." Structured filters enforce category, size, voltage, certification and other typed requirements.

A practical pipeline is:

async function search(request: SearchRequest): Promise<CheckedVariant[]> {
  validateIntent(request);

  const [lexical, semantic] = await Promise.all([
    lexicalIndex.search(request.query, request.category, 120),
    vectorIndex.search(request.query, request.category, 120),
  ]);

  const fused = reciprocalRankFuse(lexical, semantic);
  const structurallyValid = fused
    .map(loadStableFacts)
    .filter((v) => satisfiesIndexedConstraints(v, request.hard))
    .slice(0, 40);

  const offers = await offerService.batchGet({
    variantIds: structurallyValid.map((v) => v.variantId),
    market: request.context,
  });

  return structurallyValid
    .map((v) => attachAndValidateOffer(v, offers, request))
    .filter((v) => v.failedConstraints.length === 0)
    .sort((a, b) => finalScore(b, request) - finalScore(a, request));
}

The numbers are starting points, not universal settings. Tune candidate depth using your evaluation set and latency budget. Record the candidate IDs at each stage. Without stage-level traces, a missing result could be an intent-parser error, retrieval miss, live-state rejection or reranker defect.

Never ask an LLM to "fix" a failed hard constraint. A model may suggest an explicit alternative, but the response must name what changed. For example: "No waterproof EU 44 variant is currently available under €150. These two exceed the budget by €12 and €19."

Resolve live state after retrieval

Calling price and inventory services for every indexed item is expensive and slow. Calling them for none is unsafe. Resolve live state for the bounded pool that survives stable constraints.

Use an offer contract that carries:

  • exact variant and market identity
  • price in minor units and currency
  • tax inclusion semantics
  • availability or purchasability state
  • promotion conditions, not merely a promotional label
  • destination assumptions for delivery
  • observation and expiry timestamps
  • source request or trace identifier

Google Merchant Center's availability specification requires supported values and consistency between submitted product data, landing pages and checkout (Google Merchant availability). An agent-facing service should similarly detect divergence rather than rationalize it.

Cache live state only within a declared freshness budget. The budget can differ by field and operation. A five-minute browse cache might be acceptable for a low-stock warning, while cart creation may require immediate revalidation. Store the observation time, not just a TTL in cache infrastructure, so downstream systems can determine age.

Before cart or checkout, revalidate the chosen variant. Search is evidence for a recommendation, not a reservation.

Rank eligible results, not plausible prose

Hard constraints must be applied before preference scoring. A useful final score can combine retrieval relevance, preference fit, evidence completeness and business-neutral quality signals. Keep each feature inspectable.

function finalScore(v: CheckedVariant, r: SearchRequest): number {
  if (v.failedConstraints.length > 0 || !v.live.purchasable) return -Infinity;
  return (
    0.3 * normalize(v.lexicalScore) +
    0.3 * normalize(v.semanticScore) +
    0.25 * preferenceFit(v, r.preferences) +
    0.15 * evidenceCompleteness(v)
  );
}

These weights are illustrative. Learn or tune them on judged data, then test by segment. A global average can hide failures for long-tail categories, non-English queries or compatibility-heavy products.

Return a short candidate set with matchReasons, tradeoffs, failedAlternatives and fact provenance. The conversational layer can transform that data into an answer, but a verifier should reject claims that are absent from the result contract.

For catalog modeling details, use the companion ecommerce product discovery guide. For large-catalog mechanics, see product search at catalog scale. For the publishing side of agent visibility, see AI search optimization for agentic commerce.

Failure and recovery cases

Intent parser changes "about $200" into a hard cap. Preserve linguistic confidence and the original phrase. Treat approximate language as a preference unless the user confirms a boundary. Add contrast cases to the parser test set.

Semantic search drops an exact SKU. Run lexical and semantic retrieval in parallel and fuse ranks. Include SKU and model-number queries in every release evaluation.

Reranker promotes an unavailable item. Make eligibility a filter or an infinite penalty outside the learned model. Recheck the invariant after ranking.

Inventory service times out for half the pool. Return verified results if enough remain and label the response partial. If none are verified, enter state_unavailable; do not substitute cached "available" values beyond their expiry.

Promotion is customer-specific. Pass the relevant authenticated context only after consent and authorization. If no context exists, return the ordinary price and describe the promotion as conditional.

Index and offer service disagree on variant identity. Suppress the record, emit a reconciliation event and preserve both source versions. Do not attach an offer to the nearest title match.

The answer cites the wrong candidate. Give every fact a variant ID and validate generated claims against that candidate's evidence. Reject cross-candidate attribute leakage.

Delivery date changes before checkout. Revalidate with the exact destination and selected fulfillment method. Present the new date for confirmation if it materially changes the choice.

Evaluate the whole path reproducibly

An embedding benchmark is not an ecommerce search evaluation. Freeze an index snapshot, mock authoritative live responses and set the clock. Each test case should specify expected eligible variants, forbidden variants and acceptable clarifications.

{
  "id": "adapter-240v-germany",
  "clock": "2026-08-11T10:00:00Z",
  "query": "travel adapter for a 240V laptop, delivery to Berlin by Friday",
  "context": { "country": "DE", "postalCode": "10115", "currency": "EUR" },
  "mustInclude": ["adapter-77-eu"],
  "mustExclude": ["adapter-12-us-only"],
  "requiredEvidence": ["voltage", "plugCompatibility", "delivery.earliestDate"],
  "maximumOfferAgeSeconds": 120
}

Use the following scorecard:

LayerMetricFailure it reveals
Intentconstraint extraction exact matchlost or distorted requirements
Retrievaleligible recall at krelevant variant never reached validation
Eligibilityhard-constraint precisioninvalid candidate survived filtering
Live statefreshness and source validitystale price, stock or ETA
Generationunsupported-claim rateanswer invented or mixed facts
Recoverysafe-state accuracytimeout or conflict produced a promise

Slice results by category, locale, query length, head versus tail inventory and constraint count. Add every production incident as a minimized regression fixture. Run deterministic layers on every change and reserve slower human judgments for preference quality and explanation usefulness.

Implementation checklist

  • Declare which fields are indexed, live and derived.
  • Version product identity mappings and source records.
  • Represent hard constraints, preferences and unknowns separately.
  • Fuse lexical, semantic and structured retrieval.
  • Trace candidate IDs and rejection reasons at every stage.
  • Batch-fetch live state for a bounded candidate pool.
  • Preserve unknown and expiry instead of forcing Boolean availability.
  • Enforce eligibility outside the generative model.
  • Revalidate before cart, checkout or another consequential action.
  • Verify generated claims against candidate-specific evidence.
  • Freeze catalog, live responses and time in release fixtures.
  • Review security, privacy and payment integrations with qualified experts.

The Intelliger boundary

Intelliger's Commerce Graph, Merchant Agent Runtime, connector network and Agent Search Console are target architecture, not shipped customer infrastructure. The blueprint applies the split described here: stable catalog knowledge in a graph, volatile state from authoritative merchant systems and outcome data feeding evaluation.

OATI is an open-standard developer preview for consequential agent actions. Implemented assets include schemas, TypeScript SDK, portable Python and Go core, CLI, conformance tests, local Commerce and RWA sandboxes, an Envoy reference and a public trust/lookup vertical slice. A complete policy compiler, independent review, evidence and dispute workflows, a customer gateway fleet and production acceptance across two enterprises remain incomplete. Current details are available in the OATI overview, developer docs and GitHub repository.

If your team has a real query set and catalog snapshot, request an Intelliger search architecture review and bring the failure cases, not a demo script.