What it was
You can know what you want a Magic card to do and still have no idea what it's called. Grimoire ML lets you describe it in ordinary language, then turns that description into a Scryfall query. The model produces a structured representation first. I can look at that to see what it understood, then build and test the actual search separately. There's a Next.js frontend, a FastAPI backend and a separate card-image proxy, with Redis caches between the services. It's a prototype.
Grimoire MLBuild
- The query service turns natural language into a structured intermediate representation, then builds the Scryfall query from that. Redis caches the stages.
- A card-image proxy has its own cache and metrics, keeping image requests off the main backend.
- The frontend uses Next.js and TypeScript, with Tailwind and Mantine for the UI.
- Docker Compose runs the services, Postgres and Redis locally. Prometheus and Grafana show what each service is doing.
Key decisions
The query representation
I wanted to inspect the model's interpretation before it became search syntax. The structured format also means the query code can be tested on its own.
Caching
Card data changes slowly, while model calls cost time and money. Redis means repeating a search doesn't need to repeat all that work.
Seeing inside the services
I wired in Prometheus and Grafana one afternoon. They were useful whenever Claude gave crappy responses to my prompts, because I could see which service had started doing something odd.
Lesson learned
I needed to see what the model thought I'd asked for.the rest of it ↓fold it back up ↑
Having the model write search syntax directly made a bad result difficult to work out. Had it misunderstood the request, or was the query wrong? Putting a structured representation in the middle let me look at those separately. I could also test the whole query layer without making a model call. I put that in late, I'd start there if I built it again.