Project · AI agent for GEO and AEO in Ruby on Rails

product_geo_agent

A Rails command-line AI agent that checks whether AI assistants can find and recommend a Shopify product, scores it 0 to 100 and names the top gaps.

Ruby 4.0 · Rails 8.1 · little_ghost · Gemini · Shopify Storefront GraphQL API · PostgreSQL · RSpec

The problem

Shoppers now ask AI assistants what to buy, and a store owner has no easy way to know whether an assistant would recommend their product, or why not. Most “AI readiness” audits are SEO checklists with an AI label. This agent asks the question that is specific to AI discoverability: would an AI assistant actually recommend this product?

GEO (generative engine optimization) is about being understood, quoted and recommended by tools like ChatGPT, Gemini and Perplexity. AEO (answer engine optimization) is the same idea aimed at direct answers. Classic SEO is about ranking in a list of links. GEO and AEO are about being the answer.

What I built

An AI agent is a loop, not a single model call: Context → Reason → Act → Observe → Repeat → Answer. This one has five tools and decides which to call:

Diagram of the product_geo_agent loop: 1. context, one Shopify product, goes into the agent loop, where Gemini 2. reasons and picks the next tool, 3. acts by calling one of five tools, 4. observes the tool result and 5. repeats until the checks are done. Then 6. it answers, with the score computed in Ruby, not by the model.
Tool What it checks
get_product_data Title, description, images and alt text, variants, SEO fields
check_faq_page Whether the store has a FAQ page
check_faq_metafield A FAQ on the product itself, only when the FAQ page finds nothing
check_structured_data Product and FAQPage JSON-LD on the live product page
check_ai_citation Asks an LLM for a recommendation and checks whether the product comes up

Three real audits on a sandbox store, one run each:

Product Score What the agent found
The Complete Snowboard 70 / 100 Full description and complete Product schema. No FAQ, not recommended by AI.
The Videographer Snowboard 33 / 100 Schema present, but no sizing or binding details. No FAQ, not recommended.
The Out of Stock Snowboard 10 / 100 Empty description, incomplete schema, no FAQ.

These are single runs. Across five eval runs the complete snowboard scored between 65 and 70.

What I verified

What broke, and what I learned

A green test suite sat on top of a broken agent. Every spec passed while a bug in the agent framework silently stopped my hooks (retry handling and tool-result collection among them) from running on real audits. Mocked tests could not catch it, because mocks assume the connection already works. Only running the real agent did. I traced it to three bugs in the little_ghost gem, fixed them, and all three fixes were merged upstream.

The model could not add. In one audit the code calculated 75 points lost, but the model wrote “55”. Generating text one word at a time is not arithmetic. I moved all math into Ruby and let the model only describe finished, correct results.

Approach: key decisions

Status

Working end to end, with retry and backoff for Gemini rate limits, usage tracking, a CLI with a live trace, and an eval harness. It is a learning project, not a complete GEO audit. It reads one product at a time and never writes to the store.

Related services

Need something like this in your own product? See AI discoverability for brands and online stores (GEO and AEO) and AI engineering and integration.

Other projects