Files
novi-lessons/Les11-AI-SDK/Les11-Lesopdracht.md
2026-05-19 18:50:11 +02:00

196 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Les 11 — Lesopdracht
## Bouw je eigen AI + Supabase app
**Vak:** AI-Assisted Development
**Opleiding:** NOVI Hogeschool Utrecht
**Wanneer:** Thuis, vóór volgende les
**Inleveren:** GitHub URL + screenshot van werkende chat
---
## Doel
Bouw een complete versie van wat Tim live demonstreerde — **met je eigen thema**. Tim bouwde Polderfest 2027. Jij bouwt iets anders.
Je oefent end-to-end:
- Next.js project from scratch
- Nieuwe Supabase aanmaken + koppelen
- Eigen seed-script schrijven (mag AI bij helpen)
- Chat-route + chat-UI met `streamText` + `useChat`
- 3 vragen kunnen stellen die alleen via jouw data beantwoord kunnen worden
> **Belangrijk:** dit is **niet** dezelfde Polderfest-demo namaken. Je kiest een eigen thema. Anders leer je vooral kopiëren.
---
## Vereisten
### Jouw thema moet:
- [ ] **Volledig fictief zijn** — geen Spotify, geen restaurants in Amsterdam, geen Wikipedia-data
- [ ] Minstens 5 velden hebben (waarvan 1 categorisch, 1 numeriek, 1 tekstrijk)
- [ ] Minstens **100 records** bevatten
- [ ] Vragen oproepen die je écht niet aan ChatGPT kunt stellen zonder jouw data
### Verboden thema's (te bekend voor LLMs):
- Restaurants in een echte stad
- Films / muziek / boeken die echt bestaan
- Sport-statistieken uit de echte wereld
- Klimaat / financiële data uit publieke bronnen
### Geschikte thema-richtingen (kies of bedenk eigen):
- Fictief restaurant-aggregator in een verzonnen stad (bv. "Polderstad")
- Galactische bestuurders archief (sci-fi)
- Verzonnen scriptie-archief van NOVI (1000 nep-titels)
- Fictieve museumcollectie met verzonnen kunstenaars
- Fictief NPO-programma overzicht voor 2030
- Verzonnen mysteries / cryptid-sightings database NL
- D&D campagne-NPCs voor een fictieve wereld
- Fictieve nederlands ondernemers ecosysteem
---
## Stappenplan
### Stap 1 — Thema kiezen + schema ontwerpen (30 min)
- Bedenk thema
- Schrijf op papier (of in Notion): welke velden? Welke vragen wil je kunnen stellen?
- Vertaal naar Supabase SQL schema (zie `schema.sql` van Polderfest als voorbeeld)
### Stap 2 — Next.js project + Supabase (15 min)
```bash
npx create-next-app@latest mijn-thema \
--typescript --tailwind --app --eslint --no-src-dir --turbopack
cd mijn-thema
npm i @supabase/supabase-js ai @ai-sdk/openai zod
npm i tsx dotenv --save-dev
```
- Maak nieuwe Supabase project aan
- Run je schema in SQL Editor
- Vul `.env.local` met URL + keys + OpenAI key
### Stap 3 — Seed script (45 min)
Open `seed-polderfest.ts` (zie bijlage) als referentie. Je hebt twee opties:
**Optie A — Met de hand:**
- Kopieer de structuur
- Vervang Polderfest-bouwstenen (genres, stages, cities…) door jouw thema-bouwstenen
- Pas de `generateBand` functie aan naar `generateItem` voor jouw thema
**Optie B — Met AI hulp (aanbevolen):**
- Open OpenCode / Cursor met `seed-polderfest.ts` als context
- Vraag: "Pas dit seed-script aan voor [mijn thema]. Schema is [paste schema]. Genereer 100+ records."
- Review wat AI maakt — vragen om aanpassingen waar nodig
Run je seed:
```bash
npx tsx scripts/seed-mijn-thema.ts
```
Verifieer in Supabase Table Editor: 100+ records.
### Stap 4 — Chat route (20 min)
`app/api/chat/route.ts` — gebruik Polderfest-versie als template:
```typescript
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);
export async function POST(req: Request) {
const { messages } = await req.json();
const { data: items } = await supabase.from("items").select("*");
const context = items!.map((i) =>
`- ${i.name} (${i.category}, ${i.rating})`
).join("\n");
const system = `Je bent een assistent voor [thema-naam].
Hier is alle data:
${context}
Beantwoord vragen op basis van bovenstaande data. Verzin niets.
Antwoord in het Nederlands.`;
const result = streamText({
model: openai("gpt-4o-mini"),
system,
messages,
});
return result.toDataStreamResponse();
}
```
### Stap 5 — Chat UI (15 min)
`app/chat/page.tsx` — kopieer Polderfest UI, pas titel + placeholder aan.
### Stap 6 — Testen + 3 vragen (15 min)
Browse naar `/chat`. Stel deze 3 vragen aan jouw AI:
1. Een **filter-vraag** ("Welke X hebben Y?")
2. Een **aggregatie-vraag** ("Hoeveel X zijn er in totaal?" / "Wie heeft de hoogste Z?")
3. Een **samenvatting-vraag** ("Vat de Z-categorie samen in 3 zinnen")
Screenshots van werkende antwoorden bewaren — die heb je nodig.
---
## Inleveren (vóór volgende les)
1. **GitHub repo** met je code
2. **3 screenshots** van werkende chat-antwoorden in je README
3. **Eén alinea** onder de screenshots: waarom kan een gewone LLM deze vragen niet beantwoorden zonder jouw data?
---
## Veelvoorkomende problemen
| Probleem | Oplossing |
|----------|-----------|
| `OPENAI_API_KEY is not defined` | Dev server herstarten na `.env.local` aanpassen |
| Supabase insert: `permission denied` | Gebruik `SUPABASE_SERVICE_ROLE_KEY` in seed-script (geen anon) |
| AI verzint dingen | System prompt verstevigen: "Verzin niets. Gebruik alleen onze data." |
| AI antwoordt in Engels | Voeg toe aan prompt: "Antwoord in het Nederlands." |
| Chat hangt / streamt niet | API endpoint moet `result.toDataStreamResponse()` returnen |
| `tsx command not found` | `npm i tsx --save-dev`, run met `npx tsx ...` |
---
## Tijd-indicatie
| Stap | Tijd |
|------|------|
| Thema + schema bedenken | 30 min |
| Project + Supabase setup | 15 min |
| Seed script (met AI hulp) | 45 min |
| Chat route + UI | 35 min |
| Testen + screenshots | 15 min |
| **Totaal** | **~2,5 uur** |
Loop je vast? Vraag in Brightspace of plan korte 1-op-1 met Tim.
---
## Tips
- **Begin klein.** 100 records is genoeg. 500 als je extra wil.
- **AI laten helpen bij seed.** Schaal je productiviteit 10×.
- **System prompt is je hefboom.** Goede prompt = goede antwoorden. Slechte prompt = AI verzint.
- **Test met simpele vraag eerst** ("Hoeveel records zijn er?"). Dan opbouwen.
- **Token cost in de gaten houden** — onze hele les kostte <2 cent. Jouw test ook.
Succes!