This is my submission for the Side Hustle challenge.
The problem nobody wants to proofread
If you sell on eBay or Etsy, you have probably written a title that says "Bluetooth 5.3" above a spec table that says "5.0". Or photographed a product next to a charger and never said whether the charger comes with it. Or typed "dishwasher-safe" because the supplier's page did.
Each of these is small. Each costs a return, a refund, or a one-star review that says "not as described". And the only tool most sellers have for catching them is rereading their own listing, which is the one thing you can't do well, because you already know what you meant.
Most AI tooling for sellers goes the other direction and writes more listings. I wanted the opposite: a quality-control pass that tells you what's wrong with the one you already have.
What Realist does
Paste a title, description and spec list, add up to eight photos, and Realist returns findings. Every finding has the exact fields or photo involved, a confidence, and a next step. For my test listing it reports:
🔴 Contradiction · bluetooth_version · high · confidence 100%
- title: Bluetooth 5.3
- specifications.Bluetooth Version: 5.0
Next: Check the manufacturer's documentation and make every field agree.
Findings come in four kinds, and keeping them apart is the core design decision:
| Type | Meaning |
|---|---|
text_conflict |
Two fields disagree. This is a fact about the listing. |
image_mismatch |
A photo appears to disagree with the text. This is an observation, with uncertainty. |
possible_omission |
Something visible isn't explained, such as an accessory in the photo. |
unverified_claim |
Nothing supplied can back the claim up. This is not an accusation. |
A photo that doesn't show an IP67 rating doesn't prove the product isn't IP67. Realist says "verify this", never "this is false".
The design choice: don't ask the LLM everything
My first instinct was to hand the model the whole listing and ask whether it looks right. I decided against that, for a reason that shaped the project: a model's judgment is the wrong tool for anything you can compare exactly.
So the work is split in two.
-
Plain Python does the comparing. It extracts Bluetooth version, IP rating, weight, quantity, battery capacity and color from the title, description and specs, normalizes them, and checks them against each other.
1.5 kgand1500 gare consistent, because weights are converted to grams first.5.3against5.0is a conflict every time, with no sampling and no temperature. That is why the confidence on a text conflict is 1.0. It's confidence that the fields disagree, not that either one is right. - A vision model only reports what it sees. It returns structured observations per photo (colors, visible accessories, legible text, item count) and never judgments. Python then compares those observations to the listing. A model that says "I see a USB cable" is much easier to trust, and to check, than one that says "this listing seems incomplete".
The same split sets how much each finding is trusted. A photo-based color mismatch is capped at 0.8 confidence, because lighting and image processing can shift color. An OCR'd model number that's close to the listed one but different gets 0.5, because OCR misreads characters.
Why open models matter here
This is the part where the open approach did real work, rather than being a checkbox.
-
Seller data stays on the seller's machine. Supplier photos, unreleased products, cost-bearing spec sheets: for a seller, a listing draft is business data. Realist runs Qwen2.5-VL-7B through a local Ollama server (default
qwen2.5vl:7b). Photos are resized and stripped of metadata, then sent to127.0.0.1and nowhere else. I'd still tell anyone to verify their own setup's telemetry before promising "never leaves your computer", and I turned off Streamlit's usage stats for that reason. -
The model is a swappable part. The audit depends on a three-line
VisionBackendinterface. When a better vision model appears, or the 7B turns out too slow, I change one class. With a hosted API I'd be rewriting around someone else's pricing and deprecation schedule. - Cost per audit is close to zero. A seller auditing a few hundred listings pays in electricity, not tokens. That decides whether a $9/month plan is a business or a loss. It isn't free (a 7B vision model on a CPU-only machine is slow, and I haven't benchmarked it yet), but the cost is mine to optimize.
- I can read what's running. Apache-2.0 for the model and for PaddleOCR (the optional OCR layer) means I can check the licensing for commercial use instead of trusting a terms page.
What I tested, and what I haven't
Honesty section, because I'd rather you hear it from me.
Tested: the deterministic engine, with 10 unit tests. They cover a matching listing producing zero findings, a deliberately broken listing producing exactly the planted conflicts (Bluetooth version, color, weight, quantity), unit equivalence not being flagged, claims supported by a spec not being flagged, a claim contradicted by a spec being caught, and HTML export escaping hostile input. The Streamlit UI also runs end to end headless.
Not tested yet: I tested the photo checks with hand-written observations, so I can't yet tell you how often the model's real observations are accurate.
Not built: a labelled evaluation set with precision, recall and false-positive rate, and a model-only baseline to compare against. My hypothesis is that the hybrid approach produces fewer false alarms and more actionable findings than "ask an LLM if this looks right". It is a hypothesis, and I haven't measured it.
What I'd do next
- Build the 30–50 listing evaluation set and publish the numbers, including the baseline.
- Add more rule families: dimensions, voltage and wattage, compatibility claims, material claims.
- Batch audits and a downloadable report for agencies running hundreds of listings. Free for 5 audits, then somewhere around $9 to $29 a month. Those prices are guesses to test, not market rates.
Try it
https://github.com/rafayet-git/realist
python -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/streamlit run app.py
Photo analysis is optional: install Ollama and ollama pull qwen2.5vl:7b. Without it, Realist runs the text checks and tells you the photos weren't analyzed.
Top comments (0)