OpenTrailPaper
Open-source bike computer firmware for the LilyGO T5S3 4.7" E-Paper PRO, with offline maps, GPX routes, FIT recording and Bluetooth sensors.
Eval-driven retrieval over pinned NBA-history Wikipedia Articles
Translation pending
Sports & fitnessPython · TypeScriptGitHub @milanmos13OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Question answering over a fixed, reproducible Corpus of pinned NBA-history Wikipedia Articles, with core retrieval built from scratch and judged by an Eval set.
Status: full Corpus. The Corpus is all 266 Articles from the inclusion rule below (prose only), searched with the tutorial's baseline embeddings. See the spec for where this is heading; domain terms are defined in CONTEXT.md.
backend/
manifest.json Articles and pinned revision IDs: the only Corpus artifact in git
(generated by nba_rag.generate_manifest from the inclusion rule)
src/nba_rag/ the library: Corpus building, Embedders, retrieval
eval_set.jsonl the Eval set
results/ eval results files, one per configuration, split and manifest
src/nba_rag_api/ thin FastAPI layer (POST /search, GET /results)
tests/ pytest, with saved HTML fixtures and a fake Embedder
frontend/ Next.js (App Router, TypeScript, Tailwind, shadcn/ui)
docker-compose.yml development stack
Requires Docker.
# One-off: fetch the manifest's Articles, chunk and embed them into the `data` volume.
# Wikimedia requires a contact address in the user agent. Fetching is polite (one
# request a second) and cached on disk in the volume, so the first build takes a few
# minutes and a rebuild after a parser change makes no network calls.
[email protected] docker compose run --rm backend python -m nba_rag.build
# Backend on :8000 (auto-reload), frontend on :3000 (dev server).
docker compose up
Search directly:
curl -X POST localhost:8000/search -H 'content-type: application/json' \
-d '{"question": "Who blocked Andre Iguodala in Game 7?", "k": 3}'
The inclusion rule: every NBA/BAA season, every NBA/BAA Finals, the 30 current
franchises and the 76 players of the NBA 75th Anniversary Team. manifest.json is
generated from it and pins every Article to a revision:
# Articles already in manifest.json keep their pinned revision, so Eval Evidence stays
# valid; delete the file first to re-pin everything to today's revisions.
docker compose run --rm backend python -m nba_rag.generate_manifest \
--version full-2026-10 --last-season 2025
Embeddings are stored as one matrix per embedding setup (embeddings/<setup>.npy) and
searched with vectorised operations.
backend/eval_set.jsonl holds the Eval set: one Eval question per line, with its
question type, source, split and verbatim Evidence spans. A retrieved Chunk is a hit
when it contains an Evidence span after whitespace normalization; a span split across
two Chunks counts as a miss (ADR 0001).
# Score a configuration on a split and write backend/results/. The split defaults to
# dev; test is for deliberate final runs, and all mixes the two.
docker compose run --rm backend python -m nba_rag.evaluate --configuration baseline --split dev
The command first checks that every Evidence span is still in the built Corpus and is a
single sentence. Results
files are committed; the API serves the latest at GET /results and the frontend shows
it at /results. Commit new results before deploying, because the production image
ships the committed files.
cd backend && pip install -e ".[dev]" && pytest # fast suite, no model needed
pip install -e ".[ml]" && pytest -m slow # real bge-small model
cd frontend && npm ci && npm test # Vitest + React Testing Library + MSW
CI runs ruff, eslint, tsc and the unit tests on every push, and checks that the production image builds and serves a search offline.
The backend runs on Google Cloud Run and the frontend on Vercel. See docs/deploy.md.
Row 1 of the planned experiment table reproduces the original tutorial exactly: BGE embeddings with mean pooling, no normalization and no query instruction, ranked by cosine similarity. Chunks are built by greedy word accumulation up to 200 tokens within a paragraph, with no overlap.
Code is MIT. Article text comes from Wikipedia and is licensed under CC BY-SA 4.0.
Originally based on Building Retrieval Augmented Generation (RAG) From Scratch; the generic version lives in git history.