Files
novi-lessons/Les14-Agents/Les14-Slide-Overzicht.md
2026-06-07 13:35:02 +02:00

443 lines
13 KiB
Markdown

# Les 14 — Agents
## Slide Overzicht (Klas A — 3 uur fysiek, demo-driven)
**Lesvorm:** Tim demonstreert klassikaal. Studenten kijken. Zelf bouwen = huiswerk.
**Demo-app:** Nieuwe research-agent (from scratch, los van Polderfest)
**Vervolg op:** Les 13 — Cursor + Vercel deploy
**Aansluit op:** Les 15 — RAG + Embeddings
---
## Slide 1: Title
### Les 14 — Agents
**Visual:**
- Background: CREAM
- "Les 14" in BLUE
- "Agents" in BLACK
- Subtitle: "Een LLM in een loop met tools — autonoom tot het klaar is"
---
## Slide 2: Terugblik
### Waar staan we?
**Vorige les (Les 12):**
- Tool Calling — AI roept zelf functies aan
- `tool({ description, inputSchema, execute })`
- `stopWhen: stepCountIs(5)` — multi-step
- Polderfest chat met 6 tools (search, stats, schedule, favorites)
**Wat een tool-call bot nog NIET kan:**
- Lange ketens (30+ stappen)
- Eigen plan opstellen + bijstellen
- Tools die andere tools triggeren
- Dynamisch het model wisselen per stap
**Vandaag: agents. Eén stap verder.**
**Visual:** Pijltje van "5-step tool calling" naar "20-50 step agent loop"
---
## Slide 3: Planning
### Vandaag — 180 minuten
| Onderwerp | Duur |
|-----------|------|
| Welkom + Terugblik | 10 min |
| Theorie: wat is een agent? | 30 min |
| **Live Demo 1** — Setup nieuwe research-agent | 25 min |
| **Live Demo 2** — ToolLoopAgent + stopWhen | 25 min |
| **Pauze** | 15 min |
| **Live Demo 3** — prepareStep + dynamic control | 25 min |
| **Live Demo 4** — Planning patterns + done-tool | 20 min |
| Wanneer agent vs tool-call vs workflow? | 10 min |
| Lesopdracht + Huiswerk uitleg | 15 min |
| Vragen + Afsluiting | 5 min |
**Format:** Demo-driven. Code-fragmenten in slides + live in editor.
---
## Slide 4: Wat is een agent?
### LLM + Tools + Loop
**De definitie van Vercel AI SDK:**
> Agents are LLMs that use tools in a loop to accomplish tasks.
**Drie componenten:**
1. **LLM** — beslist wat de volgende actie is
2. **Tools** — uitbreiding (search, read, write, anything)
3. **Loop** — runtime die deze twee orchestreert
- *Context management:* wat ziet model in elke stap
- *Stopping condition:* wanneer is de taak klaar
**Het verschil met Les 12:**
- Les 12: tot 5 stappen, korte taken
- Les 14: 20-50+ stappen, langere autonome workflows
**Visual:** Loop-diagram — LLM → kies tool → execute → resultaat → LLM → ... → klaar
---
## Slide 5: De anatomie van de loop
### Wat gebeurt er per stap?
```
┌─────────────────────────────────────┐
│ Loop iteratie (1 step): │
│ │
│ 1. Stuur messages naar model │
│ 2. Model genereert response: │
│ - text? → loop stopt │
│ - tool-call? → ga door │
│ 3. Voer tool execute() uit │
│ 4. Voeg tool-result toe aan msgs │
│ 5. Check stop-conditie │
│ 6. Volgende iteratie │
└─────────────────────────────────────┘
```
**De loop stopt wanneer:**
- Model geeft text in plaats van tool-call (natural finish), OF
- `stopWhen`-conditie is voldaan, OF
- Tool zonder execute wordt aangeroepen (done-pattern), OF
- Tool-call needs approval
**Default in v6:** `stepCountIs(20)` — veiligheidsgrens.
---
## Slide 6: ToolLoopAgent
### De nieuwe agent-abstractie in v6
**In plaats van zelf streamText loopen, gebruik je ToolLoopAgent:**
```typescript
import { ToolLoopAgent, tool, stepCountIs } from "ai";
const researchAgent = new ToolLoopAgent({
model: "openai/gpt-4o",
system: "You are a research assistant...",
tools: {
webSearch,
readPage,
saveReport,
},
stopWhen: stepCountIs(30),
});
const result = await researchAgent.generate({
prompt: "Onderzoek de impact van AI op de Nederlandse bouwsector",
});
console.log(result.text); // antwoord
console.log(result.steps); // alle stappen
```
**Wat krijg je:**
- Minder boilerplate (geen eigen loop schrijven)
- Herbruikbaar (definieer 1x, gebruik overal)
- Built-in loop, context, stopping
**Visual:** Side-by-side: handmatige while-loop vs ToolLoopAgent.
---
## Slide 7: Stop-condities
### Wanneer is een agent klaar?
**Built-in condities:**
| Conditie | Wanneer | Wanneer gebruiken |
|----------|---------|-------------------|
| `stepCountIs(N)` | Na N stappen | Default veiligheid |
| `hasToolCall("done")` | Specifieke tool gebruikt | Done-pattern |
| `isLoopFinished()` | Nooit — model bepaalt | Lange autonomie |
**Combineren met array:**
```typescript
stopWhen: [
stepCountIs(50), // max budget
hasToolCall("submit"), // OF submit-tool aangeroepen
]
```
**Custom conditie:**
```typescript
const budgetExceeded: StopCondition<typeof tools> = ({ steps }) => {
const cost = computeCost(steps);
return cost > 0.50; // stop bij $0.50
};
```
**Visual:** Drie traffic lights — rood (step limit), oranje (tool reached), groen (kostgrens).
---
## Slide 8: prepareStep
### Per stap iets anders doen
**`prepareStep` runt VOOR elke stap. Je kunt aanpassen:**
- Model wisselen (mini → sonnet voor complex)
- Tools beperken (alleen search in fase 1, alleen write in fase 3)
- Messages trimmen (context-budget bewaken)
- `toolChoice` forceren
**Voorbeeld — dynamic model:**
```typescript
new ToolLoopAgent({
model: "openai/gpt-4o-mini", // default
prepareStep: async ({ stepNumber, messages }) => {
if (stepNumber > 2 && messages.length > 10) {
return { model: "anthropic/claude-sonnet-4.5" };
}
return {}; // niks aanpassen
},
});
```
**Voorbeeld — fase-gebaseerde tools:**
```typescript
prepareStep: async ({ stepNumber }) => {
if (stepNumber <= 3) return { activeTools: ["webSearch"] };
if (stepNumber <= 6) return { activeTools: ["readPage"] };
return { activeTools: ["saveReport"], toolChoice: "required" };
};
```
---
## Slide 9: Wat we vandaag bouwen
### Research-agent from scratch
**Doel:** Een agent die zelfstandig een onderzoeksvraag beantwoordt door web te zoeken, pagina's te lezen, en een rapport in Supabase op te slaan.
**Stack:**
- Next.js 16 + TypeScript + Tailwind + Shadcn
- AI SDK v6 (ToolLoopAgent)
- Tavily API (web search)
- Supabase (rapport opslag)
- OpenAI gpt-4o / Anthropic Sonnet
**Tools die we bouwen:**
| Tool | Wat | Gebruik in flow |
|------|-----|-----------------|
| `webSearch` | Tavily query → 5 resultaten | Fase 1: oriëntatie |
| `readPage` | URL → fulltext extractie | Fase 2: diepgang |
| `saveReport` | Insert in `research_reports` | Fase 3: opslaan |
| `done` | No-execute, signaal klaar | Eind: stoppen |
**Visual:** Diagram van research-flow: vraag → search → read → save → done.
---
## Slide 10: LIVE DEMO 1 — Setup research-agent
### ~25 min
**Wat ik laat zien:**
1. `pnpm create next-app research-agent --typescript --tailwind --app`
2. `pnpm add ai @ai-sdk/openai @ai-sdk/anthropic zod @supabase/supabase-js`
3. `.env.local` — TAVILY_API_KEY, OPENAI_API_KEY, SUPABASE_*
4. Supabase schema: `research_reports` (id, query, summary, sources jsonb, created_at)
5. `lib/tools.ts` — eerste tool `webSearch` met Tavily fetch
6. `lib/agent.ts``ToolLoopAgent` initialiseren
7. `app/api/research/route.ts` — POST endpoint die agent.generate() doet
8. Eerste test in terminal: `curl /api/research -d '{"query": "..."}'`
**Belangrijk:** Tavily API key is gratis tier (1000 calls/maand). Studenten krijgen instructie om zelf account te maken.
**Visual:** Folder-tree van de research-agent repo.
---
## Slide 11: LIVE DEMO 2 — ToolLoopAgent + stopWhen
### ~25 min
**Wat ik laat zien:**
1. Tweede en derde tool toevoegen: `readPage`, `saveReport`
2. `ToolLoopAgent` configuren met alle drie + `stopWhen: stepCountIs(30)`
3. System prompt schrijven: "plan eerst, search dan, lees relevante pagina's, vat samen, sla op"
4. Test met `"Schrijf een rapport over de Polderfest 2027 lineup"`
5. `result.steps` loggen — zien dat agent 8-15 stappen doet
6. Wisselen naar `isLoopFinished()` — zien dat agent zelf stopt
7. `hasToolCall("saveReport")` toevoegen — stoppen zodra opgeslagen
**Visual:** Console-log met alle stappen (toolName, input, output) — laat zien hoe agent zelf plant.
---
## Slide 12: Pauze
### 15 minuten
---
## Slide 13: LIVE DEMO 3 — prepareStep
### ~25 min
**Wat ik laat zien:**
**Use case 1 — Dynamic model:**
- Default: `gpt-4o-mini` (snel + goedkoop)
- Vanaf stap 5: `claude-sonnet-4.5` (beter reasoning)
- Console-log per stap welk model
**Use case 2 — Fase-gebaseerde tools:**
- Stap 0-3: alleen `webSearch` (oriëntatie)
- Stap 4-7: alleen `readPage` (diepgang)
- Stap 8+: alleen `saveReport` + `done` (afronden)
- Zien: agent kan niet 'cheaten' door te vroeg op te slaan
**Use case 3 — Context-trimming:**
- Na 15 messages: trim oude tool-results
- System prompt + laatste 10 berichten
- Voorkomt token-explosie bij lange agents
**Visual:** Timeline-strip met de drie fasen + model-switch.
---
## Slide 14: LIVE DEMO 4 — Done-tool + custom stop
### ~20 min
**Wat ik laat zien:**
**Pattern 1 — Done-tool (no-execute):**
```typescript
done: tool({
description: "Signaleer dat onderzoek klaar is.",
inputSchema: z.object({
finalReportId: z.number(),
summary: z.string(),
}),
// GEEN execute — stopt de loop
})
```
Met `toolChoice: "required"` forceer je dat agent ALTIJD een tool aanroept — en `done` is hoe-ie stopt.
**Pattern 2 — Custom stop op kosten:**
```typescript
const costLimit: StopCondition<typeof tools> = ({ steps }) => {
const tokens = steps.reduce((sum, s) =>
sum + (s.usage?.totalTokens ?? 0), 0);
return tokens > 50_000;
};
```
**Pattern 3 — Plan-act-reflect loop:**
- Stap 0: agent maakt plan (text)
- Stap 1-N: voert plan uit (tools)
- Eind: agent schrijft reflectie (text)
**Visual:** Plan-Act-Reflect ReAct-diagram.
---
## Slide 15: Wanneer agent vs tool-call vs workflow?
### Niet alles hoeft autonoom
| Scenario | Aanpak |
|----------|--------|
| Vraag → 1 tool → antwoord | Plain tool-call |
| Vraag → 2-5 tools → antwoord | `stopWhen: stepCountIs(5)` (Les 12) |
| Onderzoek → 10-50 tools → rapport | **Agent** (Les 14) |
| Productie pipeline met validatie | **Workflow** (explicit code) |
| Wettelijk: must be reproducible | **Workflow** — geen agent |
**Wanneer GEEN agent gebruiken:**
- Deterministisch nodig (audit, finance, juridisch)
- Voorspelbare kosten
- Latency-sensitive (< 1s antwoord)
**Wanneer WEL agent:**
- Open-ended taken (research, planning, debugging)
- Tot stand komen via meerdere stappen
- Cost en latency mag wat hoger
**Quote uit AI SDK docs:** *"Agents are flexible and powerful, but non-deterministic. When you need reliable, repeatable outcomes, use workflow patterns."*
---
## Slide 16: Lesopdracht + Huiswerk
### Bouw je eigen agent
**Lesopdracht (in-class, 30 min):**
- Setup research-agent in eigen repo
- Tavily account aanmaken + key in .env
- Agent draaien met `stepCountIs(10)` en eerste eigen query stellen
- Logs bekijken: hoeveel stappen, welke tools
**Huiswerk (voor Les 14):**
- 4e tool toevoegen — `listReports` om opgeslagen rapporten op te halen
- `prepareStep` toevoegen — minimaal 1 use case (model OF tools OF context)
- Custom `StopCondition` schrijven (kosten OF specifieke conditie)
- `AGENT.md` schrijven: tool-lijst + stop-strategie + 1 voorbeeld-run met logs
**Bonus:**
- UI met live-step-rendering (elke stap als card)
- Sub-agent: 2e agent die per pagina samenvat, hoofdagent gebruikt sub-agent als tool
---
## Slide 17: Volgende les + Afsluiting
### Vragen?
**Vandaag gezien:**
- Agent = LLM + tools + loop
- `ToolLoopAgent` met `stopWhen` en `prepareStep`
- 4 stop-condities: stepCountIs, hasToolCall, isLoopFinished, custom
- prepareStep voor dynamic model / tools / context
- Done-tool pattern voor forced tool calling
- Wanneer wel/niet een agent
**Volgende les (Les 15): RAG + Embeddings**
- Semantic search op grote datasets
- pgvector in Supabase
- Embedding models — wat zijn vectors
- RAG-pipeline: chunk → embed → retrieve → generate
- Combo: RAG-tool in een agent — best of both worlds
**Daarna in deze leerlijn:**
- Les 14-16: Testing + Deployment + Performance
- Les 17-18: Eindopdracht-werkdagen + Pitch
**Vragen? Feedback?**
---
## Slide Summary
| # | Title | Type |
|---|-------|------|
| 1 | Title | Opening |
| 2 | Terugblik | Recap |
| 3 | Planning | 180-min |
| 4 | Wat is een agent | Theorie |
| 5 | Anatomie van de loop | Theorie |
| 6 | ToolLoopAgent | Theorie |
| 7 | Stop-condities | Theorie |
| 8 | prepareStep | Theorie |
| 9 | Wat we vandaag bouwen | Intro demo |
| 10 | **LIVE DEMO 1** — Setup | Demo |
| 11 | **LIVE DEMO 2** — stopWhen | Demo |
| 12 | Pauze | Break |
| 13 | **LIVE DEMO 3** — prepareStep | Demo |
| 14 | **LIVE DEMO 4** — done + custom stop | Demo |
| 15 | Wanneer wel/niet | Reflectie |
| 16 | Lesopdracht + Huiswerk | Praktijk |
| 17 | Afsluiting + Les 14 preview | Closing |
---
## Bronnen
- AI SDK Agents — Overview: https://ai-sdk.dev/docs/agents/overview
- AI SDK Agents — Loop Control: https://ai-sdk.dev/docs/agents/loop-control
- AI SDK Agents — Building Agents: https://ai-sdk.dev/docs/agents/building-agents
- AI SDK Agents — Workflows: https://ai-sdk.dev/docs/agents/workflows
- Tavily API: https://tavily.com/
- Anthropic — Building effective agents: https://www.anthropic.com/research/building-effective-agents