Imagine every Shed bulletin ever sent, laid out on one enormous workbench — and a helpful member who has read all of them, ready to answer whatever you ask.
Over the years The Shed has emailed around 130 bulletins: bee box milestones, working bees, member profiles, welding courses, AGMs, the lot. That's a wonderful history — but if you wanted to know "when did we make our 5,000th bee box?" you'd be scrolling through years of PDFs to find it.
The Bulletin Assistant does the scrolling for you. You type a question the way you'd ask a mate, and it finds the handful of bulletin pieces that actually talk about your topic, then writes you a short answer — and tells you which bulletins it came from, so you can trust it.
How it works, in three moves
It reads the shelf
Every bulletin is broken into its separate articles and filed by topic — like sorting a decade of newsletters into labelled pigeonholes.
It finds the right pieces
When you ask something, it pulls out just the few articles that match your question by meaning — not just matching words, but what you meant.
It answers in plain words
It reads those pieces and writes a short, friendly answer, listing the bulletins it used so you can check the originals.
Under the bonnet it's a retrieval-augmented generation (RAG) pipeline: a local vector search over the bulletin corpus, feeding a language model that answers only from what it retrieves.
The pipeline, end to end
The main players
| Component | Role | Choice & why |
|---|---|---|
| Extractor | Splits each PDF into per-article records with heading + date | PyMuPDF — reads font styling to detect headings across 10 years of template drift |
| Embedding model | Turns text into vectors that capture meaning | all-MiniLM-L6-v2 — small, fast, runs locally, no data leaves the box at index time |
| Vector store | Holds the vectors + metadata, does similarity search | Chroma — file-based, no server to run, the whole DB is a portable folder |
| API service | Retrieve → prompt → stream the answer | FastAPI + server-sent events for token-by-token streaming |
| Language model | Writes the final answer from retrieved excerpts | Anthropic (hosted) — swappable via one setting; a local model is possible for full privacy |
Design decisions worth noting
GroundingAnswers are constrained to the corpus
The model is instructed to answer only from the retrieved excerpts and to say when something isn't covered. Only the handful of matched chunks — never the whole archive — are sent to the model per question.
MetadataEvery answer is traceable
Each chunk keeps its heading, bulletin date, and source file. The service returns those alongside the answer, so any claim can be checked against the original bulletin. Dates are also stored numerically for range filtering (e.g. "since 2022").
PortabilityBuild local, serve anywhere
The index is built on a workstation and the resulting Chroma folder is copied to the server as-is — no rebuild. The service runs independently of the main WordPress site and is embedded via its own subdomain.
