AI-agent op het web: een echte Chrome met GPU voor Claude
Een AI-agent die op het web handelt (een formulier invullen, aanbiedingen vergelijken, een dashboard in de gaten houden) heeft een echte browser nodig die continu draait, ergens anders dan op je laptop. Twee fouten zorgen ervoor dat hij al op de eerste pagina als bot wordt herkend:
- hem in headless-modus starten: Chrome meldt zichzelf dan als
HeadlessChromein zijn User-Agent; - hem zonder GPU starten: de grafische kaart wordt
SwiftShader(een geëmuleerde GPU), of WebGL verdwijnt helemaal.
Een desktop-pc heeft nooit deze kenmerken. De regel is dus eenvoudig: een echte Chrome, in een venster, op een virtueel scherm, met een echte GPU.
Dit artikel laat zien hoe je Chrome met de GPU laat draaien voor een Claude-agent, vergelijkt Xvfb en Xorg „dummy”, behandelt Selenium, en legt uit wat de GPU wel (of niet) verandert tegenover de botdetectie van Cloudflare. Alle metingen zijn reproduceerbaar: het script is openbaar.
De architectuur
- De agent (Claude Code of de Claude Agent SDK) beslist over de acties;
- Playwright MCP stelt de browser als tools beschikbaar aan de agent
(
browser_navigate,browser_click,browser_type,browser_snapshot…) en stuurt Chromium aan via CDP (Chrome DevTools Protocol); - Chromium draait in venstermodus op een virtueel scherm Xvfb, en rendert op de GPU via ANGLE/Vulkan;
- met x11vnc kun je het scherm bekijken en de controle overnemen (bijvoorbeeld voor tweestapsverificatie).
Het verloop van een actie:
De metingen
Omstandigheden
- Linux GPU-testserver, VM geconfigureerd zoals het Perf 2-aanbod (4 vCPU), Intel UHD 770-GPU gedeeld tussen meerdere VM’s (de VM ziet zijn eigen GPU-apparaat, /dev/dri, met de standaard Linux-driver), Debian 13;
- Chromium 156, Playwright MCP 0.0.83, Selenium 4.31 + chromedriver 156,
Xvfb (Xorg 21) en
xserver-xorg-video-dummy0.4.0; - de GPU werd tijdens de metingen niet door andere VM’s belast;
- metingen van 29-10-2026.
Hoe het berekend wordt
De benchmark is een WebGL 2-pagina (webgl-bench.html):
- een canvas van 1920×1080;
- een fragment shader die 64 sinussen/cosinussen per pixel berekent, dus ongeveer 265 miljoen sinussen/cosinussen per beeld;
?draws=Ntekent N fullscreen-beelden per frame (requestAnimationFrame);- na elke frame leest
readPixelséén pixel uit: dat dwingt de browser om het renderen af te ronden, anders zou hij de commando’s in een wachtrij kunnen zetten en een flatteuze maar onjuiste score tonen; - na 5 s: beelden/s = aantal beelden ÷ duur. We controleren ook dat het programma correct gelinkt is en dat de uitgelezen pixel de juiste kleur heeft.
Chrome wordt gestart met --disable-gpu-vsync --disable-frame-rate-limit om
niet beperkt te worden tot 60 beelden/s. De CPU-belasting is het verschil
tussen de tellers van /proc/stat over alleen de duur van de test, uitgedrukt
in bezette vCPU’s.
chromium --headless=new --use-angle=vulkan --ignore-gpu-blocklist \
--disable-gpu-vsync --disable-frame-rate-limit \
--enable-logging=stderr --v=0 "file:///root/webgl-bench.html?draws=10" \
2>&1 | grep -m1 RESULT
Resultaat 1: de GPU maakt het verschil (×20)
--headless=new, 10 beelden per frame:
| Rendering | 1080p-beelden/s | Bezette CPU |
|---|---|---|
| SwiftShader (standaard, CPU) | 13 | 3,9 van de 4 vCPU |
UHD 770, --use-angle=vulkan | ~260 | 0,6 vCPU |
UHD 770, --use-angle=gl-egl | ~230 | — |
Met de GPU is de rendering 20 keer sneller en blijft de processor vrij. Voor een agent is dat het kernpunt: zonder GPU legt een zware pagina (kaart, dashboard, video) alle 4 vCPU’s vol, en vechten de agent, Playwright en het virtuele scherm om wat er overblijft.
Resultaat 2: Xvfb of Xorg dummy, maakt weinig uit
Je hoort vaak dat je Xvfb moet vervangen door Xorg met de dummy-driver om het „echter” te laten lijken. Gemeten, in venstermodus, 1 beeld per frame:
| Virtueel scherm | Zonder opties | SwiftShader geforceerd | GPU (--use-angle=vulkan) |
|---|---|---|---|
| Xvfb | WebGL uitgeschakeld | 9,2 beelden/s | 67,6 beelden/s |
| Xorg + dummy-driver | WebGL uitgeschakeld | 8,7 beelden/s | 58,8 beelden/s, daarna WebGL-context verloren |
- Geen van beide gebruikt uit zichzelf de GPU:
glxinfotoontllvmpipe(softwarerendering) op allebei; - zonder opties schakelt Chrome WebGL uit op allebei;
- met de dummy-driver verloor onze GPU-test na enkele beelden de
WebGL-context (
eglCreateWindowSurface failed with error EGL_BAD_MATCH). Xvfb bleef stabiel.
De keuze van het virtuele scherm is dus bijzaak: voor de prestaties telt meestal de GPU. Blijf bij Xvfb, dat is eenvoudiger, en voeg de twee GPU-opties toe aan Chrome.
Resultaat 3: welke renderer ziet de site
Dit is wat een detectiescript uitleest (WEBGL_debug_renderer_info):
| Configuratie | Gemelde WebGL-renderer |
|---|---|
--headless=new zonder opties | SwiftShader (geëmuleerde CPU) |
| Xvfb of dummy, zonder opties | geen WebGL |
| Selenium + Xvfb, zonder opties | geen WebGL |
| Selenium + Xvfb, GPU-opties | Intel(R) UHD Graphics 770 |
| Playwright MCP, venstermodus op Xvfb, GPU-opties | Intel(R) UHD Graphics 770 |
| headless, GPU-opties | Intel(R) UHD Graphics 770 |
Resultaat 4: headless = meteen herkend
Wat een JavaScript-script met één regel op de pagina uitleest, in de vier configuraties (Chromium 156):
| Headless zonder GPU | Headless + GPU | Venster op Xvfb zonder GPU | Venster op Xvfb + GPU | |
|---|---|---|---|---|
navigator.userAgent | ❌ HeadlessChrome/156… | ❌ HeadlessChrome/156… | ✅ Chrome/156… | ✅ Chrome/156… |
| Grafische kaart (WebGL) | ❌ SwiftShader | ✅ Intel UHD Graphics 770 | ❌ geen (WebGL uitgeschakeld) | ✅ Intel UHD Graphics 770 |
screen | ❌ 800×600 | ❌ 800×600 | ✅ 1920×1080 | ✅ 1920×1080 |
| Venstergrootte | 780×580 | 780×580 | 945×1060 | 1919×1079 |
- De headless-modus verraadt zichzelf: het woord
HeadlessChromestaat in de User-Agent, die bij elk verzoek wordt meegestuurd. Dat is het eenvoudigste signaal om te blokkeren, en alle antibotsystemen doen dat. Het scherm van 800×600 bevestigt de diagnose; - zonder GPU verdwijnt WebGL, zelfs in een venster: geen enkele moderne desktopbrowser zit in die situatie;
- alleen de laatste kolom lijkt op een echte werkplek: een Chrome in een venster op een 1080p-scherm, met een echte Intel-grafische kaart.
De User-Agent met de hand aanpassen is niet genoeg: de headless-modus heeft nog andere verschillen (schermgrootte, renderingsgedrag, ontbrekende API’s), en een User-Agent die niet strookt met de rest is zelf verdacht. Het betrouwbaarst is om de headless-modus helemaal niet te gebruiken: op een server is dat precies waar Xvfb voor dient.
Resultaat 5: in een venster ontlast de GPU de CPU enorm
De venstermodus heeft een prijs: Chrome moet de hele pagina op het scherm tekenen. Zonder GPU doet de processor alles. Dezelfde WebGL-animatie in 1080p, Chrome in een venster op Xvfb, normale framerate (maximaal 60 beelden/s), CPU-belasting gemeten over de hele VM tijdens de test:
| Chrome in een venster op Xvfb | Beelden/s | Bezette CPU (VM met 4 vCPU) |
|---|---|---|
| Zonder GPU (SwiftShader) | 9,8 | 3,4 vCPU: de VM is verzadigd |
| Zonder GPU, 3× zwaardere scène | 4,0 | 3,7 vCPU |
| Met de UHD 770-GPU | 60 (vloeiend) | 0,3 vCPU |
| Met de GPU, 3× zwaardere scène | 60 | 0,3 vCPU |
Met de GPU toont Chrome 6 keer meer beelden en gebruikt het meer dan 10 keer minder CPU, dus ongeveer 70 keer minder CPU per beeld. Zonder GPU is de VM verzadigd en haalt hij zelfs geen 10 beelden/s: de agent, Playwright en de rest van het systeem vechten om de kruimels, elke actie duurt langer, en zware pagina’s worden onbruikbaar. Met de GPU blijven er 3,7 vCPU vrij voor nuttig werk.
Dat is de winnende combinatie: de venstermodus voorkomt dat je wordt herkend, en de GPU maakt hem gratis voor de processor.
Wat de GPU verandert tegenover Cloudflare
Cloudflare (Bot Management, Turnstile) combineert talloze signalen:
TLS- en HTTP/2-vingerafdruk, reputatie van het IP-adres, JavaScript-tests in
de pagina, gedrag (tempo, bewegingen), statistische modellen. Een browser
zonder GPU verraadt zich snel in de JavaScript-tests: SwiftShader als
grafische kaart, of helemaal geen WebGL, is een typische signatuur van een
geautomatiseerde browser in een datacenter.
Met de GPU meldt Chrome een echte Intel-kaart en rendert het de pagina zoals een desktop-pc. Concreet vermindert dat de valse positieven: CAPTCHA’s of blokkades op sites waar je agent gewoon mag komen.
Maar laten we duidelijk zijn: CDP + driver + goed IP maakt je niet ondetecteerbaar.
- aansturing via CDP laat zelf detecteerbare sporen na;
- datacenteradressen zijn als zodanig bekend;
- het gedrag van een agent (snelheid, opeenvolging van acties) valt op;
- de regels veranderen voortdurend: wat vandaag lukt, wordt morgen geblokkeerd.
De juiste aanpak: jezelf laten herkennen
Voor een legitieme agent is de duurzame weg om geïdentificeerd te zijn in plaats van verborgen:
- Web Bot Auth („signed agents” bij Cloudflare): de agent ondertekent zijn HTTP-verzoeken met een Ed25519-sleutel (HTTP Message Signatures, RFC 9421) en publiceert zijn publieke sleutel in een register; sites kunnen hem dan expliciet toelaten;
- een eerlijke User-Agent, respect voor
robots.txten de gebruiksvoorwaarden, een redelijk verzoektempo; - op je eigen sites achter Cloudflare (E2E-tests, monitoring), een WAF-regel die het IP van je server doorlaat.
Installatie
1. Pakketten
apt install chromium xvfb x11vnc nodejs npm
2. Virtueel scherm en VNC (systemd)
# /etc/systemd/system/xvfb.service
[Unit]
Description=Xvfb :99
[Service]
ExecStart=/usr/bin/Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp
Restart=always
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/x11vnc.service
[Unit]
Description=x11vnc op :99 (alleen localhost)
After=xvfb.service
Requires=xvfb.service
[Service]
ExecStart=/usr/bin/x11vnc -display :99 -localhost -forever -shared -nopw
Restart=always
[Install]
WantedBy=multi-user.target
systemctl enable --now xvfb x11vnc
# vanaf je eigen computer:
ssh -L 5900:localhost:5900 root@jouw-server # daarna een VNC-client op localhost:5900
VNC luistert alleen op localhost: je bereikt het uitsluitend via de
SSH-tunnel.
3. Playwright MCP met de GPU
Bestand /root/mcp.json:
{
"browser": {
"browserName": "chromium",
"launchOptions": {
"executablePath": "/usr/bin/chromium",
"headless": false,
"args": ["--use-angle=vulkan", "--ignore-gpu-blocklist", "--no-sandbox"]
}
}
}
Met Claude Code geïnstalleerd op de server:
claude mcp add playwright --env DISPLAY=:99 -- \
npx @playwright/mcp@latest --config /root/mcp.json
Of als HTTP-server, als de agent ergens anders draait (SSH-tunnel naar de poort):
DISPLAY=:99 npx @playwright/mcp@latest --config /root/mcp.json --port 8931
# MCP-endpoint: http://localhost:8931/mcp
Ter controle vraag je de agent een pagina te openen die de WebGL-renderer
toont: die moet Intel(R) UHD Graphics 770 melden.
4. Selenium + Xvfb
apt install python3-selenium chromium-driver
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
o = webdriver.ChromeOptions()
o.binary_location = "/usr/bin/chromium"
for a in ["--use-angle=vulkan", "--ignore-gpu-blocklist",
"--no-sandbox", "--window-size=1920,1080"]:
o.add_argument(a)
driver = webdriver.Chrome(options=o, service=Service("/usr/bin/chromedriver"))
xvfb-run -a -s "-screen 0 1920x1080x24" python3 mijn_script.py
Geef met de Selenium 4.31 van Debian chromedriver expliciet op via
Service(...): anders vindt hij het niet (NoSuchDriverException).
Veelgestelde vragen
Headless of venstermodus op Xvfb?
Venstermodus, zonder twijfel. Headless meldt zich als HeadlessChrome en
wordt op de meeste beschermde sites geblokkeerd. In venstermodus kun je de
agent bovendien via VNC volgen en de controle overnemen. Bewaar headless
voor je eigen tests, op je eigen sites.
En computer use van Claude (screenshots + klikken)? Dat heeft een echt scherm nodig: Xvfb + een browser in venstermodus, precies het schema hierboven. De GPU rendert elke screenshot sneller en laat de CPU vrij voor de rest.
Is een Perf 1-aanbod genoeg? Voor een agent die gewone sites bezoekt, ja. De metingen hierboven zijn gedaan met 4 vCPU (Perf 2), handig als de agent meerdere tabbladen of zware pagina’s opent.
Probeer het
Linux GPU-server met Intel UHD 770 in de VM, Mesa en Vulkan al geïnstalleerd. Vanaf €14,99 excl. btw/mnd, root-toegang, eigen IPv6-adres. Zie ook: Chrome met de GPU op een Linux-server en Xvfb: praktische gids.