<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Artikelen over AI integratie | Nixo News</title>
	<atom:link href="https://nixonews.nl/tag/ai-integratie/feed/" rel="self" type="application/rss+xml" />
	<link>https://nixonews.nl</link>
	<description>Het laatste nieuws over AI, Webdesign en Development</description>
	<lastBuildDate>Fri, 18 Sep 2026 06:04:15 +0000</lastBuildDate>
	<language>nl-NL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>AI agent tools bouwen zonder vijftien versies bij te houden</title>
		<link>https://nixonews.nl/ai-agent-tool-manifest-unified-schema/</link>
					<comments>https://nixonews.nl/ai-agent-tool-manifest-unified-schema/#respond</comments>
		
		<dc:creator><![CDATA[Sepp Stokbroekx]]></dc:creator>
		<pubDate>Fri, 18 Sep 2026 06:04:10 +0000</pubDate>
				<category><![CDATA[Data Integratie]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[AI agents]]></category>
		<category><![CDATA[AI integratie]]></category>
		<category><![CDATA[Anthropic]]></category>
		<category><![CDATA[JSON Schema]]></category>
		<category><![CDATA[OpenAI]]></category>
		<category><![CDATA[tool manifest]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[webdevelopment]]></category>
		<guid isPermaLink="false">https://nixonews.nl/ai-agent-tool-manifest-unified-schema/</guid>

					<description><![CDATA[Elke AI-provider wil zijn eigen tool-formaat. Het resultaat: je schrijft dezelfde functie drie keer. Met één unified manifest los je dat op.]]></description>
										<content:encoded><![CDATA[<p><strong>Kort antwoord:</strong> Als je AI agent tools bouwen wil voor meerdere providers (OpenAI, Claude, eigen agent-loop), onderhoud je nu voor elke tool een aparte definitie per provider. Met een unified JSON Schema manifest schrijf je een tool één keer en compileer je die automatisch naar elk provider-formaat. Dat scheelt bij 5 tools en 3 providers al 10 extra definities die je anders handmatig gesynchroniseerd moet houden.</p>
<h2>Waarom heb je straks vijftien tool-definities zonder dat je het wilt?</h2>
<p>OpenAI, Anthropic en eigen agent-loops gebruiken elk een ander formaat voor tool-definities. Hetzelfde gereedschap, drie keer opschrijven. Dat klinkt als een klein ongemak, maar het schaalt kwaadaardig: 5 tools keer 3 providers is 15 definities die je allemaal gesynchroniseerd moet houden. Één vergeten veld, en de AI laat stilletjes een verplichte parameter weg. Dat soort fouten zie je niet in je logs.</p>
<p>Stel je bouwt een <code>web_search</code>-tool. Bij OpenAI verpak je die in een <code>tools</code>-array met een geneste <code>function</code>-sleutel. Bij Anthropic wil je een plat object met <code>input_schema</code> aan de top. Klinkt als een kleine aanpassing. Het is er een, maar je moet hem voor elke tool apart bijhouden.</p>
<p>Het echte probleem is drift. Je past een parameter aan in je OpenAI-definitie en vergeet de Anthropic-versie. De tool werkt nog, maar de AI dwingt de parameter niet meer af. De tool call komt binnen zonder dat verplichte veld, en je applicatie crasht op een plek die niks met de wijziging te maken leek te hebben.</p>
<p>Ik zou dit niet accepteren voor reguliere code. Je schrijft een functie ook niet twee keer. Voor <a href="/ai-begrippen-uitgelegd-glossary-ux-design/">AI-begrippen en agent-architecturen</a> geldt hetzelfde principe: één bron van waarheid, de rest is compilatie.</p>
<h2>Wat is een unified manifest en hoe werkt het?</h2>
<p>Een unified manifest is één JSON-bestand dat een AI-tool volledig beschrijft: wat hij heet, welke parameters hij accepteert, welke rechten hij nodig heeft en hoe hij zich gedraagt bij fouten. TypeScript-adapters lezen dat bestand en compileren het naar het exacte formaat dat OpenAI of Anthropic verwacht. Je schrijft de tool één keer; de adapter regelt de rest.</p>
<p>Het manifest gebruikt JSON Schema draft 2020-12 als vocabulaire voor de parameter-beschrijvingen. JSON Schema is een open standaard voor het beschrijven van datastructuren. Handig, want elke JSON Schema-validator werkt direct op je manifests, zonder custom code.</p>
<p>Een manifest heeft vijf onderdelen:</p>
<ul>
<li><strong>toolId + metadata:</strong> een stabiele identifier, versienummer en beschrijving die naar de provider gaat.</li>
<li><strong>inputSchema:</strong> de parameters van de tool, beschreven als gewone JSON Schema-objecten.</li>
<li><strong>outputSchema:</strong> de verwachte returnwaarde. Providers gebruiken dit nu nog niet, maar je eigen agent-loop kan ermee valideren.</li>
<li><strong>permissions:</strong> welke systeemrechten de tool claimt, zoals <code>network</code> of <code>exec</code>. Een sandbox-runtime kan een tool weigeren als die meer vraagt dan toegestaan.</li>
<li><strong>executionBoundary:</strong> timeouts, retry-beleid en concurrency-limieten. Dit is voor je eigen orchestrator, niet voor de provider-API.</li>
</ul>
<p>De adapter doet daarna het simpele maar foutgevoelige werk: hij pakt de <code>toolId</code> als functienaam voor OpenAI, wikkelt de <code>inputSchema</code> in de juiste nesting, en laat de rest weg. Voor Anthropic doet hij hetzelfde met een andere wrapper. Structureel zijn de inner schemas bijna identiek; alleen de buitenste laag verschilt.</p>
<p>Let op: <code>default</code>-waarden in JSON Schema zijn documentatie, geen gedrag. OpenAI noch Anthropic passen die toe. Je implementeert defaults in je eigen aanroep-laag, niet in het manifest.</p>
<h2>5 tools × 3 providers = 15 definities: de wiskunde die je wil vermijden</h2>
<p>De rekensom is eenvoudig. Met een unified manifest-architectuur heb je N manifests plus M adapters. De adapters schrijf je één keer en test je onafhankelijk van de tools. Nieuwe provider? Eén nieuwe adapter, en alle bestaande tools werken direct. Nieuwe tool? Één manifest, en hij werkt op alle providers.</p>
<p>Vergelijk het met een tolk bij een vergadering. Zonder tolk praat elke deelnemer een andere taal en heb je voor elk gesprekspaar een aparte vertaling nodig. Met een tolk vertaal je alles via één gemeenschappelijke taal. De tolk is de adapter; het manifest is die gemeenschappelijke taal.</p>
<p>De wiskunde is het sterkste argument. Stel je voegt een vierde provider toe aan een systeem met 10 tools:</p>
<ul>
<li><strong>Zonder manifest:</strong> 10 nieuwe definities schrijven, elke bestaande tool aanpassen.</li>
<li><strong>Met manifest:</strong> 1 nieuwe adapter schrijven, klaar.</li>
</ul>
<p>Adapters zijn bovendien onafhankelijk testbaar. Je kunt een unit-test schrijven die controleert of de OpenAI-adapter altijd een <code>strict</code>-veld meeneemt, of dat de Anthropic-adapter nooit een <code>type: "function"</code>-wrapper toevoegt. Die tests slagen of zakken ongeacht welke tools je later toevoegt.</p>
<p>Voor developers die werken met multi-agent setups, zie ook <a href="/deerflow-open-source-multi-agent-framework/">DeerFlow als open-source voorbeeld van zo&#8217;n multi-agent architectuur</a>. Zo houd je het beheerbaar naarmate het aantal tools groeit.</p>
<h2>Hoe ziet een concreet manifest eruit in TypeScript?</h2>
<p>Een manifest is een gewoon JSON-bestand met vijf verplichte velden. TypeScript-interfaces spiegelen die structuur zodat je bij het schrijven van adapters direct compile-time feedback krijgt als je een veld mist of verkeerd typt. Validatie via AJV vangt fouten af vóór runtime.</p>
<p>Hier is een minimaal manifest voor een zoektool:</p>
<pre><code>{
  "toolId": "web_search",
  "version": "1.0.0",
  "name": "Webzoekopdracht",
  "description": "Zoekt actuele informatie op het web.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": { "type": "string", "description": "Zoekterm" },
      "max_results": { "type": "integer", "description": "Aantal resultaten", "default": 5 }
    },
    "required": ["query"]
  },
  "permissions": ["network"],
  "executionBoundary": {
    "timeout": 5000,
    "retryPolicy": { "maxRetries": 2, "backoffMs": 500 }
  }
}</code></pre>
<p>De TypeScript-adapter voor OpenAI pakt dit manifest en geeft terug:</p>
<pre><code>{
  type: "function",
  function: {
    name: manifest.toolId,
    description: manifest.description,
    parameters: manifest.inputSchema,
    strict: false
  }
}</code></pre>
<p>De Anthropic-adapter geeft:</p>
<pre><code>{
  name: manifest.toolId,
  description: manifest.description,
  input_schema: manifest.inputSchema
}</code></pre>
<p>Twaalf regels verschil. Mechanisch. En toch is het iets wat je handmatig fout gaat zodra je tien tools hebt en onder tijdsdruk werkt. Geautomatiseerd gaat het altijd goed.</p>
<p>De <code>toolId</code> volgt een patroon van kleine letters, cijfers, underscores en punten. Max 64 tekens, want sommige providers knippen namen af. Dat soort grenzen staan in het schema zelf, zodat validatie ze al afvangt voordat je ook maar één API-call doet.</p>
<h2>Wat lost dit niet op, en wanneer is het overkill?</h2>
<p>Een unified manifest werkt goed als je écht meerdere providers ondersteunt of verwacht te gaan ondersteunen. Bouw je voor één provider en blijft dat zo, dan voeg je een abstractielaag toe zonder directe winst. Eerlijk is eerlijk: voor een eenvoudig side-project met twee tools en één provider is dit te veel infrastructuur.</p>
<p>De benadering heeft ook echte beperkingen die je moet kennen.</p>
<p><strong>Provider-specifieke functies verdwijnen.</strong> OpenAI&#8217;s <code>strict</code>-modus, waarbij alle properties verplicht zijn en <code>additionalProperties</code> false moet zijn, past niet in een generiek manifest. Je kunt het als extensie-veld toevoegen, maar dan verlies je de vendor-neutraliteit deels weer.</p>
<p><strong>Output-validatie werkt alleen in je eigen loop.</strong> Noch OpenAI noch Anthropic valideert tool-output tegen je <code>outputSchema</code>. Je moet dat zelf implementeren in de orchestrator die de tool-resultaten verwerkt voordat ze terug naar het model gaan.</p>
<p><strong>Defaults zijn documentatie, geen gedrag.</strong> Als je <code>"default": 5</code> in je schema zet, doet geen enkele provider daar iets mee. Je implementeert defaults in je eigen aanroep-code.</p>
<p>Dit patroon is het meest waardevol voor teams die nu al twee providers gebruiken, of die een tool-bibliotheek bouwen die anderen gaan gebruiken. Voor een solo-project met één AI-provider: begin gewoon met het native formaat en refactor als je een tweede provider toevoegt. Vroeg abstraheren verspilt tijd. Vergelijk het met migreren tussen LLM-modellen: je doet het als de noodzaak er is, niet als voorzorgsmaatregel voor een probleem dat misschien nooit komt.</p>
<div class="nn-related-posts">
<h3>Dit vind je misschien ook interessant</h3>
<ul>
<li><a href="https://nixonews.nl/design-system-code-connect-ai-kosten/">Design system opzetten met AI: Code Connect verlaagt kosten met 22%</a></li>
<li><a href="https://nixonews.nl/ai-begrippen-uitgelegd-glossary-ux-design/">AI begrippen uitgelegd: de termen die je écht moet kennen</a></li>
<li><a href="https://nixonews.nl/figma-skills-ai-workflows-designers/">Figma Skills: 10 AI-workflows die designers zelf bouwen</a></li>
</ul>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://nixonews.nl/ai-agent-tool-manifest-unified-schema/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
