AI agents
OpenSCAD vs Adam vs CadQuery: kern kiezen voor offerte-agent
Zaterdagavond 23:14. Een klant uploadt een SolidWorks 2018-assembly bij een printbureau in Enschede met 21 mensen. Welke CAD-laag offreert het voor maandag?

Zaterdag 23:14. Het Slack-kanaal #offertes bij een printbureau in Enschede met 21 mensen licht op: "Aanvraag #4711 — klant uploadde SLDASM. Sub-parts ontbreken. Handmatige review nodig." Wie nu dienst heeft, heeft een keuze. SolidWorks openen, de ontbrekende referentie-parts opzoeken, de assembly opnieuw genereren, de volume-berekening draaien en het voor maandag offreren. Of "we komen er maandagochtend op terug" sturen en de lead zien doodbloeden.
Die ene faalmodus is de bril waarmee we drie parametrische modelleerlagen hebben afgewogen voor de offerte-agent die we voor deze tent hebben opgeleverd: OpenSCAD, het kakelverse Adam (YC W25) als open-source AI CAD, en een zelfgebouwde CadQuery + Claude tool-use loop. De agent verwerkt 940 STL-uploads per week. Elk bestand heeft geometrie-analyse nodig, een oriëntatiebeslissing, een schatting van support-materiaal en een offerte binnen zestig seconden na de upload. De parametrische laag bepaalt of de agent het bestand daadwerkelijk begrijpt of alleen de bounding box meet.
De werkenveloppe van 940 uploads
940 uploads per week komt neer op gemiddeld 134 per dag, maar zo komen ze niet binnen. Maandag tussen 09:00 en 13:00 is goed voor ongeveer 280 stuks. Vrijdagmiddag piekt het als ontwerpers "kan dit nog voor maandag?" sturen. De meeste uploads zijn STL — een gesloten mesh, geen parametrische historie. Een serieus deel (we maten 12% over een sample van zes weken) komt binnen als STEP, IGES of native SolidWorks, omdat de klant om 17:55 op exporteren klikte en stuurde wat de dialoog standaard aanbood.
De agent heeft drie taken die de parametrische laag moet ondersteunen:
- Inlezen wat de klant heeft gestuurd en daar een volume, bounding box en georiënteerde support-schatting van maken.
- Als de klant terug-mailt met "kan dit 10% groter?" of "zonder het lipje aan de zijkant?", reparametriseren — niet de mesh herschalen.
- Iets op onze schijf bewaren dat, als je het over vijf jaar opnieuw opent, het onderdeel kan reconstrueren.
Die derde is de IP-vraag. Heb je alleen de mesh opgeslagen die de klant uploadde, dan heb je een ingevroren foto. Heb je het parametrische script bewaard dat de agent genereerde om die mesh te interpreteren, dan heb je een recept. Een recept is waar bedrijfsgeheimbescherming in NL aan vastzit.
OpenSCAD als script-laag
OpenSCAD is het voor de hand liggende gratis antwoord. Het is een kleine, deterministische, CSG-only modeler met zijn eigen scripttaal; het .scad-bestand IS de parametrische bron. OpenSCAD bestaat sinds 2010 en is bij 940 jobs per week echt gratis te draaien. We maten ongeveer 0,4 seconden per eenvoudig onderdeel op één c7i.large core, dus de infra-kosten per request zijn praktisch nul.
De problemen beginnen op het moment dat een klant iets uploadt dat niet in OpenSCAD zelf is gebouwd.
- Geen bruikbare STEP- of IGES-import. Je kunt
import("foo.stl")doen als mesh, maar dan ben je alle parametrische structuur kwijt. Vanaf dat moment is het .scad-bestand slechts een wrapper van vijf regels rond een ingevroren mesh, en is het IP-retentie-argument verdampt. - Geen SolidWorks-importer. SLDASM en SLDPRT zijn gesloten binaire formaten en OpenSCAD heeft daar geen pad naartoe.
- Geen fillet-primitive die overeind blijft bij niet-triviale geometrie. Je kunt het faken met
minkowski(), maar de kernel verslikt zich op alles van betekenis.
Voor de agent werkt OpenSCAD alleen als parametrische laag als je de klant beperkt tot "upload een STL van een eenvoudig onderdeel." Dat is niet de realiteit van een industrieel printbureau. De SLDASM op zaterdagavond gaat niet open. Einde verhaal.
Adam, de nieuwkomer uit YC W25
Adam ging eerder deze week live op Hacker News als open-source AI CAD. De pitch is natural-language-naar-geometrie met een echte B-rep-kernel eronder. We hebben hem op de dag van de launch in een sandbox gezet en 50 aanvraag-bestanden er doorheen gehaald.
Wat werkt: prompts als "make this 10% larger and remove the side tab" doen het juiste op onderdelen die Adam zelf heeft gegenereerd. De output is een echt solid, geen mesh, wat betekent dat het verhaal rond broncode-retentie tenminste theoretisch overeind blijft.
Wat in juni 2026 nog niet werkt:
- SolidWorks-import zit niet in v0.x. STEP-import is er, maar wankel bij AP242-bestanden met PMI-annotaties — en zo zien moderne SolidWorks-exports er nu eenmaal uit.
- Het "patch"-pad als er iets breekt is een GitHub-issue tegen een project van een paar maanden oud. De mediane fix-tijd op een CAD-kernel-bug bij een vier maanden oude startup is geen getal waar wij een zaterdagnacht-klant op gokken.
- Self-hosted inferentiekosten hangen af van welk model je inhangt. Een hosted endpoint zet je weer in de vendor-SLA.
Adam is van de drie het interessantst voor de komende 18 maanden. Vandaag is het de meest risicovolle keuze voor een tent van 21 mensen die de pipeline vannacht moet laten lopen.
CadQuery plus een Claude tool-use loop
Deze hebben we opgeleverd. CadQuery is een Python-bibliotheek bovenop OpenCascade (OCCT), dezelfde B-rep-kernel die FreeCAD gebruikt. STEP, IGES, BREP en (via FreeCAD-CLI als sidecar) SolidWorks-bestanden landen allemaal in hetzelfde Python-objectmodel.
De loop, schetsmatig:
from anthropic import Anthropic
import cadquery as cq
TOOLS = [
{"name": "load_step", "description": "Load a STEP/STP file from disk.",
"input_schema": {"type": "object",
"properties": {"path": {"type": "string"}}}},
{"name": "bounding_box", "description": "Return XYZ extents in mm.",
"input_schema": {"type": "object",
"properties": {"part_id": {"type": "string"}}}},
{"name": "rebuild_param",
"description": "Emit CadQuery Python recreating the part with new params.",
"input_schema": {"type": "object", "properties": {
"part_id": {"type": "string"},
"params": {"type": "object"}}}},
# ... volume, orientation, support_estimate, etc.
]
client = Anthropic()
parts = {}
def run_tool(name, args):
if name == "load_step":
parts[args["path"]] = cq.importers.importStep(args["path"])
return {"part_id": args["path"]}
if name == "bounding_box":
bb = parts[args["part_id"]].val().BoundingBox()
return {"x": bb.xlen, "y": bb.ylen, "z": bb.zlen}
# ...
def quote(upload_path):
msgs = [{"role": "user",
"content": f"Quote this print job: {upload_path}"}]
while True:
resp = client.messages.create(
model="claude-sonnet-4-5",
tools=TOOLS,
messages=msgs,
max_tokens=2048,
)
if resp.stop_reason == "end_turn":
return resp.content[-1].text
msgs.append({"role": "assistant", "content": resp.content})
msgs.append({"role": "user", "content": [
{"type": "tool_result", "tool_use_id": tc.id,
"content": str(run_tool(tc.name, tc.input))}
for tc in resp.content if tc.type == "tool_use"
]})
Het punt van deze code is niet "Claude doet CAD." Het punt is dat Claude kiest welke CadQuery-primitive als volgende wordt aangeroepen, en de geometrie-wiskunde draait in CadQuery — deterministisch, op de OCCT-kernel, zonder hallucinatie-oppervlak. Het model beslist "load_step, dan bounding_box, dan orientation_for_support_minimization." OCCT beslist de getallen.
Bij ons gemeten gemiddelde van zo'n 7.800 input-tokens en 1.400 output-tokens per aanvraag komt de Claude-rekening uit op ongeveer $0,044 per offerte op Sonnet 4.5 listprijzen ($3/M input, $15/M output — check de actuele prijzen voor je dit getal overneemt). Bij 940 uploads per week is dat ongeveer $41 per week. Pakweg €1.950 per jaar, wat een printbureau van 21 mensen in een kwartaal aan koffie uitgeeft.
Kosten per aanvraag, eerlijk
Bij 940 wekelijkse uploads is de token-rekening per request het minst interessante regeltje. Het vendor-risico op de zaterdagavond-faalmodus is de regel die er werkelijk toe doet. De drie lagen, op de metric waar de tent echt wakker van ligt:
- OpenSCAD: ~€0 per request. Faalt op elke upload die geen STL is. Geen SolidWorks-pad, punt.
- Adam (vandaag): kosten hangen af van hosted versus lokale inferentie. STEP-import deels, SolidWorks niet. Patch-pad is GitHub.
- CadQuery + Claude: ~€0,04 per request. STEP, IGES, BREP en SolidWorks (via FreeCAD-CLI sidecar) werken allemaal. Patch-pad is de Python aanpassen.
IP-retentie als deliverable
De klant uploadt een tekening. De agent offreert het. Zes maanden later komt dezelfde klant terug en vraagt om hetzelfde onderdeel, maar dan in PETG, 10% groter. Wat heb je bewaard?
Heb je alleen de STL bewaard, dan kun je herschalen, maar je kunt geen ontwerpintentie reproduceren. Het gatenpatroon schuift niet correct mee, de wanddikte schaalt niet lineair, de fillets zijn geen fillets meer. Heb je een CadQuery Python-bestand bewaard, dan heb je het recept. Dat bestand is jouw IP, en het is ook onderdeel van de waarde die je terug verkoopt aan de klant: "we hebben jouw onderdeel als code, niet als mesh." Probeer dat eens te zeggen in een salesgesprek bij een klant wiens hoofdontwerper net is vertrokken.
OpenSCAD geeft je een .scad-bestand, maar alleen voor onderdelen die de agent vanaf nul heeft gebouwd, wat in echt klantenverkeer bijna nooit gebeurt. Adam geeft je wat zijn output-formaat ook moge zijn, en dat verandert vandaag de dag nog wekelijks. CadQuery geeft je een deterministische .py die elke Python-engineer in 2031 nog kan lezen.
De SLDASM op zaterdagavond, wie patcht hem
Als je offerte-agent afhankelijk is van de parser van een vendor om SolidWorks in te lezen, dan is je bottleneck de bug-queue van die vendor. Plan daarnaar.
De eerlijke vergelijking: als een klant op zaterdagavond 23:14 een SolidWorks 2018-assembly uploadt, heeft OpenSCAD niets te melden. Adam opent een GitHub-issue. De CadQuery-loop valt om bij de import met een stack trace die naar STEPCAFControl_Reader wijst. Het verschil zit hem in wat daarna gebeurt. Met CadQuery grept de operator van dienst de trace, vindt dat FreeCAD-CLI zes van zeven sub-parts heeft geconverteerd en op de zevende faalde door een niet-ondersteunde AP242 PMI-extensie, en patcht de converter-call om als fallback een platte STEP-export te genereren. Die patch is 12 regels Python. Met Adam is het een issue.
Dit is geen sneer naar Adam. Het is eerlijke boekhouding van vendor-risico bij een tent van 21 mensen die 's nachts offertes verstuurt.
Wat we daadwerkelijk hebben gebouwd
We zijn voor CadQuery + de Claude tool-use loop gegaan. Niet omdat het elegant is — het is grotendeels glue — maar omdat het faalmodus-verhaal overeind blijft. STEP en IGES landen native. SolidWorks routeert via een FreeCAD-CLI sidecar die wij in handen hebben. Als een klant iets uploadt wat de loop nog nooit heeft gezien, past de operator van dienst de Python aan en deployt, in plaats van een ticket aan te maken en te wachten.
Toen we de offerte-agent voor dit printbureau in Twente bouwden, brak het SLDASM-op-zaterdag-probleem onze pipeline twee keer in de eerste maand — eenmaal op een PMI-annotatie in AP242, eenmaal op een ingebed sub-part dat als nul-byte placeholder binnenkwam. We hebben beide opgelost door FreeCAD-CLI als fallback-converter te wrappen en de onconverteerbare vijf procent naar een handmatige review-queue te routeren met een Slack-ping van één regel, en dat is precies het patch-pad-control dat je daadwerkelijk koopt als je AI-agents in een 24/7-inbox zet.
Een audit van vijf minuten die je deze week kunt doen
Pak één aanvraag van deze week. Open het bestand dat de klant heeft gestuurd. Schrijf 30 regels CadQuery — of 30 regels OpenSCAD, of 30 regels Adam-prompt — die het onderdeel parametrisch vanaf nul herbouwen. Klok jezelf. Stel jezelf dan de vraag: als jouw offerte-agent dit zelfstandig moest doen op zaterdagavond 23:14, had de laag die je hebt gekozen dan eigenlijk een kans gehad?
Kern
Bij 940 uploads per week is de token-rekening per request ruis. De regel die er werkelijk toe doet is wie de parametrische laag patcht als een klant op zaterdag SolidWorks uploadt.
FAQ
Kan OpenSCAD SolidWorks-bestanden inlezen?
Nee. OpenSCAD heeft geen SolidWorks-importer en geen bruikbare STEP- of IGES-parser, dus het werkt alleen op onderdelen die je zelf als .scad-script hebt geschreven of als platte STL-mesh hebt geïmporteerd.
Is Adam vandaag production-ready voor een printbureau?
Per juni 2026 is Adam een net gelanceerd YC W25-project. STEP-import is deels, SolidWorks zit niet in v0.x en het patch-pad zijn GitHub-issues tegen een jonge codebase.
Waarom CadQuery en niet direct de Python-API van FreeCAD?
CadQuery heeft een fluent API die voor parametrisch scripten is ontworpen en draait op dezelfde OCCT-kernel als FreeCAD. We gebruiken FreeCAD-CLI alleen als sidecar voor het inlezen van oude SolidWorks-bestanden.
Wat kost het per offerte op Claude-prijzen?
Met ongeveer 7,8k input- en 1,4k output-tokens per aanvraag komt Sonnet 4.5 listprijs uit op ongeveer $0,04 per offerte. Bij 940 uploads is dat zo'n $41 per week. Check de huidige prijzen voor je op dat getal vertrouwt.
Waarom is broncode-retentie belangrijk voor het IP van de klant?
Een mesh is een ingevroren foto; een parametrisch script is een recept. Bedrijfsgeheimbescherming hangt vast aan het recept, en het recept is wat je in staat stelt om het onderdeel over vijf jaar opnieuw te bouwen wanneer de engineer van de klant allang weg is.