Priyansh Kumar

A few weeks ago I wrote about Siagnos, a personal taste engine for fanfiction that learns from reading behavior instead of matching tags. I was three stages in: scraper done, schema designed, embeddings working as a proof of concept.

Then I got a two-week internship window to build something deployable, and I made a call. Instead of pushing Siagnos forward stage by stage, I built Opsis: a scoped-down, content-based recommender that answers one specific question. Given a fic, what else in a real, collected corpus is closest to it in content?

Opsis doesn't do taste modeling. It doesn't touch my reading behavior at all. It's the layer underneath that, and it's live right now.


Why not just keep building Siagnos directly

Two weeks isn't enough time to get a reading tracker, a feature pipeline, and a trained preference model all working end to end. It is enough time to take the scraper and schema I already had and turn them into something real: a working recommender, deployed, with a UI, that someone else can actually use today.

So I scoped down on purpose. No personal taste model yet. No behavior tracking yet. Just: can I take one fic and find genuinely similar ones, from AO3 metadata alone, using content instead of tags?


What Opsis actually does

  1. Scrapes AO3 metadata under conditions the OTW Communications Committee confirmed were acceptable before I collected anything: one persistent session, randomized delays, capped retries
  2. Cleans and validates the raw data, log-and-skip instead of all-or-nothing, so one malformed row doesn't take down a 7,000-fic load
  3. Normalizes everything into PostgreSQL: fics, six lookup tables, six join tables, idempotent upserts so re-running the loader is always safe
  4. Embeds every fic's summary with sentence-transformers/all-MiniLM-L6-v2
  5. Ranks candidates with a blended score: 0.70 embedding cosine similarity, 0.15 fandom overlap, 0.10 relationship overlap, 0.05 popularity
  6. If you submit a fic that isn't in the database yet, Opsis scrapes it, cleans it, stores it, and embeds it on the spot, then recommends, closing the loop between "not yet known" and "recommendable" without me touching anything That last part started as a stretch goal. It shipped.

Where it stands

Deployed and reachable right now: FastAPI and Jinja2 on Render, PostgreSQL on Neon. Not a notebook, not a local script, an actual multi-page site: a landing page, a recommend page with three ways to submit a fic (work ID, URL, or title and author), and an about page walking through the pipeline for anyone non-technical who lands on it.

The dataset: 7,031 fics, mostly My Hero Academia with a meaningful share of crossover works pulling in other fandoms, 1,549 distinct fandom tags, 5,584 relationships, 5,785 characters, 30,132 freeform tags. Metadata only. No fanwork text is ever scraped or stored.

What I haven't done: a formal accuracy benchmark. No precision or recall number, because that needs labeled relevance data I don't have yet, and a fixed corpus snapshot to test against, which a system with on-demand ingestion doesn't naturally have. I said so directly in the project report instead of making up a number. What I do have: informal testing across manual queries, top recommendations consistently landing in a 50 to 70 percent blended similarity range, which is a plausibility check, not a quality claim.


What this sets up for Siagnos

The architecture wasn't built to only solve Opsis's narrower problem. The embedding storage sits behind an abstract interface specifically so a future pgvector migration doesn't touch the ranking logic that consumes it. The schema already has a behaviour table and a rating_types enum, sitting there unpopulated, waiting for Stage 4.

That's next: a reading tracker, logging what I actually open, how far I get, whether I come back. Once that exists, the fixed linear ranking blend Opsis uses today gets replaced by something trained on real ground truth, my ground truth, instead of a hand-picked weight for embedding similarity versus tag overlap.

Opsis proved the retrieval half works. Siagnos is still about the half that matters more: whether a system can learn what I actually like.


I recorded a two-minute walkthrough of the pipeline and the live site, linked below. Both repos are public: