<?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>methodology &#8211; Smals Research</title>
	<atom:link href="https://www.smalsresearch.be/tag/methodology/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.smalsresearch.be</link>
	<description></description>
	<lastBuildDate>Mon, 08 Jun 2026 06:17:00 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://www.smalsresearch.be/wp-content/uploads/2026/01/cropped-cropped-Smals_Research-32x32.png</url>
	<title>methodology &#8211; Smals Research</title>
	<link>https://www.smalsresearch.be</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Les jumeaux numériques dans un contexte administratif</title>
		<link>https://www.smalsresearch.be/jumeaux-numeriques-dans-contexte-administratif/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Fri, 29 May 2026 07:12:26 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Digital Twin]]></category>
		<category><![CDATA[Digitalisation]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<guid isPermaLink="false">https://www.smalsresearch.be/?p=29569</guid>

					<description><![CDATA[Le "jumeau numérique" est un concept qui fait le buzz. Mais peut-il également avoir un sens dans un environnement administratif ?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Dit artikel is ook beschikbaar&nbsp;</em><a href="https://www.smalsresearch.be/digital-twins-in-administratieve-context/" data-type="post" data-id="24294">in het Nederlands</a><em>.</em></p>



<p class="wp-block-paragraph"><a href="https://ntrs.nasa.gov/citations/20210023699">La NASA</a> affirme avoir été la première à appliquer le concept de <a href="https://www.ibm.com/think/topics/digital-twin">jumeau numérique</a> <em>(&#8220;Digital Twin&#8221;)</em>. Afin de mieux prédire le comportement des objets qu&#8217;elle envoyait dans l&#8217;espace, elle avait besoin d&#8217;une copie sur Terre – non seulement physique, mais aussi numérique. Certains scénarios sont tout simplement difficiles à reproduire sur Terre, mais doivent pouvoir être simulés de manière aussi détaillée que possible.&nbsp; Cette approche s&#8217;est répandue dans d&#8217;autres secteurs, comme l&#8217;aéronautique, où des erreurs de conception pourraient avoir des conséquences catastrophiques, ou encore là où une méthode par essais et erreurs serait trop coûteuse ou pratiquement impossible.&nbsp;&nbsp;&nbsp;</p>



<p class="wp-block-paragraph">Le jumeau numérique n&#8217;est toutefois apparu sur le <a href="https://www.forbes.com/sites/gartnergroup/2016/10/26/gartners-top-10-strategic-technology-trends-for-2017/">radar de Gartner</a> qu&#8217;à la fin de l&#8217;année 2016. <a href="https://fr.wikipedia.org/wiki/Jumeau_num%C3%A9rique">La page Wikipédia consacrée à ce sujet</a> est aussi relativement récente, puisqu’elle a été créée en 2015, bien plus tard que celles dédiées à la <a href="https://fr.wikipedia.org/wiki/R%C3%A9alit%C3%A9_virtuelle">réalité virtuelle</a> (2001) et à <a href="https://fr.wikipedia.org/wiki/Internet_des_objets">l’Internet des objets</a> (2007). L&#8217;idée des jumeaux numériques a toutefois rapidement gagné en popularité, aidée en cela par le programme européen Horizon 2020 qui y a vu un potentiel et a financé divers projets sur ce thème à hauteur de plusieurs millions d&#8217;euros (<a href="https://www.horizon-europe.gouv.fr/supporting-development-digital-twin-improve-management-operations-and-resilience-eu-electricity">[1]</a>, <a href="https://www.digitalurbantwins.com/">[2]</a>, <a href="https://www.imec.be/nl/vlaamse-innovatiemotor/impactdomeinen/smart-cities/precinct">[3]</a>, <a href="https://sphere-project.eu/">[4]</a>). En Flandre, cette opportunité a été saisie avec empressement, avec l’<a href="https://www.imec.be/nl/vlaamse-innovatiemotor/samenwerking/vlaamse-onderzoeksprogrammas/city-of-things">IMEC dans un rôle central</a>, soutenu par un <a href="https://www.vlaanderen.be/digitaal-vlaanderen/digitaal-vlaanderen-zet-vaart-achter-europese-digital-twins-en-baant-zo-de-weg-naar-een-citiverse">Digitaal Vlaanderen</a> enthousiaste, sans oublier <a href="https://vito.be/en/research/digital-twins-in-health">VITO</a>, qui est également convaincu.</p>



<p class="wp-block-paragraph">D&#8217;un point de vue marketing, le jumeau numérique a donc déjà fait ses preuves. Mais peut-il apporter une valeur ajoutée concrète aux administrations publiques ? Dans ce domaine également, les flux opérationnels deviennent rapidement complexes, les modifications peuvent s’avérer coûteuses, et l’on souhaite peut-être pouvoir simuler certaines choses avant de les mettre en œuvre. Dans cet article, nous examinerons ce que le jumeau numérique peut apporter dans un contexte administratif.</p>



<h2 class="wp-block-heading">Définitions</h2>



<p class="wp-block-paragraph">Il existe de nombreuses interprétations du jumeau numérique. L&#8217;essence même du concept n&#8217;est en tout cas pas nouvelle : un système est représenté numériquement afin de pouvoir être observé, testé et amélioré sans impact direct sur son fonctionnement réel. La principale caractéristique distinctive est la <strong>synchronisation</strong> continue (ou du moins régulière) entre le système réel (l&#8217;entité cible ou <em>target entity</em>) et son homologue numérique. Le Centre commun de recherche de l’UE adopte un <a href="https://interoperable-europe.ec.europa.eu/sites/default/files/document/2020-06/ELISEWebinar_9_DigitalTwins.pdf">modèle de maturité</a> qui distingue différents niveaux d’intégration ; ce n’est que dans le cas d’un échange bidirectionnel de données entre l’entité cible et le jumeau que l’on parle véritablement de jumeau. À l&#8217;échelle internationale, des efforts sont entrepris pour <a href="https://www.iso.org/standard/81442.html">standardiser la terminologie</a>.</p>



<figure class="wp-block-image aligncenter size-large"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model.png"><img fetchpriority="high" decoding="async" width="1024" height="643" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-1024x643.png" alt="" class="wp-image-29555" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-1024x643.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-300x189.png 300w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-768x483.png 768w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model.png 1071w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">&#8220;Digital Twin Maturity Spectrum&#8221;. Source: IET &amp; Atkins, &#8220;Digital Twins for the Built Environment&#8221;, 2019.</figcaption></figure>



<p class="wp-block-paragraph">Pour être utile, un jumeau numérique doit être développé avec suffisamment de détails. Le niveau de granularité ou de résolution variera en fonction de l’application. Le jumeau doit pouvoir représenter fidèlement l’entité cible tout au long de son cycle de vie, mais cela ne signifie pas que chaque détail doive être simulé dans les moindres détails. Dans le <a href="https://www.nature.com/articles/s41746-024-01073-0">secteur médical</a>, on voit apparaître des jumeaux numériques au niveau de la <a href="https://www.rfi.ac.uk/focus/projects/digital-twin-cell/">cellule</a>, de l’<a href="https://www.turing.ac.uk/science-innovation/health/cardiac-digital-twins">organe</a>, d’un <a href="https://digital-strategy.ec.europa.eu/en/policies/virtual-human-twins">individu</a> ou de la <a href="https://pubmed.ncbi.nlm.nih.gov/40762974/">population</a>. Rien n’empêche non plus qu’un jumeau numérique ne constitue qu’une partie d’un système plus vaste&nbsp;; il peut, par exemple, n’être élaboré que pour un seul composant critique.</p>



<p class="wp-block-paragraph">On distingue deux courants de jumeaux numériques&nbsp;:</p>



<ul class="wp-block-list">
<li>Les jumeaux technologiques de haut niveau (aéronautique, industrie, infrastructure), où le jumeau est utilisé pour le diagnostic, la maintenance prédictive ou la conception itérative sur la base de données opérationnelles – à la <a href="https://ntrs.nasa.gov/api/citations/20210023699/downloads/ASME%20Digital%20Twin%20Summit%20Keynote_final.pdf">NASA</a>, pour la <a href="https://initiatives.weforum.org/future-power-system/case-study-details/digital-twin-grid/aJYTG00000010pB4AQ">distribution d’électricité</a>&#8230;</li>



<li>Les jumeaux de systèmes d&#8217;information ou sociotechniques (villes, organisations, services), dans lesquels l&#8217;entité cible n&#8217;est pas tant une machine qu&#8217;un système complexe impliquant plusieurs parties prenantes, composé de processus, de règles, de personnes et de flux de données. C&#8217;est dans ce deuxième courant que s&#8217;inscrit le secteur public, mais c&#8217;est aussi là que les <a href="https://interoperable-europe.ec.europa.eu/collection/elise-european-location-interoperability-solutions-e-government/glossary/term/digital-twin-government">définitions deviennent floues</a> et que le &#8220;jumeau numérique&#8221; est parfois utilisé comme <a href="https://eprintspublications.npl.co.uk/9880/">terme marketing pour désigner une structure &#8220;tableau de bord + modèle</a>&#8220;.</li>
</ul>



<p class="wp-block-paragraph">Alors que le flou est peut-être inévitable sur le plan politique, nous souhaitons néanmoins une interprétation plus opérationnelle dans la pratique. Nous pourrions définir un jumeau numérique administratif comme une <strong>représentation numérique de la réalité de la prestation de services, continuellement actualisée et testable</strong>. Cela inclut les processus, les dossiers et leur état d&#8217;avancement, un système applicable des règles en vigueur, ainsi que l&#8217;ensemble des flux de données nécessaires au bon fonctionnement de l&#8217;ensemble. Cela doit permettre de suivre de près la situation actuelle et de simuler à l&#8217;avance les modifications éventuelles avant leur application.</p>



<figure class="wp-block-image aligncenter size-full"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png"><img decoding="async" width="603" height="211" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png" alt="" class="wp-image-29558" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png 603w, https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49-300x105.png 300w" sizes="(max-width: 603px) 100vw, 603px" /></a><figcaption class="wp-element-caption">Les jumeaux numériques (DT) conceptuellement&nbsp;: données du système cible + moteurs de calcul (= enabler) + applications (= usage). Source: Oakes, Parsai, Van Mierlo, Demeyer, Denil, De Meulenaere, Vangheluwe, &#8220;Improving digital twin experience reports&#8221;, <a href="https://doi.org/10.5220/0010236101790190">DOI: 10.5220/0010236101790190</a></figcaption></figure>



<p class="wp-block-paragraph">Pour un processus industriel piloté par des données de capteurs et les lois immuables de la physique, cela s’avère plus facile que pour le secteur public, où l’on traite souvent des données sensibles et où l’on dépend de règles changeant régulièrement qui laissent place à l’interprétation (voir également nos articles précédemment publiés sur les <a href="https://www.smalsresearch.be/rules-as-code-fr/">Rules As Code</a>). Les préoccupations liées à la gouvernance des données (<a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">RGPD</a>, etc.) peuvent compliquer la mise en place d’une synchronisation avec les données en temps réel. La logique décisionnelle est souvent étroitement liée au code des applications, ce qui complique les ajustements et les contrôles de conformité. C&#8217;est pourquoi, dans le contexte public, la mise en place d&#8217;un <a href="https://en.wikipedia.org/wiki/Digital_twin_integration_level"><em>Digital Shadow</em></a>, que l&#8217;on peut situer quelque part entre un &#8220;bête&#8221; modèle et un véritable jumeau synchronisé, constitue souvent déjà un exploit en soi.</p>



<h2 class="wp-block-heading">Projets phares</h2>



<p class="wp-block-paragraph">En Europe, les projets de jumeaux numériques les plus marquants concernent principalement le climat et la science&nbsp;:</p>



<ul class="wp-block-list">
<li><a href="https://destination-earth.eu/">Destination Earth ou DestinE</a> combine des données à grande échelle provenant de <a href="https://www.eumetsat.int/">satellites (météorologiques)</a> et de <a href="https://www.copernicus.eu/">Copernicus</a> dans un <a href="https://destination-earth.eu/destination-earth/destines-components/destination-earth-data-lake/">lac de données</a>. Sur cette base, deux jumeaux numériques ont vu le jour : <a href="https://destine.ecmwf.int/climate-change-adaptation-digital-twin-climate-dt/">Climate Change Adaptation</a> (long terme) et <a href="https://destine.ecmwf.int/weather-induced-extremes-digital-twin/">Weather-induced Extremes</a> (court terme). Pour ce faire, ils ont développé leur propre <a href="https://stories.ecmwf.int/the-digital-twin-engine/">Digital Twin Engine</a>. Le projet se <a href="https://destination-earth.eu/news/destination-earth-moves-into-phase-three/">poursuit</a>, l’objectif étant de faciliter davantage les &#8220;applications en aval&#8221; d’utilisateurs externes qui peuvent approfondir certains aspects ou des questions de recherche spécifiques. Tout cela doit être partagé via <a href="https://platform.destine.eu/">une plateforme</a> unique coordonnée par l’<a href="https://www.esa.int/Applications/Observing_the_Earth/Destination_Earth">ESA</a>.</li>



<li>Le projet <a href="https://www.edito.eu/">EDITO</a> vise à atteindre des objectifs similaires, mais dans le domaine des océans.<br>À cette fin, les données d’<a href="https://emodnet.ec.europa.eu/en">EMODnet</a> et de <a href="https://marine.copernicus.eu/">Copernicus</a> sont mises en commun. L’accès passe par un <a href="https://datalab.dive.edito.eu/">Datalab</a> qui propose également une série d’autres modules et services, et les applications qui y sont développées peuvent être hébergées sur la <a href="https://dive.edito.eu/">plateforme numérique</a> de l’initiative.</li>



<li><a href="https://www.intertwin.eu/use-cases">Plusieurs use cases</a> sont également répertoriés dans le cadre du projet de recherche interTwin, <a href="https://www.intertwin.eu/article/intertwin-has-ended-whats-next">récemment achevé</a> (et <a href="https://cordis.europa.eu/project/id/101058386">financé</a> par l’Union européenne), qui visait à développer une <a href="https://zenodo.org/records/10650440">architecture quelque peu standardisée</a> avec des <a href="https://www.intertwin.eu/intertwin-digital-twin-engine">composants réutilisables</a> pour les jumeaux numériques. Ils ont abordé le sujet plutôt sous l’angle du <a href="https://openlab.cern/intertwin/">CERN</a>, et indépendamment des deux initiatives mentionnées précédemment. Au fil du temps, ils ont toutefois pris conscience de l’existence les uns des autres et une <a href="https://zenodo.org/records/16966835">interopérabilité potentielle</a> avec le projet <a href="https://www.esa.int/Applications/Observing_the_Earth/Destination_Earth">DestinE, lié à l’ESA</a>, a déjà été étudiée.</li>
</ul>



<figure class="wp-block-image aligncenter size-full"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg"><img decoding="async" width="621" height="511" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg" alt="" class="wp-image-29560" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg 621w, https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring-300x247.jpg 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-element-caption">Utilisation d&#8217;un jumeau numérique pour la surveillance. Source: Davila Delgada &amp; Oyedele, &#8220;Digital Twins for the built environment: learning from conceptual and process models in manufacturing&#8221;, <a href="https://doi.org/10.1016/j.aei.2021.101332">DOI: 10.1016/j.aei.2021.101332</a></figcaption></figure>



<p class="wp-block-paragraph">Dans un contexte administratif, les données issues de satellites ou d’accélérateurs de particules nous sont moins utiles. En raison des exigences en matière de gouvernance, l’accent est plutôt mis sur une interopérabilité et un échange de données corrects, conformément à tous les cadres juridiques en vigueur. À cet égard, les initiatives européennes les plus utiles sont peut-être encore les <a href="https://digital-strategy.ec.europa.eu/en/policies/data-spaces">Espaces européens des données</a> – pour un &#8220;jumeau politique&#8221;, par exemple, l&#8217;<a href="https://data.europa.eu/en/ELDS">Espace européen des données juridique</a>. Il existe également des points communs avec le concept de bacs à sable réglementaires tel qu’il apparaît notamment dans le <a href="https://eur-lex.europa.eu/EN/legal-content/summary/interoperable-europe-act.html">Règlement pour une Europe interopérable</a> ou, plus récemment, dans la <a href="https://www.europarl.europa.eu/RegData/etudes/BRIE/2022/733544/EPRS_BRI(2022)733544_EN.pdf">législation sur l’intelligence artificielle</a> : un jumeau numérique administratif peut remplir le rôle d’un tel bac à sable s’il existe de bons mécanismes de développement et d’évaluation de scénarios.</p>



<h2 class="wp-block-heading">Use Cases administratifs</h2>



<p class="wp-block-paragraph">Avant de nous lancer dans des secteurs complexes tels que les soins de santé et la sécurité sociale, nous devons tout de même nous demander si les jumeaux numériques peuvent apporter une réelle valeur ajoutée à ce qui existe déjà aujourd’hui – car l&#8217;engouement en soi n’apporte rien.</p>



<h3 class="wp-block-heading">Use Case 1&nbsp;: Simulation des politiques et de leur impact opérationnel</h3>



<p class="wp-block-paragraph">En matière de modélisation de politiques pour la sécurité sociale, il existe par exemple déjà une base solide avec le modèle de microsimulation <a href="https://joint-research-centre.ec.europa.eu/euromod_en">EUROMOD</a>, dont la variante belge s&#8217;appelle <a href="https://socialsecurity.belgium.be/fr/elaboration-de-la-politique-sociale/impact-assessment-research/belmod">BELMOD</a>. Il s&#8217;agit de microsimulations statiques dans lesquelles des données très détaillées sont combinées à des règles codifiées, permettant de simuler des réformes des paramètres de la sécurité sociale (cotisations, allocations&#8230;). Ces études sont généralement menées dans les <a href="https://cape-saintlouis.be/">universités</a>. On peut se faire une idée de ce que cela implique via <a href="https://euromod-web.jrc.ec.europa.eu/euromod-online/">EUROMOD Online</a>.</p>



<p class="wp-block-paragraph">D&#8217;une certaine manière, ce type de modèle s&#8217;apparente déjà à un jumeau numérique pour la politique sociale, mais il lui manque encore deux éléments essentiels&nbsp;:</p>



<ul class="wp-block-list">
<li>des liens en temps réel avec les données administratives&nbsp;: cela permettrait de simuler les effets budgétaires et distributifs sur la situation actuelle, plutôt que sur des données obsolètes datant de plusieurs années.</li>



<li>des informations sur les processus de prestation de services (délais de traitement des dossiers, capacité de traitement&#8230;)&nbsp;: cela permettrait également d&#8217;évaluer l&#8217;impact opérationnel des réformes sur les services exécutifs.</li>
</ul>



<p class="wp-block-paragraph">Il ne serait pas du tout simple d&#8217;ajouter cela : les données en question sont de nature très sensible. L&#8217;utilisation des données réelles comme source de données en temps réel pour les simulations nécessiterait certainement une anonymisation poussée (conformément au RGPD), en plus d&#8217;une série d&#8217;autres <a href="https://www.ksz-bcss.fgov.be/fr/page/csi-en-bref">mesures de sécurité</a>. Il s&#8217;agit là d&#8217;un exercice complexe en soi, qui pourrait également entraîner la perte d&#8217;informations utiles.</p>



<p class="wp-block-paragraph">Le statut d&#8217;une personne au sein de la sécurité sociale est en outre déterminé par une succession d&#8217;événements susceptibles d&#8217;avoir des répercussions à long terme et d&#8217;interagir entre eux (emploi, licenciement, maladie, accident, pension, naissance d&#8217;un enfant&#8230;). Pour être vraiment utile, un jumeau devrait pouvoir modéliser l’ensemble du parcours d’un individu au sein du système. Non seulement le statut individuel, mais aussi celui des dossiers (les délais sont-ils respectés&nbsp;?) et de l’administration (y a-t-il un retard dans le traitement&nbsp;?) évoluent au fil du temps.</p>



<p class="wp-block-paragraph">Si, aujourd’hui, une bonne ombre numérique (<em>digital shadow</em>) d’un service est déjà disponible, l’ajout de données évolutives relatives à la répartition de la charge de travail, aux capacités, à l’avancement des dossiers&#8230; permettrait de franchir une nouvelle étape, comme une simulation du flux de dossiers. De telles simulations sélectives peuvent servir à des analyses contrefactuelles (&#8220;et si&#8221;) qui permettent de mieux évaluer l&#8217;impact d&#8217;un changement (au niveau organisationnel ou réglementaire). À l&#8217;inverse, on peut également y voir un cadre pour des tests de régression&nbsp;: les calculs effectués sur des échantillons représentatifs peuvent être répétés chaque fois qu&#8217;un élément change, afin de localiser l&#8217;impact le plus important.</p>



<h3 class="wp-block-heading">Use Case 2&nbsp;: Planification organisationnelle dans les soins de santé</h3>



<p class="wp-block-paragraph">L&#8217;administration des soins de santé a d&#8217;autres priorités : le suivi des patients et des consultations est urgent, l&#8217;affectation du personnel et des ressources est un casse-tête de planification complexe, sans parler des divers remboursements et assurances&#8230; Pour évoluer vers le jumeau numérique, les <a href="https://www.ehealth.fgov.be/fr/page/ehds-european-health-data-space---le-reglement-europeen-relatif-a-l-espace-europeen-des-donnees-de-sante">espaces européens des données de santé</a> pourraient jouer un rôle important, tout comme les nouvelles solutions que l&#8217;on s&#8217;efforce actuellement de mettre au point pour <a href="https://tehdas.eu/">l&#8217;utilisation secondaire des données de santé</a>.</p>



<p class="wp-block-paragraph">Nous sommes encore loin du rêve des soins de santé optimisés individuellement sur la base d&#8217;un <a href="https://digital-strategy.ec.europa.eu/en/policies/virtual-human-twins">jumeau numérique personnel du patient</a>, une idée qui s&#8217;accompagne d&#8217;ailleurs de <a href="https://zenodo.org/records/14516807">nombreux risques non négligeables</a> sur les plans <a href="https://www.frontiersin.org/journals/genetics/articles/10.3389/fgene.2018.00031/full">de l&#8217;éthique et de la confidentialité</a>. À plus court terme, les possibilités se situent plutôt au niveau de l&#8217;organisation. En ajoutant à une ombre numérique existante des données relatives aux admissions, aux listes d’attente, à l’affectation du personnel et à l’activité, il devient possible de mieux absorber les évolutions stratégiques et opérationnelles.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg"><img loading="lazy" decoding="async" width="800" height="383" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg" alt="" class="wp-image-29564" style="width:800px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg 800w, https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks-300x144.jpg 300w, https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks-768x368.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-element-caption">Les nombreux aspects d&#8217;un jumeau numérique, ici pour l&#8217;immunologie. Source: Niarakis et.al., &#8220;Immune digital twins for complex human pathologies: applications, limitations, and challenges&#8221;, <a href="https://doi.org/10.1038/s41540-024-00450-5" target="_blank" rel="noreferrer noopener">DOI: 10.1038/s41540-024-00450-5</a></figcaption></figure>



<h2 class="wp-block-heading">La mise en œuvre: une opération couteuse&nbsp;?</h2>



<p class="wp-block-paragraph">Pour rester concentrées sur ce qui est possible aujourd&#8217;hui ou à court terme, les administrations peuvent s&#8217;inspirer des &#8220;piles de référence&#8221; de composants technologiques, développées dans le cadre de jumeaux numériques existants. Nous en avons déjà mentionné quelques-unes précédemment et ne les répéterons pas ici.</p>



<p class="wp-block-paragraph">Un jumeau numérique doit pouvoir contenir une représentation de l&#8217;état actuel d&#8217;un système et traiter les événements qui ont un impact sur celui-ci. À cette fin, dans le cadre des initiatives européennes <a href="https://www.fiware.org/">FIWARE</a> (Future Internet), le groupe de travail Context Information Management au sein de l’ETSI (l&#8217;Institut européen des normes de télécommunications) a développé le standard et l&#8217;<a href="https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.09.01_60/gs_CIM009v010901p.pdf">API</a> <a href="https://ngsi-ld.org/">NSGI-LD</a>.  Il semble toutefois que ce standard <a href="https://fr.wikipedia.org/wiki/NGSI-LD#Uses">ne soit pas encore très répandu</a> en dehors de son <a href="https://www.fiware.org/about-us/smart-industry/">propre réseau</a> composé principalement des initiatives Smart City et IoT.</p>



<p class="wp-block-paragraph">Les systèmes administratifs ne se résument pas à de simples décisions. Les processus impliquent des interactions, des documents et, parfois, une certaine marge d&#8217;appréciation. Les standards ouverts issus du <em>business process management</em> s’avèrent ici utiles. <a href="https://www.omg.org/dmn/">DMN (decision modeling)</a>, <a href="https://www.omg.org/bpmn/">BPMN (business processes)</a> et <a href="https://www.omg.org/cmmn/">CMMN (case management)</a> sont complémentaires et permettent de modéliser ces aspects. Des extensions voient également le jour à partir de ces initiatives, comme <a href="https://cdmn.readthedocs.io/">Constraint DMN (cDMN)</a>, développé à la KULeuven, qui permet une logique plus complexe. Nous pouvons alors composer un jumeau numérique à partir d’un moteur de décision DMN qui calcule &#8220;ce que disent les règles&#8221; (c’est là que l&#8217;approche Rules As Code peut éventuellement trouver sa place), enrichi de couches qui prennent en charge les processus et le flux de dossiers (statut, délais, documents de support), et enfin d’une synchronisation régulière pour pouvoir mettre à jour l&#8217;état opérationnel (ou le contexte). Cette approche est compatible avec le <a href="https://interoperable-europe.ec.europa.eu/sites/default/files/document/2020-06/ELISEWebinar_9_DigitalTwins.pdf">modèle de maturité du CCR</a> (model -> shadow -> twin).</p>



<p class="wp-block-paragraph">Les jumeaux numériques ne sont pas coûteux parce qu’ils intègrent beaucoup de visualisation ou des capacités de reporting. Ils sont coûteux parce qu&#8217;ils constituent une réplique du système cible qui, tout comme l&#8217;original, doit continuer à fonctionner correctement au fil du temps. Pour <a href="https://eprintspublications.npl.co.uk/9880/">aller au-delà de l&#8217;engouement</a>, ils nécessitent un investissement constant en maintenance. Ces coûts récurrents comprennent au moins les éléments suivants :</p>



<ul class="wp-block-list">
<li>surveillance et validation : un jumeau numérique doit suivre chaque modification apportée au système cible avec la plus grande précision possible, ce qui nécessite des mises à jour régulières ;</li>



<li>maintenance des règles et traçabilité&nbsp;: cela représente un coût important, surtout lorsque les règles changent fréquemment. C&#8217;est là que la gestion des versions, les suites de tests et la gestion des changements jouent un rôle&nbsp;;</li>



<li>fonctionnement des pipelines de données et interopérabilité&nbsp;: cela englobe également la sémantique, le contrôle des accès, <a href="https://www.intertwin.eu/ker-4-quality-framework">la qualité des données, la précision</a> et la sécurité.</li>



<li>confidentialité et conformité&nbsp;: indispensables, certainement pour les systèmes qui traitent des données à caractère personnel (santé, revenus, famille).</li>
</ul>



<p class="wp-block-paragraph">Pour un cas d&#8217;utilisation administratif, la meilleure première étape consiste donc à mettre en place de manière systématique ce que l&#8217;on pourrait appeler une &#8220;ombre numérique respectueuse de la vie privée&#8221; : initialement limitée à des fonctionnalités de surveillance et de répétition, avec un contrôle d&#8217;accès strict et une <a href="https://www.edpb.europa.eu/sme-data-protection-guide/data-protection-basics_nl">minimisation des données</a>. On peut ensuite envisager une extension à des simulations sur des jeux de données anonymisées ou synthétiques. Une éventuelle synchronisation en temps quasi réel avec les données du système cible réel, afin de créer un véritable jumeau numérique, ne peut intervenir qu&#8217;à la fin du processus et s&#8217;avère souvent assez complexe à mettre en œuvre.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Un jumeau numérique est-il la solution adéquate, ou existe-t-il une alternative plus simple&nbsp;?<br>En résumé, les jumeaux numériques ne doivent être envisagés que si toutes les conditions suivantes sont remplies (sinon, une autre approche peut s&#8217;avérer plus efficace et mieux adaptée)&nbsp;:</p>



<ul class="wp-block-list">
<li>Le système cible modélisé est dynamique&nbsp;: les résultats dépendent de situations en constante évolution (flux de dossiers, files d&#8217;attente, cycle de vie des événements), et pas uniquement de contrôles d&#8217;éligibilité ou de formulaires.</li>



<li>Il est possible d&#8217;identifier des sources de données de référence et de maintenir une synchronisation continue. Sans mises à jour régulières avec des données opérationnelles, on construit un modèle et non un jumeau.</li>



<li>Les simulations mènent à de vraies décisions. Si l&#8217;organisation ne dispose pas d&#8217;une liberté suffisante pour intervenir (modification des politiques, adaptation du flux de dossiers, priorisation, tâches du personnel&#8230;), une série de tableaux de bord suffira probablement.</li>



<li>Il existe un plan crédible d&#8217;audit et de contrôle qualité permanent. Cela ne doit pas être une considération a posteriori, mais un critère d&#8217;acceptation. Il est inutile de construire un jumeau qui se détériore plus vite que le système cible.</li>



<li>L&#8217;environnement juridique et de conformité est compatible. Si des données à caractère personnel sont impliquées, le RGPD et l&#8217;AI Act peuvent entraîner des obligations qui influencent fortement la faisabilité et le coût. Cela peut limiter un jumeau à un simple système de test amélioré au lieu d&#8217;apporter une véritable contribution à l&#8217;automatisation opérationnelle.</li>
</ul>



<p class="wp-block-paragraph">Un système non jumeau peut également s&#8217;avérer utile : avec des règles codifiées, un <a href="https://en.wikipedia.org/wiki/Test_harness">harnais de test</a> et une surveillance, on dispose déjà d&#8217;une configuration transparente permettant d&#8217;obtenir toutes sortes d&#8217;informations, sans la complexité ni le coût d&#8217;une synchronisation complète ou d&#8217;une infrastructure de simulation. Dans un environnement administratif, un tel modèle de politique peut déjà répondre à de nombreux besoins sans jumeau numérique opérationnel, même si cela risque d&#8217;être décevant pour ceux qui aiment s’appuyer sur des mots à la mode.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Digital Twins in administratieve context</title>
		<link>https://www.smalsresearch.be/digital-twins-in-administratieve-context/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Tue, 19 May 2026 06:31:50 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Digital Twin]]></category>
		<category><![CDATA[Digitalisation]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<guid isPermaLink="false">https://www.smalsresearch.be/?p=26822</guid>

					<description><![CDATA[Digital Twin is een trendy buzzword. Maar kan het ook iets betekenen in een administratieve omgeving?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Cet article est aussi disponible&nbsp;<a href="https://www.smalsresearch.be/jumeaux-numeriques-dans-contexte-administratif/" data-type="link" data-id="https://www.smalsresearch.be/jumeaux-numeriques-dans-contexte-administratif/">en français</a>.</em></p>



<p class="wp-block-paragraph">Van het concept <em><a href="https://www.ibm.com/think/topics/digital-twin">Digital Twin</a></em> claimt <a href="https://ntrs.nasa.gov/citations/20210023699">de NASA</a> dat zij het als eersten toepasten. Om beter het gedrag te kunnen voorspellen van wat ze de ruimte in schoten, had men nood aan een kopie op aarde &#8211; niet alleen fysiek, maar ook digitaal. Sommige scenario&#8217;s zijn nu eenmaal moeilijk na te bootsen op aarde, maar moeten wel zo gedetailleerd mogelijk doorgerekend kunnen worden. Deze aanpak vond navolging in andere industrieën, zoals de luchtvaart, waar ontwerpfouten catastrofale gevolgen zouden kunnen hebben, of waar een <em>trial-and-error</em> methodiek te duur of praktisch onmogelijk zou zijn.</p>



<p class="wp-block-paragraph"><em>Digital Twin</em> verschijnt echter pas als onderwerp op de <a href="https://www.forbes.com/sites/gartnergroup/2016/10/26/gartners-top-10-strategic-technology-trends-for-2017/">radar van Gartner</a> eind 2016. Ook de <a href="https://en.wikipedia.org/wiki/Digital_twin">Wikipedia-pagina over het onderwerp</a> is een relatief recent gegeven, aangemaakt in 2015, veel later dan die over <a href="https://en.wikipedia.org/wiki/Virtual_reality">Virtual Reality</a> (2001) en <a href="https://en.wikipedia.org/wiki/Internet_of_things">Internet of Things</a> (2007). Het idee van <em>Digital Twin</em>s werd echter snel populair, daarbij geholpen door het Europese Horizon-2020 programma dat er brood in zag en verschillende projecten rond het thema financierde voor miljoenen euro&#8217;s (<a href="https://www.horizon-europe.gouv.fr/supporting-development-digital-twin-improve-management-operations-and-resilience-eu-electricity">[1]</a>, <a href="https://www.digitalurbantwins.com/">[2]</a>, <a href="https://www.imec.be/nl/vlaamse-innovatiemotor/impactdomeinen/smart-cities/precinct">[3]</a>, <a href="https://sphere-project.eu/">[4]</a>). Alvast in Vlaanderen heeft men die kans gretig gegrepen, met <a href="https://www.imec.be/nl/vlaamse-innovatiemotor/samenwerking/vlaamse-onderzoeksprogrammas/city-of-things">IMEC in een centrale rol</a>, bijgestaan door een enthousiast <a href="https://www.vlaanderen.be/digitaal-vlaanderen/digitaal-vlaanderen-zet-vaart-achter-europese-digital-twins-en-baant-zo-de-weg-naar-een-citiverse">Digitaal Vlaanderen</a>, en ook <a href="https://vito.be/en/research/digital-twins-in-health">VITO</a> is overtuigd.</p>



<p class="wp-block-paragraph">Marketinggewijs heeft de <em>Digital Twin</em> zijn waarde dus alvast bewezen. Maar kan het een concrete meerwaarde zijn voor publieke administraties? Ook daar worden workflows snel complex, kunnen wijzigingen duur zijn, en wil men misschien éen en ander kunnen simuleren alvorens het effectief te implementeren. In dit artikel onderzoeken we wat de <em>Digital Twin</em> kan betekenen in een administratieve context.  </p>



<h2 class="wp-block-heading">Definities</h2>



<p class="wp-block-paragraph">Er bestaan nogal wat verschillende interpretaties van <em>Digital Twin</em>. De essentie is alleszins niet nieuw: een systeem wordt digitaal weergegeven zodat het kan worden geobserveerd, getest en verbeterd zonder de daadwerkelijke werking direct aan te tasten. Het belangrijkste onderscheidende kenmerk is de continue (of in ieder geval regelmatige) <strong>synchronisatie </strong>tussen het reële systeem (de &#8216;doelentiteit&#8217; of <em>&#8216;target entity&#8217;</em>), en zijn digitale tegenhanger. De EU JRC adopteert een <a href="https://interoperable-europe.ec.europa.eu/sites/default/files/document/2020-06/ELISEWebinar_9_DigitalTwins.pdf">maturiteitsmodel</a> dat verschillende niveau&#8217;s van integratie onderscheidt; enkel in het geval van tweerichtings-datauitwisseling tussen target en twin wordt echt van een twin gesproken. Op internationaal vlak worden pogingen ondernomen tot <a href="https://www.iso.org/standard/81442.html">standaardisering van terminologie</a>.</p>



<figure class="wp-block-image aligncenter size-large"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model.png"><img loading="lazy" decoding="async" width="1024" height="643" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-1024x643.png" alt="" class="wp-image-29555" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-1024x643.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-300x189.png 300w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model-768x483.png 768w, https://www.smalsresearch.be/wp-content/uploads/2026/05/IET-Atkins-maturity-model.png 1071w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Digital Twin Maturity Spectrum. Bron: IET &amp; Atkins, &#8220;Digital Twins for the Built Environment&#8221;, 2019.</figcaption></figure>



<p class="wp-block-paragraph">Om nuttig te kunnen zijn moet een Digital Twin uitgewerkt zijn in voldoende detail. Al naargelang de toepassing zal het niveau van granulariteit of resolutie variëren. De twin moet de doelentiteit gedurende diens volledige <em>life cycle</em> getrouw kunnen weergeven, maar dat betekent niet dat elk detail tot in de puntjes gesimuleerd moet zijn. In de <a href="https://www.nature.com/articles/s41746-024-01073-0">medische sector</a> zien we digital twins opduiken op het niveau van de <a href="https://www.rfi.ac.uk/focus/projects/digital-twin-cell/">cel</a>, van het <a href="https://www.turing.ac.uk/science-innovation/health/cardiac-digital-twins">orgaan</a>, van een <a href="https://digital-strategy.ec.europa.eu/en/policies/virtual-human-twins">persoon</a> of van de <a href="https://pubmed.ncbi.nlm.nih.gov/40762974/">populatie</a>. Niets belet ook dat een Digital Twin slechts een onderdeeltje vormt van een groter systeem &#8211; het kan bijvoorbeeld alleen maar uitgewerkt zijn voor 1 kritische component. </p>



<p class="wp-block-paragraph">We kunnen twee stromingen van Digital Twins onderscheiden:</p>



<ul class="wp-block-list">
<li>Hoogwaardige technologische twins (luchtvaart, industrie, infrastructuur), waarbij de twin wordt gebruikt voor diagnostiek, voorspellend onderhoud of iteratief ontwerp op basis van operationele gegevens &#8211; bij <a href="https://ntrs.nasa.gov/api/citations/20210023699/downloads/ASME%20Digital%20Twin%20Summit%20Keynote_final.pdf">NASA</a>, voor <a href="https://initiatives.weforum.org/future-power-system/case-study-details/digital-twin-grid/aJYTG00000010pB4AQ">elektriciteitsdistributie</a>, &#8230; </li>



<li>Informatiesysteem- of socio-technische twins (steden, organisaties, dienstverlening), waarbij de doelentiteit niet zozeer een machine is maar eerder een complex systeem met meerdere belanghebbenden, bestaande uit processen, regels, mensen en gegevensstromen. Deze tweede stroom is waar de publieke sector in past, maar het is ook waar de <a href="https://interoperable-europe.ec.europa.eu/collection/elise-european-location-interoperability-solutions-e-government/glossary/term/digital-twin-government">definities vaag worden</a> en <em>Digital Twin</em> soms wordt gebruikt als <a href="https://eprintspublications.npl.co.uk/9880/">marketingterm voor &#8216;dashboard+model&#8217;</a>.</li>
</ul>



<p class="wp-block-paragraph">Waar beleidsmatig enige vaagheid misschien onvermijdelijk is, willen we in de praktijk toch een meer operationele interpretatie. We zouden een administratieve digital twin kunnen definiëren als: <strong>een continu geüpdatete, testbare, digitale representatie van de realiteit van de dienstverlening</strong>. Dit omvat processen, dossiers en de status waarin die zich bevinden, een uitvoerbaar systeem van de regels die van toepassing zijn, en alle dataverkeer dat nodig is om het geheel te doen werken. Dat moet toelaten de huidige realiteit van nabij te monitoren, en eventuele wijzigingen vooraf te simuleren voordat ze worden toegepast.</p>



<figure class="wp-block-image aligncenter size-full"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png"><img loading="lazy" decoding="async" width="603" height="211" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png" alt="" class="wp-image-29558" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49.png 603w, https://www.smalsresearch.be/wp-content/uploads/2026/05/2026-05-28_15h43_49-300x105.png 300w" sizes="auto, (max-width: 603px) 100vw, 603px" /></a><figcaption class="wp-element-caption">Concept van een Digital Twin (DT): data uit het doelsysteem + engine (= enabler) + applicaties (= usage). Bron: Oakes, Parsai, Van Mierlo, Demeyer, Denil, De Meulenaere, Vangheluwe, &#8220;Improving digital twin experience reports&#8221;, <a href="https://doi.org/10.5220/0010236101790190">DOI: 10.5220/0010236101790190</a></figcaption></figure>



<p class="wp-block-paragraph">Voor een industrieel proces gedreven door sensordata en de onveranderlijke wetten van de fysica, ligt dat gemakkelijker dan voor het overheidswezen, waar men vaak gevoelige gegevens verwerkt en afhangt van regelmatig wijzigende regels die ruimte laten voor interpretatie (zie ook onze eerder gepubliceerde artikels over <a href="https://www.smalsresearch.be/rules-as-code-nl/">Rules As Code</a>). Bezorgdheden rond <em>data governance</em> (<a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">GDPR</a> etc.) kunnen het moeilijk maken om synchronisatie met real-time gegevens op te zetten. Beslissingslogica is vaak nauw verweven met de code van applicaties, wat aanpassingen en  compliance checking bemoeilijkt. Het is daarom vaak al een hele prestatie als men in overheidscontext tot een <a href="https://en.wikipedia.org/wiki/Digital_twin_integration_level"><em>Digital Shadow</em></a> komt, die we ergens kunnen situeren tussen een &#8220;dom&#8221; model en een echte gesynchroniseerde twin.</p>



<h2 class="wp-block-heading">Toonaangevende projecten</h2>



<p class="wp-block-paragraph">In Europa gaan de opvallendste Digital Twin projecten overwegend over klimaat en wetenschap:</p>



<ul class="wp-block-list">
<li><a href="https://destination-earth.eu/">Destination Earth of DestinE</a> combineert grootschalige gegevens van <a href="https://www.eumetsat.int/">(weer)satellieten</a> en <a href="https://www.copernicus.eu/">Copernicus</a> in een <a href="https://destination-earth.eu/destination-earth/destines-components/destination-earth-data-lake/">data lake</a>. Op basis daarvan zagen 2 Digital Twins het licht: <a href="https://destine.ecmwf.int/climate-change-adaptation-digital-twin-climate-dt/">Climate Change Adaptation</a> (langetermijn) en <a href="https://destine.ecmwf.int/weather-induced-extremes-digital-twin/">Weather-induced Extremes</a> (kortetermijn). Daarvoor ontwikkelden ze hun eigen <a href="https://stories.ecmwf.int/the-digital-twin-engine/">Digital Twin Engine</a>. Het project wordt <a href="https://destination-earth.eu/news/destination-earth-moves-into-phase-three/">voortgezet</a>, waarbij men gemakkelijker &#8220;downstream applicaties&#8221; van externe gebruikers wil faciliteren die deelaspecten of specifieke onderzoeksvragen verder kunnen uitdiepen. Dat alles moet gedeeld worden via <a href="https://platform.destine.eu/">1 platform</a> gecoördineerd door <a href="https://www.esa.int/Applications/Observing_the_Earth/Destination_Earth">ESA</a>.</li>



<li>Het <a href="https://www.edito.eu/">EDITO</a> project probeert gelijkaardige doelstellingen te bereiken maar dan voor oceanen. Hiervoor wordt data van <a href="https://emodnet.ec.europa.eu/en">EMODnet</a> en <a href="https://marine.copernicus.eu/">Copernicus</a> samengebracht. Toegang verloopt via een <a href="https://datalab.dive.edito.eu/">Datalab</a> dat ook een reeks andere bouwblokken en services aanbiedt, en de applicaties die erop gebouwd worden kunnen een plaats krijgen op het <a href="https://dive.edito.eu/">digitaal platform</a> van het initiatief.</li>



<li><a href="https://www.intertwin.eu/use-cases">Verschillende use cases</a> worden ook opgelijst in het kader van het <a href="https://www.intertwin.eu/article/intertwin-has-ended-whats-next">recent afgelopen</a> (en Europees <a href="https://cordis.europa.eu/project/id/101058386">gefinancierde</a>) interTwin onderzoeksproject, dat een enigszins <a href="https://zenodo.org/records/10650440">gestandaardiseerde architectuur</a> met <a href="https://www.intertwin.eu/intertwin-digital-twin-engine">herbruikbare componenten</a> voor Digital Twins trachtte ontwikkelen. Zij benaderden het onderwerp eerder vanuit de wereld van het <a href="https://openlab.cern/intertwin/">CERN</a>, en onafhankelijk van de twee eerder vermelde initiatieven. Onderweg leerden ze wel van elkaars bestaan en werd een <a href="https://zenodo.org/records/16966835">mogelijke interoperabiliteit</a> met het <a href="https://www.esa.int/Applications/Observing_the_Earth/Destination_Earth">ESA-gelinkte DestinE</a> alvast onderzocht.</li>
</ul>



<figure class="wp-block-image aligncenter size-full"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg"><img loading="lazy" decoding="async" width="621" height="511" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg" alt="" class="wp-image-29560" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring.jpg 621w, https://www.smalsresearch.be/wp-content/uploads/2026/05/digital-twin-monitoring-300x247.jpg 300w" sizes="auto, (max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-element-caption">Gebruik van een digital twin voor monitoring. Bron: Davila Delgada &amp; Oyedele, &#8220;Digital Twins for the built environment: learning from conceptual and process models in manufacturing&#8221;, <a href="https://doi.org/10.1016/j.aei.2021.101332">DOI: 10.1016/j.aei.2021.101332</a></figcaption></figure>



<p class="wp-block-paragraph">In een administratieve context hebben we minder boodschap aan gegevens van satellieten of deeltjesversnellers. Omwille van de <em>governance</em>-vereisten komt de nadruk veeleer te liggen op correcte interoperabiliteit en data-uitwisseling, conform alle geldende wettelijke kaders. In dat opzicht zijn de nuttigste Europese initiatieven misschien nog de <a href="https://digital-strategy.ec.europa.eu/en/policies/data-spaces">Data Spaces</a> &#8211; voor een &#8220;policy twin&#8221; bijvoorbeeld de <a href="https://data.europa.eu/en/ELDS">Legal Data Space</a>. Er zijn ook raakvlakken met het idee van Regulatory Sandboxes zoals dat opduikt in o.a. de <a href="https://eur-lex.europa.eu/EN/legal-content/summary/interoperable-europe-act.html">Interoperable Europe Act</a> of recenter de <a href="https://www.europarl.europa.eu/RegData/etudes/BRIE/2022/733544/EPRS_BRI(2022)733544_EN.pdf">AI Act</a>: een administratieve digital twin kan de rol van zo&#8217;n sandbox vervullen als er goede mechanismen voor scenario-ontwikkeling en -evaluatie zijn.</p>



<h2 class="wp-block-heading">Administratieve Use Cases</h2>



<p class="wp-block-paragraph">Voordat we zelf aan de slag zouden gaan in complexe sectoren zoals gezondheidszorg en sociale zekerheid, moeten we ons toch afvragen of Digital Twins echt iets kunnen toevoegen aan wat vandaag al bestaat &#8211; want hype op zich draagt niets bij.</p>



<h3 class="wp-block-heading">Use Case 1&nbsp;: Simulatie van beleid en uitvoeringsimpact</h3>



<p class="wp-block-paragraph">Inzake policy modeling voor sociale zekerheid, is er bijvoorbeeld al een sterke basis met het <a href="https://joint-research-centre.ec.europa.eu/euromod_en">EUROMOD</a> microsimulatie model, waarvan de Belgische variant <a href="https://socialsecurity.belgium.be/nl/sociaal-beleid-mee-vorm-geven/impact-assessment-research/belmod">BELMOD</a> heet. Dit zijn statische microsimulaties waarbij gegevens op fijnmazig niveau worden gecombineerd met gecodeerde regels zodat het mogelijk wordt om hervormingen aan de parameters van de sociale zekerheid te simuleren (bijdragen, uitkeringen, etc.). Zulke studies worden typisch uitgevoerd aan <a href="https://cape-saintlouis.be/">universiteiten</a>, men kan een idee krijgen van wat dat inhoudt via <a href="https://euromod-web.jrc.ec.europa.eu/euromod-online/">EUROMOD Online</a>.</p>



<p class="wp-block-paragraph">In zekere zin komt dit type model al in de buurt van een digital twin voor sociaal beleid, maar het mist nog twee cruciale lagen: </p>



<ul class="wp-block-list">
<li>actuele/live koppelingen met administratieve gegevens: hiermee kan men dan budgettaire en verdelingseffecten simuleren op de situatie van vandaag, in plaats van op verouderde data van enkele jaren geleden. </li>



<li>procesinformatie over de dienstverlening (doorlooptijden van dossiers, behandelingscapaciteit etc): dit zou toelaten ook de operationele impact van hervormingen op de uitvoerende diensten in te schatten.</li>
</ul>



<p class="wp-block-paragraph">Het zou allerminst eenvoudig zijn om dat toe te voegen: de gegevens in kwestie zijn zeer gevoelig van aard. De echte data gebruiken als real-time databron voor simulaties zou al zeker verregaande anonymisering vereisen (voortvloeiend uit de GDPR), naast een resem andere <a href="https://www.ksz-bcss.fgov.be/nl/page/ivc-in-het-kort">veiligheidsmaatregelen</a>. Dat is een complexe oefening op zich, waarbij mogelijk ook nuttige informatie verloren gaat.</p>



<p class="wp-block-paragraph">De status van een persoon binnen de sociale zekerheid wordt daarenboven bepaald door een opeenvolging van gebeurtenissen die lang kunnen doorwerken en met elkaar interageren (werk, ontslag, ziekte, ongeval, pensioen, geboorte van een kind, &#8230;). Om echt waardevol te kunnen zijn zou een twin de hele weg moeten kunnen modelleren die een individu aflegt in het systeem. Niet alleen de individuele status, maar ook die van dossiers (worden er deadlines gemist) en administratie (is er behandelingsachterstand) evolueert doorheen de tijd. </p>



<p class="wp-block-paragraph">Als er vandaag al een goede <em>digital shadow</em> beschikbaar is van een dienst, dan kan met de toevoeging van evolutieve gegevens over werklastverdeling, capaciteit, dossiervoortgang, &#8230; een volgende stap gezet worden, zoals de simulatie van dossierdoorstroming. Zulke selectieve simulaties kunnen dienen voor tegenfeitelijke (&#8220;wat-als&#8221;) analyses die de impact van verandering (organisatorisch, of in de regelgeving) beter in te schatten maakt. Andersom kan men zoiets ook zien als een framework voor regressietesten: berekeningen op representatieve steekproeven kunnen herhaald worden telkens iets wijzigt, om na te gaan waar de grootste impact ligt.</p>



<h3 class="wp-block-heading">Use Case 2&nbsp;: Organisatorische planning in de gezondheidszorg</h3>



<p class="wp-block-paragraph">De administratie van de gezondheidszorg kent andere prioriteiten: opvolging van patiënten en consultaties is tijdskritisch, de toekenning van mensen en middelen is een complexe planningspuzzel, allerlei terugbetalingen en verzekeringen, &#8230; Om daarin richting Digital Twin te evolueren kan er een grote rol weggelegd zijn voor de <a href="https://www.ehealth.fgov.be/nl/page/ehds-european-health-data-space---de-europese-verordening-betreffende-de-europese-ruimte-voor-gezondheidsgegevens">European Health Data Spaces</a>, en voor nieuwe oplossingen die men momenteel tracht uit te denken voor <a href="https://tehdas.eu/">secundair gebruik van gezondheidsdata</a>. </p>



<p class="wp-block-paragraph">We staan nog ver van de droom van individueel geoptimaliseerde gezondheidszorg op basis van een <a href="https://digital-strategy.ec.europa.eu/en/policies/virtual-human-twins">persoonlijke digital twin van een patiënt</a> &#8211; idee dat trouwens ook gepaard gaat met heel wat <a href="https://zenodo.org/records/14516807">niet triviale</a> <a href="https://www.frontiersin.org/journals/genetics/articles/10.3389/fgene.2018.00031/full">risico&#8217;s inzake ethiek en privacy</a>. Op kortere termijn liggen de mogelijkheden eerder op niveau van de organisatie. Met gegevens over opnames, wachtlijsten, personeelsinzet en activiteit, toegevoegd aan een bestaande <em>digital shadow</em>, kunnen strategische en operationele wijzigingen mogelijk beter opgevangen worden.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><a href="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg"><img loading="lazy" decoding="async" width="800" height="383" src="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg" alt="" class="wp-image-29564" style="width:800px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks.jpg 800w, https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks-300x144.jpg 300w, https://www.smalsresearch.be/wp-content/uploads/2026/05/immunology-digital-twin-building-blocks-768x368.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-element-caption">De talrijke aspecten van een digital twin, hier voor immunologie. Bron: Niarakis et.al., &#8220;Immune digital twins for complex human pathologies: applications, limitations, and challenges&#8221;, <a href="https://doi.org/10.1038/s41540-024-00450-5" target="_blank" rel="noreferrer noopener">DOI: 10.1038/s41540-024-00450-5</a></figcaption></figure>



<h2 class="wp-block-heading">Implementatie: een kostelijke affaire?</h2>



<p class="wp-block-paragraph">Om de focus te behouden op wat vandaag of op korte termijn mogelijk is, kunnen administraties zich inspireren op &#8220;reference stacks&#8221; van technologische componenten, die uitgebouwd zijn in het kader van bestaande digital twins. Enkele daarvan haalden we reeds eerder aan en herhalen we hier niet. </p>



<p class="wp-block-paragraph">Een Digital Twin moet een representatie kunnen bevatten van de huidige staat van een systeem, en moet gebeurtenissen kunnen verwerken die daarop een impact hebben. In het kader van de Europese <a href="https://www.fiware.org/">FIWARE</a> initiatieven (Future Internet) werd daarvoor door een werkgroep Context Information Management bij ETSI de <a href="https://ngsi-ld.org/">NSGI-LD</a> standaard en <a href="https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.09.01_60/gs_CIM009v010901p.pdf">API</a> ontwikkeld. Het lijkt er echter op dat er <a href="https://en.wikipedia.org/wiki/NGSI-LD#Uses">nog niet veel adoptie</a> is van deze standaard buiten het <a href="https://www.fiware.org/about-us/smart-industry/">eigen netwerk</a> van voornamelijk Smart City en IoT-initiatieven.</p>



<p class="wp-block-paragraph">Administratieve systemen bestaan niet louter uit beslissingen. De processen omvatten interactie, documenten, en soms ook enige beoordelingsvrijheid. Open standaarden uit de business process management wereld komen hier van pas. <a href="https://www.omg.org/dmn/">DMN (decision modeling)</a>, <a href="https://www.omg.org/bpmn/">BPMN (business processes)</a> en <a href="https://www.omg.org/cmmn/">CMMN (case management)</a> zijn complementair aan elkaar en laten het modelleren van deze aspecten toe. Op deze initiatieven verschijnen ook uitbreidingen, zoals het aan de KULeuven ontwikkelde <a href="https://cdmn.readthedocs.io/">Constraint DMN (cDMN)</a> dat complexere logica toelaat. Een Digital Twin kunnen we dan samenstellen uit een DMN beslissingsmotor die berekent &#8220;wat de regels zeggen&#8221; (hier kan Rules As Code eventueel een plaats krijgen), verrijkt met lagen die de processen en caseflow voor hun rekening nemen (status, deadlines, ondersteunende documenten), en tot slot een regelmatige synchronisatie om de operationele status (of context) te kunnen updaten. Dit is compatibel met het <a href="https://interoperable-europe.ec.europa.eu/sites/default/files/document/2020-06/ELISEWebinar_9_DigitalTwins.pdf">JRC maturiteitsmodel</a> (model -&gt; schaduw -&gt; twin).</p>



<p class="wp-block-paragraph">Digital Twins zijn niet duur omdat ze veel visualisatie bevatten of rapporteringsmogelijkheden ingebouwd hebben. Ze zijn duur omdat ze een duplicaat vormen van het doelsysteem, dat net zoals het origineel, doorheen de tijd correct moet blijven werken. Om <a href="https://eprintspublications.npl.co.uk/9880/">meer te zijn dan enkel hype</a>, is constante investering in onderhoud nodig. Die recurrente kosten omvatten ten minste het volgende:</p>



<ul class="wp-block-list">
<li>monitoring en validatie: een digital twin moet elke verandering aan het doelsysteem zo accuraat mogelijk volgen, dit vraagt regelmatige updates,</li>



<li>onderhoud van de regels en traceerbaarheid: zeker wanneer regels vaak wijzigen is dit een grote kost. Hier spelen versionering, test suites en veranderingsmanagement een rol, </li>



<li>functioneren van data pipelines en interoperabiliteit: omvat ook semantiek, toegangscontrole, <a href="https://www.intertwin.eu/ker-4-quality-framework">datakwaliteit, accuraatheid</a> en beveiliging,</li>



<li>privacy en compliance: onontbeerlijk, zeker voor systemen die persoonsgegevens verwerken (gezondheid, inkomen, familie)</li>
</ul>



<p class="wp-block-paragraph">Voor een administratieve use case is de beste eerste stap daarom een stelselmatige uitbouw van wat we een <em>privacy-aware digital shadow </em>zouden kunnen noemen: initieel beperkt tot monitoring + replay functionaliteit, met strikte toegangscontrole en <a href="https://www.edpb.europa.eu/sme-data-protection-guide/data-protection-basics_nl">dataminimalisatie</a>. Daarna kan gedacht worden aan uitbreiding met simulaties op geanonimiseerde of synthetische datasets. Eventuele near-real-time synchronisatie met gegevens uit het echte doelsysteem, om een echte Digital Twin te vormen, kan pas op het einde volgen, en heeft vaak nogal wat voeten in de aarde.</p>



<h2 class="wp-block-heading">Conclusie</h2>



<p class="wp-block-paragraph">Is een Digital Twin het juiste type oplossing, of kan het ook eenvoudiger? Samengevat zijn Digital Twins pas te overwegen als al het volgende waar is (anders kan een andere aanpak efficiënter zijn en beter aansluiten):</p>



<ul class="wp-block-list">
<li>Het doelsysteem dat gemodelleerd wordt is dynamisch: uitkomsten hangen af van evoluerende situaties (caseflow, wachtrijen, levenscyclus van gebeurtenissen), niet enkel van <em>eligibility checks</em> of formulieren.</li>



<li>Je kan referentiedatabronnen identificeren en doorlopende synchronisatie volhouden. Zonder regelmatige updates met operationele data, bouw je een model en geen twin.</li>



<li>Simulaties leiden tot echte beslissingen. Als de organisatie niet voldoende vrijheid heeft om in te grijpen (beleid veranderen, caseflow wijzigen, prioritisering, personeelstaken, &#8230;), zal een reeks dashboards waarschijnlijk volstaan.</li>



<li>Er is een geloofwaardig plan voor audit en permanente kwaliteitsbewaking. Dit mag niet achteraf komen maar moet een acceptatiecriterium zijn. Het heeft geen zin een twin te bouwen die sneller rot dan het doelsysteem.</li>



<li>De wettelijke/compliance omgeving is compatibel. Als er persoonsgegevens aan te pas komen kunnen GDPR en AI Act verplichtingen met zich meebrengen die de haalbaarheid en de kostprijs erg beïnvloeden. Dat kan een Twin limiteren tot een veredeld testsysteem in plaats van een echte bijdrage tot operationele automatisering te leveren.</li>
</ul>



<p class="wp-block-paragraph">Een niet-Twin kan ook waardevol zijn &#8211; met gecodeerde regels + <a href="https://en.wikipedia.org/wiki/Test_harness">testharnas</a> + monitoring heb je ook al een transparante setup waarmee allerlei inzichten verworven kunnen worden, zonder de complexiteit en kost van volledige synchronisatie of simulatie-infrastructuur. In een administratieve omgeving kan zulk <em>policy model </em>al veel noden lenigen zonder operationele digital twin, al zal dat misschien teleurstellend zijn voor wie graag uitpakt met trendy buzzwords.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rules as Code&#160;: leçons tirées d&#8217;une expérience</title>
		<link>https://www.smalsresearch.be/rules-as-code-partie2-fr/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Sat, 31 Jan 2026 19:35:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[AI4GOV]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[Society]]></category>
		<guid isPermaLink="false">/?p=26114</guid>

					<description><![CDATA[Que se passe-t-il lorsqu'on s'attaque à un projet de Rules As Code avec un EDI basé sur l'IA ?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Dit artikel is ook beschikbaar&nbsp;<a href="/rules-as-code-deel2-nl/" data-type="post" data-id="22734">in het Nederlands</a>.</em></p>



<p class="wp-block-paragraph"><a href="/rules-as-code-fr/">Dans un article précédent</a>, nous avons examiné <a href="https://interoperable-europe.ec.europa.eu/collection/govtechconnect/news/rules-code-rac">Rules as Code</a>, une approche visant à réduire l&#8217;écart entre les réglementations et les logiciels. Nous avons illustré qu&#8217;il existe de nombreux obstacles pratiques à surmonter, malgré l&#8217;objectif louable. L&#8217;encodage uniforme des règles avec leur historique, leurs interdépendances et leurs dépendances est un défi qui peut nécessiter un investissement considérable en termes de personnel et de ressources. De plus, une gestion active permanente est nécessaire pour prendre en compte chaque modification apportée aux règles. Même à petite échelle, une collaboration étroite entre juristes et développeurs est indispensable, car des décisions motivées devront régulièrement être prises en matière d&#8217;interprétation. En l&#8217;absence de normes industrielles et alors que les meilleures pratiques sont encore en cours d&#8217;élaboration, les <em>early adopters</em> risquent de devoir payer la <a href="https://terryu.substack.com/p/bridging-the-gap-between-early-and">pioneer tax</a>. La complexité des compétences gouvernementales ne facilite pas une éventuelle application en Belgique.</p>



<p class="wp-block-paragraph">Partiellement sous l&#8217;impulsion du <a href="https://www.oecd.org/en/publications/cracking-the-code_3afe6ba5-en.html">rapport détaillé de l&#8217;OCDE de 2020</a>, certaines administrations se sont déjà pleinement engagées dans l&#8217;élaboration de proof-of-concepts, parfois à grande échelle. Il existe donc aujourd&#8217;hui plusieurs cadres relativement matures. La France est sans aucun doute le pays pionnier&nbsp;; l&#8217;initiative que nous allons présenter ci-dessous vient de France. Les <a href="https://regels.overheid.nl/">Pays-Bas</a> ne sont pas en reste&nbsp;: l&#8217;administration fiscale néerlandaise utilise depuis un certain temps déjà son propre langage de domaine, <a href="https://regels.overheid.nl/docs/methods/REGELSPRAAK">RegelSpraak</a>, qu&#8217;elle interprète et traite à l&#8217;aide du <em>rule engine</em> <a href="https://regels.overheid.nl/docs/methods/ALEF">ALEF</a>. Cependant, le <a href="https://gitlab.com/normativesystems">code source publié</a> à ce sujet semble pour l&#8217;instant se concentrer davantage sur la méthodologie que sur les applications.</p>



<h1 class="wp-block-heading">OpenFisca</h1>



<p class="wp-block-paragraph">OpenFisca <a href="https://openfisca.org/en/about/">a vu le jour en 2011 </a>en tant que moteur de <a href="https://en.wikipedia.org/wiki/Microsimulation">microsimulation</a> open source permettant de convertir les règles fiscales et sociales (&#8220;tax &amp; benefit system&#8221;) en code exécutable. Les effets de cette réglementation, et les éventuelles modifications, peuvent alors être simulés tant pour des cas individuels que pour des populations entières. Parmi les sites web utilisant OpenFisca en arrière-plan, on peut citer <a href="https://leximpact.an.fr/">LexImpact</a> (simulation des modifications de la législation socio-fiscale), <a href="https://www.mesdroitssociaux.gouv.fr/">Mes droits sociaux</a> (simulation des droits sociaux) et <a href="https://mes-aides.1jeune1solution.beta.gouv.fr/">1jeune1solution</a> (mesures de soutien diverses). Parmi les exemples étrangers, citons <a href="https://benefitme.nz/">BenefitMe</a> (Nouvelle-Zélande), <a href="https://lesmevesajudes.barcelona.cat/">Les meves ajudes</a> (Barcelone) ou <a href="https://www.policyengine.org/">PolicyEngine</a> (Royaume-Uni/États-Unis) – ces derniers ayant toutefois nécessité des <a href="https://github.com/PolicyEngine">modifications importantes</a> du moteur.</p>



<p class="wp-block-paragraph">Afin de modéliser notre propre système fiscal et/ou de sécurité sociale, nous devons créer une <em>fourche </em>du <a href="https://github.com/openfisca/country-template">Template country OpenFisca</a> générique. Plusieurs autres pays ont déjà expérimenté cette approche, comme le Sénégal, le Paraguay et la Tunisie, qui figurent dans la <a href="https://github.com/orgs/openfisca/repositories">liste des repositories</a>. La législation régionale ou locale peut être ajoutée grâce à <a href="https://openfisca.org/doc/contribute/extensions.html">des extensions plugin</a>à un système national, comme <a href="https://github.com/openfisca/openfisca-paris">celui de Paris</a>. Une fois le repository initialisé, nous pouvons commencer à travailler sur ce qui pourrait un jour devenir <em>openfisca-belgium</em>. La modélisation dans OpenFisca se fait en écrivant des classes et des méthodes Python, qui représentent les entités, les variables et les formules de calcul issues de la réglementation.</p>



<p class="wp-block-paragraph">Malheureusement, c&#8217;est à peu près là que s&#8217;arrête la partie facile. Le repository du country template est minimaliste et, bien qu&#8217;il existe une <a href="https://openfisca.org/doc/index.html">documentation</a> avec un petit tutoriel pour créer sa propre version, celle-ci se concentre principalement sur les premières étapes. Les directives sur la manière de structurer au mieux notre propre fourche dès que le nombre de variables et de paramètres augmente font largement défaut. Le repository du projet parent <a href="https://github.com/openfisca/openfisca-france/tree/master">openfisca-france</a> peut certes servir d&#8217;exemple, mais il est très volumineux et ne permet pas vraiment de comprendre les raisons de leurs choix structurels ou architecturaux.</p>



<p class="wp-block-paragraph">L&#8217;aspect d&#8217;une GUI ou d&#8217;une interface web reste également sous-estimé. Pourtant, l&#8217;interface de <a href="https://socio-fiscal.leximpact.an.fr/?parameters=irpp_economique&amp;waterfall=brut_to_disponible">LexImpact simulator pour l&#8217;impôt sur le revenu en France</a>, par exemple, est justement un point fort. Comme guide pour la construction d&#8217;une interface web, on se réfère à <a href="https://github.com/redte-ch/ReDistributeMe/tree/main">tutoriels et slides d&#8217;un workshop</a>, où les premières étapes sont présentées dans <a href="https://svelte.dev/">Svelte</a>, <a href="https://react.dev/">React</a> et <a href="https://vuejs.org/">VueJS</a>. Cependant, le fait qu&#8217;une GUI ou une application web doive encore être construite <em>from scratch</em> en plus d&#8217;une instance OpenFisca propre constitue un obstacle supplémentaire à l&#8217;adoption. La construction d&#8217;une GUI est en effet chronophage. Il serait utile de disposer de bibliothèques OpenFisca-GUI avec des composants réutilisables pour les principaux frameworks web, afin qu&#8217;un serveur OpenFisca puisse éventuellement être associé à une interface web générique par défaut. Un <a href="https://www.drupal.org/project/webform_openfisca">plugin Drupal</a> semble actuellement être le seul à aller quelque peu dans cette direction.</p>



<h1 class="wp-block-heading">L&#8217;IA à la rescousse&nbsp;?</h1>



<p class="wp-block-paragraph">Étant donné qu&#8217;OpenFisca, Svelte, React et Vue sont tous nouveaux pour l&#8217;auteur, et que les outils d&#8217;IA promettent d&#8217;accélérer l&#8217;intégration des développeurs, nous saisissons l&#8217;occasion pour tester simultanément l&#8217;IDE <a href="https://cursor.com/download">Cursor</a> alimenté par l&#8217;IA. Ce clone de <a href="https://code.visualstudio.com/">Visual Studio Code</a> est enrichi de la possibilité d&#8217;appeler des LLM (dans notre cas, basés sur le cloud public). De plus, des sélections issues de fichiers du projet peuvent être marquées comme contexte pour la question. Cursor peut fournir des <a href="https://cursor.com/docs">suggestions</a> d&#8217;ajouts ou de modifications à apporter aux fichiers qui, une fois approuvées, peuvent être directement intégrées dans la base de code.</p>



<p class="wp-block-paragraph">Interagir avec des modèles d&#8217;IA <a href="https://news.stanford.edu/stories/2025/10/ai-chatbot-privacy-concerns-risks-research">comporte des risques pour la confidentialité</a>. Cette expérience est principalement possible car nous travaillons avec du code open source, des réglementations publiées et leur documentation également publique, qui ne sont pas sensibles. Cependant, étant donné que tout ce qui se trouve dans l&#8217;IDE peut être envoyé au modèle de langage, nous devons toujours veiller à ne pas ouvrir dans l&#8217;IDE des fichiers contenant des identifiants, des clés API ou des informations personnelles. Cela reste la responsabilité de chaque développeur. Dans tous les cas, il est recommandé d&#8217;être prêt à faire tourner les clés API ou les credentials, car dans le feu de l&#8217;action d&#8217;un debugging, il est facile de partager trop d&#8217;informations avec un LLM.</p>



<p class="wp-block-paragraph">Enfin, il convient de mentionner que cette expérience a été réalisée avec les versions 1.6 et 1.7 de Cursor en septembre-octobre 2025, avec le modèle de langage sous-jacent GPT-4.5 d&#8217;OpenAI, puis GPT-5.0, utilisé avec une clé API dédiée (et non via Cursor). Les versions ultérieures disposent de nombreuses fonctionnalités plus récentes (notamment des workflows <em>agentic</em>) et il est possible que l&#8217;expérience soit aujourd&#8217;hui (janvier 2026) très différente. Cependant, les principaux enseignements restent généralement valables pour tout développement alimenté par l&#8217;IA, que ce soit via IDE, ligne de commande ou les deux (par exemple, Anthropic <a href="https://code.claude.com/docs/en/overview">Claude Code</a>).</p>



<p class="wp-block-paragraph">Dans un premier temps, nous ajoutons la documentation nécessaire à notre projet. Nous prenons comme exemple la <a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=2002052647&amp;caller=eli&amp;&amp;view_numac=2002052647nl">loi du 26 mai 2002 concernant le droit à l&#8217;intégration sociale</a>. Avec tous les autres arrêtés royaux, lois et circulaires pertinents, elle est clairement répertoriée sur le site web du <a href="https://www.mi-is.be/fr/reglementations">SPP Intégration sociale</a>. Afin de faciliter la recherche et l&#8217;interprétation du texte pour un LLM dans un IDE, nous l&#8217;enregistrons sous forme de fichier texte plat sans mise en forme, que nous ajoutons à un nouveau dossier contenant les sources pertinentes dans l&#8217;arborescence source du projet. Nous ne pouvons que supposer que cette approche est optimale, mais il faut bien commencer quelque part.</p>



<h2 class="wp-block-heading">Entités</h2>



<p class="wp-block-paragraph">Les entités dans OpenFisca indiquent pour qui nous effectuons le calcul. Il peut s&#8217;agir d&#8217;individus, de familles ou d&#8217;autres groupes de personnes (entreprises, organisations, etc.). Ce sont les fondements sur lesquels nous pourrons ensuite spécifier des variables qui, ensemble, formeront une &#8220;situation&#8221; pour laquelle nous pourrons effectuer un calcul.&nbsp;Les entités <em>Person</em> et <em>Household</em> sont déjà présentes <a href="https://github.com/openfisca/country-template/blob/main/openfisca_country_template/entities.py">dans le code</a>. Une question logique se pose donc&nbsp;: sur la base du texte de loi donné, pouvons-nous définir d&#8217;autres entités qui seraient utiles&nbsp;?</p>



<p class="wp-block-paragraph">Après avoir posé la question à GPT-5 dans Cursor, avec le texte de loi sélectionné comme contexte, il nous est proposé d&#8217;ajouter les entités suivantes&nbsp;:</p>



<ul class="wp-block-list">
<li>Eligible Person for Societal Integration</li>



<li>Living Wage Recipient</li>



<li>Employment Project Participant</li>
</ul>



<p class="wp-block-paragraph">Les modifications proposées au code sont syntaxiquement correctes. Cependant, aucune de ces trois modifications n&#8217;est utile ou nécessaire&nbsp;: dans les trois cas, il s&#8217;agit de variantes de<em> Person</em>. Les propriétés qui leur permettraient, par exemple, de percevoir un revenu d&#8217;intégration sont plutôt des variables ajoutées à l&#8217;entité <em>Person</em> déjà existante. La valeur de ces variables dépend en outre d&#8217;autres variables également liées à ce même individu, telles que les revenus du travail ou le statut d&#8217;invalidité. Les entités, qui servent principalement à des concepts autonomes, ne sont pas le bon choix dans ce cas.&nbsp;</p>



<p class="wp-block-paragraph">En outre, GPT-5 semble avoir mal interprété le concept de &#8220;rôle&#8221; au sein d&#8217;une entité de groupe OpenFisca. Il tente de construire &#8220;Eligible Person for Societal Integration&#8221; avec différents &#8220;rôles&#8221; comme composants&nbsp;: &#8220;Belgian National&#8221;, &#8220;EU Citizen&#8221;, &#8220;Foreigner&#8221;, &#8220;Stateless&#8221;, &#8220;Refugee&#8221;&#8230; Sans doute parce que ces possibilités apparaissent à l&#8217;<a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=2002052647&amp;caller=eli&amp;&amp;view_numac=2002052647nl#Art.3">Art.3, 3°, de la loi</a>. Dans OpenFisca, cependant, une entité de groupe est composée de personnes qui se voient chacune attribuer un rôle. Un <em>Household</em> comprend ainsi des rôles <em>Adult</em> et <em>Child</em>. Il est assez absurde qu&#8217;une <em>EligiblePerson</em> puisse comprendre plusieurs <em>Foreigners</em>. La nationalité ou l&#8217;origine, ou d&#8217;autres conditions fixées dans cette loi, sont également ici des variables liées à la personne, et non à une entité en soi.&nbsp;</p>



<p class="wp-block-paragraph">À un autre moment, une entité distincte a été créée pour le CPAS. Bien qu&#8217;il semble logique de modéliser les CPAS et de les considérer comme une entité – ils sont en effet mentionnés dans la loi –, ce n&#8217;est pas (encore) le cas ici. Il n&#8217;existe en effet pas différents types de CPAS avec des caractéristiques ou des rôles différents, pour lesquels nous devrions effectuer des calculs différents à chaque fois. Dans le contexte de cette loi, où c&#8217;est le citoyen pour lequel nous calculons le droit à l&#8217;aide sociale, le CPAS est avant tout une donnée constante et invariable. Dans OpenFisca, nous pouvons donc pour l&#8217;instant ignorer cet aspect. (Un type d&#8217;entité &#8220;institut&#8221; n&#8217;est pas non plus prévu.)&nbsp;</p>



<p class="wp-block-paragraph">Nous constatons ici que Cursor ne peut pas répondre &#8220;non&#8221; à la question de savoir si d&#8217;autres entités utiles peuvent être ajoutées. Il ne peut pas critiquer ou corriger de son propre chef le raisonnement qui sous-tend cette question. Tout au long de l&#8217;expérience, Cursor et GPT-5 ont également montré une tendance à la complexité inutile. Cela représente un risque important pour les développeurs qui travaillent avec du code ou des frameworks inconnus&nbsp;: si l&#8217;on suit trop rapidement ces suggestions, on risque de perdre le contrôle par la suite et de devoir apporter des corrections très difficiles aux fondements du projet. Une fois qu&#8217;une mauvaise voie a été empruntée, il s&#8217;avère également difficile de revenir en arrière et de faire oublier ces étapes. Surtout si on les a d&#8217;abord acceptées par ignorance, elles s&#8217;inscrivent dans le contexte et sont reprises dans les questions suivantes. Ce <a href="https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html">&#8220;context rot&#8221;</a> insidieux est désormais un problème bien connu et une cause importante de perte de temps avec le <em>AI enabled coding</em>.</p>



<h2 class="wp-block-heading">Variables</h2>



<p class="wp-block-paragraph">Le cœur du modèle réside dans les variables qui représentent les droits et les conditions prévus par la loi.&nbsp;L&#8217;<a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=2002052647&amp;caller=eli&amp;&amp;view_numac=2002052647nl#Art.2">article 2</a> de la loi énumère les différentes formes d&#8217;intégration sociale auxquelles une personne peut avoir droit (notamment l&#8217;emploi, le revenu d&#8217;intégration, le projet individualisé).&nbsp;L&#8217;<a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=2002052647&amp;caller=eli&amp;&amp;view_numac=2002052647nl#Art.2">article 3</a> contient les conditions qu&#8217;une personne doit remplir pour exercer ce droit. Nous avons transposé ces dispositions étape par étape dans le code.</p>



<p class="wp-block-paragraph">Dans la pratique, le droit à l&#8217;intégration sociale signifie qu&#8217;un CPAS doit soutenir une personne par le biais (1) d&#8217;un emploi ou d&#8217;une formation, (2) d&#8217;un revenu d&#8217;intégration, ou (3) d&#8217;un projet individualisé d&#8217;intégration sociale. Cela peut se traduire par trois variables booléennes sur l&#8217;entité Personne, par exemple <code>employment_right</code>, <code>living_wage_right</code> et <code>individualized_project_right</code>. Cursor fournit ici une suggestion de code pertinente et propose une formule <em>placeholder</em> simple&nbsp;: tant qu&#8217;une personne &#8220;est éligible à l&#8217;intégration&#8221; (une autre variable), le droit s&#8217;applique. Nous obtenons ainsi la définition suivante de<em> </em><code>employment_right</code>&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class employment_right(Variable):
  value_type = bool
  entity = Person
  definition_period = MONTH
  def formula(person, period, parameters):
    return person("eligible_for_integration", period)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">employment_right</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">Variable</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">  value_type = </span><span style="color: #4EC9B0">bool</span></span>
<span class="line"><span style="color: #D4D4D4">  entity = Person</span></span>
<span class="line"><span style="color: #D4D4D4">  definition_period = MONTH</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">def</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">formula</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">person</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">period</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">parameters</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> person(</span><span style="color: #CE9178">&quot;eligible_for_integration&quot;</span><span style="color: #D4D4D4">, period)</span></span></code></pre></div>



<p class="wp-block-paragraph">Le contenu de cette formule <em>placeholder </em>est abordé dans l&#8217;article 3 ci-dessous. Celui-ci modélise les conditions suivantes pour être éligible&nbsp;:</p>



<ul class="wp-block-list">
<li><strong>Séjour en Belgique </strong>(selon les règles à déterminer par arrêté royal).</li>



<li><strong>Âge</strong>&nbsp;: la personne est<strong> majeure</strong> (18 ans et plus) ou, si elle est mineure, <strong>assimilée </strong>à une personne majeure selon les exceptions prévues par la présente loi.</li>



<li><strong>Nationalité ou statut de séjour&nbsp;</strong>: la personne est belge, citoyenne de l&#8217;UE (après 3 mois de séjour), étrangère enregistrée, apatride, réfugiée ou bénéficiaire d&#8217;une protection subsidiaire.</li>



<li><strong>Ressources insuffisantes</strong></li>



<li><strong>Disposition à travailler</strong> (sauf si cela est impossible pour des raisons de santé ou d&#8217;équité).</li>



<li><strong>Épuisement des droits issus d&#8217;autres régimes</strong></li>
</ul>



<p class="wp-block-paragraph">Toutes ces conditions sont regroupées dans une variable booléenne centrale <code>societal_integration_right</code>. Cette variable indique si une personne, compte tenu de sa situation personnelle, <strong>peut</strong> prétendre à l&#8217;intégration sociale. En fait, il s&#8217;agit de la traduction de <em>&#8220;la personne remplit-elle toutes les conditions de l&#8217;article 3&nbsp;?</em>&#8220;. La formule combine toutes les sous-conditions&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class societal_integration_right(Variable):
  value_type = bool
  entity = Person
  definition_period = MONTH
  label = "Right to societal integration"
  def formula(person, period, parameters):
    residency = person("residency_status", period)
    is_major = person("is_major", period)
    nationality = person("nationality_status", period) in &#91;"belgian", "eu_citizen", "registered_foreigner", "stateless", "refugee"&#93;
    insufficient_income = not person("has_sufficient_income", period)
    willing_to_work = person("willing_to_work", period)
    claiming_benefits = person("claiming_benefits", period)
    return (residency and is_major and nationality and insufficient_income and willing_to_work and claiming_benefits)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">societal_integration_right</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">Variable</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">  value_type = </span><span style="color: #4EC9B0">bool</span></span>
<span class="line"><span style="color: #D4D4D4">  entity = Person</span></span>
<span class="line"><span style="color: #D4D4D4">  definition_period = MONTH</span></span>
<span class="line"><span style="color: #D4D4D4">  label = </span><span style="color: #CE9178">&quot;Right to societal integration&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">def</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">formula</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">person</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">period</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">parameters</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">    residency = person(</span><span style="color: #CE9178">&quot;residency_status&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    is_major = person(</span><span style="color: #CE9178">&quot;is_major&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    nationality = person(</span><span style="color: #CE9178">&quot;nationality_status&quot;</span><span style="color: #D4D4D4">, period) </span><span style="color: #569CD6">in</span><span style="color: #D4D4D4"> &#91;</span><span style="color: #CE9178">&quot;belgian&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;eu_citizen&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;registered_foreigner&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;stateless&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;refugee&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    insufficient_income = </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> person(</span><span style="color: #CE9178">&quot;has_sufficient_income&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    willing_to_work = person(</span><span style="color: #CE9178">&quot;willing_to_work&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    claiming_benefits = person(</span><span style="color: #CE9178">&quot;claiming_benefits&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> (residency </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> is_major </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> nationality </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> insufficient_income </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> willing_to_work </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> claiming_benefits)</span></span></code></pre></div>



<p class="wp-block-paragraph">Notons ici quelques lacunes étranges dans la suggestion de Cursor. Ainsi, le nom de la variable <code>societal_integration_right</code> n&#8217;est pas identique au placeholder <code>eligible_for_integration</code> défini précédemment, alors que c&#8217;était pourtant l&#8217;intention. En outre, la condition de nationalité omet tout simplement la possibilité d&#8217;une protection subsidiaire. Enfin, la sixième condition, qui stipule que la personne doit d&#8217;abord faire valoir ses droits à d&#8217;éventuelles prestations sociales, est mentionnée de manière très rudimentaire sous le nom de <code>claiming_benefits</code>, un nom de variable qui ne reflète pas vraiment ce qui est visé.</p>



<p class="wp-block-paragraph">Nous pouvons donc accepter cette suggestion, mais nous sommes immédiatement obligés d&#8217;apporter trois corrections. Nous pouvons facilement détecter la non-conformité du nom de la variable, car les tests ne fonctionneront pas s&#8217;il reste des variables non déclarées dans le code. Un élément manquant dans la formule, tel qu&#8217;une condition oubliée, est cependant beaucoup plus facile à négliger et, s&#8217;il n&#8217;est pas détecté, entraîne à coup sûr des erreurs d&#8217;exécution. Nous constatons donc ici la nécessité de se référer au texte de loi afin de vérifier que le code généré correspond bien à ce que dit le texte de loi. Cette vérification doit être effectuée avec suffisamment d&#8217;attention pour pouvoir identifier les appellations malheureuses ou les interprétations subtiles erronées du texte.</p>



<p class="wp-block-paragraph">Les corrections éventuelles doivent également être effectuées le plus rapidement possible. Si un code erroné reste présent dans l&#8217;éditeur, il fera en effet partie du contexte utilisé par le modèle d&#8217;IA et servira lui-même de base pour les suggestions suivantes. Cela peut conduire à une situation où l&#8217;on continue à recevoir des suggestions contenant toujours les mêmes erreurs, qu&#8217;il faut donc corriger à chaque fois, ce qui n&#8217;est pas propice à la productivité.</p>



<p class="wp-block-paragraph">Les variables utilisées dans la méthode <code>formula()</code> de <code>societal_integration_right</code> ci-dessus doivent bien sûr être définies à leur tour&nbsp;: pour chacune de ces variables, nous devons écrire une classe. Cela peut donner lieu à des chaînes complexes de dépendances. Ainsi,<em> </em><code>is_major</code> pourrait être une simple variable d&#8217;entrée booléenne, mais nous pouvons également la calculer sur la base de la date du jour et d&#8217;une nouvelle variable <code>birthdate</code>. Le calcul de la formule des variables peut également utiliser les paramètres d&#8217;une loi – ainsi, en Belgique, la majorité n&#8217;est atteinte qu&#8217;à partir de 18 ans depuis le <a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=1990011930&amp;caller=eli&amp;&amp;view_numac=1990011930nl">1<sup>er</sup> mai 1990</a>. Cela nous ramènerait alors au Code civil et à son histoire – pour rester concis, nous n&#8217;approfondirons pas cette question pour l&#8217;instant.</p>



<p class="wp-block-paragraph">Dernière remarque&nbsp;: le modèle tel qu&#8217;il est construit ici est bien sûr une représentation simplifiée. Notez toutefois que même dans ce cas, après seulement trois articles de loi, nous avons déjà défini une dizaine de classes Python, avec la possibilité d&#8217;en ajouter d&#8217;autres si nous souhaitons approfondir le sujet. Cursor et GPT-5 écrivent un code relativement verbeux, avec de nombreuses variables et méthodes auxiliaires, qui pourraient parfois être simplifiées. Certains détails de la loi, tels que le délai d&#8217;attente de trois mois pour les citoyens de l&#8217;UE ou les exceptions qui existent pour certaines catégories de mineurs (<a href="https://www.ejustice.just.fgov.be/cgi_loi/article.pl?language=fr&amp;lg_txt=f&amp;type=&amp;sort=&amp;numac_search=&amp;cn_search=2002052647&amp;caller=eli&amp;&amp;view_numac=2002052647nl#Art.7">art. 7</a>), nécessiteraient de nombreuses variables ou conditions supplémentaires dans un modèle complet.</p>



<h1 class="wp-block-heading">IA et code&nbsp;: quelques pièges</h1>



<p class="wp-block-paragraph">En ce qui concerne les meilleures pratiques pour l&#8217;utilisation de l&#8217;IA dans le cadre de tels projets, nous identifions encore quelques pièges, en plus de ceux que nous avons déjà mentionnés.</p>



<p class="wp-block-paragraph">Ajouter trop de documentation au début conduit rapidement à une &#8220;<a href="https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html">confusion contextuelle</a>&#8220;, dans laquelle les suggestions ou les réponses du LLM sont basées sur des informations qui ne sont pas (encore) pertinentes. Il est préférable d&#8217;ajouter la documentation progressivement, au fur et à mesure que la fonctionnalité se développe, plutôt que d&#8217;ajouter l&#8217;analyse complète et le contexte à l&#8217;IDE dès le départ. Dans le cas de la réglementation, ajoutez les règles article par article à l&#8217;IDE, au fur et à mesure de l&#8217;avancement du projet, et résistez à la tentation d&#8217;intégrer à l&#8217;avance l&#8217;ensemble du texte de loi dans l&#8217;IDE en tant que &#8220;référence encyclopédique&#8221;.</p>



<p class="wp-block-paragraph">Le &#8220;context rot&#8221; ou &#8220;context poisoning&#8221; survient lorsque l&#8217;IA s&#8217;engage dans une mauvaise voie, s&#8217;y enlise et finit par oublier des informations plus pertinentes, ce qui rend la récupération plus difficile. Le &#8220;<a href="https://www.anthropic.com/engineering/multi-agent-research-system">context quarantining</a>&#8220;, qui consiste à diviser le problème en sous-problèmes plus petits, chacun avec son propre contexte, est un remède logique à ce problème. C&#8217;est également la voie empruntée par la plupart des systèmes de &#8220;deep research&#8221; ou &#8220;<a href="https://www.anthropic.com/engineering/multi-agent-research-system">multi agentic</a>&#8220;. Dans un IDE, cela impliquerait qu&#8217;un système d&#8217;IA devrait segmenter la base de code et la documentation à partir d&#8217;une certaine taille. La mise en œuvre technique de cette solution en arrière-plan semble être un défi de taille, et différents IDE développeront probablement leur propre approche à cet égard dans un avenir proche.</p>



<p class="wp-block-paragraph">Une autre source de frustration était que l&#8217;IA plaçait parfois le code ou les fichiers au mauvais endroit ou supposait que certaines choses existaient. Par exemple, les formules générées faisaient référence à des variables qui n&#8217;étaient pas encore définies. Cela génère bien sûr des messages d&#8217;erreur lors des tests. Nous devions alors ajuster l&#8217;IA ou insérer nous-mêmes des variables supplémentaires pour couvrir ces références. Même des détails mineurs, tels que le formatage de la documentation ou la création ou non des importations nécessaires, nécessitaient parfois une correction manuelle. Ce type d&#8217;incohérences démontre qu&#8217;il n&#8217;est pas possible de se fier aveuglément aux suggestions de l&#8217;IA. Un développeur doit constamment vérifier si le code généré correspond à l&#8217;intention et, dans le cas contraire, intervenir immédiatement.</p>



<h1 class="wp-block-heading">publi.codes</h1>



<p class="wp-block-paragraph">Nous souhaitons également signaler l&#8217;existence de <a href="https://publi.codes/">publi.codes</a> comme alternative possible à OpenFisca. Plus récent et plus moderne, ce dernier exige que les règles soient codées au format YAML, ce qui est beaucoup plus pratique que l&#8217;écriture de sous-classes en Python et beaucoup plus lisible pour les non-développeurs. En contrepartie, on est toutefois limité aux <a href="https://publi.codes/docs/mecanismes">opérations autorisées</a> par le moteur sous-jacent. Ce n&#8217;est qu&#8217;à partir de la <a href="https://github.com/orgs/publicodes/projects/5">version 2, encore en cours de développement</a>, que des possibilités d&#8217;encoder des <a href="https://github.com/publicodes/publicodes/issues/707">barèmes</a> ou des <a href="https://github.com/publicodes/publicodes/issues/705">abattements</a> (montants exonérés), très fréquents en Belgique, seront ajoutées.</p>



<p class="wp-block-paragraph">La version actuelle de publi.codes dépend en outre de l&#8217;écosystème NPM, qui est actuellement régulièrement affecté par des <a href="https://about.gitlab.com/blog/gitlab-discovers-widespread-npm-supply-chain-attack/">attaques du supply chain</a>. Publi.codes v2 serait quant à lui <a href="https://publi.codes/blog/publicodes-v2">compilé vers OCaml</a>, un langage de programmation que nous n&#8217;utilisons pas chez Smals. Étant donné qu&#8217;il y a peu de chances que Smals souhaite introduire ce langage de programmation dans son portefeuille (et mettre en place une équipe de support à cet effet), il ne semblait pas très utile d&#8217;examiner publi.codes en profondeur dans le cadre de cet exercice. Il convient toutefois de noter que publi.codes dispose de <a href="https://publi.codes/docs/api/react-ui">quelques libraries</a> prêtes à l&#8217;emploi en matière de composants UI.</p>



<h1 class="wp-block-heading">Conclusion</h1>



<p class="wp-block-paragraph">OpenFisca et publi.codes sont deux systèmes particulièrement performants lorsque les règles peuvent être modélisées sous forme de calculs explicites et testables. Ils sont moins adaptés aux réglementations qui font appel aux décisions discrétionnaires, à la libre interprétation, aux exceptions sans paramètres clairs ou aux workflows de &#8220;case management&#8221;. Il s&#8217;agit avant tout de systèmes de calcul et de règles, et non de plateformes de traitement de dossiers. Ils peuvent donc éventuellement servir de moteur pour des applications capables de calculer les impôts ou les allocations au niveau de la personne/du ménage (droit à quelque chose + montant), ou pour simuler l&#8217;impact politique d&#8217;éventuelles modifications (&#8220;combien coûte cette réforme&nbsp;?&#8221;, &#8220;qui y gagne/y perd&nbsp;?&#8221;). Cela peut être intéressant tant pour les législateurs que pour les citoyens.</p>



<p class="wp-block-paragraph">Cependant, un projet OpenFisca ne se met pas en place rapidement. Sur le plan conceptuel, OpenFisca est quelque peu déroutant pour un développeur&nbsp;: bien qu&#8217;OpenFisca utilise des classes Python, celles-ci ne servent pas à modéliser des objets, mais à enregistrer de manière déclarative des entités, des variables et des règles de calcul issues de la réglementation. Étant donné que par variable, il faut écrire une classe et que des dizaines de variables peuvent facilement entrer en jeu dans un article de loi complexe, on se retrouve avec une pile de code qui s&#8217;accumule rapidement et qui est difficile à organiser de manière claire. En outre, le développement d&#8217;une interface graphique nécessite également beaucoup de travail supplémentaire. Le projet manque encore de <em>tooling </em>nécessaire pour atténuer ces problèmes récurrents. (Bien sûr, cela n&#8217;aide pas lorsque l&#8217;<a href="https://openfisca.org/en/about/">administration publique</a>, qui semble considérer que les projets open source peuvent par définition s&#8217;autofinancer, décide soudainement de fermer les vannes en 2020.</p>



<p class="wp-block-paragraph">Enfin, nous pouvons ajouter que cette expérience a été à la fois un <em>reality check</em> utile et instructif sur ce que les LLM peuvent apporter, et gâcher, à un environnement de travail de développeur. Le meilleur conseil reste de garder les rênes fermement en main et de travailler par petites étapes incrémentielles. Certains outils d&#8217;IA seront plus performants que d&#8217;autres dans divers domaines. Donner des réponses négatives ou détecter des erreurs dans les questions reste un défi pour les LLM, ce qui comporte certains risques. Cependant, l&#8217;assistance IA dans les IDE évolue rapidement, et une expérience similaire se déroulera sans doute différemment l&#8217;année prochaine.</p>



<p class="wp-block-paragraph">Rules As Code ne signifie certainement pas qu&#8217;aujourd&#8217;hui, nous pouvons fournir un texte de loi à une IA pour qu&#8217;elle déploie un programme. Cependant, dans les années à venir, les <a href="https://rules-as-code.yellenge.nl/">forums spécialisés</a> accorderont sans aucun doute une grande attention à l&#8217;interaction entre la loi, la mise en œuvre et les outils d&#8217;IA. Pour l&#8217;instant, la complexité de la réglementation elle-même, même avec une IA de plus en plus performante, reste le principal obstacle aux projets Rules As Code.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rules as Code: lessen uit een experiment</title>
		<link>https://www.smalsresearch.be/rules-as-code-deel2-nl/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 18:57:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[AI4GOV]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[Society]]></category>
		<guid isPermaLink="false">/?p=25971</guid>

					<description><![CDATA[Wat gebeurt er als een leek zich waagt aan een Rules as Code project met een AI-powered IDE?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Cet article est aussi disponible&nbsp;<a href="/rules-as-code-partie2-fr/" data-type="post" data-id="24294">en français</a>.</em></p>



<p class="wp-block-paragraph"><a href="/rules-as-code-nl/">In een vorig artikel</a> fileerden we <a href="https://interoperable-europe.ec.europa.eu/collection/eugovtech/news/rules-code-rac">Rules as Code</a>, een aanpak die erop gericht is om de kloof tussen regelgeving en software te verkleinen. We illustreerden daarbij dat er heel wat praktische obstakels te overkomen zijn, niettegenstaande het lovenswaardige doel. De uniforme encodering van regels met hun geschiedenis, verwevenheden en afhankelijkheden is een uitdaging die een aanzienlijke investering van mensen en middelen kan vergen. Permanent actief beheer is daarenboven nodig om elke wijziging aan de regels op te vangen. Zelfs op kleine schaal is een nauwe samenwerking tussen juristen en ontwikkelaars onontbeerlijk, want regelmatig zullen gemotiveerde beslissingen genomen moeten worden over interpretatie. Omdat industriestandaarden nog ontbreken en best practices nog volop in ontwikkeling zijn, riskeer je als <em>early adopter</em> de zogenaamde <a href="https://terryu.substack.com/p/bridging-the-gap-between-early-and">pioneer tax</a> te moeten betalen. De complexe lasagna van overheidsbevoegdheden maakt een eventuele toepassing in België niet eenvoudiger.</p>



<p class="wp-block-paragraph">Mede onder impuls van het uitgebreide <a href="https://www.oecd.org/en/publications/cracking-the-code_3afe6ba5-en.html">rapport van de OESO uit 2020</a>, hebben enkele overheden toch al volop ingezet op het uitwerken van, soms vrij grootschalige, proof-of-concepts. Er bestaan vandaag dan ook enkele frameworks die relatief matuur zijn. Ongetwijfeld is Frankrijk het voortrekkersland; het initiatief dat we hieronder zullen toelichten komt van Franse bodem. Ook <a href="https://regels.overheid.nl/">in Nederland</a> beweegt er wel wat: de Nederlandse fiscus gebruikt al enige tijd haar eigen domeintaal <a href="https://regels.overheid.nl/docs/methods/REGELSPRAAK">RegelSpraak</a> die zij met de <em>rule engine</em> <a href="https://regels.overheid.nl/docs/methods/ALEF">ALEF</a> interpreteert en verwerkt, echter lijkt de daarover <a href="https://gitlab.com/normativesystems">gepubliceerde broncode</a> vooralsnog meer op methodologie dan op applicaties te focussen.</p>



<h1 class="wp-block-heading">OpenFisca</h1>



<p class="wp-block-paragraph">OpenFisca is <a href="https://openfisca.org/en/about/">ontstaan in 2011</a> als open-source <a href="https://en.wikipedia.org/wiki/Microsimulation">microsimulatie</a>-motor om belasting- en uitkeringsregels (“tax &amp; benefit system”) om te zetten naar uitvoerbare code. De effecten van die regelgeving, en eventuele wijzigingen, kunnen dan gesimuleerd worden voor zowel individuele cases als hele populaties. Websites met OpenFisca in de achtergrond zijn onder andere <a href="https://leximpact.an.fr/">LexImpact</a> (simulatie van wijzigingen in socio-fiscale wetgeving), <a href="https://www.mesdroitssociaux.gouv.fr/">Mes droits sociaux</a> (simulatie van sociale rechten), en <a href="https://mes-aides.1jeune1solution.beta.gouv.fr/">1jeune1solution</a> (allerhande steunmaatregelen). Buitenlandse voorbeelden zijn <a href="https://benefitme.nz/">BenefitMe</a> (Nieuw-Zeeland), <a href="https://lesmevesajudes.barcelona.cat/">Les meves ajudes</a> (Barcelona), of <a href="https://www.policyengine.org/">PolicyEngine</a> (UK/USA) &#8211; deze laatsten wel met <a href="https://github.com/PolicyEngine">grondige aanpassingen</a> aan de engine.</p>



<p class="wp-block-paragraph">Om ons eigen belasting- en/of sociale-zekerheidsstelsel te modelleren, moeten we een fork maken van het generieke <a href="https://github.com/openfisca/country-template">OpenFisca country-template</a>. Verschillende andere landen hebben er tenminste al mee geëxperimenteerd, zo vinden we in de <a href="https://github.com/orgs/openfisca/repositories">lijst van repositories</a> o.a. Senegal, Paraguay en Tunesië. Regionale of lokale wetgeving kan middels <a href="https://openfisca.org/doc/contribute/extensions.html">plugin-extensies</a> toegevoegd worden aan een nationaal systeem, zoals <a href="https://github.com/openfisca/openfisca-paris">deze voor Parijs</a>. Eens de repository geïnitialiseerd, kunnen we beginnen werken aan wat misschien ooit <em>openfisca-belgium</em> kan worden. De modellering in OpenFisca gebeurt door het schrijven van Python-klassen en -methodes, die de entiteiten, variabelen en berekeningsformules uit de regelgeving vertegenwoordigen.</p>



<p class="wp-block-paragraph">Helaas houdt het gemakkelijke deel daar ongeveer op. De <em>country-template</em> repository is minimalistisch en hoewel er wel <a href="https://openfisca.org/doc/index.html">documentatie</a>, met een kleine tutorial, beschikbaar is om een eigen versie uit te bouwen, focust deze vooral op de eerste stappen. Richtlijnen over hoe we onze eigen fork best zouden structureren zodra het aantal variabelen en parameters groeit, ontbreken grotendeels. De repository van moederproject <a href="https://github.com/openfisca/openfisca-france/tree/master">openfisca-france</a> kan weliswaar als voorbeeld dienen, maar is dan weer erg groot, en het waarom van hun structurele of architecturale keuzes is er niet echt uit af te leiden.</p>



<p class="wp-block-paragraph">Ook het aspect van een GUI of webinterface blijft onderbelicht. Nochtans is de interface van bijvoorbeeld de <a href="https://socio-fiscal.leximpact.an.fr/?parameters=irpp_economique&amp;waterfall=brut_to_disponible">LexImpact simulator van de Franse inkomstenbelasting</a>, net een sterk punt. Als leidraad voor bouwen van een webinterface verwijst men naar <a href="https://github.com/redte-ch/ReDistributeMe/tree/main">tutorials en slides van een workshop</a>, waar men de eerste stappen toont in <a href="https://svelte.dev/">Svelte</a>, <a href="https://react.dev/">React</a> en <a href="https://vuejs.org/">VueJS</a>. Het is echter een extra barrière voor adoptie, dat een GUI of webapp nog <em>from scratch</em> zelf te bouwen is bovenop een eigen OpenFisca-instantie. Het bouwen van een GUI is immers tijdrovend. Het zou nuttig zijn om OpenFisca-GUI-libraries te hebben met herbruikbare componenten voor de belangrijkste web frameworks, zodat een OpenFisca server misschien met een generieke <em>default</em> webinterface gebundeld kan worden. Een <a href="https://www.drupal.org/project/webform_openfisca">Drupal-plugin</a> lijkt momenteel het enige project dat enigszins in die richting gaat.</p>



<h1 class="wp-block-heading">AI to the rescue?</h1>



<p class="wp-block-paragraph">Gezien OpenFisca, Svelte, React en Vue allen nieuw zijn voor de auteur, en AI-tooling belooft om developers sneller te laten onboarden, grijpen we de kans om de AI-powered IDE <a href="https://cursor.com/download">Cursor</a> tegelijk uit te testen. Deze kloon van <a href="https://code.visualstudio.com/">Visual Studio Code</a> is verrijkt met de mogelijkheid tot het aanroepen van (in ons geval public-cloud-gebaseerde) LLMs. Daarbij kunnen selecties uit bestanden in het project worden gemarkeerd als context bij de vraag. Cursor kan <a href="https://cursor.com/docs">suggesties geven</a> voor toevoegingen of wijzigingen aan bestanden die, eens goedgekeurd, direct geïntegreerd kunnen worden in de codebase.</p>



<p class="wp-block-paragraph">Interageren met AI-modellen <a href="https://news.stanford.edu/stories/2025/10/ai-chatbot-privacy-concerns-risks-research">houdt privacy-risico&#8217;s in</a>. Dit experiment vooral mogelijk omdat we werken met open-source code, gepubliceerde regelgeving, en de eveneens openbare documentatie daarvan, wat niet gevoelig is. Maar gezien alles wat zich in de IDE bevindt naar het taalmodel gestuurd kan worden, moeten we er nog steeds op letten dat we geen bestanden openen in de IDE die credentials, API keys of persoonlijke informatie bevatten. Dat blijft de verantwoordelijkheid van de individuele developer. Sowieso is het goede praktijk om voorbereid te zijn op het roteren van API keys of credentials, want in het heetst van een debugging-strijd is <em>oversharing</em> met een LLM snel gebeurd.</p>



<p class="wp-block-paragraph">Tot slot moeten we vermelden dat dit experiment nog werd uitgevoerd met Cursor versies 1.6 en 1.7 in september-oktober 2025, met OpenAI&#8217;s GPT-4.5 en later GPT-5.0 als achterliggend taalmodel, gebruikt met een eigen API key (niet via Cursor). Latere versies hebben heel wat nieuwere features (waaronder meer <em>agentic</em> workflows) en het zou kunnen dat de ervaring vandaag (januari 2026) al heel anders zou zijn. De belangrijkste lessen blijven echter algemeen gelden voor alle AI-powered development, of dat nu via IDE, command line of beide gebeurt (vb. Anthropic <a href="https://code.claude.com/docs/en/overview">Claude Code</a>).</p>



<p class="wp-block-paragraph">Als eerste stap voegen we de nodige documentatie toe aan ons project. Als case nemen we de <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel">Wet op de Maatschappelijke Integratie van 26 mei 2002</a>. Samen met alle andere relevante wetten, koninklijke besluiten en omzendbrieven is die overzichtelijk geïnventariseerd op de website van de <a href="https://www.mi-is.be/nl/wetgeving">POD Maatschappelijke Integratie</a>. Om de tekst gemakkelijk doorzoekbaar en interpreteerbaar te maken voor een LLM in een IDE, slaan we hem op als plat tekstbestand zonder opmaak, en dat voegen we toe aan een nieuw mapje voor relevant bronmateriaal in de source tree van het project. Of dat optimaal is, daar hebben we het raden naar, maar we moeten ergens beginnen.</p>



<h2 class="wp-block-heading">Entiteiten</h2>



<p class="wp-block-paragraph">Entiteiten in OpenFisca drukken uit voor wie we de berekening maken. Dat kunnen individuen, gezinnen of andere groeperingen van mensen zijn (bedrijven, organisaties, &#8230;). Het zijn de basisbouwstenen waarvoor we later variabelen zullen kunnen specifiëren die samen een &#8220;situatie&#8221; vormen waarvoor we een berekening zullen kunnen doen. <em>Person </em>en <em>Household </em>zijn al aanwezig <a href="https://github.com/openfisca/country-template/blob/main/openfisca_country_template/entities.py">in de code</a>. Een logische vraag is dus of we, op basis van de gegeven wettekst, andere entiteiten kunnen definiëren die nuttig zouden zijn.</p>



<p class="wp-block-paragraph">Na het stellen van de vraag aan GPT-5 in Cursor, met de wettekst geselecteerd als context, wordt voorgesteld de volgende entiteiten toe te voegen: </p>



<ul class="wp-block-list">
<li>Eligible Person for Societal Integration</li>



<li>Living Wage Recipient</li>



<li>Employment Project Participant</li>
</ul>



<p class="wp-block-paragraph">De voorgestelde aanpassingen aan de code zijn syntactisch correct. Geen van deze 3 zijn echter nuttig of noodzakelijk: het gaat in alledrie de gevallen om varianten van <em>Person</em>. De eigenschappen die maken dat ze bijvoorbeeld een leefloon zouden ontvangen, zijn veeleer variabelen toegevoegd aan de reeds bestaande <em>Person </em>entiteit. De waarde van die variabelen hangt bovendien af van andere variabelen die eveneens aan datzelfde individu gebonden zijn, zoals een inkomen uit werk of een handicapstatus. Entiteiten, die vooral dienen voor op zichzelf staande concepten, zijn hiervoor niet de juiste keuze.</p>



<p class="wp-block-paragraph">Daarnaast lijkt GPT-5 het concept van een &#8220;rol&#8221; binnen een OpenFisca groepsentiteit verkeerd te hebben begrepen. Hij probeert &#8220;Eligible Person for Societal Integration&#8221; op te bouwen met verschillende &#8220;rollen&#8221; als onderdelen: &#8220;Belgian National&#8221;, &#8220;EU Citizen&#8221;, &#8220;Foreigner&#8221;, &#8220;Stateless&#8221;, &#8220;Refugee&#8221;&#8230; Dit ongetwijfeld omdat deze mogelijkheden verschijnen in <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel#Art.3">Art.3, 3° lid, van de wet</a>. In OpenFisca is een groepsentiteit echter samengesteld uit Personen die elk een rol krijgen. Een <em>Household </em>bevat zo <em>Adult </em>en <em>Child </em>rollen. Het is vrij nonsensicaal dat een EligiblePerson meerdere Foreigners zou kunnen bevatten. Nationaliteit of herkomst, of andere voorwaarden die gesteld worden in deze wet, zijn ook hier variabelen die gebonden zijn aan de persoon, geen entiteit op zich.</p>



<p class="wp-block-paragraph">Op een ander moment werd nog een aparte entiteit gecreëerd voor het OCMW. Hoewel het logisch lijkt om de OCMWs te modelleren en als een entiteit te beschouwen &#8211; ze worden immers vermeld in de wet &#8211; is het dat hier (nog) niet. Er zijn immers geen verschillende types OCMWs met verschillende eigenschappen of rollen, waarvoor we telkens andere berekeningen moeten maken. In de context van deze wet, waarbij het de burger is voor wie we het recht op maatschappelijke steun berekenen, is het OCMW vooral een constant, invariant gegeven. In OpenFisca kunnen we dat dus vooralsnog overslaan. (Een entiteitstype &#8220;instituut&#8221; is ook niet voorzien.)</p>



<p class="wp-block-paragraph">We merken hier dus dat Cursor niet &#8220;nee&#8221; kan antwoorden op de vraag of er nuttige andere entiteiten kunnen toegevoegd worden. Het kan de denkrichting achter die vraag niet bekritiseren of corrigeren uit eigen beweging. Doorheen het hele experiment bleken Cursor en GPT-5 ook een neiging te vertonen tot onnodige complexiteit. Dit is voor developers die met onbekende code of frameworks werken een groot risico:  indien men te snel te ver meegaat met zulke suggesties, dreigt men later de pedalen te verliezen en achteraf erg moeilijke correcties te moeten aanbrengen aan de fundamenten van het project. Eens een verkeerde route is ingeslagen, blijkt het ook moeilijk om op de stappen terug te keren en deze weer te doen vergeten. Zeker als men ze eerst onwetend heeft toegelaten, komen ze terecht in de context en wordt er in vervolgvragen op verdergebouwd. Deze sluipende &#8220;<a href="https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html">context rot</a>&#8221; is ondertussen een bekend probleem en een belangrijke oorzaak van tijdverlies met AI-enabled coding.</p>



<h2 class="wp-block-heading">Variabelen</h2>



<p class="wp-block-paragraph">De kern van het model zit in de variabelen die de rechten en voorwaarden uit de wet voorstellen. <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel#Art.2">Artikel 2</a> van de wet somt de verschillende vormen van maatschappelijke integratie op waarop iemand recht kan hebben (o.a. tewerkstelling, leefloon, geïndividualiseerd project). <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel#Art.2">Artikel 3</a> bevat de voorwaarden waaraan een persoon moet voldoen om van dat recht gebruik te maken. We hebben deze bepalingen stap voor stap in code omgezet.</p>



<p class="wp-block-paragraph">Recht op maatschappelijke integratie betekent in de praktijk dat een OCMW een persoon moet ondersteunen via (1) een job of opleiding, (2) een leefloon, of (3) een geïndividualiseerd project voor maatschappelijke integratie. Dit kan vertaald worden naar drie boolean variabelen op de Persoon-entiteit, bijvoorbeeld <em>employment_right</em>, <em>living_wage_right </em>en <em>individualized_project_right</em>. Cursor geeft hier een goede code-suggestie, en voorziet een eenvoudige <em>placeholder</em>-formule: zolang iemand “in aanmerking komt voor integratie” (een andere variabele) zou het recht gelden. We bekomen een definitie van <em>employment_right</em> als volgt:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class employment_right(Variable):
  value_type = bool
  entity = Person
  definition_period = MONTH
  def formula(person, period, parameters):
    return person("eligible_for_integration", period)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">employment_right</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">Variable</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">  value_type = </span><span style="color: #4EC9B0">bool</span></span>
<span class="line"><span style="color: #D4D4D4">  entity = Person</span></span>
<span class="line"><span style="color: #D4D4D4">  definition_period = MONTH</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">def</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">formula</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">person</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">period</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">parameters</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> person(</span><span style="color: #CE9178">&quot;eligible_for_integration&quot;</span><span style="color: #D4D4D4">, period)</span></span></code></pre></div>



<p class="wp-block-paragraph">De invulling van deze placeholder-formule komt aan bod in het daaropvolgende Artikel 3. Die modelleert de volgende voorwaarden om in aanmerking te komen:</p>



<ul class="wp-block-list">
<li><strong>Verblijf in België </strong>(volgens de regels nader te bepalen bij KB).</li>



<li><strong>Leeftijd:</strong> De persoon is <strong>meerderjarig</strong> (18+), of als minderjarige <strong>gelijkgesteld</strong> aan een meerderjarige volgens de uitzonderingen in deze wet.</li>



<li><strong>Nationaliteit of verblijfsstatuut:</strong> De persoon is Belg, EU-burger (na 3 maanden verblijf), ingeschreven vreemdeling, staatloze, vluchteling of subsidiair beschermde. </li>



<li><strong>Onvoldoende bestaansmiddelen</strong></li>



<li><strong>Werkbereidheid </strong>(tenzij onmogelijk om gezondheidsredenen of billijkheidsredenen).</li>



<li><strong>Rechten uit andere stelsels uitgeput</strong></li>
</ul>



<p class="wp-block-paragraph">Al deze voorwaarden komen samen in één centrale boolean variabele <em>societal_integration_right</em>. Die variabele geeft aan of iemand, gegeven zijn persoonlijke situatie, recht <strong>kan</strong> hebben op maatschappelijke integratie. In feite is dit de vertaalslag van <em>“voldoet de persoon aan alle voorwaarden van art.3?”</em>. De formule combineert alle subvoorwaarden:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>class societal_integration_right(Variable):
  value_type = bool
  entity = Person
  definition_period = MONTH
  label = "Right to societal integration"
  def formula(person, period, parameters):
    residency = person("residency_status", period)
    is_major = person("is_major", period)
    nationality = person("nationality_status", period) in &#91;"belgian", "eu_citizen", "registered_foreigner", "stateless", "refugee"&#93;
    insufficient_income = not person("has_sufficient_income", period)
    willing_to_work = person("willing_to_work", period)
    claiming_benefits = person("claiming_benefits", period)
    return (residency and is_major and nationality and insufficient_income and willing_to_work and claiming_benefits)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">societal_integration_right</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">Variable</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">  value_type = </span><span style="color: #4EC9B0">bool</span></span>
<span class="line"><span style="color: #D4D4D4">  entity = Person</span></span>
<span class="line"><span style="color: #D4D4D4">  definition_period = MONTH</span></span>
<span class="line"><span style="color: #D4D4D4">  label = </span><span style="color: #CE9178">&quot;Right to societal integration&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">def</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">formula</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">person</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">period</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">parameters</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">    residency = person(</span><span style="color: #CE9178">&quot;residency_status&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    is_major = person(</span><span style="color: #CE9178">&quot;is_major&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    nationality = person(</span><span style="color: #CE9178">&quot;nationality_status&quot;</span><span style="color: #D4D4D4">, period) </span><span style="color: #569CD6">in</span><span style="color: #D4D4D4"> &#91;</span><span style="color: #CE9178">&quot;belgian&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;eu_citizen&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;registered_foreigner&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;stateless&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;refugee&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    insufficient_income = </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> person(</span><span style="color: #CE9178">&quot;has_sufficient_income&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    willing_to_work = person(</span><span style="color: #CE9178">&quot;willing_to_work&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    claiming_benefits = person(</span><span style="color: #CE9178">&quot;claiming_benefits&quot;</span><span style="color: #D4D4D4">, period)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> (residency </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> is_major </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> nationality </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> insufficient_income </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> willing_to_work </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> claiming_benefits)</span></span></code></pre></div>



<p class="wp-block-paragraph">Let hier vooral op enkele vreemde lacunes in de suggestie van Cursor. Zo is de naam van de variabele <code>societal_integration_right</code> niet gelijk aan de eerder gedefinieerde placeholder <code>eligible_for_integration</code>, hoewel dat wel de bedoeling is. Daarnaast wordt in de nationaliteitsvoorwaarde de mogelijkheid van subsidiair beschermden simpelweg vergeten! Tot slot is de zesde voorwaarde, dat men eerst zijn rechten laat gelden op eventuele sociale uitkeringen, wel erg rudimentair benoemd als <code>claiming_benefits</code> &#8211; een variabelenaam die niet echt dekt wat bedoeld wordt.</p>



<p class="wp-block-paragraph">We kunnen deze suggestie dus wel aanvaarden, maar we zijn al direct verplicht om 3 correcties door te voeren. De niet-overeenkomst van de variabelenaam kunnen we daarbij nog gemakkelijk detecteren&nbsp;omdat de tests niet zullen werken als er nog ongedeclareerde variabelen in de code zitten. Een mankerend element in de formule, zoals een vergeten voorwaarde, is echter veel gemakkelijker over het hoofd gezien, en leidt wanneer dat ongedetecteerd blijft gegarandeerd tot fouten in de uitvoering. Hier merken we dus echt wel de noodzaak om terug te koppelen naar de wettekst om te verifiëren dat de gegenereerde code wel degelijk overeenkomt met wat de wettekst zegt. Deze terugkoppeling moet aandachtig genoeg gebeuren om ook ongelukkige benamingen of subtiele misinterpretaties van te tekst te kunnen identificeren.</p>



<p class="wp-block-paragraph">Eventuele correcties kunnen daarnaast ook best zo snel mogelijk gebeuren. Als foutieve code in de editor aanwezig blijft, gaat ze immers deel uitmaken van de context die het AI-model gebruikt en dient ze zelf als fundament voor daaropvolgende suggesties. Dit kan leiden tot een situatie waarbij men suggesties blijft ontvangen waarin steeds dezelfde fouten terugkomen, die men dus ook telkens weer moet corrigeren, wat niet bevorderlijk is voor de productiviteit.</p>



<p class="wp-block-paragraph">De variabelen gebruikt in de <code>formula()</code> methode van <code>societal_integration_right</code> hierboven, moeten uiteraard op hun beurt ook gedefinieerd worden: voor elk van deze variabelen moeten we een klasse schrijven. Dit kan aanleiding geven tot complexe kettingen van afhankelijkheden. Zo zou <code>is_major</code> een eenvoudige booleaanse inputvariabele kunnen zijn, maar we kunnen dat ook berekenen op basis van de datum van vandaag en weer een nieuwe variabele <code>birthdate</code>. De berekening van de formule van de variabelen kan daarnaast ook gebruik maken van de parameters van een wet &#8211; zo is de meerderjarigheid in België pas vanaf 18 jaar <a href="https://www.ejustice.just.fgov.be/eli/wet/1990/01/19/1990009050/justel">sinds 1 mei 1990</a>. Dat zou ons dan weer bij het Burgerlijk Wetboek brengen, en haar geschiedenis &#8211; om het beknopt te houden gaan we daar nu niet verder op in.</p>



<p class="wp-block-paragraph">Laatste opmerking: het model zoals hier gebouwd is uiteraard een vereenvoudigde weerspiegeling. Merk wel op dat we zelfs dan, slechts 3 artikels ver in een wet, al snel 10 Python-klassen hebben gedefinieerd hebben, met potentieel voor meer als we echt in de diepte zouden willen gaan. Cursor en GPT-5 schrijven daarbij relatief <em>verbose </em>code, met vele hulpvariabelen en -methodes, die soms echt wel eenvoudiger kan. Sommige details uit de wet, zoals de 3-maanden wachttijd voor EU-burgers, of de uitzonderingen die bestaan voor bepaalde categorieën van minderjarigen (<a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel#Art.7">Art. 7</a>), zouden in een volwaardig model nog heel wat extra variabelen of condities vergen. </p>



<h1 class="wp-block-heading">AI en code: enkele valkuilen</h1>



<p class="wp-block-paragraph">Wat betreft <em>best practices</em> voor de inzet van AI-hulp bij zulke projecten, identificeren we nog enkele valkuilen, naast diegene die we tot nu toe al genoemd hebben.</p>



<p class="wp-block-paragraph">Teveel documentatie toevoegen in het begin leidt snel tot &#8220;<a href="https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html">context confusion</a>&#8220;, waarbij de suggesties of de antwoorden van de LLM gebaseerd gaan zijn op stukken informatie die (nog) niet relevant zijn. Het is beter de documentatie geleidelijk toe te voegen, in gelijke tred met de functionaliteit, in plaats van de volledige analyse en achtergrond op voorhand toe te voegen aan de IDE. In het geval van regelgeving: voeg de regels artikel per artikel toe aan de IDE, naarmate de projectontwikkeling vordert, en weersta de verleiding om de hele wettekst op voorhand als &#8220;encyclopedische referentie&#8221; te integreren in de IDE.</p>



<p class="wp-block-paragraph">Context rot of context poisoning ontstaat dan weer wanneer de AI een verkeerde weg is ingeslagen,&nbsp; daarop voortboomt, en uiteindelijk relevantere informatie vergeet zodat het ook moeilijker wordt om ervan te herstellen. &#8220;<a href="https://www.anthropic.com/engineering/multi-agent-research-system">Context quarantining</a>&#8220;, het opdelen van het probleem in kleinere deelproblemen elk met hun eigen context, is daarvoor een logische remedie. Dit is ook de weg die de meeste &#8220;deep research&#8221; of &#8220;<a href="https://www.anthropic.com/engineering/multi-agent-research-system">multi-agentic</a>&#8221; systemen inslaan. In een IDE zou dat impliceren dat een AI-systeem de codebase en de documentatie vanaf een zekere grootte zou moeten segmenteren. Hoe dat technisch uitgewerkt kan worden achter de schermen lijkt een uitdaging van formaat, en verschillende IDEs zullen daar in de nabije toekomst waarschijnlijk hun eigen <em>approach </em>voor ontwikkelen.</p>



<p class="wp-block-paragraph">Een andere frustratie was dat de AI soms code of bestanden verkeerd plaatste of aannam dat bepaalde dingen bestonden. Zo refereerden gegenereerde formules naar variabelen die nog helemaal niet gedefinieerd waren. Dit zorgt bij het testen natuurlijk voor foutmeldingen. We moesten de AI dan bijsturen of zelf extra variabelen invoegen om die referenties af te dekken. Ook kleine zaken, zoals de formattering van documentatie of het wel/niet aanmaken van noodzakelijk imports, vergden manuele correctie. Dit soort inconsistenties tonen aan dat je AI-suggesties niet blindelings kunt vertrouwen. Een developer moet voortdurend valideren of de code die gegenereerd wordt strookt met de bedoeling, en zo niet, onmiddellijk ingrijpen.</p>



<h1 class="wp-block-heading">publi.codes</h1>



<p class="wp-block-paragraph">We willen ook nog wijzen op het bestaan van <a href="https://publi.codes/">publi.codes</a> als eventueel alternatief voor OpenFisca. Recenter en moderner, moeten de regels daar gecodeerd worden in een YAML-formaat, wat veel hanteerbaarder is dan het schrijven van subklassen in Python, en veel leesbaarder voor niet-developers. Men is in ruil daarvoor echter wel beperkt tot de <a href="https://publi.codes/docs/mecanismes">bewerkingen die zijn toegelaten</a> door de achterliggende motor. Pas vanaf de <a href="https://github.com/orgs/publicodes/projects/5">nog in ontwikkeling zijnde versie 2</a> komen daar mogelijkheden bij om <a href="https://github.com/publicodes/publicodes/issues/707">barema&#8217;s</a> te encoderen, of <a href="https://github.com/publicodes/publicodes/issues/705">abattementen</a> (vrijgestelde bedragen), die in België erg veelvuldig voorkomen. </p>



<p class="wp-block-paragraph">De huidige versie van publi.codes is bovendien afhankelijk van het NPM ecosysteem dat tegenwoordig regelmatig geplaagd wordt door <a href="https://about.gitlab.com/blog/gitlab-discovers-widespread-npm-supply-chain-attack/">supply chain aanvallen</a>. Publi.codes v2 zou dan weer <a href="https://publi.codes/blog/publicodes-v2">gecompileerd worden naar OCaml</a>, een programmeertaal die we bij Smals niet gebruiken. Gezien de kans klein is dat Smals deze programmeertaal zou willen introduceren in haar portfolio (en een ondersteunend team ervoor zou willen uitbouwen), leek het weinig nuttig om voor deze oefening ook publi.codes in de diepte te bekijken. Het valt echter wel op dat op het vlak van UI-componenten, publi.codes wel <a href="https://publi.codes/docs/api/react-ui">enkele libraries</a> heeft klaarliggen.</p>



<h1 class="wp-block-heading">Conclusie</h1>



<p class="wp-block-paragraph">Zowel OpenFisca als publi.codes zijn als platform vooral sterk wanneer je regels kunt modelleren als expliciete, testbare berekeningen. Minder ideaal is het voor regels die vooral draaien op discretionaire beslissingen, vrije interpretatie, bewijswaardering, uitzonderingen zonder heldere parameters, of “case management”-workflows. Het zijn primair reken- en regelsystemen, geen dossierbehandelingsplatformen. Daarmee zijn ze eventueel wel geschikt als motor voor apps die belastingen of uitkeringen op niveau van persoon/huishouden kunnen berekenen (recht op iets + bedrag), of om beleidsimpact te simuleren van eventuele wijzigingen (&#8220;wat kost deze hervorming?&#8221;, &#8220;wie wint/verliest?&#8221;). Dat kan voor beleidsmakers én burgers interessant zijn.</p>



<p class="wp-block-paragraph">Toch is een OpenFisca-project niet snel even opgezet. Conceptueel is OpenFisca enigszins verwarrend voor een developer: hoewel OpenFisca gebruikmaakt van Python-klassen, dienen deze niet om objecten te modelleren, maar om entiteiten, variabelen en berekeningsregels uit de regelgeving declaratief vast te leggen. Gegeven dat er 1 klasse per variabele moet geschreven worden, en er vlotjes tientallen variabelen kunnen meespelen in een fijnmazig wetsartikel, zit men met een snel groeiende stapel code die een uitdaging is om overzichtelijk georganiseerd te krijgen. Daarnaast vergt ook de ontwikkeling van een GUI veel extra werk. Het project mist nog de nodige <em>tooling</em> om deze recurrente problematieken te verlichten. (Het helpt natuurlijk niet wanneer de <a href="https://openfisca.org/en/about/">opdrachtgevende overheid in 2020 plots de kraan dichtdraait</a>, schijnbaar van mening dat open-source projecten per definitie zelfbedruipend kunnen zijn.)</p>



<p class="wp-block-paragraph">Tot slot kunnen we nog zeggen dat dit experiment tegelijk een nuttige en leerzame <em>reality check</em> was over wat LLMs kunnen bijdragen, en kunnen verknoeien, aan een developer-werkomgeving. Zelf de regie stevig in handen blijven houden en werken met kleine incrementele stapjes, blijft de beste raad. De ene AI tool zal daarbij al wat minder steken laten vallen dan de andere op allerlei vlakken. Het geven van negatieve antwoorden of het detecteren van fouten in de vraagstelling blijft erg uitdagend voor LLMs en dat brengt wat risico met zich mee. AI-assistentie in IDEs evolueert echter razendsnel, en een gelijkaardig experiment zal volgend jaar ongetwijfeld anders verlopen. </p>



<p class="wp-block-paragraph">Rules As Code betekent zeker niet dat we vandaag een wettekst aan een AI kunnen geven om er een programma te laten uitrollen. Wel zal er op <a href="https://rules-as-code.yellenge.nl/">gespecialiseerde fora</a> de komende jaren ongetwijfeld veel aandacht gaan naar de interactie tussen wet, implementatie, en AI-tooling. Vooralsnog blijft de complexiteit van de regelgeving zelf, ook met steeds betere AI, de grootste hinderpaal voor Rules As Code projecten. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Garde-fous : délimitez votre IA</title>
		<link>https://www.smalsresearch.be/garde-fous-delimitez-votre-ai/</link>
		
		<dc:creator><![CDATA[Bert Vanhalst]]></dc:creator>
		<pubDate>Thu, 27 Nov 2025 09:30:57 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[software engineering]]></category>
		<guid isPermaLink="false">/?p=24564</guid>

					<description><![CDATA[Les garde-fous contribuent à la sûreté et à la fiabilité des applications d'IA. Découvrez comment dans cet article.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Dit artikel is ook beschikbaar in het <a href="/guardrails-hou-je-ai-binnen-de-lijntjes/">Nederlands</a>.</em></p>



<p class="wp-block-paragraph">Le monde de l&#8217;IA évolue à une vitesse vertigineuse et l&#8217;émergence du <a href="/qualite-dun-systeme-generatif-de-questions-reponses/">Retrieval-Augmented Generation (RAG)</a> ouvre de nouvelles possibilités pour combiner intelligemment des données et des modèles de langage.</p>



<p class="wp-block-paragraph">Les systèmes RAG combinent la capacité générative des LLM avec l&#8217;extraction d&#8217;informations pertinentes et actualisées dans des sources de données. Cela les rend plus puissants, mais aussi plus complexes, car ils dépendent de la qualité du modèle et des données utilisées, et sont susceptibles de diffuser des informations obsolètes, incorrectes ou inappropriées.</p>



<p class="wp-block-paragraph">Dans un <a href="/experiences-pratiques-avec-levaluation-automatique-de-la-rag/">précédent article de blog</a>, nous avons expliqué comment les évaluations automatiques peuvent aider à mesurer la qualité d&#8217;un système RAG et à l&#8217;améliorer de manière interactive. Mais la qualité seule ne suffit pas. Pour que les systèmes d&#8217;IA fonctionnent non seulement <em>correctement</em>, mais aussi de manière <em>sûre</em> et <em>responsable</em>, des garde-fous s&#8217;imposent. Par garde-fous, nous entendons les directives, les restrictions techniques et les cadres éthiques qui garantissent que les systèmes d&#8217;IA opèrent dans des limites acceptables. Ils empêchent un résultat indésirable ou préjudiciable et assurent la conformité des systèmes d&#8217;IA avec les valeurs humaines et les normes sociales.</p>



<p class="wp-block-paragraph">Que sont exactement ces garde-fous et comment les utiliser efficacement&nbsp;? C&#8217;est ce que nous allons explorer dans cet article.</p>



<h1 class="wp-block-heading">La nécessité des garde-fous</h1>



<p class="wp-block-paragraph">Les applications basées sur des LLM comportent divers risques qui soulignent la nécessité de garde-fous solides. Sans protection adéquate, les instructions du système peuvent être dérobées. Celles-ci donnent un aperçu de la logique interne et des mécanismes de sécurité, que vous préférez ne pas voir divulgués. Il existe également un risque d&#8217;atteinte à la vie privée lorsque des données à caractère personnel parviennent à des fournisseurs de modèles externes. En outre, les modèles peuvent générer des réponses préjudiciables, allant de propos haineux à des conseils d&#8217;automutilation, ou des informations incorrectes en raison d&#8217;un résultat hallucinatoire. Les questions hors sujet peuvent entraîner une utilisation abusive de l&#8217;application et augmenter les coûts, tandis que des réponses inappropriées ou non conformes peuvent nuire à la réputation.</p>



<p class="wp-block-paragraph">Pour toutes ces raisons, il est essentiel de mettre en place des mécanismes de sécurité solides, car ils constituent un rempart contre ces risques divers et contribuent à la sûreté et à la fiabilité des applications d&#8217;IA ainsi qu&#8217;à leur conformité avec les attentes des utilisateurs et des organisations.</p>



<h1 class="wp-block-heading">Méthodes et techniques</h1>



<p class="wp-block-paragraph">Les garde-fous sont généralement déployés à deux niveaux&nbsp;: juste avant que les données d&#8217;entrée ne soient envoyées au modèle de langage (filtre à l&#8217;entrée) ou juste après la génération des résultats en sortie, mais avant qu&#8217;elle ne parvienne à l&#8217;utilisateur final (filtre à la sortie).</p>



<figure class="wp-block-image"><a href="/wp-content/uploads/2025/11/with_and_without_guardrails.png"><img loading="lazy" decoding="async" width="1862" height="923" src="/wp-content/uploads/2025/11/with_and_without_guardrails.png" alt="Input &amp; output guardrails" class="wp-image-24456" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails.png 1862w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-300x149.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-768x381.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-1024x508.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-1536x761.png 1536w" sizes="auto, (max-width: 1862px) 100vw, 1862px" /></a></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Garde-fous d&#8217;entrée et de sortie – source&nbsp;: <a href="https://github.com/guardrails-ai/guardrails">https://github.com/guardrails-ai/guardrails</a></p>



<p class="wp-block-paragraph">Il existe globalement quatre techniques pour concrètement mettre en œuvre les garde-fous.</p>



<ul class="wp-block-list">
<li>Les <strong>garde-fous natifs LLM</strong> sont des mécanismes de sécurité intégrés dans les services proposés par les fournisseurs des modèles eux-mêmes, celui inclut par exemple le filtrage des résultats préjudiciables ou l&#8217;exclusion de certaines instructions. Ils constituent une première ligne de défense, et doivent généralement être complétés par une ou plusieurs des techniques ci-dessous.</li>



<li>Dans le cas des <strong>garde-fous basés sur le prompt</strong>, des instructions spécifiques sont ajoutées au prompt afin d&#8217;influencer le comportement du modèle. Un exemple typique consiste à obliger le modèle à répondre exclusivement sur la base des informations contextuelles fournies (via RAG) afin qu&#8217;il ne génère pas de résultats incontrôlés ou indésirables. Un autre exemple consiste à ajouter des instructions pour éviter que le système d&#8217;IA ne donne des conseils médicaux. L&#8217;exemple ci-dessous montre les instructions ajoutées au prompt pour éviter que l&#8217;application ne donne des conseils médicaux, avec un exemple de conversation dans laquelle l&#8217;application produit la réponse souhaitée.</li>
</ul>



<figure class="wp-block-image"><a href="/wp-content/uploads/2025/11/prompt-engineering.png"><img loading="lazy" decoding="async" width="1017" height="417" src="/wp-content/uploads/2025/11/prompt-engineering.png" alt="Prompt hardening" class="wp-image-24457" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering.png 1017w, https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering-300x123.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering-768x315.png 768w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></a></figure>



<p class="wp-block-paragraph"></p>



<ul class="wp-block-list">
<li>Les<strong> garde-fous basés sur des règles</strong> agissent de manière déterministe avec des filtres basés sur des mots exacts ou des expressions régulières. Ils permettent d&#8217;effectuer un screening sur certains mots ou sujets et de filtrer des formes simples d&#8217;informations confidentielles, telles que des identifiants, des numéros de téléphone ou des adresses e-mail.</li>



<li>Les <strong style="color: initial;">garde-fous basés sur le ML/LLM</strong><span style="color: initial;"> utilisent des modèles de machine learning ou des </span><em style="color: initial;">LLM-judges</em><span style="color: initial;"> qui sont beaucoup plus aptes à gérer les nuances, l&#8217;intention et le contexte. Ils peuvent évaluer à la fois les entrées et les sorties et les classer, par exemple pour détecter les contenus préjudiciables ou les </span><em style="color: initial;">prompt injections</em><span style="color: initial;"> (tentatives des utilisateurs de manipuler le comportement de l&#8217;application via le prompt). En outre, ils peuvent filtrer les informations sensibles et vérifier les faits en s&#8217;assurant que toutes les affirmations générées en sortie sont étayées par le contexte fourni, comme dans le cas de la RAG.</span></li>
</ul>



<p class="wp-block-paragraph">Chaque technique a son utilité, sa complexité et son coût. Aussi est-il recommandé d&#8217;évaluer d&#8217;abord les risques spécifiques à un cas d&#8217;utilisation particulier, puis de déterminer les garde-fous réellement nécessaires. Commencez par les méthodes les plus simples (basées sur un prompt et des règles) et ne passez à des techniques plus complexes (basées sur le ML/LLM) que lorsque cela est nécessaire. Ces dernières entraînent en effet une latence et des coûts supplémentaires.</p>



<h1 class="wp-block-heading">Outils</h1>



<p class="wp-block-paragraph">Il existe de nombreux outils qui prennent en charge ces techniques et facilitent l&#8217;intégration de garde-fous dans une application. Les <strong>frameworks</strong> procurent un environnement complet pour définir, combiner et orchestrer des garde-fous. Ils vous permettent de configurer des règles, des workflows et des étapes de validation sans devoir tout construire vous-même. Exemples&nbsp;: <a href="https://github.com/guardrails-ai/guardrails">Guardrails AI</a>, <a href="https://github.com/protectai/llm-guard/">LLM Guard</a> et <a href="https://docs.nvidia.com/nemo/guardrails">NVIDIA NeMo Guardrails</a>.</p>



<p class="wp-block-paragraph">Il existe également des <strong>API et des services</strong> qui offrent des fonctionnalités spécifiques, telles que la détection des contenus préjudiciables, le filtrage des données sensibles ou la détection des jailbreaks. Vous pouvez les appeler directement depuis votre application. Nous pouvons citer <a href="https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview">Azure AI Content Safety</a> ou <a href="https://platform.openai.com/docs/guides/moderation">OpenAI Moderation API</a>.</p>



<p class="wp-block-paragraph">Sous le capot, ces outils utilisent une combinaison de modèles ML, de <em>LLM-judges</em> et de techniques basées sur des règles. <a href="https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-3/">Llama Guard</a> et <a href="https://www.llama.com/docs/model-cards-and-prompt-formats/prompt-guard/">Prompt Guard</a> sont des exemples de modèles ML.</p>



<p class="wp-block-paragraph">Notre propre expérience montre que certains outils de protection sont nettement moins précis en néerlandais et en français qu&#8217;en anglais. Nous constatons parfois des faux positifs, par exemple lorsque la détection d&#8217;automutilation identifie à tort des phrases inoffensives comme risquées. Pour les applications simples présentant un faible profil de risque et utilisant exclusivement des données publiques, la valeur ajoutée des outils de protection supplémentaires semble limitée. Dans de tels cas, les mécanismes de sécurité intégrés au LLM, associés à un prompt RAG bien conçu, sont généralement suffisants.</p>



<h1 class="wp-block-heading">Conclusion</h1>



<p class="wp-block-paragraph">En résumé, il est important de toujours utiliser les garde-fous de manière ciblée et stratifiée. Commencez par identifier les risques dans le cas d&#8217;utilisation spécifique, puis choisissez les techniques appropriées, en privilégiant les méthodes simples et en n&#8217;ajoutant des solutions plus complexes que lorsque cela est vraiment nécessaire. Bien qu&#8217;une combinaison de garde-fous natifs LLM, basés sur des prompts, basés sur des règles et basés sur le ML/LLM offre une protection plus robuste, il reste essentiel de comprendre qu&#8217;aucun système ne garantit une sécurité absolue. Les filtres à l&#8217;entrée et à la sortie peuvent produire à la fois des faux positifs et des faux négatifs. De plus, les garde-fous basés sur le ML/LLM occasionnent des coûts et une latence supplémentaires. Un monitoring continu de l&#8217;application d&#8217;IA est recommandé afin de détecter et de traiter rapidement les nouvelles vulnérabilités.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Guardrails: hou je AI binnen de lijntjes</title>
		<link>https://www.smalsresearch.be/guardrails-hou-je-ai-binnen-de-lijntjes/</link>
		
		<dc:creator><![CDATA[Bert Vanhalst]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 08:41:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[software engineering]]></category>
		<guid isPermaLink="false">/?p=24454</guid>

					<description><![CDATA[Guardrails helpen AI-toepassingen veiliger en betrouwbaarder te maken. Ontdek hier hoe.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Cet article est aussi disponible <a href="/garde-fous-delimitez-votre-ai/">en français</a>.</em></p>



<p class="wp-block-paragraph">De wereld van AI evolueert razendsnel, en met de opkomst van <a href="/kwaliteit-van-een-generatief-vraag-antwoordsysteem/">Retrieval-Augmented Generation (RAG)</a> openen zich nieuwe mogelijkheden om data en taalmodellen slim te combineren.</p>



<p class="wp-block-paragraph">RAG-systemen combineren het generatieve vermogen van LLM’s met het ophalen van relevante, actuele informatie uit databronnen. Dit maakt ze krachtiger, maar ook complexer: ze zijn afhankelijk van de kwaliteit van zowel het model als de gebruikte data, en lopen risico op het verspreiden van verouderde, onjuiste of ongepaste informatie.</p>



<p class="wp-block-paragraph">In een <a href="/praktische-ervaringen-met-automatische-rag-evaluatie/">vorige blogpost</a> bespraken we hoe automatische evaluaties kunnen helpen om de kwaliteit te meten van een RAG-systeem en het interatief te verbeteren. Maar kwaliteit alleen is niet genoeg. Om AI-systemen niet alleen <em>goed</em> te laten functioneren, maar ook <em>veilig</em> en <em>verantwoord</em>, zijn guardrails nodig. Onder guardrails verstaan we de richtlijnen, technische beperkingen en ethische kaders die ervoor zorgen dat AI-systemen binnen aanvaardbare grenzen opereren. Ze voorkomen ongewenste of schadelijke output en zorgen ervoor dat AI-systemen aansluiten bij menselijke waarden en maatschappelijke normen.</p>



<p class="wp-block-paragraph">Wat zijn die guardrails precies en hoe zet je ze effectief in? Dat verkennen we in deze blogpost.</p>



<h1 class="wp-block-heading">De nood aan guardrails</h1>



<p class="wp-block-paragraph">LLM-gebaseerde toepassingen brengen verschillende risico’s met zich mee die de nood aan sterke guardrails duidelijk maken. Zonder passende bescherming kunnen de systeeminstructies ontfutseld worden. Die geven inzicht in interne logica en beveiligingsmechanismen, en die zie je dus liever niet onthuld. Ook bestaat het risico op privacy­schendingen wanneer persoonlijke gegevens bij externe modelproviders terechtkomen. Daarnaast kunnen modellen schadelijke antwoorden genereren, variërend van haatspraak tot zelfbeschadigingsadviezen, of incorrecte informatie door hallucinerende output. Off-topic vragen kunnen leiden tot misbruik van de toepassing en de kosten doen oplopen, terwijl ongepaste of niet-conforme antwoorden reputatieschade kunnen veroorzaken.</p>



<p class="wp-block-paragraph">Om al deze redenen zijn robuuste guardrails essentieel, omdat ze een buffer vormen tegen deze uiteenlopende risico’s en helpen garanderen dat AI-toepassingen veilig, betrouwbaar en conform de verwachtingen van gebruikers en organisaties functioneren.</p>



<h1 class="wp-block-heading">Methodes en technieken</h1>



<p class="wp-block-paragraph">Guardrails worden doorgaans op twee niveaus ingezet: vlak vóór de input het taalmodel bereikt (<em>inputfilter</em>), of net na het genereren van de output maar vóór die bij de eindgebruiker terechtkomt (<em>outputfilter</em>).</p>



<figure class="wp-block-image"><a href="/wp-content/uploads/2025/11/with_and_without_guardrails.png"><img loading="lazy" decoding="async" width="1862" height="923" src="/wp-content/uploads/2025/11/with_and_without_guardrails.png" alt="Input &amp; output guardrails" class="wp-image-24456" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails.png 1862w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-300x149.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-768x381.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-1024x508.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/with_and_without_guardrails-1536x761.png 1536w" sizes="auto, (max-width: 1862px) 100vw, 1862px" /></a></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Input &amp; output guardrails &#8211; bron: <a href="https://github.com/guardrails-ai/guardrails">https://github.com/guardrails-ai/guardrails</a></p>



<p class="wp-block-paragraph">In grote lijnen bestaan er vier technieken om guardrails concreet te implementeren.</p>



<ul class="wp-block-list">
<li><strong>LLM-native guardrails</strong> zijn ingebouwde veiligheidsmechanismen die modelproviders zelf voorzien, zoals het vermijden van schadelijke outputs of beperkingen bij het volgen van bepaalde instructies. Ze bieden een eerste verdedigingslinie, maar moeten doorgaans aangevuld worden met één of meerdere van de technieken hieronder.</li>



<li>Bij<strong> prompt-gebaseerde guardrails</strong> worden specifieke instructies toegevoegd aan de prompt om het gedrag van het model te beïnvloeden. Een typisch voorbeeld is om het model te verplichten om uitsluitend te antwoorden op basis van aangeleverde contextinformatie (via RAG) zodat het geen ongecontroleerde of ongewenste output genereert. Een ander voorbeeld is het toevoegen van instructies om te vermijden dat het AI-systeem medisch advies geeft. In het voorbeeld hieronder zijn instructies te zien die toegevoegd worden aan de prompt om te vermijden dat de toepassing medisch advies geeft, samen met een voorbeeld van een conversatie waarbij de toepassing het gewenste antwoord geeft.<br><figure><a href="/wp-content/uploads/2025/11/prompt-engineering.png"><img loading="lazy" decoding="async" width="1017" height="417" class="size-full wp-image-24457" src="/wp-content/uploads/2025/11/prompt-engineering.png" alt="Prompt hardening" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering.png 1017w, https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering-300x123.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/prompt-engineering-768x315.png 768w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></a></figure><br></li>



<li><strong>Regelgebaseerde guardrails</strong> werken deterministisch met filters op basis van exacte woorden of reguliere expressies. Op die manier kan gescreend worden op bepaalde woorden of onderwerpen, en kunnen eenvoudige vormen van vertrouwelijke informatie gefilterd worden, zoals ID’s, telefoonnummers of e-mailadressen.</li>



<li><strong>LLM/ML-gebaseerde guardrails</strong> maken gebruik van machine learning modellen of zogenaamde <em>LLM-judges</em> die veel beter overweg kunnen met nuance, intentie en context. Ze kunnen zowel input als output beoordelen en kunnen deze classificeren, bijvoorbeeld om schadelijke inhoud of <em>prompt injections</em> te detecteren (dit zijn pogingen van gebruikers om het gedrag van de toepassing te manipuleren via de prompt). Daarnaast kunnen ze gevoelige informatie filteren en fact-checking uitvoeren door na te gaan of alle uitspraken in de output effectief worden ondersteund door de aangeleverde context, zoals bij RAG.</li>
</ul>



<p class="wp-block-paragraph">Elke techniek heeft een eigen nut, complexiteit en kost. Het is daarom aangeraden om eerst de specifieke risico’s voor een bepaalde usecase te evalueren en daarna te bepalen welke guardrails echt nodig zijn. Begin met de eenvoudigste methodes (prompt-gebaseerd en regelgebaseerd) en schakel pas over op complexere technieken (LLM/ML gebaseerd) wanneer dat noodzakelijk is. Deze laatste brengen namelijk extra latency en kosten met zich mee.</p>



<h1 class="wp-block-heading">Guardrail tools</h1>



<p class="wp-block-paragraph">Er bestaan heel wat tools die deze technieken ondersteunen en het eenvoudiger maken om guardrails in een toepassing te integreren. <strong>Frameworks</strong> bieden een volledige omgeving om guardrails te definiëren, combineren en orkestreren. Ze laten je regels, workflows en validatiestappen configureren zonder alles zelf te moeten bouwen. Voorbeelden zijn <a href="https://github.com/guardrails-ai/guardrails">Guardrails AI</a>, <a href="https://github.com/protectai/llm-guard/">LLM Guard</a> en <a href="https://docs.nvidia.com/nemo/guardrails">NVIDIA NeMo Guardrails</a>.</p>



<p class="wp-block-paragraph">Daarnaast zijn er <strong>API’s en services</strong> die specifieke functionaliteiten aanbieden, zoals het detecteren van schadelijke inhoud, het filteren van gevoelige gegevens of het opsporen van jailbreaks. Deze kun je rechtstreeks vanuit je toepassing aanroepen. Denk hierbij aan <a href="https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview">Azure AI Content Safety</a> of <a href="https://platform.openai.com/docs/guides/moderation">OpenAI Moderation API</a>.</p>



<p class="wp-block-paragraph">Onder de motorkap maken deze tools gebruik van een mix van ML-modellen, LLM-judges en regelgebaseerde technieken. Voorbeelden van ML-modellen zijn <a href="https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-3/">Llama Guard</a> en <a href="https://www.llama.com/docs/model-cards-and-prompt-formats/prompt-guard/">Prompt Guard</a>.</p>



<p class="wp-block-paragraph">Uit onze eigen ervaringen blijkt dat bepaalde guardrailtools merkbaar minder nauwkeurig presteren in het Nederlands en Frans ten opzichte van het Engels. We zien daarbij soms ook false positives, bijvoorbeeld wanneer selfharm-detectie onschadelijke zinnen foutief als risicovol markeert. Voor eenvoudige toepassingen met een laag risicoprofiel en uitsluitend publieke data lijkt de meerwaarde van extra guardrailtools beperkt. In zulke gevallen volstaan doorgaans de ingebouwde veiligheidsmechanismen van de LLM in combinatie met een goed ontworpen RAG-prompt.</p>



<h1 class="wp-block-heading">Conclusie</h1>



<p class="wp-block-paragraph">Samengevat is het belangrijk om guardrails steeds risicogestuurd en gelaagd in te zetten. Begin met het identificeren van de risico’s binnen de specifieke usecase en kies vervolgens de passende technieken, waarbij eenvoudige methodes de voorkeur krijgen en complexere oplossingen pas worden toegevoegd wanneer dat echt nodig is. Hoewel een combinatie van LLM-native, prompt-gebaseerde, regelgebaseerde en ML/LLM-gebaseerde guardrails een robuustere bescherming biedt, blijft het essentieel om te beseffen dat geen enkel systeem volledige veiligheid garandeert. Input- en outputfilters kunnen zowel false positives als false negatives opleveren. ML/LLM-gebaseerde guardrails brengen bovendien extra kosten en latency met zich mee. Een continue monitoring van de AI-toepassing is aangeraden om nieuwe kwetsbaarheden tijdig op te sporen en aan te pakken.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rules as Code, un parcours semé d&#8217;embûches ?</title>
		<link>https://www.smalsresearch.be/rules-as-code-fr/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Sun, 02 Nov 2025 21:04:39 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[AI4GOV]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[Society]]></category>
		<guid isPermaLink="false">/?p=24294</guid>

					<description><![CDATA[Un lien étroit entre la réglementation et sa mise en œuvre logicielle : cela semble séduisant, mais est-ce réalisable ?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Dit artikel is ook beschikbaar <a href="/rules-as-code-nl/" data-type="post" data-id="22734">in het Nederlands</a>.</em></p>



<p class="wp-block-paragraph"><em><em>Sauf indication contraire, cet article fait référence à la législation belge en vigueur au 15 octobre 2025. Les interprétations des textes législatifs dans cet article sont fournies à titre indicatif uniquement et ne font en aucun cas autorité.</em></em></p>



<p class="wp-block-paragraph">Dans une utopie administrative, le parlement vote une loi ou le gouvernement prend une décision qui modifie quelque chose, et le logiciel utilisé pour sa mise en œuvre pratique peut être adapté presque automatiquement à la modification. Le concept d&#8217;un lien étroit entre la réglementation et sa mise en œuvre logicielle est également connu sous le nom de <em>Rules as Code</em>, ou <em>RaC</em>.</p>



<p class="wp-block-paragraph">Au départ, il a surtout été exploré dans le monde juridique, dans les milieux <a href="https://law.stanford.edu/codex-the-stanford-center-for-legal-informatics/">universitaires</a>, dans les <a href="https://www.incubateurbxl.eu/">incubateurs</a> du secteur, parmi les <a href="https://smartlawhub.eu/">professionnels du droit</a> ou chez les <a href="https://www.legaltechmap.nl/">innovateurs</a> intéressés par la <a href="https://fr.wikipedia.org/wiki/LegalTech">LegalTech</a>. Un nouvel élan est apparu en 2020 lorsque l&#8217;OCDE <a href="https://www.oecd.org/fr/publications/dechiffrer-le-code_027bac0e-fr.html">a publié un rapport volumineux</a> dans lequel elle fait le point sur la situation du point de vue des pouvoirs publics, en se référant à des preuves de concept provenant de différents pays. Cela venait à point nommé, car la pandémie de COVID-19 cette même année avait confronté les gouvernements et leurs fournisseurs informatiques à des directives et des mesures en constante évolution à mesure que les connaissances scientifiques sur la maladie progressaient, et à une pression temporelle sans précédent pour mettre en œuvre chaque update le plus rapidement possible. Une technologie capable de faciliter la mise en œuvre harmonieuse de nouvelles réglementations est donc la bienvenue.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/07/2025-05-26_09h09_25.png"><img loading="lazy" decoding="async" width="1024" height="736" src="/wp-content/uploads/2025/07/2025-05-26_09h09_25-1024x736.png" alt="" class="wp-image-22779" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-1024x736.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-300x216.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-768x552.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25.png 1359w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">(c) Tim De Sousa, <em><a href="https://timdesousa.medium.com/towards-a-definition-of-rules-as-code-4a5617d96175">Towards a definition of Rules as Code</a></em>, 25/03/2021, CC-BY</figcaption></figure>



<p class="wp-block-paragraph">Certains pays sont donc passés à la vitesse supérieure. La France est en tête en matière de preuves de concept fonctionnelles, notamment avec les simulateurs <a href="https://www.mesdroitssociaux.gouv.fr/">Mes Droits Sociaux</a>, <a href="https://socio-fiscal.leximpact.an.fr/">LexImpact</a> et divers <a href="https://publi.codes/realisations">projets basés sur des <em>publicodes</em></a>. Des initiatives sont également en cours au <a href="https://www.fwd50.com/fr-FR/session/267/policy-difference-engine">Canada</a>, en <a href="https://datalex.org/">Australie</a>, en <a href="https://serviceinnovationlab.github.io/projects/legislation-as-code/">Nouvelle-Zélande</a> et aux <a href="https://regels.overheid.nl/">Pays-Bas</a>. L&#8217;UE a publié un <a href="https://interoperable-europe.ec.europa.eu/collection/govtechconnect/news/rules-code-rac">article thématique informatif sur sa plateforme GovTech Connect</a>, mentionnant plusieurs autres sources, et <a href="https://digitalgovernmenthub.org/library/government-briefing-ai-powered-rules-as-code/">aux États-Unis également, des voix s&#8217;élèvent</a> pour attirer l&#8217;attention sur ce sujet. Enfin, une <a href="https://regels.overheid.nl/blog/8/onderzoek-naar-regels-als-code-methoden">étude néerlandaise approfondie</a> nous fournit un aperçu pratique et récent des solutions <em>Rules as Code.</em></p>



<h2 class="wp-block-heading">Domaines d&#8217;application</h2>



<p class="wp-block-paragraph">Ce serait bien de pouvoir convertir une loi de manière semi-automatique en un logiciel (de préférence correct). Cependant, les <a href="https://hamish.dev/research/lac/executive-summary">expériences menées en Nouvelle-Zélande</a> nous ramènent à la réalité et démontrent de manière convaincante qu&#8217;une correspondance parfaite entre la loi et le logiciel correspondant, si tant est qu&#8217;elle soit réalisable, est même indésirable dans de nombreux cas.</p>



<p class="wp-block-paragraph">L&#8217;application des règles nécessite en effet une interprétation. Ainsi, la formulation de nombreuses lois est délibérément maintenue quelque peu abstraite, afin de les rendre largement applicables ou d&#8217;éviter que des lacunes n&#8217;apparaissent trop rapidement lorsque la société évolue. Pour chaque application pratique, ces concepts abstraits doivent être concrétisés. Ce n&#8217;est pas toujours facile&nbsp;: quand les petites réparations d&#8217;une maison louée sont-elles &#8220;de nature structurelle&#8221; (et donc à la charge du propriétaire)&nbsp;? Quand les mesures RGDP sont-elles &#8220;suffisantes&#8221;&nbsp;? Une dépense est-elle ou non une &#8220;dépense professionnelle déductible&#8221;&nbsp;? Et qui sont exactement ces vagues &#8220;autorités compétentes&#8221; auxquelles le texte de loi fait référence&nbsp;? Tout cela fait l&#8217;objet de discussions.</p>



<p class="wp-block-paragraph">Les circulaires ou les décisions administratives permettent parfois aux autorités publiques de clarifier l&#8217;interprétation souhaitée, mais il est rare d&#8217;aboutir à un ensemble complet et cohérent de règles. En cas d&#8217;ambiguïté, une différence minime d&#8217;interprétation peut faire toute la différence. Si nous imaginons une conversion entièrement automatique du texte de loi en logiciel, nous risquons de sauter ces étapes d&#8217;interprétation ou de les laisser remplir sans beaucoup de finesse par des valeurs par défaut préprogrammées. Tout juriste frémirait à cette idée, et à juste titre.</p>



<p class="wp-block-paragraph"><em>Rules as Code </em>n&#8217;est donc pas la panacée et trouve surtout des applications lorsque les règles sont sans ambiguïté et ne nécessitent que peu d&#8217;interprétation, ou lorsque les imprécisions sont acceptables et peuvent être conservées dans le résultat final. L&#8217;exemple classique est un ensemble de règles qui peuvent être réduites à un arbre de décision basé sur des critères objectivement calculables. Les applications associées sont, par exemple, les formulaires de demande, les simulateurs ou les modules de calcul. Les réglementations de nature plutôt normative, telles que les règlements de l&#8217;UE qui utilisent fréquemment des termes vagues tels que &#8220;suffisant&#8221;, &#8220;adéquat&#8221;, &#8220;approprié&#8221;, &#8220;pertinent&#8221;, etc. ne s&#8217;y prêtent pas, ce que certains universitaires ont judicieusement formulé ainsi&nbsp;: &#8220;<a href="https://www.sciencedirect.com/science/article/abs/pii/S0267364921000406?via%3Dihub">la justice ne peut être automatisée</a>&#8220;.</p>



<h2 class="wp-block-heading">Obstacles</h2>



<p class="wp-block-paragraph">Dès que l&#8217;on commence à transposer la réglementation en code, on se heurte rapidement à la complexité des liens internes entre toutes sortes de lois et de décisions. Un bon exemple est l&#8217;<a href="https://regels.overheid.nl/docs/lab/AOW">âge de la retraite aux Pays-Bas</a>&nbsp;: bien que défini de manière assez simple à l&#8217;<a href="https://wetten.overheid.nl/jci1.3:c:BWBR0002221&amp;hoofdstuk=III&amp;paragraaf=1&amp;z=2023-01-01&amp;g=2023-01-01">article 7a de la loi concernée</a>, il affecte ou est cité dans <a href="https://regels.overheid.nl/docs/assets/files/AOW-Leeftijd-vindplaatsten-in-wetgeving-6f21171f35f6fb99bf580601f64a5c51.pdf">au moins 100 autres lois ou statuts néerlandais</a>. Si l&#8217;on y touche, on risque donc rapidement de provoquer un effet domino important.</p>



<p class="wp-block-paragraph">En outre, le législateur fait preuve de créativité lorsqu&#8217;il s&#8217;agit de trouver des solutions à certaines situations rares.&nbsp;Il est courant de revoir ou d&#8217;élargir les définitions, ou d&#8217;ajouter des exceptions ou des conditions supplémentaires. Chaque amendement peut à son tour renvoyer à d&#8217;autres règles ou lois, ce qui entraîne toute une série de dépendances.</p>



<p class="wp-block-paragraph">Prenons le concept de majorité. En théorie, c&#8217;est une règle simple&nbsp;: toute personne âgée de 18 ans ou plus est majeure et donc capable d&#8217;exercer ses droits civils (<a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.488">art. 488 de l&#8217;ancien Code civil</a>). Cependant, ce tout petit article est suivi d&#8217;une série d&#8217;articles beaucoup plus longs sur les exceptions à cette règle (<a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.488/1">art. 488/1</a> et suivants), jusqu&#8217;à l&#8217;administration (art. <a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.494">494</a>&#8211;<a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.502">502</a>). Si cela ne suffit pas, le juge de paix peut également intervenir (<a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.492/1">art. 492</a>) et statuer sur une longue liste de capacités qui, au moment de la rédaction du présent document, comprend déjà 42 éléments distincts (<a href="https://www.ejustice.just.fgov.be/eli/loi/1804/03/21/1804032150/justel#Art.492/1">art. 492/1</a> §2 + §3) .</p>



<p class="wp-block-paragraph">Supposons qu&#8217;un service public soit autorisé à octroyer des subventions sur la base d&#8217;un règlement qui impose la majorité comme condition et que nous souhaitions créer un site web permettant aux citoyens de vérifier leur éligibilité. Dans ce cas, programmer<em> if (x≥18)</em> n&#8217;est pas toujours suffisant. Une personne sous tutelle qui n&#8217;est pas autorisée à gérer ses propres finances peut devoir obtenir une autre réponse. Cela n&#8217;est pas nécessairement explicitement mentionné dans le règlement relatif aux subventions, mais découle de l&#8217;application de la définition de la majorité civile telle qu&#8217;elle figure dans le code civil.</p>



<p class="wp-block-paragraph">Mais ce n&#8217;est pas tout&nbsp;: les lois peuvent étendre ou modifier les définitions antérieures. Ainsi, le concept de majorité est élargi dans la <a href="https://www.ejustice.just.fgov.be/eli/loi/2002/05/26/2002022559/justel">loi sur l&#8217;intégration sociale</a>&nbsp;: les personnes mineures mariées, enceintes ou ayant des enfants à charge sont assimilées à des personnes majeures <a href="https://www.ejustice.just.fgov.be/eli/loi/2002/05/26/2002022559/justel#Art.7">(art. 7)</a>, mais uniquement pour l&#8217;application de cette loi. En résumé&nbsp;: toute personne majeure a plus de 18 ans, mais toutes les personnes âgées de plus de 18 ans ne sont pas pleinement indépendantes, et la notion de majorité peut en outre varier selon le domaine d&#8217;application.</p>



<p class="wp-block-paragraph">L&#8217;aspect temporel introduit une dimension de complexité supplémentaire. En effet, toutes ces règles n&#8217;ont pas toujours été en vigueur. En Belgique, la majorité à 18 ans n&#8217;est entrée en vigueur que le 1er mai 1990 (loi du 19 janvier 1990, publiée au <a href="https://www.ejustice.just.fgov.be/eli/loi/1990/01/19/1990009050/staatsblad">Moniteur belge le 30 janvier 1990</a>). Auparavant, il fallait avoir 21 ans. La tutelle générale mentionnée ci-dessus a été précédée par différents statuts spéciaux, dont la &#8220;minorité prolongée&#8221; et la &#8220;tutelle provisoire&#8221;. Ces derniers ont été <a href="https://www.ejustice.just.fgov.be/eli/loi/2013/03/17/2013009163/justel#Art.27">supprimés en 2014</a>, mais en raison d&#8217;une <a href="https://www.ejustice.just.fgov.be/eli/loi/2013/03/17/2013009163/justel#Art.228">disposition transitoire</a>, ils n&#8217;ont disparu dans la pratique que le 1er septembre 2019. Des changements surviennent également en raison de fusions communales, de réformes de l&#8217;État, de pays qui n&#8217;existent plus, de règles temporaires telles que les mesures de soutien COVID, etc.</p>



<p class="wp-block-paragraph">Même si une ancienne législation a été abrogée depuis des années, ses effets peuvent encore se faire sentir longtemps. Nous voyons ainsi sur <a href="https://fin.belgium.be/fr/particuliers/declaration-impot/rentrer-declaration/declaration-impot/explications-annees-anterieures">notre déclaration d&#8217;impôts</a> de 2025 une déduction pour &#8220;<em>cotisations spéciales de sécurité sociale des années 1982 à 1988</em>&#8221; (cadre VIII, code 1388-67). Les droits sociaux acquis dans le cadre de statuts ou de régimes qui n&#8217;existent plus aujourd&#8217;hui continuent également de compter. Si un calcul dépend d&#8217;une situation passée et de la législation en vigueur à l&#8217;époque, il peut donc être nécessaire d&#8217;implémenter dans un logiciel non seulement la réglementation actuelle, mais aussi tout son historique.</p>



<p class="wp-block-paragraph">Toute cette complexité, même dans des concepts simples, ne peut que donner lieu à des lacunes ou des incohérences. Le Conseil d&#8217;État a fort à faire pour <a href="https://www.raadvst-consetat.be/?page=avis_recent_e_adviezen&amp;lang=fr">conseiller le législateur</a> et corrige régulièrement les erreurs dans les projets de texte. Même dans ce cas, le Moniteur belge doit souvent publier des errata. Le gouvernement est parfois chargé de définir les détails du contenu, mais les arrêtés royaux ou ministériels se font attendre, ce qui crée un vide pendant un certain temps. D&#8217;autres fois, la formulation n&#8217;est pas assez précise&nbsp;: par exemple, on ne précise pas s&#8217;il s&#8217;agit de jours calendaires ou de jours ouvrables.</p>



<p class="wp-block-paragraph">Lorsque des lacunes, des contradictions apparentes ou des interprétations donnent lieu à des discussions, la <a href="https://hofvancassatie.be/Arr%C3%AAts.html%23%23%23">Cour de cassation</a> doit parfois clarifier certaines choses. Bien que cela ne garantisse pas une réduction de la confusion linguistique à l&#8217;avenir, comme en témoigne ce <a href="https://hofvancassatie.be/pdf/arresten-arrets/P.25.0771.N.pdf">récent arrêt</a> dans lequel il est précisé qu&#8217;un <em>véhicule à moteur</em> au sens de la <a href="https://www.ejustice.just.fgov.be/eli/loi/1968/03/16/1968031601/justel">loi sur la circulation routière</a> ne doit pas être compris comme un <em>véhicule à moteur</em> tel que défini dans le <a href="https://www.ejustice.just.fgov.be/eli/arrete/1975/12/01/1975120109/justel">code de la route</a>&#8230;</p>



<p class="wp-block-paragraph">Enfin, il existe des cas où le texte de loi lui-même est grammaticalement ambigu. Ainsi, dans l&#8217;arrêté d&#8217;exécution du Gouvernement de la Région de Bruxelles-Capitale relatif aux travaux exemptés de permis d&#8217;urbanisme, il est mentionné à l&#8217;<a href="https://www.ejustice.just.fgov.be/eli/arrete/2008/11/13/2008031599/justel#Art.21">article21/1, 3°&nbsp;</a>: &#8220;<em>[&#8230;] la pose d&#8217;isolation [&#8230;] sur un mur mitoyen ou une façade non visible depuis l&#8217;espace public [&#8230;]&#8221;</em>. Il n&#8217;est pas clair ici si la phrase subordonnée (&#8220;non visible depuis l&#8217;espace public&#8221;) se rapporte uniquement à la façade ou à la fois à la façade et au mur mitoyen. Sans doute au grand dam de <a href="https://homegrade.brussels/">homegrade.brussels</a>, qui doit conseiller les particuliers à ce sujet et qui doit admettre dans sa <a href="https://homegrade.brussels/wp-content/uploads/2024/04/Homegrade_ficheinfo_isolation_exterieur-mur-mitoyen_FR.pdf">fiche d&#8217;information</a> sur le sujet&nbsp;: &#8220;Cet article est sujet à diverses interprétations&#8221;.</p>



<p class="wp-block-paragraph">Cela représente déjà un défi de taille dans le cadre du développement d&#8217;applications classiques. La tâche serait-elle plus simple si nous construisions notre application autour d&#8217;un framework <em>Rules as Code</em>&nbsp;? Pas vraiment&nbsp;: un framework <em>RaC</em> peut fournir une méthodologie ou une approche fixe, mais cela ne suffit pas à éliminer la complexité&nbsp;: la même quantité d&#8217;informations doit toujours être programmée, et les ambiguïtés continuent de poser les mêmes problèmes. Certains moteurs<em> RaC</em> permettent de <a href="https://medium.com/computational-law-diary/how-rules-as-code-makes-laws-better-115ab62ab6c4">détecter les lacunes dans les règles</a>, mais il faut encore décider quoi en faire. Bien définir le projet et fixer des limites reste nécessaire pour éviter d&#8217;être submergé par une avalanche de dépendances, de références et d&#8217;historique des modifications.</p>



<h2 class="wp-block-heading">La base&nbsp;: l&#8217;analyse législative</h2>



<p class="wp-block-paragraph">Supposons que nous voulions créer un logiciel qui mette en œuvre une certaine législation et qui calcule, par exemple, si vous avez droit à une subvention spécifique et, si oui, à quel montant.</p>



<p class="wp-block-paragraph">Tout d&#8217;abord, il faut trouver un moyen de convertir cette loi en une forme structurée qui facilite la conversion en code.&nbsp;Grâce à une analyse législative, nous essayons de décomposer chaque règle de cette loi en ses différents éléments. Le schéma d&#8217;analyse ci-dessous, provenant du <a href="https://minbzk.github.io/wetsanalyse/">ministère néerlandais de l&#8217;Intérieur</a>, est générique et prévoit une division en 15 classes&nbsp;:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="566" src="/wp-content/uploads/2025/07/juridisch-analyseschema-1024x566.png" alt="" class="wp-image-22781" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-1024x566.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-300x166.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-768x425.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema.png 1346w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Schéma d&#8217;analyse juridique (en NL). (c) Anouschka Ausems, John Bulles, Mariette Lokin, <a href="https://minbzk.github.io/wetsanalyse/"><em>Wetsanalyse met het juridisch analyseschema v1.0.10</em></a>, 29/11/2024, CC-0 Public Domain</figcaption></figure>



<p class="wp-block-paragraph">Les <em>variables </em>sont des caractéristiques qui peuvent varier pour chaque sujet de droit (personne ou entité)&nbsp;: pour une personne, il s&#8217;agit par exemple du sexe, du lieu de résidence, du nom, de l&#8217;état civil. Les <em>paramètres</em>, en revanche, sont les caractéristiques de la règle qui sont identiques pour tout le monde&nbsp;: un champ d&#8217;application, une date de début, une valeur d&#8217;indice, etc. Ainsi, une circulaire aura souvent pour objectif d&#8217;adapter des <em>paramètres</em> tels que la valeur de l&#8217;indice, tandis qu&#8217;une loi définira quelles <em>variables</em> peuvent être prises en compte dans l&#8217;application d&#8217;une règle et dans quelles <em>conditions</em>. Il est parfois difficile de déterminer si un terme relève des variables ou des paramètres. Les créateurs de cette méthode fournissent pour chaque catégorie une <a href="https://minbzk.github.io/wetsanalyse/#Éléments du schéma d'analyse">description et des exemples</a> qui clarifient la manière dont ils peuvent être exprimés dans un texte législatif.</p>



<p class="wp-block-paragraph">Prenons l&#8217;exemple du droit au congé de maternité, régi par le chapitre IV, <a href="https://www.ejustice.just.fgov.be/eli/loi/1971/03/16/1971031602/justel#Art.39">art.39 et suivants</a> de la loi sur le travail. En résumé, la règle de base est qu&#8217;une femme enceinte a droit à ce congé à partir de 6 semaines avant la date prévue de l&#8217;accouchement estimée par le médecin (8 semaines en cas de grossesse multiple), plus 9 semaines après l&#8217;accouchement. Une analyse rudimentaire de cette règle selon le schéma ci-dessus peut être commencée comme suit&nbsp;:</p>



<ul class="wp-block-list">
<li>La femme, son employeur et son médecin sont tous des <em>sujets de droit</em>, liés entre eux par une relation de travail ou une relation médecin-patient qui sont des <em>relations juridiques</em>.</li>



<li>L&#8217;une des<em> conditions</em> de cette loi est que la date de l&#8217;accouchement soit estimée par un médecin dans un certificat médical remis à l&#8217;employeur. Ce certificat est ici un <em>objet juridique</em>.</li>



<li>Les <em>variables</em> applicables à la femme sont notamment&nbsp;: le nombre d&#8217;enfants qu&#8217;elle attend, son lieu de résidence, son lieu de travail, la date prévue pour l&#8217;accouchement&#8230; Elles sont différentes pour chaque femme.</li>



<li>Les <em>paramètres</em> de cette loi sont notamment les délais minimaux et maximaux mentionnés&nbsp;: 6 semaines, 8 semaines, 9 semaines&#8230; Ils sont identiques pour toutes les femmes.</li>



<li><em>L&#8217;indication de la durée et du lieu</em> précise où et quand la règle s&#8217;applique&nbsp;: sur le territoire belge, et depuis les dernières modifications législatives, c.à.d. à partir du 1er juillet 2004 pour la partie prénatale et du 1er mars 2009 pour la partie postnatale du congé de maternité. L&#8217;historique des paramètres peut également être consigné. Les variables peuvent également comporter des indications temporelles si elles évoluent dans le temps.</li>
</ul>



<p class="wp-block-paragraph">La réglementation effective prévoit notamment des situations exceptionnelles pour les enfants prématurés, malades ou mort-nés, etc. En tenir compte dans l&#8217;analyse peut conduire à l&#8217;ajout de nombreux paramètres et variables supplémentaires afin de couvrir toutes ces exceptions.</p>



<p class="wp-block-paragraph">La <em>règle de déduction</em> prend alors la forme d&#8217;un calcul, dans lequel&nbsp;:</p>



<ul class="wp-block-list">
<li>l&#8217;input consiste en une &#8220;situation&#8221; décrite comme un ensemble de <em>variables</em>,</li>



<li>les <em>conditions</em> permettent d&#8217;activer ou non certains composants du calcul,</li>



<li>les <em>paramètres</em> donnent un poids aux composants du calcul,</li>



<li>l&#8217;output peut être une valeur catégorielle ou numérique,</li>



<li>le calcul peut s&#8217;appuyer sur d&#8217;autres<em> règles de déduction</em> avec leurs propres paramètres, conditions et variables.</li>
</ul>



<p class="wp-block-paragraph">Nous sommes libres de choisir le niveau de granularité ou la profondeur de notre analyse. Nous pouvons pinailler et essayer d&#8217;encoder chaque détail de la réglementation, mais nous pouvons tout aussi bien nous contenter de faire quelques généralisations, ne serait-ce que pour éviter que le logiciel final ait plus de boutons qu&#8217;un cockpit d&#8217;avion. Nous avons donc pris la femme comme point de départ ci-dessus, mais en réalité, la loi parle d&#8217;employée. Cela implique un contrat de travail valide. Nous pouvons intégrer cela avec des variables et des conditions supplémentaires, et même avec des règles supplémentaires sur les contrats de travail, mais cela apporte-t-il une valeur ajoutée&nbsp;? Il peut suffire de laisser les choses telles quelles et d&#8217;indiquer dans une clause de non-responsabilité que l&#8217;application ne s&#8217;applique qu&#8217;aux employées.</p>



<p class="wp-block-paragraph">Traduire correctement la législation en code n&#8217;est donc pas chose aisée et nécessite de prendre en compte certains éléments. Il est utile à cet égard d&#8217;établir une collaboration étroite entre les juristes, qui peuvent expliquer clairement les règles, et les développeurs de logiciels qui doivent les traduire en code informatique, avec ou sans approche <em>RaC</em>. Il en résulte également de nouveaux profils combinant des compétences juridiques et techniques&nbsp;: nous assistons progressivement à l&#8217;émergence de &#8220;legal engineers&#8221; et de &#8220;programmateurs politiques&#8221;.&nbsp;</p>



<h2 class="wp-block-heading">L&#8217;approche <em>Rules as Code</em></h2>



<p class="wp-block-paragraph">L&#8217;objectif d&#8217;une approche <em>Rules as Code</em> est de traduire les lois, les règles, les politiques, etc. dans un format structuré compréhensible par une machine. Cela peut ensuite être directement intégré dans des applications ou des sites web. L&#8217;idée est que ces applications puissent ainsi être plus facilement adaptées à une réglementation en constante évolution et que les utilisateurs puissent compter sur une plus grande transparence grâce au lien direct avec la législation.</p>



<p class="wp-block-paragraph">Il n&#8217;existe pas de normes internationalement reconnues pour l&#8217;analyse législative, ni pour l&#8217;encodage des textes législatifs. L&#8217;exemple néerlandais ci-dessus est applicable de manière générique, mais cette initiative est encore jeune. Les moteurs <em>Rules as Code</em> existants utilisent d&#8217;autres conventions, qui peuvent varier considérablement les unes des autres. Ils définissent généralement leur propre encodage, sous la forme d&#8217;un <a href="https://fr.wikipedia.org/wiki/Langage_d%C3%A9di%C3%A9">Domain-Specific Language</a> ou d&#8217;un <a href="https://fr.wikipedia.org/wiki/Langue_contr%C3%B4l%C3%A9e">Controlled Natural Language</a>, dans lequel la réglementation doit d&#8217;abord être convertie. Ce n&#8217;est qu&#8217;une fois cette étape franchie que d&#8217;autres applications peuvent être développées.</p>



<p class="wp-block-paragraph">L&#8217;absence de formats, de modèles et d&#8217;ontologies standardisés rend difficile l&#8217;adoption de <em>Rules as Code</em>. Entre les différents preuves de concept dans différents pays, parfois même au sein d&#8217;un même pays, l&#8217;<a href="https://interoperable-europe.ec.europa.eu/collection/eugovtech/document/rules-code-open-approach">interopérabilité</a> reste encore assez faible. Chaque pays ou chaque département risque ainsi d&#8217;utiliser son propre langage, approche ou méthodologie, ce qui entraîne une fragmentation et une duplication des efforts. Idéalement, il faudrait viser un vocabulaire standardisé et des règles publiées dans un format uniforme, afin qu&#8217;elles puissent être réutilisées et échangées entre différents systèmes et services publics.</p>



<p class="wp-block-paragraph">Parmi les outils <em>Rules as Code</em> existants d&#8217;une certaine importance, on trouve <a href="https://openfisca.org/en/">OpenFisca</a>, <a href="https://publi.codes/">PubliCodes</a>, <a href="https://catala-lang.org/">Català</a> et <a href="https://wendbarewetsuitvoering.pleio.nl/page/view/ba938b8f-0668-4451-a7e6-81de78bbe66a/regelspraak">RegelSpraak</a>. Nous nous tenons délibérément à distance des <a href="https://fr.wikipedia.org/wiki/Business_process_model_and_notation">BPMN</a>, <a href="https://en.wikipedia.org/wiki/CMMN">CMMN</a>, <a href="https://fr.wikipedia.org/wiki/Programmation_logique">langages de programmation logiques</a> et <a href="https://en.wikipedia.org/wiki/Business_rules_engine">rule engines</a> classiques, qui ne sont pas adaptés aux textes juridiques. Dans un prochain article, nous approfondirons notre analyse en nous focalisant sur les outils spécialement conçus pour la législation, et nous en choisirons un pour l&#8217;étudier en détail sur le plan technique.</p>



<h2 class="wp-block-heading">Conclusion provisoire</h2>



<p class="wp-block-paragraph">Les frameworks <em>Rules as Code</em> fournissent une méthode uniforme et générique pour analyser la législation. Ils offrent aux programmeurs une bibliothèque contenant les éléments de base nécessaires pour mettre en œuvre la réglementation et créer des scénarios de test, quel que soit le domaine dans lequel ils travaillent. En analysant la réglementation et en la convertissant en un <em>domain-specific language</em>, celle-ci peut être traitée par un <em>rule engine</em> ou un <em>interpreter</em>. Il est important de noter que cette conversion nécessite pour l&#8217;instant un travail humain minutieux et analytique, car elle implique une interprétation. (L&#8217;externalisation de cette étape à de grands modèles de langage ne donne pas de résultats entièrement positifs, mais nous y reviendrons dans un prochain article).</p>



<p class="wp-block-paragraph">Le niveau de détail de nombreuses réglementations rend l&#8217;analyse et la conversion vers un format <em>Rules as Code</em> rarement aisée. Si l&#8217;on souhaite aboutir à un système complet et cohérent qui tienne compte de nombreuses dépendances et situations exceptionnelles, on se retrouve confronté à une quantité impressionnante de paramètres et de variables. Si les calculs doivent pouvoir être rétroactifs et que l&#8217;historique de la législation joue également un rôle, cela ajoute une dimension supplémentaire. Les interdépendances internes entre toutes les règles font que, pour mettre en place une application <em>Rules as Code</em>, il faut rapidement s&#8217;attendre à un effort initial important.</p>



<p class="wp-block-paragraph">L&#8217;un des arguments en faveur du <em>Rules as Code</em> est qu&#8217;il permettrait de développer certains types d&#8217;applications de manière générique pour n&#8217;importe quel domaine&nbsp;: eligibility checkers, compliance tools, tax/benefit calculators, formulaires web, simulateurs de calcul, gestion de dossiers, etc. Tant que la législation sous-jacente est suffisamment claire et concrète, une même application<em> template</em> pourrait être utilisée sans trop de modifications dans tous les départements gouvernementaux. Cette idée louable se heurte toutefois à des difficultés pratiques liées à la législation elle-même, qui se réinvente presque dans chaque domaine&nbsp;: il est ainsi difficile de développer des composants communs pour la majorité ou les véhicules à moteur lorsque ces termes ont des définitions différentes dans différentes lois.</p>



<p class="wp-block-paragraph">Une autre promesse de <em>Rules as Code</em> est que les applications développées sur la base de tels frameworks restent étroitement liées à la législation, ce qui peut également être rendu visible. Ce lien doit offrir des garanties plus transparentes qu&#8217;une application est bien conforme à la législation et qu&#8217;elle le restera si cette législation venait à changer demain. En outre, il existe un potentiel pour aider à l&#8217;élaboration de règles. Un processus itératif dans lequel une version <em>RaC</em> des règles est élaborée parallèlement à la version préliminaire du texte peut permettre de détecter et de combler rapidement les lacunes, voire de faciliter l&#8217;analyse politique <em>ex ante</em> en simulant d&#8217;abord l&#8217;impact de modifications législatives hypothétiques (voir également le <a href="https://www.oecd.org/fr/publications/dechiffrer-le-code_027bac0e-fr.html">rapport de l&#8217;OCDE</a> à ce sujet). Il n&#8217;en reste pas moins que, même avec le framework <em>RaC</em>, la mise en œuvre de ce processus nécessite les mêmes investissements importants.</p>



<p class="wp-block-paragraph">Pour rassurer ceux qui craignent que les ordinateurs ne prennent bientôt le contrôle du système judiciaire, nous en sommes encore très loin. Rappelons également que le RGPD, dans son <a href="https://eur-lex.europa.eu/legal-content/FR/TXT/PDF/?uri=CELEX:32016R0679#art_22">article 22</a>, fixe des limites claires à la prise de décision automatique. En outre, une version codifiée d&#8217;une loi n&#8217;a pour l&#8217;instant aucun statut juridique ni aucune validité légale&nbsp;: seul le texte original de la loi est contraignant. En d&#8217;autres termes, même si nous convertissons la réglementation en code, le contrôle humain reste indispensable et le Moniteur belge a toujours le dernier mot.</p>



<p class="wp-block-paragraph">Affaire à suivre&#8230;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rules as Code, een hindernissenparcours?</title>
		<link>https://www.smalsresearch.be/rules-as-code-nl/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 09:29:27 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[AI4GOV]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[Society]]></category>
		<guid isPermaLink="false">/?p=22734</guid>

					<description><![CDATA[Een nauwe koppeling tussen regelgeving en de softwarematige implementatie ervan: klinkt mooi, maar is het ook haalbaar?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Cet article est aussi disponible <a href="/rules-as-code-fr/" data-type="post" data-id="24294">en français</a>.</em></p>



<p class="wp-block-paragraph"><em>Noot: dit artikel refereert naar Belgische wetgeving zoals deze gold op 15 oktober 2025, tenzij waar anders aangeduid. De interpretaties van wetteksten in dit artikel dienen slechts ter illustratie en zijn in geen geval autoritatief. </em></p>



<p class="wp-block-paragraph">In een administratief utopia stemt het parlement een wet, of neemt de regering een besluit, dat iets wijzigt, en kan de software gebruikt voor de praktische uitwerking ervan haast automatisch aangepast worden aan de wijziging. Het concept van een nauwe koppeling tussen regelgeving en de softwarematige implementatie ervan, staat ook bekend onder de naam <em>Rules as Code</em>, afgekort <em>RaC</em>.</p>



<p class="wp-block-paragraph">Initieel werd het vooral verkend in de juridische wereld, in <a href="https://law.stanford.edu/codex-the-stanford-center-for-legal-informatics/">academia</a>, in <a href="https://www.incubateurbxl.eu/">incubatoren</a> in de sector, <a href="https://smartlawhub.eu/">onder juridische professionals</a>, of bij <a href="https://www.legaltechmap.nl/">innovatoren</a> met interesse in <a href="https://en.wikipedia.org/wiki/Legal_technology">LegalTech</a>. Een hernieuwd elan kwam er in 2020 toen de OESO <a href="https://www.oecd.org/en/publications/cracking-the-code_3afe6ba5-en.html">een lijvig rapport publiceerde</a> waarin ze een stand van zaken geeft vanuit overheidsperspectief, daarbij refererend naar proof-of-concepts uit verschillende landen. Goed getimed, want de COVID-pandemie in datzelfde jaar had overheden en hun IT-leveranciers geconfronteerd met snel wijzigende richtlijnen en maatregelen naarmate de wetenschappelijke kennis over de ziekte toenam, en een ongeziene tijdsdruk om elke update zo snel mogelijk in de praktijk om te zetten. Technologie die een soepele implementatie van nieuwe regulering kan faciliteren, klinkt dan als muziek in de oren.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/07/2025-05-26_09h09_25.png"><img loading="lazy" decoding="async" width="1024" height="736" src="/wp-content/uploads/2025/07/2025-05-26_09h09_25-1024x736.png" alt="" class="wp-image-22779" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-1024x736.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-300x216.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25-768x552.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/07/2025-05-26_09h09_25.png 1359w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">(c) Tim De Sousa, <em><a href="https://timdesousa.medium.com/towards-a-definition-of-rules-as-code-4a5617d96175">Towards a definition of Rules as Code</a></em>, 25/03/2021, CC-BY</figcaption></figure>



<p class="wp-block-paragraph">Sindsdien zijn enkele landen dan ook een versnelling hoger geschakeld. Frankrijk loopt op kop wat betreft werkende proof-of-concepts, waaronder simulatoren op <a href="https://www.mesdroitssociaux.gouv.fr/">Mes Droits Sociaux</a>, <a href="https://socio-fiscal.leximpact.an.fr/">LexImpact</a>, en verscheidene <a href="https://publi.codes/realisations">projecten gebaseerd op <em>publicodes</em></a>. Ook in <a href="https://www.fwd50.com/session/267/policy-difference-engine">Canada</a>, <a href="https://datalex.org/">Australië</a>, <a href="https://serviceinnovationlab.github.io/projects/legislation-as-code/">Nieuw-Zeeland</a> en <a href="https://regels.overheid.nl/">Nederland</a> lopen er initiatieven. De EU publiceerde een informatief <a href="https://interoperable-europe.ec.europa.eu/collection/govtechconnect/news/rules-code-rac">thema-artikel op haar GovTech Connect platform</a> met vermelding van verschillende andere bronnen, en <a href="https://digitalgovernmenthub.org/library/government-briefing-ai-powered-rules-as-code/">ook in de VS gaan stemmen op</a> om er aandacht aan te besteden. Een <a href="https://regels.overheid.nl/blog/8/onderzoek-naar-regels-als-code-methoden">diepgaande Nederlandse studie</a> tenslotte voorziet ons van een handig en recent overzicht van <em>Rules as Code</em> oplossingen.</p>



<h2 class="wp-block-heading">Toepassingsdomein</h2>



<p class="wp-block-paragraph">Het klinkt mooi om een wet semi-automatisch te kunnen omzetten in (liefst correcte) software. <a href="https://hamish.dev/research/lac/executive-summary">Ervaringen uit Nieuw-Zeeland</a> zetten ons echter met de voeten op de grond en tonen overtuigend aan dat een 1-op-1 mapping tussen wet en bijhorende software, als dat al haalbaar is, in veel gevallen zelfs onwenselijk is.</p>



<p class="wp-block-paragraph">De toepassing van regels vereist immers interpretatie. Zo wordt de verwoording van veel wetgeving met opzet enigszins abstract gehouden, om ze breed toepasbaar te maken, of om te voorkomen dat er te snel mazen ontstaan wanneer de samenleving evolueert. Voor elke praktische toepassing moeten die abstracte concepten concreet ingevuld worden. Dat is niet altijd gemakkelijk: wanneer zijn kleine reparaties aan een huurhuis &#8220;structureel van aard&#8221; (dus voor rekening van de huisbaas)? Wanneer zijn GDPR-maatregelen &#8220;voldoende&#8221;? Is een uitgave wel of niet een &#8220;aftrekbare beroepskost&#8221;? En wie zijn nu exact die vage &#8220;bevoegde instanties&#8221; waar de wettekst naar verwijst? Allemaal voer voor discussie.</p>



<p class="wp-block-paragraph">Via omzendbrieven of rulings wordt de gewenste interpretatie soms wel verder verduidelijkt van overheidswege, maar dan nog kom je zelden tot een volledige en sluitende verzameling regels. Is er onduidelijkheid, dan kan een miniem verschil in interpretatie een zaak maken of kraken. Beelden we ons een volautomatische omzetting van wettekst naar software in, dan riskeren we deze interpretatieve stappen over te slaan of zonder veel finesse te laten invullen door voorgeprogrammeerde <em>default</em>-waarden. Elke jurist zal huiveren bij dat idee, en terecht.</p>



<p class="wp-block-paragraph"><em>Rules as Code</em> is dus niet zaligmakend en vindt vooral toepassingen waar regels ondubbelzinnig zijn en weinig interpretatie behoeven, of wanneer vaagheden aanvaardbaar zijn en behouden kunnen blijven in het eindresultaat. Het klassieke voorbeeld is een set regels die te herleiden zijn tot een beslisboom op basis van objectief berekenbare criteria. Applicaties die daarmee gepaard gaan zijn bijvoorbeeld aanvraagformulieren, simulatoren of rekenmodules. Regelgeving die eerder normatief van aard is, zoals EU-verordeningen met hun veelvuldig gebruik van vage termen zoals &#8220;voldoende&#8221;, &#8220;adequaat&#8221;, &#8220;geschikt&#8221;, &#8220;relevant&#8221;, &#8230; leent zich er niet toe &#8211; wat enkele academici gevat verwoord hebben als: <a href="https://www.sciencedirect.com/science/article/abs/pii/S0267364921000406?via%3Dihub">&#8220;rechtvaardigheid kan men niet automatiseren&#8221;</a>.</p>



<h2 class="wp-block-heading">Hindernissen</h2>



<p class="wp-block-paragraph">Eens men begint aan de oefening om regelgeving om te zetten in code, botst men al snel op de complexe interne verwevenheden tussen allerlei wetten en besluiten. Een mooie illustratie is de  <a href="https://regels.overheid.nl/docs/lab/AOW">Nederlandse pensioenleeftijd</a>: zelf vrij rechttoe rechtaan gedefinieerd in <a href="https://wetten.overheid.nl/jci1.3:c:BWBR0002221&amp;hoofdstuk=III&amp;paragraaf=1&amp;z=2023-01-01&amp;g=2023-01-01">artikel 7a van de betreffende wet</a>, heeft ze impact op, of wordt ernaar verwezen in, <a href="https://regels.overheid.nl/docs/assets/files/AOW-Leeftijd-vindplaatsten-in-wetgeving-6f21171f35f6fb99bf580601f64a5c51.pdf">minstens 100 andere Nederlandse wetten</a> of statuten. Als daaraan gemorreld wordt, riskeer je dus al snel grote domino-effecten.</p>



<p class="wp-block-paragraph">Daarnaast komt de wetgever creatief uit de hoek als er oplossingen gevonden moeten worden voor bepaalde zeldzame situaties.&nbsp;Het herbekijken of uitbreiden van definities, of toevoegen van uitzonderingsbepalingen of extra voorwaarden, is courante praktijk. Elk amendement kan op zijn beurt verwijzen naar weer andere regels of wetten, wat een hele keten aan afhankelijkheden met zich meebrengt.</p>



<p class="wp-block-paragraph">Neem het concept van meerderjarigheid. In theorie is dat een eenvoudige regel: wie 18 is of ouder, is meerderjarig en bijgevolg handelingsbekwaam (<a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.488">art. 488 oud B.W.</a>). Dat piepkleine artikeltje wordt echter gevolgd door een resem veel langere artikels over de uitzonderingen daarop (<a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.488/1">art.488/1</a> e.v.), tot en met bewindvoering (art. <a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.494">494</a>&#8211;<a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.502">502</a>). Als dat niet voldoet, kan ook de vrederechter ingrijpen (<a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.492/1">art.492</a>) en oordelen over een waslijst aan bekwaamheden die op moment van schrijven al 42 afzonderlijke items bevat (<a href="https://www.ejustice.just.fgov.be/eli/wet/1804/03/21/1804032150/justel#Art.492/1">art.492/1</a> §2 + §3).</p>



<p class="wp-block-paragraph">Stel dat een overheidsdienst subsidies mag uitdelen op basis van een reglement dat meerderjarigheid als voorwaarde stelt, en we willen een website bouwen waar burgers een <em>eligibility check</em> kunnen doen, dan is <code><em>if (x≥18)</em></code> programmeren niet altijd voldoende. Iemand die onder bewindvoering staat en zijn eigen geldzaken niet mag beheren, moet mogelijk alsnog een ander antwoord krijgen. Dat staat niet noodzakelijk expliciet in dat subsidiereglement, maar is een gevolg van het hanteren van de definitie van meerderjarigheid uit het burgerlijk wetboek.</p>



<p class="wp-block-paragraph">Daarmee is de kous nog niet af: wetten kunnen eerdere definities uitbreiden of wijzigen. Zo wordt het concept van meerderjarigheid in de <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel">wet op de Maatschappelijke Integratie</a> verruimd: minderjarigen die gehuwd zijn, zwanger zijn, of kinderen ten laste hebben worden gelijkgesteld aan meerderjarig <a href="https://www.ejustice.just.fgov.be/eli/wet/2002/05/26/2002022559/justel#Art.7">(Art. 7)</a> &#8211; maar enkel voor de toepassing van die wet. Samengevat: elke meerderjarige is 18+, maar niet elke 18+er is ten volle zelfstandig meerderjarig, en wat begrepen mag worden onder meerderjarigheid kan bovendien per toepassingsgebied nog verschillen.</p>



<p class="wp-block-paragraph">Het temporele aspect voegt daar nog een hele dimensie van complexiteit aan toe. Niet al deze regels golden immers altijd. De meerderjarigheid op 18 jaar is in België pas in werking getreden op 1 mei 1990 (wet van 19 januari 1990, gepubliceerd in het <a href="https://www.ejustice.just.fgov.be/eli/wet/1990/01/19/1990009050/staatsblad">Belgisch staatsblad op 30 januari 1990</a>). Voordien moest men 21 zijn. De hierboven aangehaalde algemene bewindvoering werd dan weer voorafgegaan door verschillende speciale statuten, waaronder &#8220;verlengde minderjarigheid&#8221; en &#8220;voorlopige bewindvoering&#8221;. Deze werden <a href="https://www.ejustice.just.fgov.be/eli/wet/2013/03/17/2013009163/justel#Art.27">afgeschaft in 2014</a>, maar door een <a href="https://www.ejustice.just.fgov.be/eli/wet/2013/03/17/2013009163/justel#Art.228">overgangsbepaling</a> doofden ze pas uit in de praktijk op 1 september 2019. Wijzigingen gebeuren ook door gemeentelijke fusies, staatshervormingen, landen die niet meer bestaan, tijdelijke regels zoals de COVID-steunmaatregelen, &#8230;</p>



<p class="wp-block-paragraph">Al is oude wetgeving al jaren opgeheven, de effecten ervan kunnen nog lang nazinderen. Zo zien we op <a href="https://fin.belgium.be/nl/particulieren/belastingaangifte/indienen/aangifte/toelichting-voorgaande-jaren">onze belastingaangifte</a> in 2025 nog een aftrekpost voor <em>&#8220;bijzondere bijdragen voor de sociale zekerheid van de jaren 1982 tot 1988&#8221;</em> (vak VIII, code 1388-67). Ook sociale rechten opgebouwd in statuten of regimes die vandaag niet meer bestaan, tellen nog steeds mee. Als een berekening afhangt van een situatie uit het verleden en de destijds geldende wetgeving, kan het dus nodig zijn om in een applicatie naast de huidige regelgeving ook de hele voorgeschiedenis ervan te implementeren.</p>



<p class="wp-block-paragraph">Met al deze complexiteit in zelfs eenvoudige concepten, kan het niet anders of er duiken onvolledigheden of inconsistenties op. De Raad van State heeft haar handen vol met het <a href="https://www.raadvst-consetat.be/?lang=nl&amp;page=avis_recent_e_adviezen">adviseren van de wetgever</a>, en haalt regelmatig fouten uit ontwerpteksten. Zelfs dan moet het Staatsblad vaak nog errata publiceren. Soms wordt de invulling van inhoudelijke details overgelaten aan de regering, maar laten de Koninklijke of ministeriële besluiten lang op zich wachten, waardoor er een tijd lang een vacuüm ontstaat. Andere keren is men niet exact genoeg in de verwoording: men verduidelijkt bijvoorbeeld niet of men spreekt over kalenderdagen of werkdagen.</p>



<p class="wp-block-paragraph">Daar waar onvolledigheid, ogenschijnlijke tegenspraak of interpretatie voor discussie zorgt, moet het <a href="https://hofvancassatie.be/nl/Arr%C3%AAts.html">Hof van Cassatie</a> soms één en ander ophelderen. Al is dat geen garantie op minder spraakverwarring in de toekomst, getuige <a href="https://hofvancassatie.be/pdf/arresten-arrets/P.25.0771.N.pdf">dit recente arrest</a> waarin ze aanstippen dat een <em>motorvoertuig</em> in de <a href="https://www.ejustice.just.fgov.be/eli/wet/1968/03/16/1968031601/justel">Wegverkeerswet</a>, niet begrepen mag worden als een <em>motorvoertuig </em>zoals gedefinieerd in de <a href="https://www.ejustice.just.fgov.be/eli/besluit/1975/12/01/1975120109/justel">Wegcode</a>&#8230;</p>



<p class="wp-block-paragraph">Tot slot zijn er nog gevallen waar de wettekst zelf grammaticaal ambigu is. Zo wordt in het uitvoeringsbesluit van de Brusselse Hoofdstedelijke Regering over werken die vrijgesteld zijn van stedenbouwkundige vergunning, vermeld in <a href="https://www.ejustice.just.fgov.be/eli/besluit/2008/11/13/2008031599/justel#Art.21">art. 21/1, 3° lid</a>: <em>&#8220;[&#8230;] de plaatsing van isolatie [&#8230;] op een mandelige muur of een gevel die niet zichtbaar is vanaf de openbare ruimte [&#8230;]&#8221;</em>. Het is hier onduidelijk of de bijzin (aangevat met <em>die</em>) enkel betrekking heeft op de gevel, of zowel op de gevel als op de gedeelde muur. Ongetwijfeld tot ergernis van <a href="https://homegrade.brussels/nl">homegrade.brussels</a>, dat particulieren hierover moet adviseren, en in <a href="https://homegrade.brussels/wp-content/uploads/2024/04/Homegrade_infofiche_isolatie_buitenzijde-gemene-muur_NL.pdf">haar informatiefiche</a> over het onderwerp moet toegeven: &#8220;Dit artikel is voor verschillende interpretaties vatbaar&#8221;.</p>



<p class="wp-block-paragraph">Dit alles is bij klassieke applicatie-ontwikkeling al een hele kluif. Wordt het dan eenvoudiger als we onze app bouwen rond een <em>Rules as Code</em>-framework? Niet echt: een <em>RaC</em>-framework reikt misschien een vaste methodiek of werkwijze aan, maar dat neemt de complexiteit niet weg: dezelfde karrevracht informatie moet er nog steeds ingeprogrammeerd worden, en ambiguïteiten blijven voor dezelfde problemen zorgen. Sommige <em>RaC</em>-engines zullen toelaten om <a href="https://medium.com/computational-law-diary/how-rules-as-code-makes-laws-better-115ab62ab6c4">lacunes in de regels te detecteren</a>, maar dan nog moet je beslissen wat je ermee doet. Het project goed afbakenen en grenzen stellen is nog steeds noodzakelijk, om te vermijden overdonderd te worden door een lawine van afhankelijkheden, verwijzingen, en wijzigingshistoriek.</p>



<h2 class="wp-block-heading">De basis: wetsanalyse</h2>



<p class="wp-block-paragraph">Stel dat we een app willen maken die een bepaalde wetgeving implementeert, en bijvoorbeeld berekent of je recht hebt op een specifieke subsidie en zo ja, hoeveel. </p>



<p class="wp-block-paragraph">Allereerst is dan een manier nodig om die wet om te zetten in een gestructureerde vorm die de omzetting naar code faciliteert.&nbsp;Via een <em>wetsanalyse</em> trachten we elke regel uit die wet te ontleden in haar onderdelen. Het analyseschema hieronder, afkomstig van het <a href="https://minbzk.github.io/wetsanalyse/">Nederlands ministerie van Binnenlandse Zaken</a>, is generiek toepasbaar en voorziet een opdeling in 15 klassen:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="566" src="/wp-content/uploads/2025/07/juridisch-analyseschema-1024x566.png" alt="" class="wp-image-22781" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-1024x566.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-300x166.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema-768x425.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/07/juridisch-analyseschema.png 1346w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Juridisch Analyseschema. (c) Anouschka Ausems, John Bulles, Mariette Lokin, <a href="https://minbzk.github.io/wetsanalyse/"><em>Wetsanalyse met het juridisch analyseschema v1.0.10</em></a>, 29/11/2024, CC-0 Public Domain</figcaption></figure>



<p class="wp-block-paragraph">De <em>variabelen</em> zijn eigenschappen die voor elk rechtssubject (persoon of entiteit) kunnen verschillen: voor een persoon zijn dat bijvoorbeeld het geslacht, de woonplaats, de naam, de burgerlijke staat. De <em>parameters </em>daarentegen zijn de eigenschappen van de regel die gelijk zijn voor iedereen: een toepassingsgebied, een startdatum, een indexwaarde, &#8230; Zo zal een omzendbrief vaak tot doel hebben om <em>parameters </em>zoals de indexwaarde aan te passen, en zal een wet definiëren welke <em>variabelen </em>onder welke <em>voorwaarden </em>bij de toepassing van een regel in rekening gebracht mogen worden. Het is soms moeilijk te beoordelen of een term nu onder de variabelen of de parameters valt. De makers van deze methode geven bij elke klasse een <a href="https://minbzk.github.io/wetsanalyse/#elementen-uit-het-jas">omschrijving en voorbeelden</a> die verduidelijken hoe ze uitgedrukt kunnen worden in een wettekst. </p>



<p class="wp-block-paragraph">Nemen we als voorbeeld het recht op het moederschapsverlof, geregeld in hoofdstuk IV, <a href="https://www.ejustice.just.fgov.be/eli/wet/1971/03/16/1971031602/justel#Art.39">art. 39 e.v.</a> van de Arbeidswet. De basisregel daarvan is, bondig samengevat, dat een zwangere vrouw recht heeft op dit  verlof vanaf 6 weken vóór de door de arts geschatte datum van de bevalling (8 weken bij meerlingen), plus 9 weken na de bevalling. Een rudimentaire analyse van deze regel volgens bovenstaand schema kunnen we als volgt aanvangen:</p>



<ul class="wp-block-list">
<li>De vrouw, haar werkgever en haar arts zijn allen <em>rechtssubjecten</em>, met elkaar verbonden door een arbeidsrelatie resp. arts-patiëntrelatie die <em>rechtsbetrekkingen</em> zijn.</li>



<li>Een van de <em>voorwaarden </em>in deze wet is dat de bevallingsdatum is ingeschat door een arts in een geneeskundig attest dat aan de werkgever wordt overgemaakt. Dat attest is hier een <em>rechtsobject</em>.</li>



<li>De <em>variabelen </em>van toepassing op de vrouw zijn onder andere: hoeveel kinderen ze verwacht, haar woonplaats, arbeidsplaats, bevallingsdatum&#8230; dit is voor elke vrouw anders.</li>



<li><em>Parameters </em>van deze wet zijn o.a. de minimum- en maximumtermijnen waarvan sprake: 6 weken, 8 weken, 9 weken, &#8230; die zijn gelijk voor elke vrouw.</li>



<li><em>Tijds</em>&#8211; en <em>plaatsaanduiding </em>zeggen waar en wanneer de regel geldt: op Belgisch grondgebied, en sinds de laatste wetswijzigingen vanaf 1 juli 2004 voor het prenatale en 1 maart 2009 voor het postnatale deel van het moederschapsverlof. De voorgeschiedenis van parameters kan ook worden vastgelegd. V<em>ariabelen </em>kunnen ook tijdsaanduidingen hebben als ze evolueren doorheen de tijd.</li>
</ul>



<p class="wp-block-paragraph">De eigenlijke regelgeving voorziet o.a. nog in uitzonderingssituaties voor kinderen die te vroeg, ziek, of levenloos geboren worden,&#8230; Dat meenemen in de analyse kan leiden tot de toevoeging van vele extra parameters en variabelen om al deze uitzonderingen te vatten.</p>



<p class="wp-block-paragraph">De <em>afleidingsregel</em> neemt dan de vorm aan van een berekening, waarbij:</p>



<ul class="wp-block-list">
<li>de input bestaat uit een &#8220;situatie&#8221; die beschreven wordt als een verzameling <em>variabelen</em>,</li>



<li>de <em>voorwaarden </em>toelaten om bepaalde componenten van de berekening te activeren of niet,</li>



<li>de <em>parameters </em>aan componenten van de berekening een gewicht geven,</li>



<li>de output zowel een categorische als numerieke waarde kan zijn,</li>



<li>de berekening kan steunen op andere <em>afleidingsregels </em>met hun eigen parameters, voorwaarden en variabelen.</li>
</ul>



<p class="wp-block-paragraph">Het staat ons vrij om te kiezen hoe granulair we daarin willen zijn, of hoe diep we willen gaan in onze analyse. We kunnen pietje precies zijn en elk detail van de regelgeving proberen encoderen, maar even goed kunnen we vrede nemen met het maken van enkele veralgemeningen, al was het maar om te vermijden dat de uiteindelijke app meer knopjes heeft dan een vliegtuigcockpit. Zo namen we hierboven de <em>vrouw </em>als startpunt, maar eigenlijk spreekt de wet van <em>werkneemster</em>. Dat impliceert een geldig arbeidscontract. Dat kunnen we integreren met extra variabelen en voorwaarden, en zelfs met extra regels over arbeidscontracten, maar biedt dat ook meerwaarde? Het kan voldoende zijn om het zo te laten en in een disclaimer te zeggen dat de app enkel van toepassing is voor werkneemsters.</p>



<p class="wp-block-paragraph">Wetgeving correct in code vertalen is dus niet eenvoudig, en vergt de nodige afwegingen. Het is daarbij nuttig om een nauwe samenwerking op te zetten tussen juristen, die de regels helder kunnen uitleggen, en de software-ontwikkelaars die dat in code moeten gieten, met of zonder <em>RaC</em>-framework. Daaruit komen ook nieuwe profielen voort met zowel juridische als technische vaardigheden: we zien stilaan &#8220;legal engineers&#8221; en &#8220;beleidsprogrammeurs&#8221; opduiken.&nbsp;</p>



<h2 class="wp-block-heading">de <em>Rules as Code</em> aanpak</h2>



<p class="wp-block-paragraph">Het opzet van een <em>Rules as Code</em> benadering is om wetten, regels, policies, &#8230; te hertalen in een gestructureerd formaat dat door een machine begrepen kan worden. Dit kan dan op zijn beurt direct geïntegreerd worden in applicaties of websites. Het idee is dat deze applicaties zo gemakkelijker kunnen aangepast worden aan snel evoluerende regelgeving, en dat ook gebruikers ervan door de directe link met de wetgeving op meer transparantie kunnen rekenen.</p>



<p class="wp-block-paragraph">Er bestaan geen internationaal aanvaarde standaarden voor wetsanalyse, noch voor encodering van wettekst. Het Nederlandse voorbeeld hierboven is generiek toepasbaar, maar is nog een jong initiatief. Bestaande <em>Rules as Code</em> engines hanteren andere conventies, die sterk van elkaar kunnen verschillen. Ze definiëren meestal hun eigen encodering, in de vorm van een <a href="https://en.wikipedia.org/wiki/Domain-specific_language">Domain-Specific Language</a> of <a href="https://en.wikipedia.org/wiki/Controlled_natural_language">Controlled Natural Language</a>, waarin de regelgeving eerst omgezet moet worden. Pas als die stap is gebeurd, kunnen er verder applicaties op worden gebouwd.</p>



<p class="wp-block-paragraph">Het gebrek aan gestandaardiseerde formaten, modellen en ontologieën bemoeilijkt de adoptie van <em>Rules as Code</em>. Tussen de verschillende proof-of-concepts in verschillende landen, soms ook binnen hetzelfde land, is de <a href="https://interoperable-europe.ec.europa.eu/collection/eugovtech/document/rules-code-open-approach">interoperabiliteit</a> nog steeds vrij laag. Ieder land of ieder departement dreigt zo een eigen taal, aanpak of methodiek te gaan hanteren, wat leidt tot fragmentatie en dubbel werk. Idealiter zou gestreefd moeten worden naar een gestandaardiseerd vocabularium, en regels gepubliceerd in een uniform formaat, zodat ze hergebruikt en uitgewisseld kunnen worden tussen verschillende systemen en overheidsdiensten.</p>



<p class="wp-block-paragraph">Onder de bestaande <em>Rules as Code</em> tools van enige grootte vinden we <a href="https://openfisca.org/en/">OpenFisca</a>,&nbsp;<a href="https://publi.codes/">PubliCodes</a>, <a href="https://catala-lang.org/">Català </a>en <a href="https://wendbarewetsuitvoering.pleio.nl/page/view/ba938b8f-0668-4451-a7e6-81de78bbe66a/regelspraak">RegelSpraak</a>. We houden met opzet wat afstand van <a href="https://nl.wikipedia.org/wiki/Business_Process_Model_and_Notation">BPMN</a>, <a href="https://en.wikipedia.org/wiki/CMMN">CMMN</a>, <a href="https://en.wikipedia.org/wiki/Logic_programming">logische programmeertalen</a> en klassieke <a href="https://en.wikipedia.org/wiki/Business_rules_engine">rule engines</a>, die niet toegespitst zijn op juridische teksten. In een volgend artikel verdiepen we onze analyse met een focus op tools die wel specifiek gebouwd zijn voor wetgeving, waarbij we er eentje zullen kiezen om technisch in detail te bekijken.</p>



<h2 class="wp-block-heading">Tussentijdse conclusie</h2>



<p class="wp-block-paragraph"><em>Rules as Code</em> frameworks voorzien in een uniforme, generieke manier om aan wetsanalyse te doen. Voor programmeurs bieden ze een library met fundamentele bouwblokken om regelgeving te implementeren en testscenario&#8217;s op te zetten, ongeacht het domein waarin men actief is. Door de regelgeving te analyseren en om te zetten naar een <em>domain-specific language</em>, kan die door een <em>rule engine</em> of <em>interpreter</em> verwerkt worden. Belangrijk te noteren is dat deze omzetting vooralsnog minutieus analytisch mensenwerk vergt, omdat er interpretatie bij komt kijken. (Deze stap uitbesteden aan Large Language Models leidt niet tot onverdeeld positieve resultaten, maar daarover meer in een volgend artikel). </p>



<p class="wp-block-paragraph">De mate van detail in veel regelgeving, maakt een analyse en omzetting naar een <em>Rules as Code</em>-formaat zelden een sinecure. Wil men tot een compleet en sluitend systeem komen dat rekening houdt met vele afhankelijkheden en uitzonderingssituaties, dan wordt men geconfronteerd met overdonderende hoeveelheden parameters en variabelen. Als berekeningen retroactief moeten kunnen zijn en ook de voorgeschiedenis van de wetgeving een rol speelt, komt daar nog een extra dimensie bij. De interne verwevenheden tussen alle regels maken dat men, om een <em>Rules as Code</em>-app van de grond te krijgen, al snel aankijkt tegen een grote initiële inspanning.</p>



<p class="wp-block-paragraph">Eén van de argumenten voor <em>Rules as Code </em>is dat men bepaalde soorten apps generiek zou kunnen ontwikkelen voor eender welk domein: eligibility checkers, compliance tools, tax/benefit calculators, webformulieren, rekensimulatoren, dossierbeheer,&#8230; Zolang de onderliggende wetgeving maar duidelijk en concreet genoeg is, zou dan eenzelfde <em>template</em>-app zonder veel aanpassingen over de grenzen van overheidsdepartementen heen benut kunnen worden. Dit lovenswaardige idee stuit in de praktijk echter op moeilijkheden door de wetgeving zelf, die zichzelf haast heruitvindt in elk domein: zo kan je moeilijk gedeelde componenten ontwikkelen voor <em>meerderjarigheid</em> of <em>motorvoertuigen</em> als die termen verschillende definities hebben in verschillende wetten.</p>



<p class="wp-block-paragraph">Een andere belofte van <em>Rules as Code</em> is dat apps ontwikkeld op basis van zulke frameworks een nauwe koppeling behouden met de wetgeving, die ook zichtbaar gemaakt kan worden. Deze koppeling moet transparantere garanties bieden dat een app wel degelijk conformeert aan de wetgeving, en dat dat ook zo blijft als die wetgeving morgen wijzigt. Daarnaast is er potentieel om te helpen bij het opstellen van regels. Een iteratief proces waarbij een <em>RaC</em>-versie van de regels wordt ontwikkeld in parallel met de ontwerpversie van de tekst, kan het mogelijk maken om vroegtijdig lacunes op te sporen en te verhelpen, of kan zelfs <em>ex ante</em> beleidsanalyse faciliteren door de impact van hypothetische wetswijzigingen eerst te simuleren (zie daarvoor ook het <a href="https://www.oecd.org/en/publications/cracking-the-code_3afe6ba5-en.html">OESO-rapport</a>). Maar ook hier komt men er niet onderuit dat de uitwerking daarvan, ook mét <em>RaC</em>-framework, dezelfde grote investeringen vergt.</p>



<p class="wp-block-paragraph">Wie vreest dat computers het rechtssysteem binnenkort gaan overnemen kunnen we dus geruststellen, daar zijn we nog heel ver van weg. We herinneren ook nog even aan de GDPR, die in <a href="https://eur-lex.europa.eu/legal-content/NL/TXT/HTML/?uri=CELEX:32016R0679#art_22">art.22</a> duidelijke grenzen stelt aan automatische besluitvorming. Daarnaast heeft een gecodeerde versie van een wet vooralsnog geen juridische status of rechtsgeldigheid &#8211; alleen de oorspronkelijke geschreven wettekst is bindend. Met andere woorden, zelfs al zetten we regelgeving om in code, is behoud van menselijk overzicht nog steeds een must, en heeft het Staatsblad nog steeds het laatste woord.</p>



<p class="wp-block-paragraph">Wordt vervolgd!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ingestion van ongestructureerde data: hoe maak je automatisch een graph op basis van tekst?</title>
		<link>https://www.smalsresearch.be/ingestion-van-ongestructureerde-data-graph/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Mon, 06 Oct 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[data ingestion]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Large Language Model]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<guid isPermaLink="false">/?p=24036</guid>

					<description><![CDATA[Dit artikel gaat in op de manieren waarop een graph kan worden verkregen op basis van tekstuele data, de verschillende soorten graphs die kunnen worden geëxtraheerd en de tools die vaak worden gebruikt.]]></description>
										<content:encoded><![CDATA[
<p><a href="/ingestion-donnees-non-structurees-vers-graphe/"><em>Version en Français</em></a></p>
<p>Graphs, en meer bepaald knowledge graphs, maken het mogelijk om <a href="/graphtechnologieen-toepassingen-en-tools-2/">informatie op een gestructureerde manier weer te geven</a>. Zo krijgt een persoon een visuele samenvatting van de inhoud van een of meerdere documenten en kan een machine deze structuur gebruiken om bijvoorbeeld de inhoud ervan te analyseren (met behulp van <a href="/graphtechnologieen-toepassingen-en-tools/">graphalgoritmen</a>) en/of redeneringen te maken op basis van de graph (bijvoorbeeld in het kader van <a href="/graphrag-naar-een-knowledge-graph-augmented-generatie/">een graphRAG-toepassing</a> of om impliciete informatie te ontdekken (af te leiden)).</p>
<p>Dit artikel gaat in op de manieren waarop een graph kan worden verkregen op basis van tekstuele data, de verschillende soorten graphs die kunnen worden geëxtraheerd en de tools die vaak worden gebruikt, afhankelijk van het type extractie dat men wil uitvoeren.</p>
<p>Aangezien grote taalmodellen (LLM&#8217;s) bijzonder geschikt zijn voor tekstverwerking, zal dit artikel zich voornamelijk richten op de presentatie van LLM-gebaseerde benaderingen en vervolgens kort ingaan op verschillende alternatieve benaderingen.</p>



<h2 class="wp-block-heading">Knowledge graphs: een kort overzicht</h2>



<p>Een graph is een structuur die bestaat uit een reeks nodes en bogen (die paren van nodes met elkaar verbinden). Een knowledge graph voegt een extra semantische laag toe aan een klassieke graph, waarbij elke node een concept vertegenwoordigt (entiteit, persoon, enz.) en elke boog een relatie tussen twee concepten vertegenwoordigt (“werkt voor”, “is bevriend met”, enz.). Het is dus een weergave van kennis in de vorm van een reeks onderling verbonden entiteiten. Meer details over de verschillende soorten graphs en de bijbehorende tools vindt u <a href="/graphtechnologieen-toepassingen-en-tools/">hier</a>.</p>



<h2 class="wp-block-heading">Voorbereiding van het documentcorpus</h2>



<p>Voor de eenvoud gaan we ervan uit dat de tekstdocumenten die worden gebruikt om de graph op te bouwen, correct zijn opgeschoond. Dit artikel is namelijk niet bedoeld om de voorbewerking van tekstdocumenten (scrapen van webpagina&#8217;s, extraheren van tekst uit pdf-bestanden, enz.) te bespreken, aangezien deze voorbewerking op zich al een uitgebreid onderwerp is dat ongetwijfeld een apart artikel verdient.</p>



<h3 class="wp-block-heading">Fragmentatie van de tekst in “chunks”</h3>



<p>Een belangrijke stap in de voorbereiding van tekstdata voordat entiteiten en relaties worden geëxtraheerd, is het opsplitsen van de tekst in fragmenten (meestal ‘chunks’ genoemd). We hebben het concept van chunking al meerdere keren besproken in <a href="/databeheer-voor-generatieve-ai-toepassingen-kernbegrippen/">vorige blogposts</a>. Wanneer een document te lang is (meer dan enkele paragrafen), is het raadzaam om het op te splitsen in chunks (tekstfragmenten van redelijke omvang) die één voor één door de LLM worden verwerkt. Deze procedure maakt het mogelijk om de hoeveelheid informatie in elke chunk te beperken, zodat deze niet te veel entiteiten en relaties bevat die moeten worden geëxtraheerd. Deze opsplitsing in chunks kan op verschillende manieren gebeuren, hetzij op basis van het aantal woorden in de chunk, hetzij op basis van een vooraf gedefinieerd scheidingsteken (bijvoorbeeld een regeleinde dat het einde van de paragraaf aangeeft).</p>



<h2 class="wp-block-heading">De informatie weergeven of de structuur weergeven</h2>



<p>Laten we beginnen met de twee belangrijkste soorten graphs die kunnen worden geconstrueerd op basis van een reeks tekstdocumenten.</p>
<p>De eerste is een graph die de structuur van het document weergeeft (<em>document structure graph</em>), en niet de informatie die in de tekst staat. Bijvoorbeeld door de chunks te koppelen aan het document waaruit ze zijn gehaald en de volgorde waarin ze in het document voorkomen:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Document_structure_graph.png"><img loading="lazy" decoding="async" width="939" height="527" src="/wp-content/uploads/2025/09/Document_structure_graph.png" alt="" class="wp-image-23750" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph.png 939w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-300x168.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-768x431.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></a><figcaption class="wp-element-caption">Figuur 1: Graph die de structuur van een eenvoudig document weergeeft</figcaption></figure>



<p>Dit type graph kan ook worden verrijkt door relaties toe te voegen tussen semantisch vergelijkbare chunks of, indien van toepassing, door de hiërarchische organisatie van het document weer te geven in secties, subsecties, enz. Dit gebeurt via nodes die de secties/subsecties vertegenwoordigen en relaties van het type “HAS_SECTION”, “HAS_SUBSECTION”, evenals relaties die de volgorde van de secties/subsecties aangeven. Zodra de graph is opgebouwd, kan deze bijvoorbeeld worden gebruikt in RAG-toepassingen voor indexeringsdoeleinden om context te bieden aan de gebruikte chunks (zie <a href="/graphrag-naar-een-knowledge-graph-augmented-generatie/">onze blogpost over graphRAG</a>).</p>
<p>Het tweede type graph bestaat uit het opnemen van de informatie in de documenten in de vorm van nodes en relaties:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Domain_graph.png"><img loading="lazy" decoding="async" width="877" height="179" src="/wp-content/uploads/2025/09/Domain_graph.png" alt="" class="wp-image-23751" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-768x157.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figuur 2: Voorbeeld van informatie-extractie</figcaption></figure>



<p>In het kader van deze blogpost zullen we ons concentreren op dit tweede type graph. Merk op dat beide benaderingen elkaar niet uitsluiten. Als men voor het tweede type graph kiest, is het trouwens vaak nuttig om ook de documentstructuur weer te geven. Zo kan men indien nodig teruggaan naar de bron van de informatie in de graph.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Graph_combined.png"><img loading="lazy" decoding="async" width="896" height="674" src="/wp-content/uploads/2025/09/Graph_combined.png" alt="" class="wp-image-23754" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined.png 896w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-300x226.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-768x578.png 768w" sizes="auto, (max-width: 896px) 100vw, 896px" /></a><figcaption class="wp-element-caption">Figuur 3: Extractie van structuur en informatie</figcaption></figure>



<h2 class="wp-block-heading">Opbouw van een knowledge graph met behulp van een LLM</h2>



<p>Eerst zullen we de algemene procedure voor het aanmaken van een knowledge graph op basis van tekstdocumenten via LLM voorstellen, alvorens te bekijken hoe deze aan de eigen behoeften kan worden aangepast.</p>
<p>LLM&#8217;s ontvangen standaard tekst als input (prompt) en sturen tekst terug als output in reactie op de prompt. Afhankelijk van de instructies bieden LLM&#8217;s echter de mogelijkheid om <strong><em>gestructureerde outputs</em></strong> te genereren, zoals JSON-bestanden. Vaak wordt deze functionaliteit gebruikt als basis voor het extraheren van kennis naar een graph, omdat deze gestructureerde output systematisch kan worden verwerkt.</p>
<p>Een script (bv. Python) haalt de chunks op en stuurt ze een voor een naar de LLM door een gestructureerd antwoord op te leggen (bv. <a href="https://python.langchain.com/docs/how_to/structured_output/">LangChain met de methode <em>llm.with_structured_output()</em></a>), met instructies over de taak, het type informatie dat in de tekst moet worden gedetecteerd en de structuur van het verwachte antwoord in de output. De gestructureerde output (meestal in JSON) wordt vervolgens eenvoudigweg ontleed in Python om de door de LLM gedetecteerde informatie (nodes/relaties) op te halen, die vervolgens rechtstreeks aan de graph kan worden toegevoegd (via een databasedriver).</p>
<p>Interessant is dat LLM&#8217;s een grote verscheidenheid aan antwoorden kunnen geven en dat het gebruik van gestructureerde output niet altijd nodig is. In sommige gevallen is het nog steeds het eenvoudigst om de LLM te vragen zijn extracties te leveren in de vorm van queries (bijvoorbeeld queries die de gedetecteerde nodes/relaties direct toevoegen), die als zodanig kunnen worden uitgevoerd, of in de vorm van RDF triples.</p>
<p>Na de algemene procedure, kijken we nu meer in detail naar de verschillende manieren om de informatie in de chunks binnen een graph te extraheren en weer te geven, te beginnen met de eenvoudigste benadering (thema-extractie) tot de meest complete (extractie van entiteiten en relaties).</p>



<h3 class="wp-block-heading">Thematische extractie</h3>



<p>In deze eerste benadering richten we ons op het opsporen en extraheren van de thema&#8217;s die in het document aan bod komen. We bouwen dus een thematische weergave van de verschillende documenten in het corpus om een structuur te verkrijgen van het type:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Theme_extraction.png"><img loading="lazy" decoding="async" width="872" height="178" src="/wp-content/uploads/2025/09/Theme_extraction.png" alt="" class="wp-image-23756" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction.png 872w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-768x157.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></a><figcaption class="wp-element-caption">Figuur 4: Ontologieschema van een thematische extractie</figcaption></figure>



<p>De graph heeft dus een lichte structuur en wordt gebruikt voor referentiedoeleinden, om gemakkelijk en snel documenten te identificeren die betrekking hebben op een (of meerdere) bepaald(e) onderwerp(en) van belang. Met dit type graph kunnen ook gelijkenissen tussen documenten (of tussen chunks) worden vastgesteld op basis van de gemeenschappelijke onderwerpen, of kan eenvoudigweg een schematische weergave worden gegeven van hun corpus van documenten en de thema&#8217;s die daarin aan bod komen.</p>
<p>Dit kan op een niet-gestuurde manier (de LLM vrij laten bepalen welke thema&#8217;s in de chunk aan bod komen) of op een gestuurde manier gebeuren (de LLM kiest een of meer thema&#8217;s uit een vooraf gedefinieerde lijst met thema&#8217;s die in de instructies van de prompt wordt gegeven).</p>



<h3 class="wp-block-heading">Extractie van <em>named entities</em></h3>



<p>De extractie (of herkenning) van <em>named entities</em> (<em>named-entity recognition</em>, vaak afgekort tot NER) is een bekend domein van natuurlijke taalverwerking (<em>natural language processing</em> (NLP)) dat bestaat uit het detecteren en categoriseren van entiteiten (personen, organisaties, plaatsen, enz.) die in een tekst worden genoemd. Het doel is dus vergelijkbaar met dat van thematische extractie: een graph maken door tekstfragmenten te koppelen aan de entiteiten die erin worden genoemd. We krijgen dus een graph met het volgende standaard schema:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Entity_extraction.png"><img loading="lazy" decoding="async" width="877" height="176" src="/wp-content/uploads/2025/09/Entity_extraction.png" alt="" class="wp-image-23752" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-300x60.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-768x154.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figuur 5: Ontologieschema van een extractie van <em>named entities</em></figcaption></figure>



<p>Met dit type graph kunnen ook gelijkenissen tussen documenten (of tussen chunks) worden vastgesteld op basis van de entiteiten die ze gemeenschappelijk hebben. Het is interessant om op te merken dat deze extractie vergelijkbaar is met een volledige extractie (inclusief entiteiten en relaties, zie onderstaande paragraaf), behalve dat hier alleen de entiteiten worden geëxtraheerd en niet de relaties die ze met elkaar verbinden. Dit is een lichtere en gemakkelijker te implementeren oplossing wanneer een volledige extractie niet nodig is.</p>
<p>Dit soort extractie kan gemakkelijk worden uitgevoerd met behulp van een LLM met gestructureerde outputs. Met het <code>pydantic</code>-pakket kunnen op maat gemaakte templates worden gemaakt voor de verwachte outputstructuur. Bijvoorbeeld:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from pydantic import BaseModel, Field
from typing import List
class Entity(BaseModel):
    category: str = Field(description="The category of the entity.")
    name: str = Field(description="The name of the entity.")
class Extraction(BaseModel):
    entityList: List&#91;Entity&#93; = Field(description="The list of extracted entities.")
structured_llm = llm.with_structured_output(Extraction)
extracted=structured_llm.invoke(myPrompt)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> pydantic </span><span style="color: #AF00DB">import</span><span style="color: #000000"> BaseModel, Field</span></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> typing </span><span style="color: #AF00DB">import</span><span style="color: #000000"> List</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Entity</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    category: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The category of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">    name: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The name of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Extraction</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    entityList: List&#91;Entity&#93; = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The list of extracted entities.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">structured_llm = llm.with_structured_output(Extraction)</span></span>
<span class="line"><span style="color: #000000">extracted=structured_llm.invoke(myPrompt)</span></span></code></pre></div>



<p> </p>
<p>In dit eenvoudige voorbeeld wordt de LLM gevraagd om een gestructureerde output van het type “Extraction” terug te geven, met als attribuut “entityList”, een lijst van “Entity”-objecten “ die net daarvoor zijn gedefinieerd.</p>
<p>Het is interessant om op te merken dat dit type template kan worden uitgebreid wanneer we extra informatie willen extraheren of het type gedetecteerde entiteiten willen beperken. Als we bijvoorbeeld alleen entiteiten van het type “persoon” en “onderneming” willen detecteren, kan de template worden aangepast door de klassen “ Persoon” en “Onderneming&#8221; aan te maken, waarin de attributen worden opgesomd die voor elke instantie van deze entiteiten moeten worden geëxtraheerd, en door het veld ”entityList“ te vervangen door twee velden “personList” en ”enterpriseList&#8221; in het uiteindelijke object dat moet worden teruggegeven.</p>
<p>Het voordeel van het gebruik van de methode <code>with_structured_output</code> is dat LangChain automatisch controleert of de output van de LLM overeenkomt met de template.</p>



<h3 class="wp-block-heading">Extractie van entiteiten en relaties</h3>



<p>Het doel hier is het bouwen van een graph die de kennis in het document of de documenten weergeeft in de vorm van onderling verbonden entiteiten (nodes) en relaties. Dit is de meest uitgebreide (en meest ingewikkelde) taak die we in detail zullen bekijken.</p>
<p>Laten we het volgende stukje tekst nemen om te illustreren wat voor soort extractie we hier willen uitvoeren:</p>
<p><em>“The San Fransisco-based 9th U.S. Circuit Court of Appeals rejected the legal challenge by the Federal Trade Commission to Microsoft’s $69</em><em> </em><em>billion acquisition of Activision Blizzard, the developer of </em><em>“</em><em>Call of Duty.</em><em>”</em><em> A three</em><em>‑</em><em>judge panel unanimously upheld a lower court</em><em>’</em><em>s decision denying a preliminary injunction, finding that the FTC had not demonstrated a likelihood of success in proving the merger would harm competition. The acquisition, completed in late</em><em> </em><em>2023 following UK regulatory approval, is the largest ever in the video gaming industry.”<br /></em>(Source: adapted from <a href="https://www.reuters.com/legal/microsoft-wins-ftc-appeal-challenging-69-bln-activision-blizzard-deal-2025-05-07/">Reuters, 2025</a>).</p>
<p>Zodra de informatie is geëxtraheerd, is dit een voorbeeld van een graph die op basis van deze tekst kan worden gemaakt:</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/09/Full_Extracted_KG.png"><img loading="lazy" decoding="async" width="1024" height="537" src="/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png" alt="" class="wp-image-23761" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG.png 1330w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 6: Voorbeeld van extractie uit een tekst</figcaption></figure>



<p>Dit type extractie kan op veel verschillende manieren worden uitgevoerd. Het volgende deel is speciaal gewijd aan de verschillende benaderingen om een volledige extractie uit te voeren, en aan de voor- en nadelen daarvan.</p>



<h2 class="wp-block-heading">Welke benaderingen zijn er voor het extraheren van entiteiten en relaties?</h2>



<h3 class="wp-block-heading">Handmatige extractie versus speciale tools</h3>



<p>Een dergelijke graph kan manueel worden opgebouwd volgens de techniek die in het vorige deel werd voorgesteld (een prompt met instructies en de chunk naar de LLM sturen, de gestructureerde output ophalen en ontleden, en vervolgens de graph bijwerken via queries), ofwel biedt LangChain een tool aan om deze verschillende taken te automatiseren via de <a href="https://python.langchain.com/api_reference/experimental/graph_transformers/langchain_experimental.graph_transformers.llm.LLMGraphTransformer.html">LLM Graph Transformer</a>.</p>
<p>Deze tool vereenvoudigt de procedure door de instructies aan de LLM, het opstellen van de template en de verwerking van de gestructureerde output voor zijn rekening te nemen. De tool biedt verschillende instelmogelijkheden, zoals de mogelijkheid om de soorten nodes die gedetecteerd moeten worden te beperken (bv. alleen nodes van het type “Person”, “Company” en “Location”), de soorten relaties te beperken of de instructieprompt aan te passen.</p>
<p>Bovendien geeft een <code>LLMGraphTransformer</code>-instantie een lijst terug met objecten van het type <code>GraphDocument</code>, die de gedetecteerde nodes en relaties bevat en die direct kan worden gebruikt door verschillende LangChain-drivers naar graph-gerichte databases (zoals Memgraph, TigerGraph, Neo4j, enz.), om de geëxtraheerde entiteiten en relaties direct in de graph te importeren.</p>
<p>Hieronder volgt een voorbeeld van het extraheren van data uit een lijst met chunks met behulp van de <code>LLMGraphTransformer</code>-tool, gevolgd door het importeren van de entiteiten en relaties naar Neo4j:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>doc_transformer=LLMGraphTransformer(llm=llm)
graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)

from langchain_neo4j import Neo4jGraph
graph=Neo4jGraph(
    url='XXXXX',
    username='YYYYY',
    password='ZZZZZ'
)
graph.add_graph_documents(graph_docs)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">doc_transformer=LLMGraphTransformer(</span><span style="color: #001080">llm</span><span style="color: #000000">=llm)</span></span>
<span class="line"><span style="color: #000000">graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> langchain_neo4j </span><span style="color: #AF00DB">import</span><span style="color: #000000"> Neo4jGraph</span></span>
<span class="line"><span style="color: #000000">graph=Neo4jGraph(</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">url</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;XXXXX&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">username</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;YYYYY&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">password</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;ZZZZZ&#39;</span></span>
<span class="line"><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">graph.add_graph_documents(graph_docs)</span></span></code></pre></div>



<p><br />Er bestaat ook een gratis alternatief voor Neo4j, waarvoor geen programmering nodig is: de <a href="https://llm-graph-builder.neo4jlabs.com/">Neo4j LLM Knowledge Graph Builder</a>. Deze online tool neemt alle stappen voor zijn rekening, van de voorbewerking van documenten (pdf, webpagina) tot de opbouw van de resulterende knowledge graphs, en biedt tal van personaliseringsopties (het beperken van de te detecteren entiteit- en/of relatietypes, enz.). Zie <a href="https://neo4j.com/labs/genai-ecosystem/llm-graph-builder/">hier</a> voor meer details.</p>



<h3 class="wp-block-heading">Vrije extractie versus begeleide extractie</h3>



<p>Merk op dat als er met deze tools geen beperkingen (op de soorten entiteiten en relaties die moeten worden geëxtraheerd) worden gedefinieerd, ze in alle vrijheid alle informatie zullen extraheren die ze kunnen vinden. Dit soort “blinde” extractie kan eventueel worden gebruikt voor kleine documenten, of in gevallen waarin men van tevoren niet weet wat voor soort structuur men kan extraheren, maar het is over het algemeen beter om van tevoren de gewenste ontologie voor de graph vast te leggen.</p>
<p>Vrije extractie is namelijk vaak een probleem om verschillende redenen:</p>
<p><strong>Explosie van entiteitstypen en relaties </strong></p>
<p>Naarmate de omvang of het aantal documenten toeneemt, bestaat het risico dat er al snel een zeer groot aantal verschillende soorten entiteiten en relaties in de graph terechtkomen, waardoor deze moeilijk te gebruiken kan worden (bijvoorbeeld voor RAG-toepassingen).</p>
<p><strong>Inconsistentie van types</strong></p>
<p>Bij gebrek aan een ontologie die een duidelijke nomenclatuur biedt, bestaat het risico van inconsistentie in de gedetecteerde types (een bedrijf kan bijvoorbeeld worden gelabeld als “Enterprise”, een ander als “Company” en een derde als “Organization”). In de praktijk kunnen dit soort problemen achteraf worden opgelost door alle soorten nodes op te sommen en semantisch verwante soorten te groeperen.</p>
<p><strong>Problemen met reïficatie</strong></p>
<p>Per definitie verbindt een relatie in een graph een node met een ander node. Er kan een probleem ontstaan wanneer een entiteit moet worden gekoppeld aan informatie die in de vorm van een relatie is gemodelleerd. Om het probleem te illustreren, nemen we als voorbeeld de overname van Activision Blizzard door Microsoft. Stel dat een eerste stuk tekst alleen deze overname vermeldt zonder verdere details, dan wordt deze hoogstwaarschijnlijk opgeslagen in de vorm:</p>
<p><code>(Microsoft)-[ACQUIRES]-&gt;(Activision Blizzard)</code></p>
<p>Stel dat de volgende chunk de informatie “<em>The FTC challenged the acquisition&#8230;</em>” vermeldt, dan hebben we een probleem omdat het niet meer mogelijk is om</p>
<p><code>(FTC)-[CHALLENGES]-&gt;(Acquisition)</code></p>
<p>te modelleren, aangezien de overname eerder werd gemodelleerd in de vorm van een relatie en niet als een node waarnaar door een relatie kan worden verwezen.</p>
<p>In dit geval kan de relatie bijvoorbeeld worden verwijderd en vervolgens worden vervangen door een node, zodat ernaar kan worden verwezen:</p>
<p><code>(Microsoft)-[INITIATES]-&gt;(Acquisition)-[TARGETS]-&gt;(Activision Blizzard)</code></p>
<p>Dit proces, dat <strong>reïficatie</strong> wordt genoemd, verloopt niet automatisch en vereist een extra verrijkingsstap om mogelijke verwijzingen naar informatie die in de vorm van relaties is gemodelleerd, op te sporen en indien nodig te reïficeren.</p>



<h2 class="wp-block-heading">Enkele alternatieven voor LLM&#8217;s</h2>



<p>Nu we een reeks benaderingen hebben bekeken die specifiek op LLM&#8217;s zijn gebaseerd, worden in dit gedeelte enkele alternatieve tools voorgesteld die zijn gebaseerd op klassieke NLP-methoden.</p>
<p>Voor wie alleen <em>named entities</em> wil extraheren, is <a href="/named-entity-recognition-une-application-du-nlp-utile/">hier een blogpost over dit onderwerp</a> te vinden, evenals een <a href="/pii-filtering/">voorbeeld van de toepassing van NER bij PII-filtering</a>.  Er zijn tal van vooraf getrainde NER-modellen beschikbaar op platforms zoals <a href="https://huggingface.co/models">Hugging Face</a>.</p>
<p>Het extraheren van entiteiten en relaties kan doorgaans op twee verschillende manieren gebeuren:</p>



<ul class="wp-block-list">
<li><strong>Extractie in twee afzonderlijke stappen</strong>: eerst wordt een NER gebruikt voor het detecteren en categoriseren van entiteiten, gevolgd door een extractie van relaties op basis van de tekst en de gedetecteerde entiteiten, om de relaties tussen deze entiteiten te bepalen. Enkele voorbeelden van tools voor het extraheren van relaties zijn <a href="https://github.com/thunlp/OpenNRE">openNRE</a>, <a href="https://github.com/alimirzaei/spacy-relation-extraction">spacy-relation-extraction</a> en <a href="https://github.com/jackboyla/GLiREL">GliREL</a>.</li>



<li><strong>End-to-end-extractie</strong>: tools die entiteiten en relaties in één stap extraheren, zoals <a href="https://nlp.stanford.edu/software/openie.html">OpenIE</a>, <a href="https://github.com/SapienzaNLP/relik">Relik</a>, <a href="https://github.com/Babelscape/rebel">REBEL</a> of <a href="https://www.diffbot.com/products/natural-language/">Diffbot</a> (commerciële oplossing).</li>
</ul>



<h2 class="wp-block-heading">Nagaan of de gedetecteerde gegevens conform zijn</h2>



<p>De grote kracht van LLM&#8217;s voor dit soort extractietaken is hun begrip van natuurlijke taal, waardoor de extractie kan worden gepersonaliseerd door de instructieprompt aan te passen. Als er bijvoorbeeld geen outputtemplate bestaat voor het gestructureerde antwoord (waar de LLM moeite mee kan hebben als de template te ingewikkeld wordt), is het mogelijk om ontologieconforme nodes en relaties te verkrijgen door de ontologie rechtstreeks in de instructieprompt te beschrijven, maar het is belangrijk om alert te blijven voor extracties. Er is namelijk geen garantie dat de LLM geen fouten maakt en geen niet-conforme relatie/entiteit als output teruggeeft.</p>
<p>In het algemeen geldt dat wanneer een LLM (of een andere tool) wordt gebruikt om automatisch informatie uit een tekst te extraheren naar een knowledge graph, het nuttig is om te controleren of datgene dat is geëxtraheerd wel degelijk in overeenstemming is met de ontologie en trouw is aan de informatie in de bron.</p>
<ol>
<li>Controleren of de extractie voldoet aan de ontologie</li>
</ol>
<p><a href="/shacl-logische-en-vormcontroles-met-kg-technologieen/">In een vorige blogpost</a> hebben we al vermeld dat het mogelijk is om de structuur en inhoud van een knowledge graph te valideren met behulp van de SHACL-standaard. Dit is een taal die de verschillende beperkingen bevat die van toepassing zijn op een knowledge graph. Het is mogelijk om ofwel een definitieve validatie van de graph uit te voeren, om te controleren of de inhoud daadwerkelijk voldoet aan de in SHACL geformuleerde beperkingen (en de data die deze beperkingen overtreden op te sommen), ofwel deze validaties transactioneel uit te voeren bij elke nieuwe toevoeging van informatie, om elke nieuwe onrechtmatige toevoeging te weigeren. Hoewel SHACL oorspronkelijk bedoeld was voor graphs in RDF, kunnen sommige databases toch SHACL-beperkingen interpreteren en de graph valideren, zoals <a href="https://neo4j.com/labs/neosemantics/">Neo4j met het <em>neosemantics</em> package (n10s)</a>.</p>
<ol start="2">
<li>Nagaan of de extractie correct is</li>
</ol>
<p>Het risico van automatische extractie is dat informatie die in de graph wordt ingevoerd feitelijk onjuist is ten opzichte van de oorspronkelijke tekst, wat in het bijzonder problematisch kan zijn als deze graph wordt gebruikt als potentiële informatiebron (bijvoorbeeld voor een graphRAG-toepassing). Er kunnen verschillende benaderingen worden gevolgd. De eenvoudigste is een menselijke controle van de geëxtraheerde informatie, maar dit kan moeilijk of zelfs onhaalbaar worden wanneer de documenten te lang/talrijk worden. De andere aanpak bestaat erin een tweede LLM te gebruiken om te controleren wat uit elk fragment is geëxtraheerd. Zoals we <a href="/praktische-ervaringen-met-automatische-rag-evaluatie/">in de post over de evaluatie van LLM&#8217;s</a> hebben vermeld, is het voor LLM&#8217;s gemakkelijker om achteraf fouten op te sporen dan ze te vermijden.</p>



<h2 class="wp-block-heading">Conclusie</h2>



<p>Deze technologieën zijn weliswaar krachtig, maar nooit perfect. Behalve vrije (blinde) extractie, die kan resulteren in een moeilijk bruikbare graph, vormt het opstellen van een knowledge graph op basis van tekst een taak die veel werk vereist. En dit zowel vooraf (voorbewerking van teksten, opstellen van een ontologie voor de graph op basis van de inhoud van de tekst), als achteraf (validatie van de structuur van de graph ten opzichte van de ontologie en controle van de juistheid en betrouwbaarheid van de inhoud).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Dit is een ingezonden bijdrage van Pierre Leleux, data scientist et network data analyst bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ingestion de données non-structurées&#160;: comment créer un graphe automatiquement à partir de texte&#160;?</title>
		<link>https://www.smalsresearch.be/ingestion-donnees-non-structurees-vers-graphe/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 11 Sep 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[data ingestion]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Large Language Model]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<guid isPermaLink="false">/?p=23748</guid>

					<description><![CDATA[Cet article s’intéresse aux façons dont une représentation graphe peut être obtenue à partir de données textuelles, les différents types de graphe qui peuvent être extraits, et les outils fréquemment utilisés.]]></description>
										<content:encoded><![CDATA[
<p><em><a href="/ingestion-van-ongestructureerde-data-graph/">Nederlandstalige versie</a></em></p>
<p>Les graphes, et plus particulièrement les graphes de connaissances, permettent de <a href="/graphes_applications_et_outils_2/">représenter l’information de manière structurée</a>. Cela permet, pour un humain, d’avoir une représentation (synthèse visuelle) du contenu d’un ou de plusieurs documents et, pour une machine, d’exploiter cette structure afin, par exemple, d’en analyser le contenu (via l’utilisation <a href="/graphes_applications_et_outils/">d’algorithmes de graphe</a>) et/ou de raisonner sur le graphe (par exemple dans le cadre d’une <a href="/graphrag-vers-une-generation-augmentee-par-les-graphes-de-connaissances/">application de graphRAG</a> ou pour découvrir (inférer) de l’information implicite).</p>
<p>Cet article s’intéresse aux façons dont une représentation graphe peut être obtenue à partir de données textuelles, les différents types de graphe qui peuvent être extraits, et les outils fréquemment utilisés suivant le type d’extraction que l’on souhaite effectuer.</p>
<p>Il est à noter que, puisque les grands modèles de langage (LLM) sont particulièrement adaptés pour le traitement de texte, cet article se concentrera principalement sur la présentation d’approches basées sur les LLM et discutera rapidement, dans un second temps, de différentes approches alternatives.</p>



<h2 class="wp-block-heading">Les graphes de connaissances&nbsp;: un rappel rapide</h2>



<p>Un graphe est une structure composée d’un ensemble de nœuds et d’arcs (qui lient des paires de nœuds). Un graphe de connaissances ajoute une couche sémantique supplémentaire à un graphe classique, où chaque nœud représente un concept (entité, personne, etc.) et chaque arc représente une relation entre deux concepts (« travaille pour », « est ami avec », etc.). Il s’agit donc d’une représentation de la connaissance sous forme d’un ensemble d’entités interconnectées. Plus de détails sur les différentes formes de graphes et les outils associés peuvent être trouvés <a href="/graphes_applications_et_outils/">ici</a>.</p>



<h2 class="wp-block-heading">Préparation du corpus de documents</h2>



<p>Il est à noter que, pour des raisons de simplicité, nous faisons l’hypothèse que les documents de texte utilisés pour construire le graphe ont été correctement nettoyés. En effet, cet article n’a pas pour but de discuter de l’aspect relatif au prétraitement des documents de texte (scrapping de pages web, extraction de texte à partir de fichiers pdf, etc.), car ce prétraitement est déjà, en tant que tel, un vaste sujet méritant sans doute un article dédié.</p>



<h3 class="wp-block-heading">Fragmentation du texte en « chunks »</h3>



<p>Une étape importante de la préparation des données de texte avant d’en extraire les entités et relations est la division du texte en fragments (généralement appelés « chunks »). Nous avons déjà mentionné le concept de chunking à plusieurs reprises dans <a href="/ingestion-de-donnees-pour-les-applications-d-ia-generative/">de précédents articles</a>. Si un document est trop long (plus de quelques paragraphes…) il convient de le séparer en chunks (fragments de texte de taille raisonnable) qui seront traités un à un par le LLM. Cette procédure permet de limiter la quantité d’information présente dans chaque chunk, pour éviter que celui-ci ne contienne une quantité trop importante d’entités et de relations à extraire. Cette séparation en chunks peut se faire de différentes manières, soit sur la base du nombre de mots dans le chunk, soit sur la base d’un séparateur prédéfini (par exemple&nbsp;: un passage à la ligne qui indiquerait la fin du paragraphe).</p>



<h2 class="wp-block-heading">Représenter l’information ou représenter la structure</h2>



<p>Commençons par regarder les deux principaux types de graphe qui peuvent être construits à partir d’un ensemble de documents textuels.</p>
<p>Le premier est un graphe qui va présenter la structure du document (<em>document structure graph</em>), et non pas l’information qui est contenue dans le texte. Par exemple, en reliant les chunks au document d’où ils sont tirés ainsi que l’ordre d’apparition de ceux-ci dans le document&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Document_structure_graph.png"><img loading="lazy" decoding="async" width="939" height="527" src="/wp-content/uploads/2025/09/Document_structure_graph.png" alt="" class="wp-image-23750" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph.png 939w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-300x168.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-768x431.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></a><figcaption class="wp-element-caption">Figure 1&nbsp;: Graphe représentant la structure d’un document simple</figcaption></figure>



<p>Ce type de graphe peut aussi être enrichi en ajoutant des relations entre chunks sémantiquement similaires ou, le cas échéant, en représentant l’organisation hiérarchique du document en sections, sous-sections, etc. Cela se fait via des nœuds représentant les sections/sous-sections et des relations de type « HAS_SECTION », « HAS_SUBSECTION », ainsi que des relations indiquant l’ordre des sections/sous-sections. Une fois le graphe construit, il peut par exemple être utilisé dans des applications de RAG à des fins d’indexation pour fournir du contexte aux chunks utilisés (voir <a href="/graphrag-vers-une-generation-augmentee-par-les-graphes-de-connaissances/">notre article sur le graphRAG</a>).</p>
<p>Le second type de graphe consiste à capturer l’information contenue dans les documents sous la forme de nœuds et de relations :</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Domain_graph.png"><img loading="lazy" decoding="async" width="877" height="179" src="/wp-content/uploads/2025/09/Domain_graph.png" alt="" class="wp-image-23751" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-768x157.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figure 2&nbsp;: Exemple d&#8217;extraction d&#8217;informations</figcaption></figure>



<p>Dans le cadre de cet article, nous nous concentrerons sur ce second type de graphe. Il est à noter que les deux approches ne sont pas mutuellement exclusives. D’ailleurs, il est souvent utile, si l&#8217;on souhaite opter pour le deuxième type de graphe, de représenter également la structure des documents. Cela permet, si nécessaire, de pouvoir remonter à la source des informations présentes dans le graphe.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Graph_combined.png"><img loading="lazy" decoding="async" width="896" height="674" src="/wp-content/uploads/2025/09/Graph_combined.png" alt="" class="wp-image-23754" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined.png 896w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-300x226.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-768x578.png 768w" sizes="auto, (max-width: 896px) 100vw, 896px" /></a><figcaption class="wp-element-caption">Figure 3&nbsp;: Extraction de structure et d&#8217;informations</figcaption></figure>



<h2 class="wp-block-heading">Construction d’un graphe de connaissances à l’aide d’un LLM</h2>



<p>Dans un premier temps, nous allons présenter la procédure générale à suivre pour la création d’un graphe de connaissances à partir de documents textuels via LLM, avant de voir comment l’adapter suivant ses besoins.</p>
<p>Les LLMs, par défaut, reçoivent en entrée du texte (prompt) et renvoient en sortie du texte généré en réponse au prompt. Cependant, suivant les instructions, les LLM offrent la possibilité de générer des <strong><em>outputs structurés</em></strong> tels que des fichiers JSON. C’est souvent sur la base de cette fonctionnalité que se base l’extraction de connaissances vers un graphe, car cet output structuré pourra être traité de façon systématique.</p>
<p>Un script (par ex. python) va récupérer les chunks et les envoyer un à un au LLM en imposant une réponse structurée (par ex. <a href="https://python.langchain.com/docs/how_to/structured_output/">langchain avec la méthode llm.with_structured_output()</a>), avec des instructions concernant la tâche, le genre d’information à détecter dans le texte, et la structure de la réponse attendue en sortie. L’output structuré (typiquement en JSON) est ensuite simplement décomposé en python afin de récupérer les informations (nœuds/relations) détectées par le LLM, qui peuvent ensuite être directement ajoutées au graphe (via un database driver).</p>
<p>Il est intéressant de noter que les LLM peuvent fournir une grande diversité de réponses, et l’utilisation d’une sortie structurée n’est pas forcément toujours nécessaire. Dans certains cas, le plus simple est encore de demander au LLM de fournir ses extractions sous la forme de requêtes (par exemple, de requêtes qui ajoutent directement les nœuds/relations détectées), qui peuvent être exécutées telles quelles, ou sous forme de triplets RDF.</p>
<p>Maintenant que nous avons vu la procédure générale, nous allons regarder plus en détail les différentes façons d’extraire et de représenter l’information contenue dans les chunks au sein d’un graphe, en commençant par l’approche la plus simple (extraction de thèmes) jusqu’à la plus complète (extraction d’entités et de relations).</p>



<h3 class="wp-block-heading">Extraction thématique</h3>



<p>Dans cette première approche, on va s’intéresser à la détection et l’extraction des thèmes abordés dans le document. On y construit donc une représentation thématique des différents documents du corpus de sorte à obtenir une structure de type&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Theme_extraction.png"><img loading="lazy" decoding="async" width="872" height="178" src="/wp-content/uploads/2025/09/Theme_extraction.png" alt="" class="wp-image-23756" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction.png 872w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-768x157.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></a><figcaption class="wp-element-caption">Figure 4&nbsp;: Schéma d’ontologie d’une extraction de thèmes</figcaption></figure>



<p>Le graphe a donc une structure légère et est utilisé à des fins de référencement, afin d&#8217;identifier facilement et rapidement les documents traitant d&#8217;un (ou plusieurs) sujet(s) d&#8217;intérêt donné(s). Ce type de graphe permet aussi d’établir des similarités entre documents (ou entre chunks) sur la base des sujets qu’ils ont en commun, ou simplement d’avoir une représentation schématique du corpus de documents et des thèmes qui y sont abordés.</p>
<p>Cela peut se faire soit de façon non-dirigée (laisser le LLM déterminer librement de la liste des thèmes abordés dans le chunk), soit dirigée (le LLM choisit un ou plusieurs thèmes parmi une liste prédéfinie de thèmes fournie dans les instructions du prompt).</p>



<h3 class="wp-block-heading">Extraction d’entités nommées</h3>



<p>L’extraction (ou reconnaissance) d’entités nommées (<em>named-entity recognition</em>, souvent abrégé en NER) est un domaine bien connu du traitement du langage naturel (<em>natural language processing</em> (NLP)) qui consiste à détecter et catégoriser les entités (personne, organisation, lieu, etc.) qui sont nommées dans un texte. L’objectif va donc être similaire à celui de l’extraction thématique&nbsp;: créer un graphe en liant les chunks de texte aux entités qui y sont mentionnées. Nous obtenons donc un graphe avec le schéma-type suivant&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Entity_extraction.png"><img loading="lazy" decoding="async" width="877" height="176" src="/wp-content/uploads/2025/09/Entity_extraction.png" alt="" class="wp-image-23752" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-300x60.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-768x154.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figure 5&nbsp;: Schéma d’ontologie d’une extraction d’entités nommées</figcaption></figure>



<p>Ce type de graphe permet aussi d’établir des similarités entre documents (ou entre chunks) sur la base des entités qu’ils ont en commun. Il est intéressant de noter que cette extraction est similaire à une extraction complète (incluant entités et relations, voir section ci-dessous), si ce n’est qu’ici seules les entités sont extraites, et pas les relations qui les interconnectent. Il s’agit d’une solution plus légère et facile à mettre en place, lorsqu’une extraction complète n’est pas nécessaire.</p>
<p>Ce genre d’extraction peut se faire facilement par l’utilisation de LLM avec outputs structurés. Le package <code>pydantic</code> permet de créer des templates sur mesure pour la structure attendue en sortie. Par exemple&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from pydantic import BaseModel, Field
from typing import List
class Entity(BaseModel):
    category: str = Field(description="The category of the entity.")
    name: str = Field(description="The name of the entity.")
class Extraction(BaseModel):
    entityList: List&#91;Entity&#93; = Field(description="The list of extracted entities.")
structured_llm = llm.with_structured_output(Extraction)
extracted=structured_llm.invoke(myPrompt)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> pydantic </span><span style="color: #AF00DB">import</span><span style="color: #000000"> BaseModel, Field</span></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> typing </span><span style="color: #AF00DB">import</span><span style="color: #000000"> List</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Entity</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    category: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The category of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">    name: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The name of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Extraction</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    entityList: List&#91;Entity&#93; = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The list of extracted entities.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">structured_llm = llm.with_structured_output(Extraction)</span></span>
<span class="line"><span style="color: #000000">extracted=structured_llm.invoke(myPrompt)</span></span></code></pre></div>



<p><br />Dans cet exemple simple, on demande au LLM de retourner une sortie structurée de type « Extraction », avec comme attribut « entityList » qui est une liste d’objets « Entity » définis juste avant.</p>
<p>Il est intéressant de noter que ce type de template peut être enrichi si l’on souhaite extraire des informations supplémentaires ou contraindre le type d’entités détectées. Par exemple, si l’on souhaite uniquement détecter des entités de type « personne » et « entreprise », le template peut être modifié en créant des classes « Personne » et « Entreprise », dans lesquelles on listera les attributs que l’on souhaite extraire pour chaque instance de ces entités, et en remplaçant le champs « entityList » par deux champs « personList » et « enterpriseList » dans l’objet final à retourner.</p>
<p>L’avantage d’utiliser la méthode <code>with_structured_output</code> est que langchain vérifiera automatiquement que la sortie du LLM est bien conforme au template.</p>



<h3 class="wp-block-heading">Extraction d’entités et de relations</h3>



<p>L’objectif ici est la construction d’un graphe qui va représenter la connaissance contenue au sein du ou des documents sous la forme d’entités (nœuds) interconnectées (relations). Il s’agit de la tâche la plus complète (et la plus compliquée), sur laquelle nous allons nous pencher le plus en détail.</p>
<p>Prenons le chunk de texte suivant, afin d’illustrer le genre d’extraction que nous souhaitons réaliser ici :</p>
<p><em>“The San Fransisco-based 9th U.S. Circuit Court of Appeals rejected the legal challenge by the Federal Trade Commission to Microsoft’s $69</em><em> </em><em>billion acquisition of Activision Blizzard, the developer of </em><em>“</em><em>Call of Duty.</em><em>”</em><em> A three</em><em>‑</em><em>judge panel unanimously upheld a lower court</em><em>’</em><em>s decision denying a preliminary injunction, finding that the FTC had not demonstrated a likelihood of success in proving the merger would harm competition. The acquisition, completed in late</em><em> </em><em>2023 following UK regulatory approval, is the largest ever in the video gaming industry.”<br /></em>(Source: adapted from <a href="https://www.reuters.com/legal/microsoft-wins-ftc-appeal-challenging-69-bln-activision-blizzard-deal-2025-05-07/">Reuters, 2025</a>).</p>
<p>Une fois l’information extraite, voici un exemple de graphe qu’il est possible de construire depuis ce texte :</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/09/Full_Extracted_KG.png"><img loading="lazy" decoding="async" width="1024" height="537" src="/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png" alt="" class="wp-image-23761" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG.png 1330w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 6&nbsp;: Exemple d’extraction depuis un texte</figcaption></figure>



<p>Ce type d’extraction peut se faire de nombreuses façons différentes. La prochaine section sera spécialement dédiée aux différentes approches qui peuvent être adoptées pour réaliser une extraction complète, leurs avantages et inconvénients.</p>



<h2 class="wp-block-heading">Quelles approches pour réaliser une extraction d’entités et de relations&nbsp;?</h2>



<h3 class="wp-block-heading">Extraction manuelle VS outils dédiés</h3>



<p>La construction d’un graphe de ce type peut se faire de manière manuelle en suivant la technique présentée dans la section précédente (envoyer un prompt incluant les instructions et le chunk au LLM, récupérer et décomposer l’output structuré renvoyé en sortie, puis mettre à jour le graphe via requêtes), ou alors langchain propose un outil permettant d’automatiser ces différentes tâches via le <a href="https://python.langchain.com/api_reference/experimental/graph_transformers/langchain_experimental.graph_transformers.llm.LLMGraphTransformer.html">LLM Graph Transformer</a>.</p>
<p>Cet outil permet de simplifier la procédure, en prenant en charge les instructions au LLM, la construction du template et le traitement de la sortie structurée. Il offre plusieurs possibilités de personnalisation, comme la possibilité de restreindre les types de nœud que l’on souhaite détecter (par ex. uniquement des nœuds de type « Person », « Company » et « Location »), de restreindre les types de relation, ou encore de personnaliser le prompt d’instructions.</p>
<p>De plus, une instance <code>LLMGraphTransformer</code> renvoie en sortie liste d’objets de type <code>GraphDocument</code>, contenant les nœuds et relations détectés, qui est exploitable directement par plusieurs drivers langchain vers des bases de données orientées graphe (telles que Memgraph, TigerGraph, Neo4j, etc.), afin de réaliser directement l’importation des entités et relations extraites vers le graphe.</p>
<p>Ci-dessous, un exemple illustratif de l’extraction des données depuis une liste de chunks via l’outil <code>LLMGraphTransformer</code>, suivie de l’importation des entités et relations vers Neo4j&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>doc_transformer=LLMGraphTransformer(llm=llm)
graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)

from langchain_neo4j import Neo4jGraph
graph=Neo4jGraph(
    url='XXXXX',
    username='YYYYY',
    password='ZZZZZ'
)
graph.add_graph_documents(graph_docs)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">doc_transformer=LLMGraphTransformer(</span><span style="color: #001080">llm</span><span style="color: #000000">=llm)</span></span>
<span class="line"><span style="color: #000000">graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> langchain_neo4j </span><span style="color: #AF00DB">import</span><span style="color: #000000"> Neo4jGraph</span></span>
<span class="line"><span style="color: #000000">graph=Neo4jGraph(</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">url</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;XXXXX&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">username</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;YYYYY&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">password</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;ZZZZZ&#39;</span></span>
<span class="line"><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">graph.add_graph_documents(graph_docs)</span></span></code></pre></div>



<p><br />Il existe aussi une alternative gratuite pour Neo4j, qui ne requiert aucune programmation, le <a href="https://llm-graph-builder.neo4jlabs.com/">Neo4j LLM Knowledge Graph Builder</a>. Cet outil en ligne prend toutes les étapes en charge, en allant du prétraitement des documents (pdf, page web) jusqu’à la construction du graphe de connaissances résultant, et offre de multiples options de personnalisation (contraindre les types d’entité et/ou de relation à détecter, etc.). Voir <a href="https://neo4j.com/labs/genai-ecosystem/llm-graph-builder/">ici</a> pour plus de détails.</p>



<h3 class="wp-block-heading">Extraction libre VS extraction supervisée</h3>



<p>Il est à noter que si aucune contrainte (sur les types d’entité et de relation à extraire) n’est définie avec ces outils, ils vont librement extraire toutes les informations qu’ils peuvent trouver. Ce genre d’extraction « à l’aveugle » peut éventuellement être utilisée pour des petits documents, ou dans des cas où l’on ne sait pas à l’avance le genre de structure que l’on peut extraire, mais il est généralement préférable d’établir à l’avance l’ontologie que l’on souhaite adopter pour le graphe.</p>
<p>Une extraction libre est en effet souvent problématique pour plusieurs raisons :</p>
<p><strong>Explosion des types d’entité et de relation </strong></p>
<p>Lorsque la taille ou le nombre de documents augmente, l&#8217;on risque rapidement de se retrouver avec un très grand nombre de types différents d’entités et de relations au sein du graphe, ce qui peut le rendre difficile à exploiter (par ex. pour des applications de RAG).</p>
<p><strong>Incohérence de types</strong></p>
<p>En l’absence d’une ontologie fournissant une nomenclature claire, il y a des risques d’incohérence dans les types détectés (par exemple, une entreprise pourra être labelisée comme « Enterprise », une autre comme « Company », et une troisième comme « Organization »). En pratique, ce genre de soucis peut potentiellement être réglé a posteriori en listant tous les types de nœud et en rassemblant les types sémantiquement proches.</p>
<p><strong>Soucis de réification</strong></p>
<p>Par définition, une relation dans un graphe relie un nœud à un autre nœud. Un souci peut émerger lorsqu’une entité doit se connecter à une information qui a été modélisée sous la forme d’une relation. Pour illustrer le problème, reprenons en guise d&#8217;exemple l’acquisition d’Activision Blizzard par Microsoft. Supposons qu&#8217;un premier chunk de texte mentionne simplement cette acquisition sans plus de détails, elle sera fort potentiellement enregistrée sous la forme&nbsp;:</p>
<p><code>(Microsoft)-[ACQUIRES]-&gt;(Activision Blizzard)</code></p>
<p>Si maintenant le chunk suivant mentionne l’information « <em>The FTC challenged the acquisition&#8230;</em> », nous avons un problème car il n’est plus possible de modéliser</p>
<p><code>(FTC)-[CHALLENGES]-&gt;(Acquisition)</code></p>
<p>puisque l’acquisition a été précédemment modélisée sous la forme d’une relation, et non d’un nœud pouvant être référencé par une relation.</p>
<p>Dans ce cas, la relation peut par exemple être supprimée puis remplacée par un nœud, afin de la rendre référençable :</p>
<p><code>(Microsoft)-[INITIATES]-&gt;(Acquisition)-[TARGETS]-&gt;(Activision Blizzard)</code></p>
<p>Ce processus, appelé <strong>réification</strong>, n’est pas automatique et demande l’ajout d’une étape d’enrichissement pour détecter de potentielles références à des informations modélisées sous forme de relations, et les réifier si nécessaire.</p>



<h2 class="wp-block-heading">Quelques alternatives aux LLM</h2>



<p>Maintenant que nous avons vu une série d’approches basées spécifiquement sur les LLM, cette section propose quelques outils alternatifs basés sur des méthodes de NLP classique.</p>
<p>Si l&#8217;objectif est uniquement de faire l’extraction d’entités nommées, vous pouvez trouver <a href="/named-entity-recognition-une-application-du-nlp-utile/">ici un article de blog dédié à ce sujet</a>, ainsi qu’un <a href="/pii-filtering-fr/">exemple d’application de NER en PII filtering</a>. Il existe de nombreux modèles de NER préentrainés disponibles sur des plateformes telles que <a href="https://huggingface.co/">Hugging Face</a>.</p>
<p>Concernant l’extraction d’entités et de relations, elle peut se faire typiquement de 2 façons distinctes&nbsp;:</p>



<ul class="wp-block-list">
<li><strong>L’extraction en 2 étapes séparées&nbsp;:</strong> l&#8217;on commence par l’utilisation d’un NER pour la détection et la catégorisation des entités, suivie d&#8217;une extraction de relations sur la base du texte et des entités détectées, afin de déterminer les relations entre ces dernières. Quelques exemples d’outils pour l’extraction de relations incluent <a href="https://github.com/thunlp/OpenNRE">openNRE</a>, <a href="https://github.com/alimirzaei/spacy-relation-extraction">spacy-relation-extraction</a> ou encore <a href="https://github.com/jackboyla/GLiREL">GliREL</a>.</li>



<li><strong>L’extraction conjointe (end-to-end) &nbsp;:</strong> il s’agit d’outils qui réalisent l’extraction d’entités et de relations en une seule étape, tels que <a href="https://nlp.stanford.edu/software/openie.html">OpenIE</a>, <a href="https://github.com/SapienzaNLP/relik">Relik</a>,&nbsp;<a href="https://github.com/Babelscape/rebel">REBEL</a> ou <a href="https://www.diffbot.com/products/natural-language/">Diffbot</a> (solution commerciale).</li>
</ul>



<h2 class="wp-block-heading">Vérifier la conformité de ce qui a été détecté</h2>



<p>La grande force des LLM pour ce genre de tâche d’extraction est leur compréhension du langage naturel, ce qui permet de personnaliser l’extraction en adaptant le prompt d’instructions. Par exemple, en l’absence de template de sortie pour la réponse structurée (que le LLM peut peiner à respecter si le template devient trop compliqué), il est possible d’obtenir des nœuds et relations conformes à l’ontologie en décrivant l’ontologie directement dans le prompt d’instructions, mais il est important de rester vigilant aux extractions. En effet, il n’y a aucune garantie que le LLM ne fasse pas d’erreur, et ne renvoie pas en sortie une relation/entité non-conforme.</p>
<p>De manière générale, lorsqu’un LLM (ou tout autre outil) est utilisé pour extraire de l’information de façon automatique depuis un texte vers un graphe de connaissances, il est utile de vérifier que ce qui a été extrait est bien conforme à l’ontologie et fidèle à l’information qui se trouve dans la source.</p>
<ol>
<li>Vérifier que l’extraction respecte l’ontologie</li>
</ol>
<p>Comme nous l’avons déjà mentionné dans un <a href="/shacl-logische-en-vormcontroles-met-kg-technologieen/">précédent article de blog</a>, il est possible de valider la structure et le contenu d’un graphe de connaissances à l’aide du standard SHACL. Il s’agit d’un langage qui va contenir les différentes contraintes qui s’appliquent sur un graphe de connaissances. Il est possible soit d’effectuer une validation finale du graphe, pour vérifier que le contenu respecte effectivement les contraintes énoncées en SHACL (et de lister les données qui violent ces contraintes), soit d’effectuer ces validations de façon transactionnelle à chaque nouvelle information qui est ajoutée, afin de refuser tout nouvel ajout illégal. Bien qu’initialement prévu pour des graphes en RDF, certaines bases de données peuvent tout de même interpréter des contraintes en SHACL et valider le graphe, comme <a href="https://neo4j.com/labs/neosemantics/">neo4j avec le package <em>neosemantics</em> (n10s)</a>.</p>
<ol start="2">
<li>Vérifier que l’extraction est correcte</li>
</ol>
<p>Le risque d’une extraction automatique est qu’une information introduite dans le graphe soit factuellement incorrecte vis-à-vis du texte d’origine, ce qui peut être particulièrement problématique si ce graphe est utilisé comme potentielle source d’information (par exemple pour une application de graphRAG). Plusieurs approches peuvent être suivies. La plus simple est une vérification humaine des informations extraites, mais cela peut devenir difficile, voire infaisable, lorsque les documents deviennent trop longs/nombreux. L’autre approche consiste à utiliser un second LLM afin de vérifier ce qui a été extrait de chaque chunk. Comme nous l’avons mentionné dans <a href="/experiences-pratiques-avec-levaluation-automatique-de-la-rag/">l’article d’évaluation de LLM</a>, il est plus facile, pour les LLM, de détecter les erreurs a posteriori que de les éviter.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Ces technologies, bien que performantes, ne sont jamais parfaites. Sauf extraction libre (à l’aveugle), mais qui risque d’aboutir à la création d’un graphe difficilement exploitable, la construction d’un graphe de connaissances à partir de texte est une tâche qui demande du travail, tant en amont (prétraitement des textes, établissement d’une ontologie pour le graphe sur la base du contenu du texte) qu’en aval (validation de la structure du graphe vis-à-vis de l’ontologie et vérification de la véracité et la fiabilité de son contenu).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Ce post est une contribution individuelle de Pierre Leleux, data scientist et network data analyst chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
