A static, localized, self-paced course on the fundamentals of generative AI, without the math.
It rests on one idea: most people who get stuck with these tools aren't short on effort, they're short on a few fundamentals. Not math, not jargon, but a plain-language sense of how a model works under the hood: enough to know why it sometimes gets things right, sometimes makes things up, and what you can do about it. Teach a handful of fundamentals well and much of the rest (prompting, agents...) follows from them.
Every lesson is short and comes with an interactive, so you can watch how the thing actually works instead of taking it on faith. It runs best on a computer, where the interactives shine.
The site is generated from a single source in src/ and published as self-contained HTML that runs offline straight from file://. There is no runtime localization: each page ships with the final text for its language.
Made for people who don't come from tech, with every term explained the moment it appears. If you already work in tech, it's a compact way to review or reorganize the fundamentals. The aim isn't the math or how to build models: it's accurate intuition. Understand how generative AI generates, what it can and can't see at a given moment, and how to judge what it produces with a critical eye.
- Self-paced (
web/): one page per lesson, with a quiz and interactives. For studying on your own. - Presentation (
present/): the same lessons as chained slides, to show to one person or a room (arrow keys navigate,Ffor full screen).
The lessons build in order, from the ground up:
- What generative AI is and how it works (the foundation)
- How to work well with it (in practice)
- The ecosystem around it (what comes next)
- Putting it together (worked through real scenarios)
The goal isn't to cover every topic, but to teach the few that most of the rest builds on.
The course is localized. Languages are configured in src/manifest.json, and each page ships as a self-contained file per language; adding a language does not change any page structure. Portuguese and English are available today.
Python 3 only (the standard library is enough). The build uses no third-party packages.
make setup # create the .venv (optional; the build needs no dependencies)
make build # generate the full site into dist/ from src/
make run # build, serve at http://localhost:8000, and rebuild on every change in src/
make check # verify tokens and compare dist/ with the rendered sources
make test # build + check (verify the round-trip)
make help # list the targetsWith the server running:
- Home: http://localhost:8000/
- Self-paced: http://localhost:8000/web/
- Presentation: http://localhost:8000/present/
make run is the development command: it builds once, serves dist/ at http://localhost:8000, and rebuilds on every change in src/ (the open page live-reloads, and a single Ctrl+C stops both the server and the watcher).
src/ is the single source. Each page is one English structure (HTML skeleton and inline code, with @@token@@ placeholders) plus one content JSON per language. Lesson titles, descriptions and the part groupings live once in lessons.json and are injected into the engines and hubs at build time. The build substitutes the tokens and writes self-contained pages per language.
src/
manifest.json language list + lesson order (id, number)
lessons.json lesson titles, descriptions, parts and eyebrows (one source, all languages)
index/
_landing.html site landing page
content/_landing.<lang>.json its text per language
_redirect.html root redirect (copied verbatim)
web/
lessons/<id>.html lesson structure (self-paced)
content/<id>.<lang>.json lesson text per language
_hub.html + content/_hub.<lang>.json
shared.css, shared.js, _redirect.html engine + redirect (copied; nav data injected from lessons.json)
present/
decks/<n>-<id>.html slide structure
content/<n>-<id>.<lang>.json slide text per language
_launcher.html + content/_launcher.<lang>.json
present.css, present.js, _redirect.html copied verbatim
build.py substitutes tokens, injects nav data, copies static assets
check.py validates tokens and the source -> dist round-trip
watch.py rebuild on save + dev server (development)
The output goes to dist/ (for example dist/web/<lang>/<id>.html and dist/present/<lang>/<n>-<id>.html). dist/ is fully generated and not tracked: the build recreates it from scratch every time, and CI rebuilds it before publishing.
- Change text: edit that page's language content JSON, then run
make buildto refreshdist/. - Change a lesson's title, description, or how lessons group into parts: edit
lessons.json, thenmake build. - Change structure or code: edit the structure file (a single one, shared across languages), then
make build. - Do not edit anything under
dist/: it is overwritten on every build. - The token delimiter is
@@name@@.@@html_lang@@and@@lang@@are provided by the build.
See CONTRIBUTING.md for how to add a language or a lesson, and the full workflow.
The site is served as static files on GitHub Pages at https://andreribeirocoelho.github.io/learn-genai/.
Deployment is handled by GitHub Actions (.github/workflows/pages.yml): it builds dist/ with make test, uploads it, and publishes it to Pages. No server runs the site; the pages are self-contained and static. The trigger is currently manual (workflow_dispatch), so nothing deploys until you run it; to publish on every push, add an on: push trigger for the main branch. Enabling Pages once (Settings, Pages, source "GitHub Actions") is a one-time step before the first run.
This project is dual-licensed: the source code (build tooling, page structure, and engine) under the MIT License, and the educational content (lesson and slide text) under Creative Commons Attribution 4.0 (CC BY 4.0). In short: reuse the code freely, and reuse the content with credit.
See CONTRIBUTING.md. The lessons follow a specific, curated teaching vision, so content proposals (new lessons, wording changes, reordering, translations) are best started as an issue for discussion rather than a direct pull request, and some may be declined to keep the course coherent. The same goes for any larger code change. Small fixes (a typo, a broken link, an obvious bug) can go straight to a pull request.