Maak uw content AI-gereed zonder naar Sanity te migreren
Maak je content AI-gereed zonder je CMS te verlaten
Er gaat momenteel een bepaald verhaal rond in de CMS-wereld dat ongeveer als volgt luidt: "Als je AI-gereed content wilt, heb je Sanity's benadering van gestructureerde content nodig." En kijk, Sanity's content lake en hun GROQ-aangedreven AI-integraties zijn echt indrukwekkend. Maar hier zit het probleem -- de meeste teams kunnen hun bestaande CMS niet zomaar verlaten. Je hebt jaren aan content in WordPress. De gegevenslaag van je app leeft in Supabase. Je bent zes maanden geleden net naar Payload CMS gemigreerd. Het idee van nog een migratie bezorgt je maagpijn.
Goed nieuws: je hoeft niet over te stappen. Je moet anders gaan denken over hoe je content is gestructureerd, opgeslagen en blootgesteld. Ik heb het afgelopen jaar teams geholpen hun bestaande stacks voor AI-consumptie aan te passen, en de patronen zijn verrassend consistent, ongeacht welke CMS of database je gebruikt. Laat me je erdoorheen lopen.
Inhoudsopgave
- Wat "AI-gereed content" werkelijk betekent
- Waarom Sanity al de aandacht krijgt
- Content structureren voor AI in WordPress
- Payload CMS: Je bent dichterbij dan je denkt
- Supabase als een AI-gereed content laag
- De universele principes van AI-gereed content
- Een AI-abstractielaag bouwen
- Vector embeddings zonder volledige migratie
- Architectuurpatronen uit de praktijk
- Veelgestelde vragen
Wat "AI-gereed content" werkelijk betekent
Voordat we praktisch worden, laten we verduidelijken waar we het eigenlijk over hebben. "AI-gereed content" is geen marketingslogan (nou ja, dat ook, maar er zit substatie onder). Het betekent dat je content aan drie criteria voldoet:
- Machine-parseerbare structuur -- AI-modellen kunnen betrouwbaar betekenis uit je content extraheren zonder naar context te gissen
- Rijke metadata -- Elk stuk content bevat genoeg semantische informatie zodat een AI relaties, intentie en context begrijpt
- API-toegankelijkheid -- Content is beschikbaar via programmatische interfaces die AI-agents, RAG-pipelines en LLM-tool-calling kunnen consumeren
Dat is het. Let op wat niet op de lijst staat: een specifieke leverancier. Dit zijn architectuurpatronen, geen productfuncties.
Het spectrum van content AI-gereedheid
Beschouw de AI-gereedheid van content als een spectrum:
| Niveau | Beschrijving | Voorbeeld |
|---|---|---|
| 0 | Massa HTML | WordPress-bericht met inline stijlen en gemengde media |
| 1 | Gescheiden concerns | Schone HTML met gestructureerde gegevensmarkering |
| 2 | Structuur op veldniveau | Content verdeeld in getypeerde velden (titel, samenvatting, body, auteur) |
| 3 | Semantische relaties | Content met expliciete verwijzingen, taxonomieën en entity-koppelingen |
| 4 | AI-native | Content met embeddings, semantische aantekeningen en machine-leesbare intentie |
Sanity's gestructureerde contentmodel duwt je standaard naar niveau 3-4. Maar elke CMS kan niveau 3 bereiken, en met wat aanvullende infrastructuur, niveau 4.
Waarom Sanity al de aandacht krijgt
Laten we Sanity waar het haar toekomt geven. Sanity's benadering van gestructureerde content is werkelijk goed ontworpen voor AI-use-cases:
- Portable Text slaat rijke tekst op als een JSON AST in plaats van HTML, waardoor het triviaal is om programmatisch te parseren
- GROQ vragen retourneren precies de vorm van gegevens die je nodig hebt, wat perfect aansluit op LLM-contextvensters
- Content Lake behandelt content als een grafiek van getypeerde documenten met expliciete verwijzingen
- Hun AI SDK-integraties in 2025 maken directe tool-calling van LLM's in content-queries mogelijk
Maar hier is wat de Sanity-voorvechters niet noemen: deze voordelen zijn architectuurpatronen, geen bedrijfseigen magie. Je kunt elk van deze in je bestaande stack implementeren. Het vereist alleen opzettelijk ontwerp.
De echte vraag is niet "moet ik naar Sanity overstappen?" Het is "hoe pas ik gestructureerde contentprincipes toe waar ik al ben?"
Content structureren voor AI in WordPress
WordPress drijft ongeveer 43% van het web in 2025. Als je WordPress gebruikt, ben je in goed gezelschap, en je hebt meer opties dan je misschien denkt.
Stap 1: Stop met de klassieke editor voor alles te gebruiken
De Gutenberg block editor slaat content al op als gestructureerde blokken. Elk blok heeft een type, attributen en content. Dit is dichterbij Sanity's Portable Text dan de meeste mensen zich realiseren.
{
"blockName": "core/paragraph",
"attrs": {},
"innerBlocks": [],
"innerHTML": "<p>Dit is gestructureerde content, niet alleen HTML.</p>",
"innerContent": ["<p>Dit is gestructureerde content, niet alleen HTML.</p>"]
}
De blokgegevens worden opgeslagen als geserialiseerde opmerkingen in post_content, maar je kunt ze programmatisch parseren:
$blocks = parse_blocks($post->post_content);
$structured = array_map(function($block) {
return [
'type' => $block['blockName'],
'attributes' => $block['attrs'],
'content' => strip_tags($block['innerHTML']),
];
}, array_filter($blocks, fn($b) => $b['blockName'] !== null));
Stap 2: Investeer in aangepaste velden en taxonomieën
Advanced Custom Fields (ACF) of Meta Box geven je niveau 2-3 contentstructuur. Maar je moet ervan doordrongen zijn. Voeg niet zomaar velden toe -- ontwerp een contentmodel.
// Registreer een gestructureerd contenttype voor AI-consumptie
register_post_type('knowledge_article', [
'supports' => ['title', 'custom-fields'],
'show_in_rest' => true, // Kritiek voor API-toegang
]);
// Definieer semantische velden
acf_add_local_field_group([
'title' => 'AI-Ready Content Fields',
'fields' => [
['key' => 'summary', 'label' => 'Samenvatting', 'type' => 'textarea'],
['key' => 'key_concepts', 'label' => 'Sleutelconcepten', 'type' => 'taxonomy', 'taxonomy' => 'concept'],
['key' => 'content_intent', 'label' => 'Content-intentie', 'type' => 'select', 'choices' => [
'informational' => 'Informatief',
'transactional' => 'Transactioneel',
'navigational' => 'Navigatie',
]],
['key' => 'related_entities', 'label' => 'Gerelateerde entiteiten', 'type' => 'relationship'],
],
]);
Stap 3: Alles blootstellen via de REST API
WordPress REST API is je brug naar AI. Zorg ervoor dat aangepaste velden blootgesteld worden:
add_action('rest_api_init', function() {
register_rest_field('knowledge_article', 'ai_metadata', [
'get_callback' => function($post) {
return [
'summary' => get_field('summary', $post['id']),
'concepts' => wp_get_post_terms($post['id'], 'concept', ['fields' => 'names']),
'intent' => get_field('content_intent', $post['id']),
'related' => get_field('related_entities', $post['id']),
'structured_blocks' => parse_blocks(get_post_field('post_content', $post['id'])),
];
},
]);
});
Als je WordPress als headless CMS gebruikt met een Next.js of Astro frontend (wat we veel doen bij Social Animal), wordt deze REST API je AI's primaire interface.
Stap 4: Voeg JSON-LD gestructureerde gegevens toe
Deze wordt vaak over het hoofd gezien voor AI-gereedheid, maar het is belangrijk. Google's AI-overzichten en andere AI-crawlers consumeren JSON-LD. Tools zoals Yoast SEO of RankMath genereren basisschema's, maar voor echte AI-gereedheid wil je gedetailleerde gestructureerde gegevens uitvoeren:
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Maak je content AI-gereed",
"abstract": "Hoe je bestaande CMS-content structureert voor AI-consumptie",
"about": [
{"@type": "Thing", "name": "Content Management"},
{"@type": "Thing", "name": "Kunstmatige Intelligentie"}
],
"mentions": [
{"@type": "SoftwareApplication", "name": "WordPress"},
{"@type": "SoftwareApplication", "name": "Payload CMS"}
]
}
Payload CMS: Je bent dichterbij dan je denkt
Als je al op Payload CMS zit, gefeliciteerd -- je bent waarschijnlijk op niveau 2-3 zonder veel extra werk. Payload's collection-gebaseerde architectuur met getypeerde velden is inherent gestructureerd.
Waarom Payload al AI-vriendelijk is
Payload slaat content op als getypeerde JSON-documenten in MongoDB of Postgres. Elk veld heeft een gedefinieerd type. Relaties zijn expliciet. Dit is exact wat AI nodig heeft.
// Payload-collectie die al AI-gereed is
const Articles: CollectionConfig = {
slug: 'articles',
fields: [
{ name: 'title', type: 'text', required: true },
{ name: 'summary', type: 'textarea' },
{ name: 'body', type: 'richText' }, // Opgeslagen als Slate/Lexical JSON
{ name: 'topics', type: 'relationship', relationTo: 'topics', hasMany: true },
{ name: 'contentType', type: 'select', options: ['guide', 'tutorial', 'reference'] },
],
};
Payload's rich text-editor (Lexical in v3.x) slaat content op als een JSON AST -- net als Sanity's Portable Text. Je hebt al gestructureerde content.
AI-specifieke velden toevoegen aan Payload
De kloof tussen Payload en volledige AI-gereedheid is vooral over metadata. Voeg deze velden toe aan je collecties:
const aiFields: Field[] = [
{
name: 'aiMetadata',
type: 'group',
fields: [
{ name: 'embedding', type: 'json', admin: { hidden: true } },
{ name: 'extractedEntities', type: 'json', admin: { readOnly: true } },
{ name: 'semanticSummary', type: 'textarea', admin: { readOnly: true } },
{ name: 'contentHash', type: 'text', admin: { hidden: true } },
],
},
];
Gebruik vervolgens Payload's hooks om embeddings automatisch bij het opslaan te genereren:
const generateEmbeddingHook: CollectionAfterChangeHook = async ({ doc, operation }) => {
if (operation === 'create' || operation === 'update') {
const textContent = extractTextFromLexical(doc.body);
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: `${doc.title}\n${doc.summary}\n${textContent}`,
});
await payload.update({
collection: 'articles',
id: doc.id,
data: {
aiMetadata: {
...doc.aiMetadata,
embedding: embedding.data[0].embedding,
contentHash: hashContent(textContent),
},
},
});
}
};
Dit is essentieel wat Sanity's AI-functies onder de motorkap doen. Je doet het zelf. Voor teams die met Payload bouwen met Next.js, integreert dit patroon natuurlijk in je bestaande deployment pipeline.
Supabase als een AI-gereed content laag
Supabase is interessant omdat het geen CMS is -- het is een databaseplatform. Maar steeds meer teams gebruiken het als hun content backend, vooral met Supabase's pgvector-extensie voor embeddings.
Het pgvector-voordeel
Supabase ondersteunt pgvector sinds 2023, en het is aanzienlijk volwassener geworden. Dit betekent dat je content EN vector embeddings in dezelfde database kunt opslaan:
-- Schakel de extensie in
create extension if not exists vector;
-- Maak een contenttabel met embedding-ondersteuning
create table content (
id uuid default gen_random_uuid() primary key,
title text not null,
body text not null,
metadata jsonb default '{}',
content_type text not null,
embedding vector(1536), -- OpenAI text-embedding-3-small dimensie
created_at timestamptz default now(),
updated_at timestamptz default now()
);
-- Maak een index voor gelijkeniszoeken
create index on content using ivfflat (embedding vector_cosine_ops)
with (lists = 100);
Een content API voor AI-agents bouwen
Supabase's auto-gegenereerde REST API plus Edge Functions geven je alles wat je nodig hebt:
// Supabase Edge Function voor AI-content-opvraging
import { createClient } from '@supabase/supabase-js';
Deno.serve(async (req) => {
const { query, limit = 5 } = await req.json();
const supabase = createClient(Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_KEY')!);
// Genereer embedding voor de query
const embeddingResponse = await fetch('https://api.openai.com/v1/embeddings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${Deno.env.get('OPENAI_API_KEY')}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'text-embedding-3-small',
input: query,
}),
});
const { data } = await embeddingResponse.json();
const queryEmbedding = data[0].embedding;
// Semantisch zoeken met pgvector
const { data: results } = await supabase.rpc('match_content', {
query_embedding: queryEmbedding,
match_threshold: 0.7,
match_count: limit,
});
return new Response(JSON.stringify(results), {
headers: { 'Content-Type': 'application/json' },
});
});
De Postgres-functie voor gelijkenismatching:
create or replace function match_content(
query_embedding vector(1536),
match_threshold float,
match_count int
) returns table (
id uuid,
title text,
body text,
metadata jsonb,
similarity float
) language sql stable as $$
select
content.id,
content.title,
content.body,
content.metadata,
1 - (content.embedding <=> query_embedding) as similarity
from content
where 1 - (content.embedding <=> query_embedding) > match_threshold
order by content.embedding <=> query_embedding
limit match_count;
$$;
Dit geeft je een volledig functionele RAG (Retrieval-Augmented Generation) backend zonder CMS-migratie. Je content leeft in Supabase, je AI kan het semantisch opvragen, en je Astro of Next.js frontend kan het via dezelfde API consumeren.
De universele principes van AI-gereed content
Ongeacht je CMS, gelden deze principes:
1. Scheiding van content van presentatie
Dit is het enige grootste wat je kunt doen. Als je content verstrengeld is met HTML, CSS-klassen en lay-outconcerns, kan AI het niet betrouwbaar parseren. Sla content op als gegevens, render het als HTML in de presentatielaag.
2. Type alles
Elk veld moet een expliciet type hebben. Gebruik niet generieke "tekst"-velden voor gestructureerde gegevens. Een datum moet opgeslagen worden als een datum. Een verwijzing moet een verwijzing zijn, geen slug-string geplakt in een tekstveld.
3. Maak relaties expliciet
Als artikel A naar product B verwijst, moet dat een getypeerde relatie zijn -- niet een vermelding in de bodytekst. AI-tools moeten je contentgrafiek kunnen traverseren, en dat kunnen ze niet met impliciete links.
4. Voeg semantische metadata toe
Ga verder dan basismetadata voor SEO. Neem op:
- Content-intentie (informatief, transactioneel, navigatie)
- Doelgroepsegment
- Vertrouwen/versheid-indicatoren
- Entiteitenaantekeningen
- Onderwerpclassificaties buiten basiscategorieën
5. Versie en timestamp alles
AI-systemen moeten weten hoe vers content is. Neem created_at, updated_at op, en idealiter een valid_until of review_date veld. Verouderde content in een RAG-pipeline leidt tot hallucinaties.
Een AI-abstractielaag bouwen
Hier is het patroon waar ik steeds op terugkom: in plaats van je CMS te migreren, voeg je een AI-abstractielaag erbovenop toe.
[WordPress/Payload/Supabase] → [Content Sync] → [AI Laag (pgvector/Pinecone)] → [AI Consumers]
De AI laag:
- Synchroniseert content van je CMS via webhooks of polling
- Normaliseert het in een consistente structuur ongeacht bron
- Genereert embeddings en slaat ze op met de genormaliseerde content
- Stelt een AI-geoptimaliseerde API bloot voor RAG, tool-calling en semantisch zoeken
// Vereenvoudigde content-synchronisatiepipeline
interface NormalizedContent {
id: string;
source: 'wordpress' | 'payload' | 'supabase';
sourceId: string;
title: string;
body: string; // Platte tekst, zonder markup
structuredBody: object; // JSON AST indien beschikbaar
metadata: {
type: string;
intent: string;
topics: string[];
entities: string[];
createdAt: string;
updatedAt: string;
};
embedding?: number[];
}
async function syncContent(source: ContentSource): Promise<void> {
const rawContent = await source.fetchAll();
for (const item of rawContent) {
const normalized = source.normalize(item);
const embedding = await generateEmbedding(
`${normalized.title}\n${normalized.body}`
);
await aiLayer.upsert({
...normalized,
embedding,
});
}
}
Deze benadering heeft een enorm voordeel: je redacteuren blijven de CMS gebruiken die ze kennen. Geen retraining, geen migratie, geen downtime. De AI-laag leeft naast je bestaande stack.
Vector embeddings zonder volledige migratie
Laten we praten over kosten en tools voor 2025, omdat dit van belang is voor echte beslissingen:
| Embedding-provider | Model | Kosten per 1M tokens | Dimensies | Opmerkingen |
|---|---|---|---|---|
| OpenAI | text-embedding-3-small | $0,02 | 1536 | Beste prijs/kwaliteit-verhouding |
| OpenAI | text-embedding-3-large | $0,13 | 3072 | Hogere nauwkeurigheid |
| Cohere | embed-v4 | $0,10 | 1024 | Goede meertalige ondersteuning |
| Voyage AI | voyage-3 | $0,06 | 1024 | Sterk voor codeinhoud |
| Lokaal (Ollama) | nomic-embed-text | Gratis | 768 | Privacy-first optie |
Voor een typische contentsite met 5.000 artikelen met gemiddeld 1.500 woorden elk, ben je naar ongeveer 7,5M tokens. Met OpenAI's small model, dat is $0,15 om je volledige contentbibliotheek in te bedden. Zelfs wekelijks opnieuw inbedden is onbelangrijk.
Opties voor vector-opslag
| Oplossing | Gratis tier | Prijzen (2025) | Beste voor |
|---|---|---|---|
| Supabase pgvector | 500MB database | $25/ma voor 8GB | Teams al op Supabase |
| Pinecone | 5M vectors | $70/ma starter | RAG op grote schaal in productie |
| Qdrant Cloud | 1GB cluster | $25/ma | Geavanceerde filterbehoefte |
| Weaviate Cloud | 50k objecten | $25/ma | Multi-modale content |
| Turbopuffer | 1M vectors | Pay-per-query | Kostenbesparende projecten |
Als je al Supabase gebruikt, is pgvector het voor de hand liggende keuze. Geen aanvullende service, geen aanvullende facturering, geen aanvullend storingspunt.
Architectuurpatronen uit de praktijk
Laat me twee architecturen delen die ik werkelijk heb gebouwd:
Patroon 1: WordPress + Supabase AI-laag
Voor een mediamaatschappij met meer dan 50k WordPress-berichten:
- WordPress webhook veuert bij artikel opslaan/bijwerken
- Een Supabase Edge Function ontvangt de webhook
- Content wordt opgehaald via WP REST API, genormaliseerd en ingebed
- Opgeslagen in Supabase met pgvector
- AI-chatbot op de Next.js frontend vraagt Supabase op voor semantisch zoeken
- Resultaten worden doorgegeven aan GPT-4o als context voor antwoordgeneratie
Totale aanvullende infrastructuurkosten: ~$25/maand voor Supabase pro tier.
Patroon 2: Payload CMS met ingebouwde AI
Voor een SaaS-documentatiesite op Payload v3:
- Payload hooks genereren embeddings bij elk document opslaan
- Embeddings opgeslagen in een
vectorkolom in dezelfde Postgres-database die Payload gebruikt - Aangepast Payload-eindpunt voor semantisch zoeken
- AI-docs assistent aangedreven door dezelfde database
- Geen externe vectorstore nodig
Totale aanvullende infrastructuurkosten: $0 buiten OpenAI API-calls (paar cent per maand).
Beide patronen duurden ongeveer 2-3 weken om te implementeren, vergeleken met de 3-6 maanden die een volledige CMS-migratie zou duren. Als je dit soort architectuur overweegt, hebben we prijsniveaus die exact deze types projecten dekken.
Veelgestelde vragen
Moet ik werkelijk mijn content voor AI restructureren, of is het gewoon hype? Het is geen hype, maar de urgentie hangt af van je use-case. Als je AI-functies (chatbots, semantisch zoeken, personalisatie) bouwt, is gestructureerde content essentieel. Als je optimiseert voor AI-aangedreven zoeken zoals Google's AI-overzichten of ChatGPT's browsen, verbeteren gestructureerde gegevens en schone contenthiërarchieën meetbaar je zichtbaarheid. Een 2025-studie van Authoritas vond dat pagina's met schemamarkering 40% waarschijnlijker verschijnen in AI-gegenereerde antwoorden.
Wat is het minimum dat ik zou moeten doen om WordPress-content AI-gereed te maken? Drie dingen: (1) Gebruik Gutenberg-blokken consistent in plaats van HTML te plakken, (2) voeg JSON-LD gestructureerde gegevens toe aan elke pagina, en (3) stel aangepaste velden bloot via de REST API. Dit brengt je van niveau 0-1 naar niveau 2-3 in een paar weken gericht werk. Je hoeft je hele site niet van de ene op de andere nacht te restructureren.
Kan Payload CMS Sanity vervangen voor AI-aangedreven content? Voor de meeste use-cases, ja. Payload v3 met Lexical rich text slaat content op als gestructureerde JSON, heeft getypeerde velden en relaties, en ondersteunt Postgres met pgvector. Het enige wat Sanity biedt dat Payload standaard niet heeft, is de beheerde Content Lake met ingebouwde AI-functies. Maar als je bereid bent je eigen embedding pipeline in te richten (wat ongeveer een dag duurt), geeft Payload je equivalente mogelijkheden.
Hoeveel kost het om vector embeddings toe te voegen aan een bestaande CMS? Verrassend weinig. Voor een site met 10.000 artikelen kost initiële embedding-generatie met OpenAI's text-embedding-3-small ongeveer $0,30. Lopende kosten voor het opnieuw inbedden van bijgewerkte content zijn typisch onder $5/maand. De vector-opslag is de grotere kostenfactor -- verwacht $0-70/maand afhankelijk van je provider en schaal. Supabase's gratis tier kan veel kleine tot middelgrote sites aan.
Moet ik een aparte vectordatabase gebruiken of embeddings in mijn bestaande database opslaan? Als je op Postgres bent (wat Payload v3 en Supabase beide gebruiken), sla embeddings in dezelfde database op met pgvector. Eén service minder om te beheren, één sync minder die kan breken. Speciale vectordatabases zoals Pinecone hebben zin wanneer je miljoenen documenten hebt of sub-milliseconde querytijden nodig hebt. Voor de meeste contentsites is pgvector meer dan snel genoeg -- typische querytijden zijn 5-20ms voor collecties onder 1M vectors.
Hoe hou ik AI-embeddings gesynchroniseerd met contentveranderingen?
Webhooks zijn je vriend. Elke moderne CMS ondersteunt ze. Wanneer content wordt aangemaakt of bijgewerkt, vuur je een webhook af die opnieuw inbedden activeert. Sla een contenthash op naast de embedding, zodat je onveranderde content kunt overslaan. Voor WordPress, gebruik de save_post actie. Voor Payload, gebruik afterChange hooks. Voor Supabase, gebruik database-triggers of Realtime-abonnementen.
Hoe zit het met content in meerdere talen -- werkt deze benadering nog steeds? Ja, maar kies je embedding-model voorzichtig. OpenAI's text-embedding-3 modellen behandelen meertalige content goed. Cohere's embed-v4 is specifiek geoptimaliseerd voor cross-taal retrieval. De normalisatielaag moet de taalcode als metadata opslaan zodat je AI-consumenten dienovereenkomstig kunnen filteren. Een belangrijk opmerking: bed elke taalversie afzonderlijk in in plaats van vertalingen aan elkaar te ketenen.
Is migratie naar een headless CMS een vereiste voor AI-gereed content? Niet een vereiste, maar het helpt enorm. Headless CMS-architectuur scheidt content van presentatie natuurlijk, wat de basis van AI-gereedheid is. Als je nog steeds een monolithische WordPress-theme uitvoert met content ingebed in template-bestanden, gaat headless (WordPress als backend met een Next.js of Astro frontend) simultaan je AI-gereedheid en je frontend-prestaties verbeteren. Het is vaak de investering waard, zelfs vóór het overwegen van AI-use-cases. Als je dit wil verkennen, neem contact met ons op -- het is letterlijk wat we elke dag doen.