PersonalLib
Your reading history plus your library's catalog — the right book, available right now.
- Context
- Built for AI Agents, UCLA Anderson MBA
- Role
- Solo
- Stack
- Python 3 (standard library) · Streamlit / Jupyter front ends · Claude Code
- Status
- Prototype — live demo below
The problem
Recommendation lists tell you what's popular, not what you'll like — and even when you find something, you don't know whether your library has it or whether you're facing a three-week hold. PersonalLib answers both at once.
What I built
A recommender that reads a Goodreads CSV export, builds a taste profile from the books you rated 4–5 stars, and returns a ranked table of new titles. Each row has a plain-language reason, a note tying it to your history (“next in a series you're reading,” “you rated Book Lovers 5★”), whether it's a standalone or part of a series, its Libby availability, and a color-coded action: Borrow now, Place hold, or Save for later. It runs as a CLI, a Jupyter notebook, or a Streamlit app — the hosted demo runs the recommendation engine directly, no setup needed.
The screenshot below is a run against the sample reading history:

How it works
Taste profile. CSV rows become structured book objects; genres and authors are counted with star ratings as vote weights, and series progress is tracked.
The recommendation engine. Every candidate in a curated database is scored on genre fit, author affinity, and series progression — with a penalty for a mid-series book whose earlier entries you haven't read, and a bump for a high average rating. Already-read titles are filtered out, and the top-scoring results are returned. It's fully deterministic — same input, same output, no API key. (The Jupyter notebook also carries an experimental GPT-4o-mini variant I built to sanity-check the rule-based scores against; the CLI and the hosted demo are the engine only.)
Availability cross-reference. Each recommendation is looked up in a mock Libby dataset (status, wait weeks, library) and turned into the Borrow / Hold / Save action.
Evaluation rubric. Every recommendation is scored on four dimensions — taste fit, actionability, accuracy, clarity — each 0–10, summed to a score out of 40, so runs can be compared.
Iterative user control. There is no ground-truth label set; the user swapping the CSV or adjusting the count is the quality signal. A daily background job can fire a macOS notification when a watched book becomes available.

What I learned
This was a chance to design a full workflow from scratch — figuring out what data the system needs, where to source it, and how to turn it into a recommendation someone can actually act on. The experimenting was the fun part: where good data lives, and how to use it well enough to make a better call.
It was also a useful reality check. As the next section notes, there isn't a real API for live library availability yet, so a production version isn't feasible today — but the pipeline is a working blueprint for when that data exists.
What I'd improve
Real Libby / OverDrive availability and a much larger catalog (Open Library or Google Books); LLM-based genre inference from descriptions instead of relying on shelf tags; collaborative filtering and automatic series-chain suggestions; and Goodreads OAuth instead of a manual CSV export.