Files
novi-lessons/Les13-Agents/Les13-Slide-Overzicht.md
2026-06-03 16:58:25 +02:00

13 KiB

Les 13 — 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 12 — Tool Calling Aansluit op: Les 14 — RAG + embeddings


Slide 1: Title

Les 13 — Agents

Visual:

  • Background: CREAM
  • "Les 13" 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 13: 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:

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:

stopWhen: [
  stepCountIs(50),         // max budget
  hasToolCall("submit"),   // OF submit-tool aangeroepen
]

Custom conditie:

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:

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:

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.tsToolLoopAgent 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):

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:

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 13)
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 14): 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 15-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