Intent Ledger

1. The Problem We're Solving

A shopper rarely states everything up front. They say "running shoes," then add "actually waterproof," then "under $80," then change their mind about color. A search agent that treats each turn as an isolated query will re-ask questions the user already answered, lose corrections, or return noisy results when a request is broad. The challenge scores agents on how quickly and accurately they surface the one hidden target product across up to 10 turns, which rewards state that persists, narrows, and corrects itself turn over turn, not just better retrieval on a single query.

Our thesis: most of the score is won or lost in state management, not in the retrieval algorithm. So we built the conversation state first, and used the simplest retrieval method that could safely exploit it.

2. Solution Overview

Intent Ledger is composed of five cooperating pieces:

2.1 The Intent Ledger (conversation state)

Every turn, extracted signals are written into a structured ledger: category, hard constraints (e.g., "must be waterproof"), soft preferences (e.g., "prefers black"), explicit no-preference statements ("any color is fine"), and metadata for each, where it came from, how confident we are, and whether it has since been superseded. Corrections don't delete history; they add a tombstone over the old value so we can audit exactly how the user's intent evolved and never silently regress to a stale constraint.

2.2 Deterministic Facet Graph

Buying-oriented constraints (taxonomy, material, color, brand, budget, feature) are represented as posting lists, the set of catalog items matching each value. When the ledger has enough explicit slots filled, we intersect the relevant posting lists smallest-to-largest for cheap, exact, explainable narrowing. No embeddings, no learned ranker, no similarity threshold decides membership, a product is either in the intersection or it isn't, which makes the retrieval fully auditable and reproducible.

2.3 Bounded Relaxation

If an exact intersection is empty, we don't dead-end. We relax at most three low-confidence soft clauses before ever touching a hard clause, and we log each relaxation step (which clause, why, and the pool size before/after) so behavior stays explainable rather than "the algorithm just changed its mind."

2.4 Safe Hybrid Gate

We only trust the exact facet intersection when it is small enough to be useful, between 1 and 10 products, so the whole pool fits inside a Top-10 response. Anything broader, unresolved, or that required relaxation instead falls back to a progressive three-view retrieval portfolio (a broader, higher-recall approach) so we never gamble precision against a request that's still ambiguous.

2.5 Catalog-Grounded Clarification (ID3-style)

When we need to ask a question, we pick the facet that maximizes information gain against the current live candidate pool (not the whole catalog), and we never repeat a facet we've already asked. We track an entropy-collapse curve and compute both an information-theoretic lower bound and expected greedy-tree depth, so the questioning strategy is measured, not just heuristic. (We're explicit in our docs that this is a strong greedy heuristic, not a provably optimal policy in general.)

Every turn also emits a structured "flight recorder" event, route taken, active ledger state, question rationale, retrieval page, candidate count, latency, fallback status, which made debugging and the ablation study possible.

3. Why This Design (and What We Rejected)

We built and measured a progression, keeping only what improved the metric:

Stage TechnicalScore
Official weak BM25 baseline 0.1067
Stateful single view 0.7504
Three-view fusion 0.7654
Progressive retrieval portfolio 0.8136
Pure facet graph + entropy questions 0.8626
Pure facet graph + universal question channel 0.8613
Hybrid exact-intersection gate (final) 0.8774

The pattern that emerged: pure lexical retrieval plateaus quickly because it can't exploit explicit structured facts once the user has stated them. A pure facet graph is precise but brittle on broad or ambiguous turns. The hybrid gate, exact intersection when it's safe, portfolio retrieval otherwise, captured the strengths of both, which is why it's the version wired into the scored agent.

4. Results (Public 200-Session Evaluator)

  • TechnicalScore: 0.877413 (vs. 0.106710 official baseline)
  • Hit Rate@10: 0.965
  • MRR: 0.766375
  • MTTC (mean turns to hit): 2.750
  • Tokens used: 0 (fully local, no LLM calls in the scored path)
  • Network calls at inference: 0
  • Index build time: ~4.27s
  • Mean/p95 latency: ~134ms / ~331ms

Scenario breakdown: Boundary 1.000, Browsing 0.975, Buying 0.963, Intent Override 0.933.

These are development-set numbers; the private 800-session set is unseen and generalization there is not guaranteed.

5. Tech Stack

  • Language: Python 3.10+
  • Storage/Indexing: SQLite with FTS5 (full-text search) for lexical posting lists and facet indices, no external database server
  • Retrieval: Custom deterministic facet-intersection engine + progressive multi-view lexical retrieval portfolio (hand-rolled, no vector DB)
  • Model usage: None in the scored path, zero LLM tokens, zero network calls at inference; the system is a rules/IR system over structured and lexical signals, not a foundation-model wrapper
  • Testing: Python unittest, with dedicated suites for contract compliance, edge cases (empty/Unicode/oversized inputs), scenario coverage, and session isolation
  • Tooling: make targets for test, evaluate, benchmark, ablate, evaluate-facets, and demo, so every claimed number is independently reproducible
  • Interface: Implements the organizer's required starter.agent.Agent contract (reset / respond) unchanged, so it drops into the official evaluator with no modification needed there

6. Engineering & Safety Properties

  • Deterministic failure handling: If the facet path throws, the hybrid falls back to the independently computed portfolio result and logs the error; the portfolio itself falls back to the last valid result or a deterministic popularity list. No retries, no unbounded loops, no silent hangs.
  • Session isolation: State is isolated per session_id, copied on reset, capped with LRU eviction, and excluded from any global ranking state, one user's session can't leak into another's.
  • Privacy: No raw user IDs, review text, timestamps, or purchase history are used or logged; profiles are copied per-session and excluded from trace output; user text is tokenized to bounded alphanumeric terms before being used to build search expressions (mitigating injection-style inputs into the FTS query).
  • Auditability: Every ledger mutation, relaxation step, and question choice is logged with rationale, which is what allowed us to run a rigorous ablation rather than tuning by feel.

7. Limitations (Stated Plainly)

  • Retrieval is lexical/metadata-grounded, which advantages queries that echo catalog vocabulary over naturally paraphrased ones.
  • Progressive pagination trades some immediate relevance for broader exploration on ambiguous turns.
  • The entropy-based question policy optimizes for catalog uncertainty reduction, not directly for user abandonment or conversion, it's a strong heuristic, not a proven-optimal policy.
  • Intent parsing is deterministic and conservative, so subtle implicit negation ("not like the last one") may not always be tombstoned correctly.
  • All reported numbers are on the public development set; private-set performance is unverified by us.

8. Compliance Checklist

  • Headless Python Agent interface: implemented as specified
  • Max 10 catalog-valid parent_asin recommendations per turn: enforced
  • 10-turn session protocol: supported
  • Catalog remains read-only, never mutated or committed
  • No multimodal components, heavy vector database, or model fine-tuning/training involved
  • Fully functional offline at inference time
  • Model choice (none/local), token usage (zero), latency, and fallback behavior disclosed as required

Full architecture diagrams, the facet-graph design rationale (including a documented failed literal-matching prototype and its correction), the threat model, and the exact ablation/benchmark JSON outputs are included in the repository's docs/ directory for anyone reviewing the submission in depth.

Built With

Share this project:

Updates

Submission history