Real-world projects
Real-world projects
A brief, open data, and named things to deliver — the way work actually arrives. Each project runs on a model on your own machine and a vector database. No API key, no account, nothing sent anywhere.
Optional and never counted. Each task has a check, and the checks are there so you know when you are done, not to score you.
| Project | What you build |
|---|---|
| 01 — What are customers really saying? | Embeddings of 958 real clothing reviews, a 2-D map of them, topics, and a "find reviews like this one" search with ChromaDB |
| 02 — What are these companies worried about? | A RAG pipeline on the risk sections of eight real annual reports, in the order a real project goes: the model alone, the raw HTML, cleaning, chunking, embedding, ChromaDB, answers with the paragraph they came from, and keyword search measured against embeddings on 20 labelled questions |
| 03 — Did the extra agents earn their calls? | Four narrow roles over project 02's filings index: a coordinator that picks the company with no model call, a researcher with read-only tools, a writer that may cite only what came back, and a critic with exactly one revision. The same team runs as a LangGraph state graph and as plain Python, routing is measured on its own against the 20 labelled questions, and the team's model calls are counted against a single loop's |
| 04 — What went wrong on that one? | The team from project 03, wrapped rather than edited, so one run records what it did in what order. Then the 20 labelled questions graded against a pass condition written down before the run, and every failure read against its own trace and put in one of five buckets, because the bucket is the thing you fix |
Ask your assistant. Each project has a file your coding assistant reads first, with the project's purpose, goals and how to run it: project 01, project 02, project 03, project 04.
Before you start
uv sync --extra projects # ChromaDB, scikit-learn, pandas, matplotlib
ollama pull nomic-embed-text # a 274 MB embedding model
ollama pull qwen2.5:7b-instruct # project 02 only: the model that writes the answers (4.7 GB)
uv sync --extra projects --extra agents # project 03 also needs LangGraph
Project 02 also runs without the 7B model. Its first cell prints [live] when Ollama
answers and [recorded] when it replays one real run instead, so every step still runs.
Only 8 GB of RAM? Run the model on Google Colab instead — see
demos/04_ollama_on_colab.ipynb, then ollama pull nomic-embed-text there.
The ideas you need, in one page
An embedding is meaning, turned into position
An embedding model reads a piece of text and returns a long list of numbers — 768
of them for nomic-embed-text. The numbers are placed so that texts which mean
similar things end up close together, even when they share no words. "Runs small"
and "order a size up" land near each other.
Close means similar: cosine distance
To compare two embeddings, measure the angle between them. Cosine distance is
0 when two vectors point the same way and grows as they diverge. In Python,
scipy.spatial.distance.cosine(a, b). Everything else in the project is built on
this one comparison.
Nobody can look at 768 dimensions: t-SNE
t-SNE squeezes high-dimensional points down to two, trying to keep neighbours as neighbours, so you can plot them. Read the plot for neighbourhoods. The gap between two far-apart clusters means very little — t-SNE does not preserve large distances, so do not read one cluster as "twice as different" as another.
A vector database stores vectors and answers "what is nearest?"
Comparing a query against 958 reviews one at a time is fine. Against a million it is not. A vector database such as ChromaDB stores the embeddings once and finds the nearest ones quickly. You give it an embedding function, add documents with ids, and query with text.
The nearest thing to a review is that review
Search a vector database with a review that is already in it, and the first result is the review itself. Ask for one more than you need, and leave it out.
Read the whole result, and measure before you claim an improvement
A search that looks wrong from the first line of each result can be right: a review that opens with the colour of a skirt may be a complaint about its quality two sentences later. And a setting the documentation recommends is still a hypothesis about your data until you have counted what it changed.
Data and licences
Project 01 uses a sample of Women's E-Commerce Clothing Reviews, released into the public domain (CC0) on Kaggle.
Project 02 uses Item 1A, Risk Factors, from the latest annual report (Form 10-K)
of eight companies, as the SEC publishes it on EDGAR. These are public filings, open
for anyone to read and reuse; the companies wrote them, so they are not government
works. data/sources.json gives the URL, accession number and dates of every file.
See each project's data/LICENSE.md.