Read the full writeup →

A LangGraph agent with retrieval as a tool

Name a dish. It picks the style, finds the bottles, then checks itself.

The agent reasons from pairing principles to a wine style, searches Wine Enthusiast reviews with your budget as a filter, recommends one or two bottles with citations, and goes back to re-strategize if its own critique finds a problem.

By Jeremy Lee, WSET Level 3 · Source on GitHub

The graph in src/graph.py. Retries stop at --max-attempts (default 2).

A recorded run

From examples/sample_run.md. The agent reasoned to a full-bodied, tannic Cabernet, retrieved six Cabernets (from Napa, Stellenbosch and Mendoza), all at or under $45, and recommended two.

The dish

Grilled ribeye steak with a peppercorn cream sauce

--budget 45
Vinifera 2006 Cabernet Sauvignon, Napa Valley95 pts · $40 · [3]

"The structure scours the cream and fat while the oak mirrors the grilled char."

Textbook 2005 Mise en Place Cabernet Sauvignon, Oakville94 pts · $44 · [5]

"that grippy structure is exactly what a fatty ribeye needs"

Critique: sound. Every bottle, score and price comes from a retrieved review.

What each node does

  1. parse turns the meal into JSON: main ingredient, body, sauce, cuisine, flavors, cooking method.
  2. strategize applies the principles in src/pairing.py (acid cuts fat, tannin binds protein, match weight, sweetness tames heat) to choose a style and write a search query.
  3. retrieve calls search_wines, a LangChain StructuredTool over a local Chroma index, with the budget as a price filter.
  4. recommend has Claude pick from the retrieved wines only and cite each as [n].
  5. critique checks for at least two candidates and one within budget, then asks an LLM whether the pairing is coherent.

Traced

--trace times each node and saves the run as JSON. In one traced ribeye run the local search took 0.3 seconds and the four LLM steps took 1.2 to 3.0 seconds each.

AGENT TRACE  (node · time · detail)
  parse         1.2s   ribeye · rich body
  strategize    2.3s   style → full-bodied tannic red
  retrieve      0.3s   6 candidate wines (tool: search_wines)
  recommend     3.0s   drafted pairing with citations
  critique      2.2s   sound

Trace tree as recorded in the README, bullet glyphs dropped.

Limits

Pairing quality is not scored against a benchmark, so this shows that the agent works and checks itself, and leaves the quality of its pairings unmeasured. The principles are a short list, retrieval filters on price only, and the default index holds the 30,000 highest-scored reviews.