fix: add les 11

This commit is contained in:
2026-05-19 18:50:11 +02:00
parent b053fc7206
commit 634789e615
37 changed files with 7587 additions and 209 deletions

View File

@@ -0,0 +1,375 @@
# Les 11 — Vercel AI SDK
## Slide Overzicht (Klas A — 3 uur fysiek, demo-driven)
**Lesvorm:** Tim demonstreert klassikaal. Studenten kijken mee, gaan thuis zelf aan de slag.
**Demo-app:** Polderfest 2027 — fictief muziekfestival met 500 verzonnen bands in Supabase. Studenten kunnen vragen stellen aan dummy data die LLM's onmogelijk vooraf konden kennen.
---
## Slide 1: Title
### Les 11 — Vercel AI SDK
**Visual:**
- Background: CREAM
- "Les 11" in BLUE
- "Vercel AI SDK" in BLACK
- Subtitle: "Praat met je eigen data — vandaag bouwen we Polderfest 2027"
---
## Slide 2: Terugblik
### Waar staan we?
**Vorige lessen:**
- Supabase geïntegreerd in je app
- Tabellen + relaties opgezet
- RLS policies bekeken (wie mag wat lezen/schrijven)
**Vandaag bouwen we niet voort op QuickPoll — we starten een nieuwe demo from scratch.**
We laten zien hoe je een Next.js app aan een verse Supabase koppelt en die data combineert met AI.
**Visual:** Twee icoontjes (database + Next.js logo) met pijl naar AI-icoon.
---
## Slide 3: Planning
### Vandaag — 180 minuten
| Onderwerp | Duur |
|-----------|------|
| Welkom + Terugblik | 10 min |
| Theorie: Wat is de Vercel AI SDK? | 30 min |
| **Live Demo 1** — Next.js scaffold + Supabase koppelen | 20 min |
| **Live Demo 2** — Seed script: 500 records in Supabase | 20 min |
| **Pauze** | 15 min |
| **Live Demo 3** — AI SDK installeren + chat-route | 30 min |
| **Live Demo 4** — Vragen stellen aan onze data | 15 min |
| Waarom data + AI samen krachtig is | 5 min |
| Lesopdracht + Huiswerk uitleg | 20 min |
| Vragen + Afsluiting | 15 min |
**Belangrijk:** Vandaag is **demo-driven**. Jullie kijken en luisteren. Thuis gaan jullie zelf aan de slag met jullie eigen thema.
---
## Slide 4: Wat is de Vercel AI SDK?
### Eén SDK, alle providers
**Content:**
- TypeScript-first SDK voor AI features
- Werkt met OpenAI, Anthropic, Google, Mistral, Groq, en meer
- **Unified API:** zelfde code voor elk model
- Streaming out-of-the-box
- React hooks (`useChat`, `useCompletion`)
- Tool Calling (volgende les)
- Open source · gemaakt door Vercel
**Code teaser:**
```typescript
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
const { text } = await generateText({
model: openai("gpt-4o-mini"),
prompt: "Vat de Polderfest line-up samen",
});
```
**Visual:** Logo's van OpenAI/Anthropic/Google met pijl naar één AI-SDK doos.
---
## Slide 5: Modellen + Kosten
### Welk model wanneer?
| Provider | Model | Use case | Prijs (in/out per 1M tokens) |
|----------|-------|----------|------------------------------|
| OpenAI | gpt-4o-mini | Default — snel + goedkoop | $0.15 / $0.60 |
| OpenAI | gpt-4o | Multimodaal (vision) | $2.50 / $10 |
| OpenAI | gpt-4.1 | Reasoning, agents | $2 / $8 |
| Anthropic | claude-sonnet-4 | Coding, lange context | $3 / $15 |
| Google | gemini-2.5-flash | Snel + multimodaal | $0.075 / $0.30 |
| Groq | llama-3.3-70b | Ultra-fast inference | $0.59 / $0.79 |
**Vuistregel:** start met `gpt-4o-mini`. Upgrade pas als nodig.
**Voor vandaag:** `gpt-4o-mini`. Onze hele les inclusief Polderfest-Q&A kost ongeveer 1-2 cent.
---
## Slide 6: De 4 kern-functies
### Wat je vandaag gaat zien
| Functie | Wat het doet | Wanneer |
|---------|--------------|---------|
| `generateText` | Wacht tot AI antwoord klaar is — string terug | Korte server-only antwoorden |
| `streamText` | Stream karakter voor karakter | Chat UI, lange antwoorden |
| `useChat` | React hook voor instant chat UI | Client-side chat |
| `generateObject` | Type-safe data via Zod schema | Database inserts, classificatie |
**Vandaag gebruiken we vooral:**
- `streamText` + `useChat` — voor de chat UI
- Onze Polderfest-data als context — AI beantwoordt vragen op basis van onze 500 bands
**Volgende les (Les 12):** `generateText` + `tools` — Tool Calling, waar AI zelf besluit welke DB-query te runnen.
---
## Slide 7: Wat bouwen we vandaag?
### Polderfest 2027 — een fictief festival
**Het idee:**
Een fictief Nederlands muziekfestival met **500 verzonnen bands**. Volledig fictief — geen enkele LLM kan dit weten uit training. Dit is precies waar AI + jouw data sterker wordt dan AI alleen.
**Schema (Supabase tabel `bands`):**
- `name`, `genre`, `sub_genre`
- `stage`, `day`, `start_time`, `duration_min`
- `origin_city`, `members`, `bio`
- `tier` (headliner / mid / opener), `popularity`, `ticket_impact`
**Voorbeeld-vragen die we kunnen stellen aan AI:**
- "Welke bands spelen vrijdagavond na 22:00 op de Main Stage?"
- "Geef me 5 acts uit Groningen, gesorteerd op populariteit"
- "Vat de hip-hop scene op Polderfest samen in 3 zinnen"
- "Welke headliner is qua bio het meest interessant voor electronic-fans?"
**Visual:** Festival-poster mock-up met genre-tags + Supabase logo.
---
## Slide 8: LIVE DEMO 1
### Next.js scaffold + Supabase koppelen (~20 min)
**Wat ik laat zien:**
1. `npx create-next-app@latest polderfest --typescript --tailwind --app`
2. Nieuw Supabase project aanmaken (dashboard)
3. SQL Editor: schema runnen (zie schema.sql)
4. Supabase client installeren: `npm i @supabase/supabase-js`
5. `.env.local` met `SUPABASE_URL` + `SUPABASE_ANON_KEY` + `SUPABASE_SERVICE_ROLE_KEY`
6. `lib/supabase.ts` aanmaken (client)
7. Tabel-check via Table Editor: leeg, klaar om te seeden
**Wat ik NIET uitleg:** Next.js / Supabase basics — dat hebben jullie al gehad.
**Visual:** Badge "LIVE DEMO" in PINK + screenshots Supabase dashboard.
---
## Slide 9: LIVE DEMO 2
### Seed script: 500 records in Supabase (~20 min)
**Wat ik laat zien:**
1. `seed-polderfest.ts` openen — uitleggen wat 't doet:
- Procedureel 500 bands genereren
- Combinaties van adjectives + nouns + bio-fragmenten
- Insert in batches van 100
2. Service role key uitleggen — alleen lokaal, niet in client
3. `npm i tsx @supabase/supabase-js dotenv --save-dev`
4. `npx tsx seed-polderfest.ts` runnen
5. Supabase Table Editor refresh → 500 records zichtbaar
6. Een paar voorbeelden tonen — "De Tigers", "Lost Mirrors", "Sanne Van Dijk & The Echoes"
**Sleutel-inzicht:** dit zijn 500 namen die **niet bestaan**. Geen enkele LLM kan ze kennen.
**Visual:** Terminal log van seed + Table Editor screenshot.
---
## Slide 10: Pauze
### 15 minuten
---
## Slide 11: LIVE DEMO 3
### AI SDK installeren + chat-route (~30 min)
**Wat ik laat zien:**
1. `npm i ai @ai-sdk/openai zod`
2. `OPENAI_API_KEY` toevoegen aan `.env.local` (schoolkey via Brightspace)
3. **`app/api/chat/route.ts`** schrijven:
- Haal alle bands op uit Supabase
- Format als context-string
- `streamText` aanroepen met system + user messages
- Return `result.toDataStreamResponse()`
4. **`app/chat/page.tsx`** schrijven:
- `"use client"` + `useChat` hook
- Simpele Tailwind chat UI (messages list + input)
5. Naar `/chat` browsen → werkt
6. Eerste prompt: "Hoeveel bands spelen vrijdag?"
**Belangrijke uitleg-momenten:**
- Waarom we **alle bands meesturen** als context (volgende les: Tool Calling lost dit op)
- Hoe `streamText` zich aansluit op `useChat`
- System prompt — hoe je de AI 'rol' geeft
**Visual:** Code-mock-up + chat preview.
---
## Slide 12: LIVE DEMO 4
### Vragen stellen aan onze data (~15 min)
**Vragen die we live uitproberen:**
1. "Welke bands spelen zaterdag op de Beach Stage?"
2. "Geef me 3 headliners met de meeste popularity, en hun bio's"
3. "Hoeveel jazz fusion acts spelen er totaal?"
4. "Vat de electronic-scene op Polderfest samen — wat zou je aanraden voor iemand die houdt van techno?"
5. **Slechte vraag:** "Wie was de hoofdacts van Polderfest 2025?" — AI antwoordt eerlijk dat hij dat niet weet (data alleen 2027)
**Sleutel-inzicht:**
- AI is **slim**, maar pas écht nuttig met **jouw data**
- LLM weet niets van Polderfest 2027 — toch krijgen we precieze antwoorden
- Combinatie = `context (jouw data) + reasoning (AI)`
**Visual:** Chat screenshots met antwoorden.
---
## Slide 13: Waarom is dit krachtig?
### Data + AI > Data alleen, AI alleen
**Data alleen:**
- Supabase query: filter + sort + select
- Geen interpretatie, geen samenvatting, geen taal
- Gebruiker moet zelf SQL-denken
**AI alleen:**
- Gebrekkige kennis over jouw domein
- Verzint vaak (hallucinatie)
- Geen toegang tot live data
**Data + AI:**
- AI interpreteert en vat samen
- Antwoorden in natuurlijke taal
- Filtert + reasoneert + presenteert
- Schaalbaar — voeg data toe = nieuwe antwoorden mogelijk
**Quote om mee weg te lopen:**
> "Een LLM zonder jouw data is een gewone chatbot.
> Een LLM mét jouw data is een product."
---
## Slide 14: Lesopdracht
### Jouw eigen thema-app
**Voor thuis (niet in de les) — bouw je eigen versie:**
1. Bedenk een **eigen thema** met data die LLM's niet kunnen weten
2. Maak een nieuw Next.js project + nieuwe Supabase
3. Schrijf eigen `seed-XXX.ts` script (mag AI je bij helpen!)
4. Seed minstens **100 records** in Supabase
5. Implementeer chat-route + chat-pagina (zelfde flow als Polderfest)
6. Stel 3 vragen aan je AI die alleen kunnen door jouw data
**Voorbeeld eigen thema's:**
- Fictief restaurant-aggregator in een verzonnen stad
- Galactische bestuurders archief (sci-fi)
- Verzonnen scriptie-archief NOVI
- Fictieve museumcollectie
- Fictief NPO-programma overzicht
- ...
**Beperking:** **GEEN echte/openbare data** (geen Spotify, geen TheCocktailDB). Het moet fictief zijn zodat de demo-kracht zichtbaar wordt.
**Visual:** 4 voorbeeld-thema's als cards.
---
## Slide 15: Huiswerk
### Polderfest seed-script aanpassen + uitbreiden
**Voor volgende week (Les 12):**
**Verplicht — onderdeel A:**
- Pas het seed-script aan voor **jouw eigen thema** (gebruik gerust AI om te helpen)
- Run het tegen je eigen Supabase
- Push naar GitHub repo
**Verplicht — onderdeel B:**
- Voeg minstens **1 extra veld** toe waarvan je denkt dat het interessante vragen mogelijk maakt
- Update schema + seed script
- Stel een vraag aan AI die alleen kan dankzij dat nieuwe veld
**Verplicht — onderdeel C:**
- Schrijf `AI-CHAT.md` in je repo met:
- Jouw thema (wat is het, waarom kun je dit niet aan een gewone LLM vragen?)
- 3 leuke vragen die werken op jouw data
- 1 vraag waar de AI moeite mee had — wat veranderde toen je de prompt aanpaste?
**Bonus:** Deploy op Vercel — preview URL meesturen.
**Visual:** Workflow-diagram + checklist.
---
## Slide 16: Volgende les — Tool Calling
### Hoe schaalt dit?
**Probleem dat we vandaag introduceren:**
- We sturen **alle 500 bands** mee als context bij elke vraag
- 500 bands ≈ 30.000 tokens — dat is veel, kost geld, traagt
- 5.000 bands? 50.000 bands? Werkt niet meer
**Oplossing (volgende les):**
- **Tool Calling** — AI besluit zelf welke query te runnen
- Voorbeeld: AI ziet vraag "Welke bands spelen vrijdag?" → roept tool `searchBands(day: "Vrijdag")` aan → krijgt 60 bands terug → antwoordt
- Schaalbaar, slim, multi-step
**Daarna in deze leerlijn:**
- Les 13: Agents + `maxSteps` (multi-step autonoom)
- Les 14: RAG + embeddings (semantic search op groot corpus)
- Les 15-16: Testing + Deployment
- Les 17-18: Eindopdracht-werkdagen + Pitch
---
## Slide 17: Afsluiting
### Vragen?
**Wat we vandaag gezien hebben:**
- Vercel AI SDK basics
- Modellen + 4 kern-functies
- Next.js + Supabase + AI SDK end-to-end gekoppeld
- Live demo met seed-script (500 records procedureel)
- Vragen stellen aan een dataset die geen LLM kent
**Vragen? Feedback?**
**Visual:** Cream achtergrond, blauw rondje met "→ Tool Calling".
---
## Slide Summary
| # | Title | Type |
|---|-------|------|
| 1 | Title | Opening |
| 2 | Terugblik | Recap (Supabase + RLS, kort) |
| 3 | Planning | 180-min schedule |
| 4 | Wat is de AI SDK | Theorie |
| 5 | Modellen + kosten | Theorie |
| 6 | 4 kern-functies | Theorie |
| 7 | Vandaag bouwen we Polderfest | Intro demo |
| 8 | **LIVE DEMO 1** — Next.js + Supabase | Demo |
| 9 | **LIVE DEMO 2** — Seed 500 records | Demo |
| 10 | Pauze | Break |
| 11 | **LIVE DEMO 3** — AI SDK + chat | Demo |
| 12 | **LIVE DEMO 4** — Vragen stellen | Demo |
| 13 | Data + AI = kracht | Reflectie |
| 14 | Lesopdracht — eigen thema | Praktijk |
| 15 | Huiswerk — seed aanpassen | Praktijk |
| 16 | Volgende les: Tool Calling | Preview |
| 17 | Afsluiting | Closing |
---
## Bronnen
- Vercel AI SDK docs — https://ai-sdk.dev/docs/introduction
- generateText / streamText / useChat / generateObject reference — https://ai-sdk.dev/docs/reference
- Supabase JS client — https://supabase.com/docs/reference/javascript
- Next.js App Router — https://nextjs.org/docs/app
- OpenAI pricing — https://openai.com/api/pricing
- Tokenizer — https://platform.openai.com/tokenizer
- Vercel templates met AI — https://vercel.com/templates?type=ai