Inspiration

Standard LLM-based shopping agents are frustrating to use. When users search for a product, generative agents often suffer from "Query Drift"—hallucinating constraints, forgetting past instructions, or wasting the user's time by asking redundant questions when the perfect product has already been found.

I saw that the TechJam baseline agent had a catastrophic Mean Turns to Completion (MTTC) of 9.81 (out of 10) and a HitRate@10 of just 12.5%. I realized that treating an e-commerce agent as a purely generative text problem was a mistake. I needed a mathematically bounded state machine.

What it does

CutCart is a high-performance e-commerce shopping agent that acts as a ruthless filter. Instead of chatting aimlessly, it tracks exactly what a user wants (and doesn't want) across a multi-turn conversation. It actively calculates the fastest mathematical path to narrow down a massive product catalog, asks only the most critical bisection questions, and instantly recommends the right product the second a high-confidence match is found.

How I built it

CutCart completely decouples Natural Language Understanding (NLU) from the Retrieval Engine. I built it in three distinct layers:

1. The Quad-State NLU Router Instead of feeding raw chat history into an LLM and hoping it generates a good search query, I constrain gpt-4o-mini using strict Pydantic schemas. The LLM's only job is to translate user utterances into a QuadStateUpdate JSON patch containing four arrays: Add, Replace, Remove, and Negative. This ensures the agent never forgets a constraint and handles "intent overrides" (e.g., "Actually, no Nike, make it red") flawlessly.

2. Deterministic Hybrid Retrieval I load the catalog.jsonl into an in-memory SQLite FTS5 Virtual Table. I query it using BM25, but I aggressively isolate explicit negative constraints so they don't bleed into the search string (a common failure point in baseline RAG). I then apply a deterministic facet-scoring algorithm on top of the BM25 base.

3. The Adaptive Boundary Engine (The Math) To slash the MTTC, CutCart calculates exactly which question it should ask the user next to perfectly bisect the remaining candidate pool. For every unset facet, it calculates a $CutScore$ using the following distribution math:

$$CutScore = \left( 1 - \frac{MaxFrequency}{ValidCount} \right) \times \frac{ValidCount}{TotalCandidates}$$

If 100% of the remaining shoes are Leather, the $CutScore$ for material drops to $0.0$, and the agent skips asking about it. CutCart only asks high-leverage questions. If the delta between the #1 and #2 ranked items exceeds a safety threshold ($\Delta \ge 3.0$), the agent triggers early convergence and confidently recommends the product.

Challenge I ran into

The Personalization Trap (Query Drift) Halfway through the hackathon, I tried injecting the user's hidden preference tags directly into the BM25 query to give users a personalized experience. This caused a catastrophic regression.

If a user asked for "running shoes" but their hidden profile said "likes vintage cameras", the search engine queried "running shoes vintage cameras", returning garbage candidates and tanking our MRR.I learned empirically that naive vector personalization poisons the search space. I ruthlessly stripped it out to protect the integrity of the bisection math.

Accomplishments that I'm proud of

I mathematically proved our architecture works. By moving from a stateless baseline to the HyperCut Architecture, I achieved:

  • HitRate@10: Increased from 0.125 to 0.510 (+308%)
  • MRR: Increased from 0.068 to 0.366 (+440%)
  • MTTC: Dropped from 9.81 to 7.27 (Saving >2.5 turns per user)
  • Overall Tech Score: Quadrupled from 0.106 to 0.439

What I learned

I learned that in agentic AI systems, strict deterministic boundaries outperform pure LLM generation. By constraining the LLM to act merely as a router, and letting traditional statistical math handle the retrieval and bisection, I built a faster, cheaper, and vastly more accurate system.

What's next for CutCart

I want to reintroduce personalization safely. Instead of injecting profile tags into the hard vector search, I plan to implement a Soft-Tensor Cross-Encoder. This would apply personalization weights only to the top 20 candidates retrieved by the deterministic bisection engine, ensuring zero query drift while still tailoring recommendations to the user.

Built With

Share this project:

Updates

Submission history