02 — AI Content Generatie
02 — AI Content Generatie
Section titled “02 — AI Content Generatie”“Je hoeft niet te weten hoe een pagina eruitziet. Je hoeft alleen te weten wat je wilt zeggen.”
De AI Page Builder laat gebruikers pagina’s genereren op basis van een simpele beschrijving. De AI vertaalt de vraag naar de juiste blocks en patterns, vult ze met content die past bij het merk, en selecteert automatisch afbeeldingen uit de media library.
Inhoudsopgave
Section titled “Inhoudsopgave”- Drie Informatiebronnen
- Twee Modi
- De AI Pipeline
- Per-Block Hergeneratie
- Tone of Voice Override
- Conversatie Modus
- Prompt Engineering
- Datamodel
- API Keuze
- Bouwvolgorde
1. Drie Informatiebronnen
Section titled “1. Drie Informatiebronnen”De AI gebruikt altijd drie contextbronnen voor content generatie:
- Brand data — de JSON uit de onboarding (tone of voice, doelgroep, beschrijving, CTA’s, etc.)
- Bestaande pagina’s — gecachede samenvattingen van andere pagina’s op dezelfde site (voor consistentie en kruisverwijzingen)
- De prompt — wat de gebruiker vraagt, eventueel verfijnd door vervolgvragen
2. Twee Modi
Section titled “2. Twee Modi”⚡ Snel Genereren
Section titled “⚡ Snel Genereren”Eén tekstveld → volledige pagina in één keer.
┌─────────────────────────────────────────────┐│ Beschrijf je pagina ││ ││ "Een diensten pagina voor onze drie ││ renovatie services met pricing en een ││ CTA naar het contactformulier" ││ ││ [✨ Genereer pagina] │└─────────────────────────────────────────────┘💬 Stap voor Stap (Conversatie)
Section titled “💬 Stap voor Stap (Conversatie)”Chat-interface waar de AI eerst vragen stelt, dan stap voor stap de pagina opbouwt.
┌─────────────────────────────────────────────┐│ AI: Wat voor pagina wil je maken? ││ ││ Gebruiker: Een pagina over onze diensten ││ ││ AI: Ik zie dat jullie in de bouw zitten. ││ Hoeveel diensten wil je tonen? En wil je ││ er pricing bij? ││ ││ Gebruiker: 3 diensten, met pricing ││ ││ AI: Dit is mijn voorstel voor de opbouw: ││ 1. Hero met titel "Onze diensten" ││ 2. 3× Dienst block met beschrijving ││ 3. Pricing tabel ││ 4. CTA naar contactformulier ││ ││ Zal ik dit genereren? ││ ││ [✅ Genereer] [✏️ Pas aan] │└─────────────────────────────────────────────┘3. De AI Pipeline
Section titled “3. De AI Pipeline”Stap 1: Prompt Verrijking
Section titled “Stap 1: Prompt Verrijking”De gebruiker typt een simpele beschrijving. Voordat de AI content gaat genereren, wordt de prompt intern verrijkt met context:
Gebruikersinput: "Een diensten pagina met pricing"
Wordt intern: Gebruikersvraag: "Een diensten pagina met pricing"
Brand context: - Bedrijf: Bouwbedrijf De Vries — renovatie en nieuwbouw - Doelgroep: Huiseigenaren 30-65, regio Utrecht - Tone of voice: Professioneel maar benaderbaar, vakkundig zonder jargon - Primaire CTA: "Vraag een gratis adviesgesprek aan" - Differentiator: Persoonlijke begeleiding, één vast aanspreekpunt
Bestaande pagina's: - Home: intro tekst over het bedrijf, 3 highlights - Over ons: geschiedenis, team, werkwijze (gecachede samenvattingen, niet volledige tekst)
Media library: - 12 afbeeldingen beschikbaar - AI beschrijvingen: "moderne woonkamer", "badkamer renovatie", etc.
Beschikbare blocks: hero, content, cta, pricing, feature, gallery, form Beschikbare patterns: "Hero Primair", "Pricing Drie Kolommen", etc.Stap 2: Structuur Bepalen
Section titled “Stap 2: Structuur Bepalen”De AI bepaalt welke blocks en patterns nodig zijn en in welke volgorde.
Output (JSON):
{ "page_title": "Onze diensten", "page_slug": "diensten", "page_description": "Overzicht van renovatie, nieuwbouw en verbouwing diensten", "structure": [ { "position": 1, "block_type": "hero", "pattern_id": null, "intent": "Paginatitel met korte intro over de diensten" }, { "position": 2, "block_type": "feature", "pattern_id": null, "repeat": 3, "intent": "Eén block per dienst met titel, beschrijving en afbeelding" }, { "position": 3, "block_type": "pricing", "pattern_id": "uuid-van-pricing-pattern", "intent": "Pricing tabel met drie pakketten" }, { "position": 4, "block_type": "cta", "pattern_id": null, "intent": "CTA naar contactformulier met primaire actieknop" } ]}Als er een bestaand pattern past, gebruikt de AI dat via pattern_id. Anders wordt een block type gekozen.
Stap 3: Content Genereren
Section titled “Stap 3: Content Genereren”Per block wordt content gegenereerd op basis van:
- De intent uit de structuur
- De brand data (tone of voice, beschrijvingen, CTA’s)
- De bestaande pagina’s (consistentie, geen herhaling)
- De media library (afbeeldingen matchen op AI beschrijvingen)
Output per block:
{ "position": 2, "block_type": "feature", "instance": 1, "content": { "title": "Renovatie", "description": "Van badkamer tot complete woningrenovatie. We begeleiden je van ontwerp tot oplevering met één vast aanspreekpunt.", "image": { "media_id": "uuid-van-badkamer-foto", "alt_text": "Moderne badkamer na renovatie door De Vries" }, "cta": { "text": "Meer over renovatie", "link": "/diensten/renovatie" } }}Stap 4: Afbeelding Matching
Section titled “Stap 4: Afbeelding Matching”De AI matcht afbeeldingen uit de media library op basis van:
- AI beschrijvingen van de afbeeldingen (gegenereerd bij upload of onboarding)
- Context van het block (bijv. “badkamer renovatie”)
- Wat al gebruikt is — voorkom duplicaten over blocks heen
Matching logica:
Block context: "Renovatie — badkamer tot complete woningrenovatie"
Media library scan: - "moderne woonkamer met eiken vloer" → score 0.4 - "badkamer renovatie tegels" → score 0.9 ✅ - "team foto kantoor" → score 0.1 - "nieuwbouw woning buitenkant" → score 0.3Als er geen passende afbeelding is, wordt een placeholder geplaatst met een suggestie (“Voeg hier een foto toe van een gerenoveerde badkamer”).
4. Per-Block Hergeneratie
Section titled “4. Per-Block Hergeneratie”Na de initiële generatie kan de gebruiker per block de content opnieuw laten genereren. In de Page Editor verschijnt bij elk AI-gegenereerd block een ✨ icoon:
┌─────────────────────────────────┐│ ✨ AI opties ││ ││ 🔄 Hergenereer content ││ ✏️ Geef instructie ││ 🎨 Andere tone of voice ││ 🖼️ Andere afbeelding │└─────────────────────────────────┘🔄 Hergenereer content — nieuwe tekst met dezelfde context, andere formulering.
✏️ Geef instructie — gebruiker typt een aanpassing:
- “Maak het korter”
- “Voeg een opsomming toe”
- “Focus meer op duurzaamheid”
De AI past de content aan op basis van de instructie, met behoud van brand context.
🎨 Andere tone of voice — tijdelijk de tone of voice aanpassen voor dit specifieke block. Toont dezelfde sliders als in de onboarding, maar dan per block. Overschrijft niet de brand data — eenmalige aanpassing.
🖼️ Andere afbeelding — AI toont de volgende best-matchende afbeeldingen uit de media library.
5. Tone of Voice Override
Section titled “5. Tone of Voice Override”Globale Tone of Voice (uit brand data)
Section titled “Globale Tone of Voice (uit brand data)”Standaard wordt de tone of voice uit de brand JSON gebruikt voor alle content generaties.
Per-Generatie Override
Section titled “Per-Generatie Override”┌─────────────────────────────────┐│ Tone of voice voor deze pagina ││ ││ [Gebruik brand standaard ✅] ││ ││ Of pas aan: ││ Formeel ●────────○ Informeel ││ Serieus ────●────○ Speels ││ ││ Preview: "Ontdek hoe wij uw ││ woning transformeren met..." │└─────────────────────────────────┘Dit overschrijft niet de brand data — het is een eenmalige aanpassing voor deze specifieke generatie.
6. Conversatie Modus
Section titled “6. Conversatie Modus”Hoe de Conversatie Werkt
Section titled “Hoe de Conversatie Werkt”De AI heeft toegang tot alle brand data en bestaande pagina’s. Op basis daarvan stelt het slimme vragen.
- Doel begrijpen — open vraag: “Wat voor pagina wil je maken?”
- Specificeren — 2–3 gerichte vervolgvragen (hoeveel items, welke CTA, specifieke inhoud?)
- Structuur voorstellen — AI toont overzicht van blocks. Gebruiker kan aanpassen.
- Genereren — na goedkeuring wordt de pagina gegenereerd.
- Verfijnen — gebruiker kan per block feedback geven in de chat: “Block 2 is te lang” of “Voeg een testimonial toe na de pricing.”
Conversatie Context
Section titled “Conversatie Context”Elke bericht bevat de volledige context:
{ "system_prompt": "Je bent de Beam page builder assistent...", "context": { "brand_data": { "..." }, "existing_pages_summary": [ "..." ], "media_library": [ "..." ], "available_blocks": [ "..." ], "available_patterns": [ "..." ] }, "conversation_history": [ { "role": "user", "content": "..." }, { "role": "assistant", "content": "..." } ]}7. Prompt Engineering
Section titled “7. Prompt Engineering”System Prompt Structuur
Section titled “System Prompt Structuur”De AI krijgt een system prompt die bestaat uit:
- Rol: “Je bent de Beam page builder assistent. Je helpt gebruikers pagina’s op te bouwen.”
- Brand context: volledige brand JSON
- Bestaande content: samenvattingen van andere pagina’s (niet volledige tekst — dat zou te veel tokens kosten)
- Block registry: beschrijving van elk beschikbaar block type en welke content velden het heeft
- Pattern registry: beschikbare patterns met hun structuur
- Media library: lijst van beschikbare afbeeldingen met AI beschrijvingen
- Output instructies: “Genereer output als JSON in het volgende format…”
- Tone of voice instructies: slider waarden vertaald naar concrete schrijfinstructies
Tone of Voice Vertaling
Section titled “Tone of Voice Vertaling”Slider waarden: formality: 0.6 seriousness: 0.7 technicality: 0.3 personality: 0.5
Wordt in de system prompt: "Schrijf in een professionele maar benaderbare stijl. Vermijd vakjargon — leg technische termen uit in eenvoudige taal. Wees zakelijk maar niet afstandelijk. Gebruik 'u' als aanspreekvorm maar houd de toon warm. Schrijf beknopt en to-the-point."Pagina Samenvattingen voor Context
Section titled “Pagina Samenvattingen voor Context”Om token-gebruik te beperken worden bestaande pagina’s niet volledig meegestuurd, maar samengevat:
{ "page": "Over ons", "summary": "Beschrijft de geschiedenis van het bedrijf (opgericht 1985), het team (8 medewerkers), en de werkwijze (persoonlijke aanpak, één aanspreekpunt). Benadrukt vakmanschap en duurzaamheid.", "key_terms": ["vakmanschap", "persoonlijke begeleiding", "duurzaam", "sinds 1985"], "ctas_used": ["Neem contact op", "Bekijk onze projecten"]}8. Datamodel
Section titled “8. Datamodel”Tabel: ai_generations
Section titled “Tabel: ai_generations”Log van alle AI generaties voor debugging en verbetering.
| Kolom | Type | Omschrijving |
|---|---|---|
id | uuid, PK | |
site_id | uuid, FK | |
page_id | uuid, FK, nullable | Nullable bij conversatie-modus |
mode | enum: quick, conversational | |
user_prompt | text | Originele input van de gebruiker |
enriched_prompt | text | Verrijkte prompt met brand context |
ai_response | jsonb | Volledige AI response (structuur + content) |
model_used | text | Bijv. claude-opus-4-6 |
tokens_used | integer | Token verbruik |
tone_override | jsonb, nullable | Afwijkende tone of voice voor deze generatie |
created_at | timestamptz |
Tabel: page_content_summaries
Section titled “Tabel: page_content_summaries”Gecachede samenvattingen van pagina’s voor AI context.
| Kolom | Type | Omschrijving |
|---|---|---|
id | uuid, PK | |
page_id | uuid, FK | |
summary | text | AI-gegenereerde samenvatting |
key_terms | text[] | Belangrijke termen |
ctas_used | text[] | CTA’s die op de pagina voorkomen |
generated_at | timestamptz |
Wordt opnieuw gegenereerd wanneer een pagina wordt opgeslagen.
Tabel: media_descriptions
Section titled “Tabel: media_descriptions”AI beschrijvingen van media items voor slimme matching.
| Kolom | Type | Omschrijving |
|---|---|---|
id | uuid, PK | |
media_id | uuid, FK | |
description | text | AI beschrijving van de afbeelding |
tags | text[] | Automatisch gegenereerde tags |
embedding | vector(1536), nullable | Toekomst: pgvector semantic search |
generated_at | timestamptz |
De embedding kolom is voorbereiding op semantic search — later kun je met pgvector de media library doorzoeken op basis van block context.
9. API Keuze
Section titled “9. API Keuze”De AI-laag is abstract zodat makkelijk gewisseld kan worden.
// Eén abstractie — interne implementatie is inwisselbaarasync function generateContent( prompt: string, context: GenerationContext, options?: GenerationOptions): Promise<GenerationResult>| Criterium | Claude (Anthropic) | GPT (OpenAI) |
|---|---|---|
| Structured JSON output | Sterk (met instructie) | Native JSON mode |
| Tone of voice controle | Uitstekend | Goed |
| Context window | 200K tokens | 128K tokens |
| Nederlandse content | Goed | Goed |
| Snelheid | Snel | Snel |
Voorkeur: Claude. Grotere context window is relevant voor het inladen van brand data + bestaande pagina’s + block registry in één call.
10. Bouwvolgorde
Section titled “10. Bouwvolgorde”Fase 1: Fundament
Section titled “Fase 1: Fundament”page_content_summariestabel + automatische samenvatting bij page savemedia_descriptionstabel + AI beschrijving generatie bij upload- Block registry — gestructureerde beschrijving van elk block type en content velden
Fase 2: Quick Generatie
Section titled “Fase 2: Quick Generatie”- UI: tekstveld + “Genereer pagina” knop
- Prompt verrijkings-pipeline (brand data + pagina-samenvattingen + media library)
- AI call → structuur bepalen (welke blocks/patterns)
- AI call → content genereren per block
- Afbeelding matching logica
- Resultaat renderen in de Page Editor
Fase 3: Per-Block Hergeneratie
Section titled “Fase 3: Per-Block Hergeneratie”- ✨ AI opties menu per block in de editor
- Hergenereer content
- Instructie-gebaseerde aanpassing
- Afbeelding herwisselen
- Tone of voice override per block
Fase 4: Conversatie Modus
Section titled “Fase 4: Conversatie Modus”- Chat interface UI
- Conversatie context management
- Structuur voorstel → goedkeuring flow
- Stapsgewijze generatie
- Per-block feedback in chat
Fase 5: Optimalisatie
Section titled “Fase 5: Optimalisatie”ai_generationslogging (debugging + verbetering)- Token optimalisatie (context window management)
- Caching van samenvattingen en beschrijvingen
- Vector embeddings voor media matching (pgvector)