<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mathieu Ledru</title>
    <description>The latest articles on DEV Community by Mathieu Ledru (@matyo91).</description>
    <link>https://dev.to/matyo91</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F182978%2F61c41098-10ce-4833-acf3-b00cc42f852c.jpeg</url>
      <title>DEV Community: Mathieu Ledru</title>
      <link>https://dev.to/matyo91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matyo91"/>
    <language>en</language>
    <item>
      <title>⬆️ Nouveautés de Symfony 8.1</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 29 May 2026 10:20:38 +0000</pubDate>
      <link>https://dev.to/matyo91/nouveautes-de-symfony-81-495l</link>
      <guid>https://dev.to/matyo91/nouveautes-de-symfony-81-495l</guid>
      <description>&lt;p&gt;Symfony 8.1 continue d'étendre progressivement la portée du framework bien au-delà du développement web traditionnel.&lt;/p&gt;

&lt;p&gt;Cette nouvelle version apporte de nombreuses améliorations à :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expérience de développeur,&lt;/li&gt;
&lt;li&gt;architectures asynchrones,&lt;/li&gt;
&lt;li&gt;Outils CLI,&lt;/li&gt;
&lt;li&gt;sérialisation,&lt;/li&gt;
&lt;li&gt;Traitement JSON,&lt;/li&gt;
&lt;li&gt;Messager,&lt;/li&gt;
&lt;li&gt;et les applications orientées travailleurs ou basées sur l'orchestration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour cet article, j'ai passé en revue toutes les nouvelles fonctionnalités publiées dans les articles « Vivre à la limite » afin de produire un aperçu technique complet des changements les plus importants de Symfony 8.1.&lt;/p&gt;

&lt;p&gt;L’objectif n’est pas de recenser chaque détail, mais plutôt de comprendre la direction prise par l’écosystème Symfony et ses implications concrètes pour les développeurs backend modernes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Résolveurs d'arguments de console
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 introduit le modèle de résolution d'arguments de contrôleur dans les commandes de la console. Les arguments et options bruts de l'interface de ligne de commande peuvent être automatiquement associés à des objets de domaine, des types valeur et des services dans les méthodes &lt;code&gt;__invoke()&lt;/code&gt;, à l'instar de la couche HTTP. Les résolveurs intégrés prennent en charge les entités Doctrine, les dates, les énumérations, les UUID et les ULID ; des implémentations personnalisées de &lt;code&gt;ValueResolverInterface&lt;/code&gt; permettent d'étendre davantage ce mécanisme.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Les commandes de console utilisant &lt;code&gt;#[Argument]&lt;/code&gt; et &lt;code&gt;#[Option]&lt;/code&gt; peuvent s'appuyer sur des résolveurs de valeurs au lieu d'une analyse et d'un chargement manuels.&lt;/li&gt;
&lt;li&gt;Les résolveurs intégrés incluent &lt;code&gt;#[MapEntity]&lt;/code&gt; (mappage de clé primaire ou de champ personnalisé) et &lt;code&gt;#[MapDateTime]&lt;/code&gt; (analyse de date prenant en compte le format).&lt;/li&gt;
&lt;li&gt;Les services peuvent être injectés directement dans les paramètres de &lt;code&gt;__invoke()&lt;/code&gt;, et pas seulement via le constructeur.&lt;/li&gt;
&lt;li&gt;Prise en charge complète des attributs DI dans les méthodes de commande : &lt;code&gt;#[Autowire]&lt;/code&gt;, &lt;code&gt;#[Target]&lt;/code&gt;, variables d'environnement et services nommés (par exemple &lt;code&gt;messenger.bus.async&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Les résolveurs personnalisés implémentent &lt;code&gt;ValueResolverInterface&lt;/code&gt;, le même modèle d'extensibilité que les contrôleurs HTTP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les commandes sont plus concises et déclaratives. L'infrastructure de résolution commune à HTTP réduit la duplication entre les points d'entrée web et en ligne de commande. Les processus de longue durée et les outils opérationnels bénéficient d'une injection et d'une conversion de type cohérentes, sans code répétitif.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Outils CLI d'administration qui acceptent les ID d'entité et résolvent les entités Doctrine complètes avant l'exécution.&lt;/li&gt;
&lt;li&gt;Commandes d'audit ou par lots injectant un bus Messenger ou un enregistreur spécifique via &lt;code&gt;#[Autowire]&lt;/code&gt; / &lt;code&gt;#[Target]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Commandes de migration de données avec options de date typées et résolveurs personnalisés pour les chemins de fichiers ou les objets de configuration.&lt;/li&gt;
&lt;li&gt;Pipelines d'IA/opérations où les commandes CLI répartissent des tâches asynchrones avec un contexte de domaine pré-résolu.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Argument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MapEntity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;MapDateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Y-m-d'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="nc"&gt;\DateTimeInterface&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Autowire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'messenger.bus.async'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="nc"&gt;MessageBusInterface&lt;/span&gt; &lt;span class="nv"&gt;$bus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/console&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-kernel&lt;/code&gt; (modèle ValueResolverInterface)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/doctrine-bridge&lt;/code&gt; (MapEntity)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/dependency-injection&lt;/code&gt; (Autowire, Target)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/messenger&lt;/code&gt; (injection de bus dans l'interface de ligne de commande)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cloneur en profondeur
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 introduit &lt;code&gt;DeepCloner&lt;/code&gt; dans le composant VarExporter, une alternative plus rapide et plus économe en mémoire à &lt;code&gt;unserialize(serialize($value))&lt;/code&gt; pour le clonage en profondeur des graphes d'objets PHP. Il préserve la sémantique de copie à l'écriture pour les chaînes de caractères et les tableaux, et prend en charge les instances de cloneur réutilisables, la substitution de classes et les charges utiles de cloneur sérialisables pour la mise en cache ou le transport interprocessus. Les composants principaux de Symfony l'utilisent désormais en interne lors de la compilation des conteneurs, des instantanés de formulaires et des opérations de cache en mémoire.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DeepCloner::deepClone($object)&lt;/code&gt; pour les clones profonds ponctuels.&lt;/li&gt;
&lt;li&gt;Les instances réutilisables de &lt;code&gt;DeepCloner&lt;/code&gt; analysent le graphe une seule fois ; les appels répétés à &lt;code&gt;clone()&lt;/code&gt; sont moins coûteux.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cloneAs(ChildClass::class)&lt;/code&gt; clone dans une sous-classe compatible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toArray()&lt;/code&gt; / &lt;code&gt;fromArray()&lt;/code&gt; exportent l'état du cloneur pour la mise en cache, MessagePack, APCu ou les fichiers PHP préchauffés ; les charges utiles sont environ 30 à 40 % plus petites que &lt;code&gt;serialize()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Les classes &lt;code&gt;Hydrator&lt;/code&gt; et &lt;code&gt;Instantiator&lt;/code&gt; sont obsolètes et remplacées par &lt;code&gt;deepclone_hydrate()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;L'extension optionnelle &lt;code&gt;symfony/php-ext-deepclone&lt;/code&gt; fournit des implémentations natives avec un repli transparent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Le clonage en profondeur est une opération fondamentale de la compilation par injection de dépendances, de la gestion des formulaires et de la mise en cache. L'utilisation de &lt;code&gt;DeepCloner&lt;/code&gt; permet des gains mesurables en termes de temps de compilation et d'exécution (jusqu'à 4 fois plus rapide sur les graphes classiques et jusqu'à 15 fois plus rapide sur les graphes riches en propriétés) sans modification au niveau de l'application. Les charges utiles de clonage exportables permettent des caches chauds efficaces et le transport de graphes d'objets entre processus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Des nœuds de calcul à haut débit qui clonent les objets de configuration ou de modèle par tâche sans état mutable partagé.&lt;/li&gt;
&lt;li&gt;Mise en cache des graphes d'objets compilés (par exemple, modèles d'invites d'IA, définitions de flux de travail) via des charges utiles &lt;code&gt;toArray()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Formulaires d'application nécessitant des instantanés de données de requête à requête sans fuites de références.&lt;/li&gt;
&lt;li&gt;Compilation de conteneurs dans les pipelines CI/CD où des builds plus rapides réduisent les boucles de rétroaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$cloner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DeepCloner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$prototype&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$clone1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$cloner&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DeepCloner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$graph&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$clone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeepCloner&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;fromArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deepclone_hydrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Alice'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;symfony/var-exporter&lt;/code&gt; (DeepCloner, deepclone_hydrate)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/dependency-injection&lt;/code&gt; (clonage de définitions de services)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/framework-bundle&lt;/code&gt; (vidages de conteneurs compilés)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/form&lt;/code&gt; (instantanés de données de formulaire)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/cache&lt;/code&gt; (ArrayAdapter)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/php-ext-deepclone&lt;/code&gt; (extension PHP optionnelle)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Améliorations de l'injection de dépendances
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 apporte de nombreuses améliorations à l'injection de dépendances, notamment pour les processus de longue durée, la composition de décorateurs et un ciblage de services plus clair. Les variables d'environnement peuvent être injectées sous forme de valeurs &lt;code&gt;Closure&lt;/code&gt; ou &lt;code&gt;Stringable&lt;/code&gt; paresseuses pour une actualisation à l'exécution ; les piles et les services étiquetés bénéficient d'une décoration déclarative ; et &lt;code&gt;#[Target]&lt;/code&gt; / &lt;code&gt;#[AsTaggedItem]&lt;/code&gt; deviennent les modèles explicites et recommandés. Plusieurs conventions héritées (correspondance d'alias basée sur le nom, méthodes d'index/priorité magiques) sont dépréciées et supprimées dans Symfony 9.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variables d'environnement en tant que Closure/Stringable&lt;/strong&gt; : &lt;code&gt;#[Autowire(env: 'DB_URL')] \Closure $dbUrl&lt;/code&gt; et balise YAML &lt;code&gt;!env_closure&lt;/code&gt; ; les valeurs sont actualisées via &lt;code&gt;Container::resetEnvCache()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Piles de services en tant que décorateurs&lt;/strong&gt; : les définitions &lt;code&gt;stack&lt;/code&gt; prennent en charge &lt;code&gt;decorates&lt;/code&gt; et &lt;code&gt;decorates_tag&lt;/code&gt; ; la couche la plus interne enveloppe le service cible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;decorates_tag&lt;/code&gt; / &lt;code&gt;#[AsTagDecorator]&lt;/code&gt;&lt;/strong&gt;: enveloppe automatiquement chaque service portant une étiquette donnée (journalisation, traçage, mise en cache).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fabriques/configurateurs de définition en ligne&lt;/strong&gt; : &lt;code&gt;setFactory()&lt;/code&gt; et &lt;code&gt;setConfigurator()&lt;/code&gt; acceptent directement les instances &lt;code&gt;Definition&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exclusions d'importation&lt;/strong&gt; : &lt;code&gt;ContainerConfigurator::import(..., exclude: [...])&lt;/code&gt; ignore les fichiers dans les importations glob.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[AsAlias(..., target: 'name')]&lt;/code&gt;&lt;/strong&gt;: déclare des alias d'injection automatique nommés côté service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[Target]&lt;/code&gt; requis explicitement&lt;/strong&gt; : la correspondance d'alias basée sur le nom du paramètre est obsolète (supprimée dans la version 9.0).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[AsTaggedItem]&lt;/code&gt; sur les votants&lt;/strong&gt; : définit la priorité des balises sans dupliquer &lt;code&gt;security.voter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Points dans les noms des variables d'environnement&lt;/strong&gt; : &lt;code&gt;%env(DATABASE.PRIMARY.URL)%&lt;/code&gt; est maintenant valide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getDefaultName()&lt;/code&gt; / &lt;code&gt;getDefaultPriority()&lt;/code&gt; obsolètes&lt;/strong&gt; : remplacés par &lt;code&gt;#[AsTaggedItem(index:, priority:)]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Ces modifications corrigent des problèmes opérationnels concrets liés aux workers et aux architectures de type microservices, où la configuration de l'environnement doit être actualisée sans reconstruction du conteneur. La décoration déclarative des balises élimine les passes de compilation personnalisées pour les problématiques transversales. Un ciblage plus strict réduit les dysfonctionnements silencieux dus aux renommages de paramètres.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Des processus Messenger/FrankenPHP/RoadRunner injectent des URL de base de données ou des indicateurs de fonctionnalités qui changent lors de l'exécution.&lt;/li&gt;
&lt;li&gt;Décorer tous les générateurs de contexte ou gestionnaires de messages de la plateforme API avec la journalisation/le traçage via &lt;code&gt;decorates_tag&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Déploiements multi-locataires utilisant des noms de variables d'environnement hiérarchiques provenant de gestionnaires de secrets externes.&lt;/li&gt;
&lt;li&gt;Systèmes d'orchestration câblant des backends de stockage nommés (&lt;code&gt;#[Target('image')]&lt;/code&gt;) sans nommage de paramètres fragile.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Autowire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'DB_URL'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;\Closure&lt;/span&gt; &lt;span class="nv"&gt;$dbUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;StorageInterface&lt;/span&gt; &lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;my_stack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;decorates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;api_platform.serializer.context_builder&lt;/span&gt;
    &lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;App\Decorator\AddGroupsContextBuilder&lt;/span&gt;
          &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;@.inner'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/dependency-injection&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/framework-bundle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/security-core&lt;/code&gt; (votants, AsTaggedItem)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/messenger&lt;/code&gt; (actualisation de l'environnement de travail de longue durée)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Attributs du contrôleur dynamique
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 rend les attributs du contrôleur (&lt;code&gt;#[Cache]&lt;/code&gt;, &lt;code&gt;#[IsGranted]&lt;/code&gt;, &lt;code&gt;#[MapRequestPayload]&lt;/code&gt;, attributs personnalisés) modifiables à l'exécution et plus faciles à étendre. Après la première résolution, les attributs sont stockés dans l'attribut de requête &lt;code&gt;_controller_attributes&lt;/code&gt;, permettant ainsi aux écouteurs d'événements de les redéfinir pour chaque requête. Des événements noyau dédiés, nommés &lt;code&gt;{kernelEvent}.{AttributeFQCN}&lt;/code&gt;, remplacent l'inspection manuelle des attributs dans les écouteurs génériques.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;attribut de requête &lt;code&gt;_controller_attributes&lt;/code&gt;&lt;/strong&gt; : le premier appel &lt;code&gt;ControllerEvent::getAttributes()&lt;/code&gt; lit à partir de la réflexion ; les lectures suivantes réutilisent les valeurs stockées.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remplacement à l'exécution&lt;/strong&gt; : les écouteurs appellent &lt;code&gt;setController($callable, $attributes)&lt;/code&gt; pour remplacer les attributs d'une seule requête.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Liste d'attributs plate&lt;/strong&gt; : &lt;code&gt;getAttributes('*')&lt;/code&gt; renvoie les attributs dans l'ordre de déclaration ; l'accès filtré par classe reste inchangé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ResponseEvent::$controllerArgumentsEvent&lt;/code&gt;&lt;/strong&gt;: les écouteurs de réponse peuvent lire les attributs appliqués sans réflexion supplémentaire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Événements nommés par attribut&lt;/strong&gt; : par exemple &lt;code&gt;kernel.controller_arguments.{Cache::class}&lt;/code&gt; avec &lt;code&gt;ControllerAttributeEvent&lt;/code&gt; (expose &lt;code&gt;$event-&amp;gt;attribute&lt;/code&gt; et &lt;code&gt;$event-&amp;gt;kernelEvent&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Écouteurs intégrés migrés&lt;/strong&gt; : &lt;code&gt;CacheAttributeListener&lt;/code&gt;, &lt;code&gt;IsGrantedAttributeListener&lt;/code&gt;, &lt;code&gt;TemplateAttributeListener&lt;/code&gt; utilisent le nouveau système ; les événements ne sont déclenchés que lorsque des écouteurs existent ; l’héritage des attributs est pris en charge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les attributs restent le comportement par défaut déclaratif dans le code source, mais le code d'infrastructure (multi-tenant, tests A/B, indicateurs de fonctionnalités, passerelles API) peut adapter son comportement à chaque requête sans dupliquer la logique du contrôleur. Les fonctionnalités transversales personnalisées basées sur des attributs deviennent pleinement opérationnelles grâce à des événements dédiés, remplaçant ainsi la réflexion fragile dans les écouteurs génériques du noyau.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Remplacement de la durée de vie du cache par locataire dans une API SaaS sans modifier les contrôleurs.&lt;/li&gt;
&lt;li&gt;Limitation dynamique du débit via des attributs personnalisés &lt;code&gt;#[RateLimit]&lt;/code&gt; gérés par des écouteurs dédiés.&lt;/li&gt;
&lt;li&gt;Sécurité basée sur les indicateurs de fonctionnalités : échanger les rôles &lt;code&gt;#[IsGranted]&lt;/code&gt; au moment de l'exécution pour les points de terminaison bêta.&lt;/li&gt;
&lt;li&gt;Contrôleurs de passerelle IA où la mise en cache ou l'autorisation dépend du contexte de la requête (modèle, niveau, paramètres régionaux).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;onKernelController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ControllerEvent&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getAttributes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxage&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
    &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getController&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;array_merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="nb"&gt;array_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[AsEventListener(event: KernelEvents::CONTROLLER_ARGUMENTS.'.'.RateLimit::class)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ControllerAttributeEvent&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$rateLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/http-kernel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/event-dispatcher&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/security-http&lt;/code&gt; (écouteur d'attribut IsGranted)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/framework-bundle&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Applications Symfony sans HTTP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 extrait l'infrastructure du noyau et des bundles de HttpKernel vers le composant DependencyInjection, permettant ainsi aux applications de démarrer un conteneur d'injection de dépendances sans inclure de code lié à HTTP. Une nouvelle paire &lt;code&gt;AbstractKernel&lt;/code&gt; + &lt;code&gt;KernelTrait&lt;/code&gt; remplace &lt;code&gt;MicroKernelTrait&lt;/code&gt; pour les charges de travail non HTTP, et le noyau de FrameworkBundle est désormais divisé en deux composants indépendants : &lt;code&gt;ServicesBundle&lt;/code&gt; et &lt;code&gt;ConsoleBundle&lt;/code&gt;. Ce changement structurel a des implications importantes pour les workers, les outils en ligne de commande et les consommateurs de messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Noyau dans le composant DI&lt;/strong&gt; : &lt;code&gt;Symfony\Component\DependencyInjection\Kernel\AbstractKernel&lt;/code&gt; et &lt;code&gt;KernelTrait&lt;/code&gt; fournissent le cycle de vie du conteneur (construction, compilation, cache) sans HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nouvelle &lt;code&gt;KernelInterface&lt;/code&gt;&lt;/strong&gt; : API réservée aux conteneurs, découplée de &lt;code&gt;HttpKernelInterface&lt;/code&gt; ; &lt;code&gt;HttpKernel\Kernel&lt;/code&gt; existant étend &lt;code&gt;AbstractKernel&lt;/code&gt; (rétrocompatible).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Répertoire de journalisation nullable&lt;/strong&gt; : &lt;code&gt;getLogDir()&lt;/code&gt; nullable ; définissez &lt;code&gt;APP_LOG_DIR=false&lt;/code&gt; pour exclure &lt;code&gt;var/log/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alias ​​obsolètes&lt;/strong&gt; : &lt;code&gt;BundleInterface&lt;/code&gt;, &lt;code&gt;MergeExtensionConfigurationPass&lt;/code&gt;, &lt;code&gt;FileLocator&lt;/code&gt; ont été déplacés de HttpKernel vers DI (les anciennes classes restent en tant qu’alias obsolètes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ServicesBundle&lt;/code&gt;&lt;/strong&gt; : services DI fondamentaux (répartiteur d’événements, système de fichiers, horloge, processeurs d’environnement).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ConsoleBundle&lt;/code&gt;&lt;/strong&gt; : services de console (enregistrement des commandes, résolveurs d’arguments, écouteur d’erreurs) ; les applications minimales n’ont besoin que de ce bundle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[RequiredBundle]&lt;/code&gt;&lt;/strong&gt;: dépendances de bundle déclaratives avec résolution récursive et &lt;code&gt;ignoreOnInvalid&lt;/code&gt; optionnel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les commandes de la console, les consommateurs Messenger et les processus en arrière-plan ne dépendent plus inutilement d'HttpKernel. Des initialisations plus légères permettent des démarrages à froid plus rapides, des déploiements allégés et une séparation architecturale plus nette entre les points d'entrée HTTP et non-HTTP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Processus de traitement Messenger dédiés avec une empreinte Symfony minimale.&lt;/li&gt;
&lt;li&gt;Processeurs d'inférence IA ou de traitement par lots utilisant l'injection de dépendances, les événements et la console sans pile HTTP.&lt;/li&gt;
&lt;li&gt;Utilitaires CLI de type microservice (pipelines de données, orchestrateurs cron) basés sur des conventions Symfony partagées.&lt;/li&gt;
&lt;li&gt;Des ensembles personnalisés déclarant des dépendances sur l'infrastructure de base via &lt;code&gt;#[RequiredBundle]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Kernel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractKernel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;KernelTrait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;Symfony\Component\Console\ConsoleBundle&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;symfony/dependency-injection&lt;/code&gt; (Espace de noms du noyau)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/console&lt;/code&gt; (ConsoleBundle)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-kernel&lt;/code&gt; (alias obsolètes, compatibilité ascendante)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/framework-bundle&lt;/code&gt; (divisé en ServicesBundle + ConsoleBundle)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/messenger&lt;/code&gt; (principal consommateur de noyaux sans HTTP)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Attribut de cache amélioré
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 améliore l'attribut de contrôleur &lt;code&gt;#[Cache]&lt;/code&gt; grâce à des variables d'expression plus claires, un calcul des en-têtes etag/lastModified basé sur les fermetures, une application conditionnelle via une option &lt;code&gt;if&lt;/code&gt; et des attributs répétables pour des politiques de cache mutuellement exclusives. Il s'agit d'améliorations incrémentales du cache HTTP ; leur impact est modéré, sauf si vous utilisez intensivement les en-têtes de cache pilotés par attributs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variables d'expression explicites&lt;/strong&gt; : &lt;code&gt;request&lt;/code&gt; (requête complète) et &lt;code&gt;args&lt;/code&gt; (arguments du contrôleur résolus) remplacent les variables fusionnées plates ; les anciennes variables plates fonctionnent toujours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prise en charge des fermetures&lt;/strong&gt; : &lt;code&gt;lastModified&lt;/code&gt; et &lt;code&gt;etag&lt;/code&gt; acceptent les fermetures PHP &lt;code&gt;(array $args, Request $request)&lt;/code&gt; pour une logique compatible avec les IDE.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mise en cache conditionnelle&lt;/strong&gt; : la nouvelle option &lt;code&gt;if&lt;/code&gt; (expression ou fermeture renvoyant un booléen) ignore l’attribut lorsqu’il est faux.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attribut répétable&lt;/strong&gt; : empilez plusieurs &lt;code&gt;#[Cache]&lt;/code&gt; avec différentes conditions &lt;code&gt;if&lt;/code&gt; sur la même action (par exemple, aperçu vs. mode public).&lt;/li&gt;
&lt;li&gt;Règle existante préservée : les en-têtes de cache déjà définis sur la réponse ne sont pas écrasés.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Réduit l'ambiguïté des expressions lorsque les noms d'arguments entrent en conflit avec les attributs de la requête. Les fermetures améliorent la maintenabilité de la logique ETag complexe. Les attributs conditionnels et répétables permettent des politiques de cache précises sans diviser les contrôleurs ni dupliquer les routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;API de contenu où l'etag combine l'identifiant de l'article et l'en-tête &lt;code&gt;Accept-Language&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Les points de terminaison en mode aperçu ne doivent jamais être mis en cache publiquement, tandis que les vues normales sont mises en cache pendant une heure.&lt;/li&gt;
&lt;li&gt;Points de terminaison CMS ou API headless avec horodatages &lt;code&gt;Last-Modified&lt;/code&gt; pilotés par entité.&lt;/li&gt;
&lt;li&gt;Politiques de mise en cache multivariantes activées par les paramètres de requête ou les indicateurs de fonctionnalités.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;etag&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"request.headers.get('Accept-Language') ~ args['article'].getId()"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Cache(public: true, maxage: 3600, if: fn (array $args, Request $r) =&amp;gt; !$r-&amp;gt;query-&amp;gt;has('preview'))]&lt;/span&gt;
&lt;span class="na"&gt;#[Cache(public: false, maxage: 0, if: fn (array $args, Request $r) =&amp;gt; $r-&amp;gt;query-&amp;gt;has('preview'))]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-kernel&lt;/code&gt; (Attribut Cache)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-foundation&lt;/code&gt; (En-têtes de cache de requête et de réponse)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/expression-language&lt;/code&gt; (expressions de chaînes de caractères)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Amélioration de la saisie sur la console
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 étend la gestion des entrées console avec des invites interactives (&lt;code&gt;#[Ask]&lt;/code&gt;, &lt;code&gt;#[AskChoice]&lt;/code&gt;), le collage d'images depuis le presse-papiers via &lt;code&gt;InputFile&lt;/code&gt;, des valeurs par défaut pour les options, le transfert des entrées brutes pour l'orchestration de sous-processus et l'intégration de Validator pour les entrées interactives et mappées. Associées aux résolveurs d'arguments de console et aux commandes basées sur des méthodes, ces nouveautés font de Symfony Console une plateforme performante pour les outils CLI opérationnels et liés à l'IA.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;InputFile&lt;/code&gt; + &lt;code&gt;#[Ask]&lt;/code&gt;&lt;/strong&gt;: les invites acceptent les images collées (Ghostty, iTerm2, Kitty, WezTerm, Konsole, Warp) ou les chemins de fichiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[AskChoice]&lt;/code&gt;&lt;/strong&gt;: invites de choix déclaratives ; prend en charge &lt;code&gt;array&lt;/code&gt; (sélection multiple) et &lt;code&gt;BackedEnum&lt;/code&gt; (choix dérivés automatiquement).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valeurs par défaut des options négatives&lt;/strong&gt; : valeur par défaut booléenne pour les options &lt;code&gt;InputOption::VALUE_NEGATABLE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valeurs par défaut des objets&lt;/strong&gt; : &lt;code&gt;#[Option] \DateTimeImmutable $from = new \DateTimeImmutable()&lt;/code&gt; est maintenant autorisé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;RawInputInterface&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;getRawArguments()&lt;/code&gt;, &lt;code&gt;getRawOptions()&lt;/code&gt;, &lt;code&gt;unparse()&lt;/code&gt; pour transférer les jetons CLI aux processus enfants sans valeurs par défaut fusionnées.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validateur sur &lt;code&gt;#[Ask]&lt;/code&gt;&lt;/strong&gt; : les contraintes sont réexaminées en cas d’échec ; &lt;code&gt;Question::setConstraints()&lt;/code&gt; pour QuestionHelper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;validation de &lt;code&gt;#[MapInput]&lt;/code&gt;&lt;/strong&gt; : contraintes de validation automatiques sur les DTO d'entrée mappés (comme &lt;code&gt;#[MapRequestPayload]&lt;/code&gt;) ; prise en charge de &lt;code&gt;validationGroups&lt;/code&gt; ; lève &lt;code&gt;InputValidationFailedException&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les commandes CLI interactives bénéficient désormais d'une validation des entrées HTTP équivalente. Le transfert des entrées brutes permet une délégation de commandes fiable et l'exécution de sous-processus parallèles. La prise en charge du collage d'images aligne Symfony Console sur les flux de travail modernes d'IA et d'opérations où les captures d'écran sont des entrées essentielles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Outils CLI assistés par IA acceptant les captures d'écran collées pour analyse (&lt;code&gt;InputFile&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Commandes d'administration de type assistant avec invites e-mail/URL validées.&lt;/li&gt;
&lt;li&gt;Exécuteurs de traitement par lots parallèles transmettant les arguments CLI d'origine aux sous-processus de travail.&lt;/li&gt;
&lt;li&gt;DTO d'entrée de commande structurée (&lt;code&gt;#[MapInput]&lt;/code&gt;) pour les opérations de création/mise à jour avec groupes de validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="na"&gt;#[Argument, Ask('Provide an image:', constraints: [new Assert\NotBlank()])]&lt;/span&gt;
    &lt;span class="nc"&gt;InputFile&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$process&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="no"&gt;\PHP_BINARY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bin/console'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'my:command'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getRawArguments&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;unparse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$options&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/console&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/validator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/process&lt;/code&gt; (transfert de sous-processus)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Amélioration du flux et de l'interrogation JSON
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 améliore JsonStreamer grâce à un mécanisme de transformation des valeurs en objets, la gestion intégrée des intervalles de date et des fuseaux horaires, des options par défaut configurables et la conversion des fuseaux horaires pour les objets DateTime. JsonPath bénéficie désormais de l'enregistrement de fonctions personnalisées via &lt;code&gt;#[AsJsonPathFunction]&lt;/code&gt;. Ces améliorations visent à optimiser le traitement JSON et l'interrogation de documents, notamment pour les API, les pipelines de streaming et les charges de travail d'IA/données manipulant d'importants volumes de données JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ValueObjectTransformerInterface&lt;/code&gt;&lt;/strong&gt; : mappe les objets vers/depuis des valeurs JSON scalaires ; les transformateurs auto-enregistrés remplacent le parcours des propriétés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Objets de valeur intégrés&lt;/strong&gt; : &lt;code&gt;DateInterval&lt;/code&gt; (durée ISO 8601) et &lt;code&gt;DateTimeZone&lt;/code&gt; (nom/décalage) ; personnalisables via &lt;code&gt;date_interval_format&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;option &lt;code&gt;date_time_timezone&lt;/code&gt;&lt;/strong&gt; : convertit les fuseaux horaires lors de l’encodage/décodage de &lt;code&gt;DateTimeInterface&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;framework.json_streamer.default_options&lt;/code&gt;&lt;/strong&gt; : valeurs par défaut à l’échelle de l’application ; options personnalisées transmises aux transformateurs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonctions JsonPath personnalisées&lt;/strong&gt; : &lt;code&gt;#[AsJsonPathFunction('upper')]&lt;/code&gt; sur les classes invocables ; &lt;code&gt;FunctionReturnType::Value&lt;/code&gt; vs &lt;code&gt;::Logical&lt;/code&gt; contrôle le contexte d'utilisation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;JsonStreamer évite le chargement de documents entiers en mémoire, ce qui est essentiel pour les réponses d'API volumineuses et les flux de journaux/événements. Les transformateurs d'objets de valeur permettent de conserver des types de domaine compacts en JSON sans avoir recours à des normalisateurs personnalisés par classe. L'extensibilité de JsonPath prend en charge le filtrage spécifique au domaine sans pipelines de prétraitement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sérialisation en flux continu d'objets financiers « Monnaie » ou de valeurs de mesure sous forme de scalaires compacts.&lt;/li&gt;
&lt;li&gt;Pipelines d'IA/RAG interrogeant de grands magasins de documents JSON avec des fonctions JsonPath personnalisées.&lt;/li&gt;
&lt;li&gt;API événementielles ou analytiques diffusant du JSON paginé avec une gestion cohérente des dates, heures et fuseaux horaires.&lt;/li&gt;
&lt;li&gt;Valeurs par défaut JSON pilotées par la configuration (inclusion de propriétés nulles, options de transformateur personnalisées) pour l'ensemble des services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MoneyValueObjectTransformer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ValueObjectTransformerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[AsJsonPathFunction('upper')]&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UppercaseFunction&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;\is_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/json-streamer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/json-path&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/type-info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/framework-bundle&lt;/code&gt; (configuration json_streamer)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Amélioration du mappage des charges utiles des requêtes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 comble plusieurs lacunes dans &lt;code&gt;#[MapRequestPayload]&lt;/code&gt;, &lt;code&gt;#[MapQueryString]&lt;/code&gt; et &lt;code&gt;#[MapUploadedFile]&lt;/code&gt; : le chargement de fichiers en plusieurs parties dans les DTO, le dépaquetage variadique des DTO, la dénormalisation des charges utiles vides et les groupes de validation dynamiques. Ces améliorations ciblées de la couche API ont un impact direct sur l’ergonomie des contrôleurs et la flexibilité de la validation des entrées.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mappage de fichiers multipart&lt;/strong&gt; : &lt;code&gt;#[MapRequestPayload]&lt;/code&gt; fusionne les paramètres de requête et les fichiers téléchargés (y compris les tableaux imbriqués) avant la désérialisation ; les propriétés &lt;code&gt;UploadedFile&lt;/code&gt; sont remplies de manière transparente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arguments DTO variadiques&lt;/strong&gt; : &lt;code&gt;#[MapRequestPayload] Price ...$prices&lt;/code&gt; décompresse les tableaux JSON en instances DTO individuelles ; fonctionne également avec &lt;code&gt;#[MapQueryString]&lt;/code&gt; et &lt;code&gt;#[MapUploadedFile]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mapWhenEmpty: true&lt;/code&gt;&lt;/strong&gt;: force la dénormalisation sur une requête/un corps vide afin que les dénormaliseurs personnalisés puissent injecter des valeurs (contexte de sécurité, session, valeurs par défaut).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groupes de validation dynamiques&lt;/strong&gt; : &lt;code&gt;validationGroups&lt;/code&gt; accepte &lt;code&gt;Expression&lt;/code&gt; ou &lt;code&gt;Closure&lt;/code&gt; évalués au moment de la validation avec &lt;code&gt;args&lt;/code&gt; (arguments de contrôleur résolus).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les contrôleurs d'API gérant les chargements de fichiers ne nécessitent plus de fusion manuelle ni de résolveurs fractionnés. Le mappage variadique est conforme aux bonnes pratiques PHP pour les points de terminaison par lots. Les groupes de validation dynamiques éliminent les appels manuels aux validateurs lorsque les règles dépendent d'entités de route résolues ou de rôles utilisateur.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;API de produit/catalogue acceptant le nom + l'image dans un seul DTO multipart.&lt;/li&gt;
&lt;li&gt;Création de prix groupés ou de lignes de commande à partir de tableaux JSON via des paramètres variadiques.&lt;/li&gt;
&lt;li&gt;Points de terminaison de recherche/filtrage où les chaînes de requête vides déclenchent toujours des valeurs par défaut basées sur le dénormaliseur (par exemple, l'ID de l'utilisateur actuel).&lt;/li&gt;
&lt;li&gt;Validation des points de terminaison de mise à jour en fonction du rôle ou du type d'entité.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductDto&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?UploadedFile&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;MapRequestPayload&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;ProductDto&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;#[MapRequestPayload(validationGroups: [new Expression('args["user"].getType()')])]&lt;/span&gt;
    &lt;span class="nc"&gt;UpdateUserDto&lt;/span&gt; &lt;span class="nv"&gt;$dto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-kernel&lt;/code&gt; (MapRequestPayload, MapQueryString, MapUploadedFile)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/serializer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/validator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/expression-language&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-foundation&lt;/code&gt; (Fichier téléchargé)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Améliorations de Messenger
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 apporte des améliorations significatives à Messenger, notamment en termes de débit des workers, de comportement du transport, d'interopérabilité de la sérialisation, de gestion des erreurs et d'observabilité opérationnelle. Le traitement par lots, les intervalles de réinitialisation des services configurables, la compatibilité des noms de types entre les langages, la correction des problèmes de priorité et de délai de quorum d'AMQP, ainsi que le routage des erreurs de décodage via le pipeline de gestion des erreurs constituent les changements les plus importants pour les architectures asynchrones en production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--fetch-size=N&lt;/code&gt;&lt;/strong&gt;: les workers récupèrent plusieurs messages par aller-retour (SQS, Redis XREADGROUP, Doctrine LIMIT, AMQP basic_get répété).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--no-reset=N&lt;/code&gt;&lt;/strong&gt;: réinitialise les services tous les N messages au lieu d'un message par message ou jamais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[AsMessage(serializedTypeName: '...')]&lt;/code&gt;&lt;/strong&gt;: en-tête de type personnalisé pour les consommateurs inter-applications/non-Symfony.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AmqpPriorityStamp&lt;/code&gt;&lt;/strong&gt; : priorité RabbitMQ par message (AMQP uniquement).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BatchHandlerTrait::getIdleTimeout()&lt;/code&gt;&lt;/strong&gt;: vide les lots partiels après la période d'inactivité.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL LISTEN/NOTIFY&lt;/strong&gt; : l’attente bloquante a été déplacée vers l’abonné aux événements d’inactivité ; la consommation prioritaire multi-files d’attente a été corrigée.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Échecs de décodage&lt;/strong&gt; : acheminés via des transports de nouvelle tentative/échec ; &lt;code&gt;DecodeFailedMessageMiddleware&lt;/code&gt; réessaie le décodage à chaque tentative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface &lt;code&gt;ListableReceiverInterface&lt;/code&gt; de Redis&lt;/strong&gt; : &lt;code&gt;all()&lt;/code&gt; et &lt;code&gt;find()&lt;/code&gt; via XRANGE pour la surveillance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Option DSN &lt;code&gt;redis_cluster=true&lt;/code&gt;&lt;/strong&gt; : connexion à un cluster Redis à point de terminaison unique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files d'attente de délai de quorum AMQP&lt;/strong&gt; : une file d'attente par jour avec expiration sécurisée.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;queues: false&lt;/code&gt; / &lt;code&gt;[]&lt;/code&gt;&lt;/strong&gt;: désactiver la liaison de file d'attente par défaut pour les transports AMQP en écriture seule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Libération du verrou de déduplication&lt;/strong&gt; : le verrou est libéré immédiatement en cas d’échec définitif (il n’est pas maintenu jusqu’à la durée de vie totale).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Ces modifications corrigent les goulots d'étranglement en production : nombre d'allers-retours réseau par message, fuites d'état et impact sur les performances des processus de longue durée, suppression silencieuse des messages erronés en cas d'échec de décodage, et cas limites de la file d'attente de quorum RabbitMQ. L'harmonisation des noms de types entre les langages et la possibilité de lister les récepteurs Redis améliorent l'interopérabilité et l'observabilité.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vectorisation à haut débit ou intégration de workers avec &lt;code&gt;--fetch-size=10&lt;/code&gt; sur SQS.&lt;/li&gt;
&lt;li&gt;Messages du pipeline d'IA (&lt;code&gt;serializedTypeName: 'crawler.vectorization_finished'&lt;/code&gt;) consommés par les services polyglottes.&lt;/li&gt;
&lt;li&gt;Expédition prioritaire pour les tâches d'inférence urgentes via &lt;code&gt;AmqpPriorityStamp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Surveillance des messages en attente du flux Redis sans les consommer (zenstruck/messenger-monitor-bundle).&lt;/li&gt;
&lt;li&gt;Récupération des messages après des déploiements qui interrompent temporairement la désérialisation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[AsMessage(serializedTypeName: 'crawler.vectorization_finished')]&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VectorizationFinished&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$crawlId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console messenger:consume async &lt;span class="nt"&gt;--fetch-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8
php bin/console messenger:consume async &lt;span class="nt"&gt;--no-reset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/messenger&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/amqp-messenger&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/redis-messenger&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/doctrine-messenger&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zenstruck/messenger-monitor-bundle&lt;/code&gt; (consommateur ListableReceiverInterface)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Commandes basées sur une méthode
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 permet d'utiliser plusieurs commandes console dans une même classe en appliquant &lt;code&gt;#[AsCommand]&lt;/code&gt; à chaque méthode, au lieu d'une classe par commande. Les dépendances partagées du constructeur sont initialisées une seule fois ; chaque méthode annotée est enregistrée comme une commande indépendante par autoconfiguration. L'impact est modéré : il s'agit principalement d'une amélioration de l'expérience utilisateur pour les groupes d'opérations CLI liées.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[AsCommand]&lt;/code&gt; sur les méthodes&lt;/strong&gt; : chaque méthode devient une commande enregistrée distincte avec son propre nom et sa propre description.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Injection par constructeur partagé&lt;/strong&gt; : une classe, un constructeur, plusieurs points d’entrée de commande.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utilisation de la console autonome&lt;/strong&gt; : enregistrez les méthodes en tant qu’objets appelables de première classe via &lt;code&gt;$application-&amp;gt;addCommand($instance-&amp;gt;create(...))&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt; : &lt;code&gt;CommandTester&lt;/code&gt; accepte directement la méthode appelable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Réduit le code répétitif lorsque plusieurs commandes partagent le même dépôt, client API ou système de journalisation. Reprend les modèles Symfony existants (plusieurs actions de contrôleur par classe, plusieurs gestionnaires par classe). Impact architectural mineur, mais significatif pour la maintenabilité des applications utilisant fréquemment l'interface en ligne de commande.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Groupes de commandes de gestion des utilisateurs (&lt;code&gt;app:user:create&lt;/code&gt;, &lt;code&gt;app:user:delete&lt;/code&gt;) partageant un dépôt.&lt;/li&gt;
&lt;li&gt;Commandes de pipeline de données (&lt;code&gt;app:import&lt;/code&gt;, &lt;code&gt;app:validate&lt;/code&gt;, &lt;code&gt;app:export&lt;/code&gt;) avec une infrastructure commune.&lt;/li&gt;
&lt;li&gt;Outils d'IA/opérations avec sous-commandes associées (indexer, réindexer, purger) dans une seule classe de service.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserCommands&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="na"&gt;#[AsCommand('app:user:create', description: 'Creates a new user')]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;OutputInterface&lt;/span&gt; &lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="na"&gt;#[AsCommand('app:user:delete', description: 'Deletes an existing user')]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;OutputInterface&lt;/span&gt; &lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/console&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/framework-bundle&lt;/code&gt; (autoconfiguration)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sérialiser l'attribut
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 introduit l'attribut de contrôleur &lt;code&gt;#[Serialize]&lt;/code&gt;, qui sérialise automatiquement la valeur de retour d'un contrôleur en une réponse HTTP avec le type de contenu, le code de statut et les en-têtes/contexte optionnels appropriés. Ceci élimine les injections répétées du Serializer et la construction manuelle de &lt;code&gt;JsonResponse&lt;/code&gt;. L'impact se concentre sur l'ergonomie du développement d'API ; le comportement dépend du composant Serializer installé et configuré.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[Serialize]&lt;/code&gt; sur les méthodes du contrôleur&lt;/strong&gt; : renvoie un objet ou un tableau ; Symfony l’encapsule dans une réponse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format de la requête&lt;/strong&gt; : dérivé du format de requête actuel (JSON par défaut) ; prend en charge la négociation de contenu via les routes &lt;code&gt;.{_format}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personnalisation&lt;/strong&gt; : options &lt;code&gt;code&lt;/code&gt;, &lt;code&gt;headers&lt;/code&gt; et &lt;code&gt;context&lt;/code&gt; (par exemple &lt;code&gt;DateTimeNormalizer::FORMAT_KEY&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Réponse 415&lt;/strong&gt; : renvoyée automatiquement lorsque le format demandé n’est pas pris en charge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Réduit le code répétitif des contrôleurs d'API et aligne les contrôleurs de valeurs de retour sur les modèles pilotés par attributs déjà utilisés pour le mappage des entrées et la mise en cache. Conserve le contexte de sérialisation au même endroit que la définition du point de terminaison.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Points de terminaison d'API CRUD renvoyant des DTO sans appels manuels au sérialiseur.&lt;/li&gt;
&lt;li&gt;API multiformats (JSON/XML) via des suffixes de format de route sur une seule méthode de contrôleur.&lt;/li&gt;
&lt;li&gt;En-têtes de réponse cohérents (par exemple, en-têtes de traçage ou de versionnage personnalisés) déclarés au niveau de l'attribut.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Serialize(code: 201, context: [DateTimeNormalizer::FORMAT_KEY =&amp;gt; 'd.m.Y H:i:s'])]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;ProductCreated&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ProductCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-kernel&lt;/code&gt; (Attribut Serialize)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symfony/serializer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/http-foundation&lt;/code&gt; (Réponse, négociation de contenu)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Améliorations de la traduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 apporte des améliorations progressives au système de traduction : prise en charge des paramètres régionaux via les variables d’environnement, correction de la traduction des espaces réservés dans les champs de choix étendus, logique de repli pour les paramètres régionaux extraits et prise en charge étendue du format XLIFF, notamment le module PGS pour le pluriel, le genre et les listes déroulantes. L’impact global est modéré et se limite aux applications à forte composante internationale (i18n) et aux intégrations de formulaires.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variables d'environnement dans &lt;code&gt;framework.enabled_locales&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;%env(LOCALE_N)%&lt;/code&gt; avec filtrage automatique des valeurs vides.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correction de l'espace réservé pour les choix étendus&lt;/strong&gt; : les champs étendus &lt;code&gt;EntityType&lt;/code&gt; utilisent désormais &lt;code&gt;translation_domain&lt;/code&gt; (et non &lt;code&gt;choice_translation_domain&lt;/code&gt;) pour la traduction de l'espace réservé.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LocaleFallbackProvider&lt;/code&gt;&lt;/strong&gt; : calcul de chaîne de repli réutilisable (&lt;code&gt;computeFallbackLocales()&lt;/code&gt;) et fonction d'assistance &lt;code&gt;validateLocale()&lt;/code&gt; extraite du traducteur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prise en charge de XLIFF 2.1 et 2.2&lt;/strong&gt; : numéros de version acceptés de manière transparente (structure compatible avec 2.0).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Module XLIFF PGS&lt;/strong&gt; : le pluriel, le genre et certains attributs ont été convertis au format de message ICU et enregistrés dans le domaine &lt;code&gt;+intl-icu&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Les déploiements multi-locataires et multi-environnements permettent de configurer les paramètres régionaux sans fichier de configuration par environnement. La correction du paramètre d'espace réservé pour EntityType résout une incohérence persistante liée à Form/i18n. La prise en charge de XLIFF PGS assure la compatibilité de Symfony avec les outils de traduction modernes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Les plateformes SaaS permettent de définir différents ensembles de paramètres régionaux par locataire via des variables d'environnement.&lt;/li&gt;
&lt;li&gt;Formulaires avec des espaces réservés pour les boutons radio/cases à cocher traduits sur les choix d'entités Doctrine.&lt;/li&gt;
&lt;li&gt;Services partagés calculant des chaînes de repli de localisation cohérentes en dehors du traducteur.&lt;/li&gt;
&lt;li&gt;Importation de fichiers XLIFF 2.2 avec règles de pluriel/genre à partir de plateformes de localisation externes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled_locales&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%env(LOCALE_1)%'&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%env(LOCALE_2)%'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$fallbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LocaleFallbackProvider&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;computeFallbackLocales&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'es_AR'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ['es_419', 'es', 'en']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/translation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/form&lt;/code&gt; (EntityType, ChoiceType)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/intl&lt;/code&gt; (Format de message ICU via le domaine +intl-icu)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Remarque :&lt;/strong&gt; Faible impact sur les systèmes backend/asynchrones/IA, sauf si l’application a des exigences importantes en matière d’internationalisation ou de formulaires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Améliorations du validateur
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bref résumé
&lt;/h3&gt;

&lt;p&gt;Symfony 8.1 intègre une contrainte &lt;code&gt;Xml&lt;/code&gt;, rend les validateurs de comparaison de dates sensibles à l'horloge pour des tests déterministes, introduit des vérifications strictes optionnelles des métadonnées de propriétés et refactorise les validateurs de contraintes pour les rendre réentrants via &lt;code&gt;validateInContext()&lt;/code&gt;. Ces améliorations concernent principalement le composant Validator ; la contrainte XML et la prise en compte de l'horloge sont celles qui ont l'impact pratique le plus évident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principaux changements techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;#[Assert\Xml]&lt;/code&gt;&lt;/strong&gt;: valide le XML bien formé ; &lt;code&gt;schemaPath&lt;/code&gt; optionnel pour la validation XSD avec des violations numérotées en ligne.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validateurs de date prenant en compte l'horloge&lt;/strong&gt; : &lt;code&gt;GreaterThan&lt;/code&gt;, &lt;code&gt;GreaterThanOrEqual&lt;/code&gt;, &lt;code&gt;LessThan&lt;/code&gt;, &lt;code&gt;LessThanOrEqual&lt;/code&gt; et &lt;code&gt;Range&lt;/code&gt; résolvent les chaînes relatives (&lt;code&gt;today&lt;/code&gt;, &lt;code&gt;-18 years&lt;/code&gt;) par rapport à &lt;code&gt;ClockInterface&lt;/code&gt; lorsqu'il est disponible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Câblage automatique de FrameworkBundle&lt;/strong&gt; : horloge injectée dans les validateurs déclarant &lt;code&gt;ClockInterface&lt;/code&gt; dans le constructeur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ValidatorBuilder::enablePropertyMetadataExistenceCheck()&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;validateProperty()&lt;/code&gt; / &lt;code&gt;validatePropertyValue()&lt;/code&gt; lève une exception sur les noms de propriétés inconnus (détection de fautes de frappe).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validateurs réentrants&lt;/strong&gt; : nouvelle &lt;code&gt;ConstraintValidatorInterface::validateInContext()&lt;/code&gt; ; les implémenteurs directs doivent migrer ; &lt;code&gt;validate()&lt;/code&gt; et &lt;code&gt;initialize()&lt;/code&gt; sont obsolètes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pourquoi c'est important
&lt;/h3&gt;

&lt;p&gt;Élimine le code répétitif de validation XML personnalisé pour les flux SOAP, les sitemaps et les charges utiles de configuration. Les validateurs prenant en compte l'horloge permettent des tests unitaires fiables pour les contrôles d'âge, les fenêtres de réservation et les règles de délai. Les validateurs réentrants corrigent les bogues subtils dans la validation imbriquée (par exemple, &lt;code&gt;CollectionValidator&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Cas d'utilisation potentiels dans le monde réel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Validation des flux XML tiers ou des réponses SOAP par rapport aux schémas XSD.&lt;/li&gt;
&lt;li&gt;Règles de vérification de l'âge ou de la date de réservation testées avec &lt;code&gt;MockClock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Validation stricte des propriétés dans les générateurs de code ou les outils d'administration qui valident les objets partiels par nom de propriété.&lt;/li&gt;
&lt;li&gt;Validation complexe des DTO imbriqués sans corruption de l'état du validateur.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extraits de code importants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Assert\Xml(schemaPath: 'config/schemas/report.xsd')]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$validatedContent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createValidatorBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;enablePropertyMetadataExistenceCheck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getValidator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composants/packages Symfony associés
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symfony/validator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/clock&lt;/code&gt; (MockClock, ClockInterface)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;symfony/framework-bundle&lt;/code&gt; (câblage de l'horloge)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Remarque :&lt;/strong&gt; La validation de la console &lt;code&gt;#[MapInput]&lt;/code&gt; et &lt;code&gt;#[Ask]&lt;/code&gt; (composant Console) réutilise les contraintes du validateur, mais est documentée séparément.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Symfony 8.1 confirme une évolution très intéressante de l'écosystème vers des architectures de plus en plus modulaires, asynchrones et orientées outils.&lt;/p&gt;

&lt;p&gt;Au-delà des améliorations apportées à l'expérience utilisateur, plusieurs nouvelles fonctionnalités témoignent clairement d'un engagement à adapter Symfony aux cas d'utilisation modernes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;travailleurs de longue date,&lt;/li&gt;
&lt;li&gt;pipelines de données,&lt;/li&gt;
&lt;li&gt;systèmes distribués,&lt;/li&gt;
&lt;li&gt;API avancées,&lt;/li&gt;
&lt;li&gt;Outils CLI,&lt;/li&gt;
&lt;li&gt;Traitement de gros volumes de JSON,&lt;/li&gt;
&lt;li&gt;et les applications orientées orchestration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Même si certaines fonctionnalités restent expérimentales ou ciblent des cas d'utilisation spécifiques, le tableau d'ensemble indique une direction cohérente pour les futures versions du framework.&lt;/p&gt;

&lt;p&gt;J'ai également préparé une présentation technique SlideWire sur les nouvelles fonctionnalités de Symfony 8.1 :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/matyo91/slidewire" rel="noopener noreferrer"&gt;Dépôt GitHub de SlideWire&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plus d'infos sur le blog symfony : &lt;a href="https://symfony.com/blog/category/living-on-the-edge/8.1" rel="noopener noreferrer"&gt;https://symfony.com/blog/category/living-on-the-edge/8.1&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>news</category>
      <category>php</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🎤 Sunday Labs #4 : ce que l’écosystème builder parisien cherche vraiment</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Tue, 26 May 2026 08:05:05 +0000</pubDate>
      <link>https://dev.to/matyo91/sunday-labs-4-ce-que-lecosysteme-builder-parisien-cherche-vraiment-3293</link>
      <guid>https://dev.to/matyo91/sunday-labs-4-ce-que-lecosysteme-builder-parisien-cherche-vraiment-3293</guid>
      <description>&lt;p&gt;Le 24 mai dernier avait lieu la quatrième édition de Sunday Labs, organisée par Build Society chez Hexa (eFounders), à Paris.&lt;/p&gt;

&lt;p&gt;Le format était simple : réunir des builders, fondateurs, freelances, profils tech et créateurs autour de discussions ouvertes, de présentations de projets et de networking.&lt;/p&gt;

&lt;p&gt;Pas de keynote.&lt;br&gt;
Pas de conférence descendante.&lt;br&gt;
L’objectif était surtout de créer des échanges utiles entre personnes qui construisent déjà quelque chose.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-05-24-sunday-labs-4/resized_IMG_4757.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-05-24-sunday-labs-4/resized_IMG_4757.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Le sujet central : pourquoi Paris attire encore moins que d’autres écosystèmes tech ?
&lt;/h2&gt;

&lt;p&gt;La première partie de l’événement tournait autour d’une question :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Que manque-t-il à Paris pour devenir un écosystème plus attractif pour les investisseurs et les entrepreneurs tech ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plusieurs thèmes sont revenus quasiment dans tous les groupes.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Le manque de lieux et de culture builder
&lt;/h3&gt;

&lt;p&gt;Beaucoup ont évoqué l’absence d’espaces réellement pensés pour les builders :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hacker houses,&lt;/li&gt;
&lt;li&gt;cafés orientés startup,&lt;/li&gt;
&lt;li&gt;lieux ouverts tard,&lt;/li&gt;
&lt;li&gt;espaces hybrides entre coworking et communauté.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’idée revient souvent : à Paris, il existe des événements tech, mais peu d’endroits où les rencontres se font naturellement au quotidien.&lt;/p&gt;

&lt;p&gt;Le parallèle avec San Francisco ou New York a été fait plusieurs fois, notamment sur la facilité à rencontrer d’autres personnes qui construisent.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. La culture du risque reste différente
&lt;/h3&gt;

&lt;p&gt;Autre sujet récurrent : la perception de l’échec.&lt;/p&gt;

&lt;p&gt;Plusieurs participants ont expliqué qu’en France :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;l’échec entrepreneurial reste stigmatisé,&lt;/li&gt;
&lt;li&gt;l’administratif freine certains projets,&lt;/li&gt;
&lt;li&gt;le cadre juridique et fiscal peut décourager des profils early-stage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;À l’inverse, l’écosystème américain est perçu comme plus tolérant au risque et plus agressif sur le financement.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Le sujet du marché américain
&lt;/h3&gt;

&lt;p&gt;Des fondateurs présents ont aussi partagé leur expérience autour des États-Unis :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;création de structures dans le Delaware,&lt;/li&gt;
&lt;li&gt;recherche de financements US,&lt;/li&gt;
&lt;li&gt;accès à un marché plus large,&lt;/li&gt;
&lt;li&gt;valorisations plus élevées.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un point intéressant : plusieurs personnes ont insisté sur le fait que les talents français existent déjà, mais que beaucoup de projets finissent par partir vers les US pour des raisons économiques et de distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. La langue et l’ouverture internationale
&lt;/h3&gt;

&lt;p&gt;Des participants internationaux ont également souligné que :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;la barrière linguistique reste réelle,&lt;/li&gt;
&lt;li&gt;beaucoup d’événements restent très francophones,&lt;/li&gt;
&lt;li&gt;Paris pourrait être plus accessible aux builders étrangers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le sujet n’était pas présenté comme un rejet du français, mais plutôt comme une question d’accessibilité dans un environnement tech mondial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Branding, contenu et distribution : des sujets omniprésents
&lt;/h2&gt;

&lt;p&gt;Une autre partie importante des échanges concernait le contenu et le personal branding.&lt;/p&gt;

&lt;p&gt;Le constat partagé :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;publier régulièrement reste l’un des meilleurs leviers pour trouver des clients, des associés ou des opportunités,&lt;/li&gt;
&lt;li&gt;LinkedIn fonctionne toujours très bien pour le B2B,&lt;/li&gt;
&lt;li&gt;Substack devient intéressant pour des niches plus techniques ou spécialisées.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plusieurs participants utilisaient déjà :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;des workflows IA pour écrire leurs posts,&lt;/li&gt;
&lt;li&gt;des agents pour automatiser la publication,&lt;/li&gt;
&lt;li&gt;des systèmes de veille et de génération de contenu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un point intéressant soulevé pendant la discussion :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;le problème n’est pas forcément l’IA sur LinkedIn, mais le manque de profondeur de beaucoup de contenus.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Substack a été cité comme alternative plus qualitative pour développer des réflexions longues et toucher des audiences plus ciblées.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les projets présentés pendant l’événement
&lt;/h2&gt;

&lt;p&gt;Comme souvent dans ce type de format, la partie la plus intéressante restait les échanges autour des projets en cours.&lt;/p&gt;

&lt;p&gt;Quelques exemples :&lt;/p&gt;

&lt;h3&gt;
  
  
  Un Agent OS grand public
&lt;/h3&gt;

&lt;p&gt;Un participant travaillait sur une interface simplifiée autour d’OpenFlow avec l’idée suivante :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rendre les agents IA accessibles à des utilisateurs non techniques,&lt;/li&gt;
&lt;li&gt;centraliser la “vie digitale” d’un utilisateur,&lt;/li&gt;
&lt;li&gt;automatiser certaines tâches via des agents personnels.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Une plateforme de matchmaking social
&lt;/h3&gt;

&lt;p&gt;Un autre projet portait sur le matchmaking relationnel appliqué aux événements.&lt;/p&gt;

&lt;p&gt;L’idée :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;utiliser des questionnaires autour des valeurs, émotions et profils,&lt;/li&gt;
&lt;li&gt;créer des groupes pertinents pendant des événements,&lt;/li&gt;
&lt;li&gt;faciliter les rencontres, notamment pour les profils introvertis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Serend
&lt;/h3&gt;

&lt;p&gt;Projet présenté comme un “réseau social anti-feed”.&lt;/p&gt;

&lt;p&gt;Le principe :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;une seule nouvelle rencontre tous les trois jours,&lt;/li&gt;
&lt;li&gt;pas de scrolling,&lt;/li&gt;
&lt;li&gt;pas de logique de visibilité,&lt;/li&gt;
&lt;li&gt;uniquement des conversations entre profils compatibles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le positionnement était clairement orienté contre les mécaniques classiques des réseaux sociaux actuels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meetable
&lt;/h3&gt;

&lt;p&gt;Plateforme de networking via des dîners en petit comité.&lt;/p&gt;

&lt;p&gt;L’objectif :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;connecter entrepreneurs, freelances et profils complémentaires,&lt;/li&gt;
&lt;li&gt;favoriser des échanges plus qualitatifs,&lt;/li&gt;
&lt;li&gt;créer des rencontres orientées compétences + compatibilité humaine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scraping LinkedIn et signaux d’intention
&lt;/h3&gt;

&lt;p&gt;Un participant présentait aussi une infrastructure de scraping LinkedIn à grande échelle :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;suivi des recrutements,&lt;/li&gt;
&lt;li&gt;détection de changements dans les entreprises,&lt;/li&gt;
&lt;li&gt;génération de signaux d’intention d’achat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le sujet a rapidement dérivé vers les limites techniques, le scraping, les datasets et les modèles commerciaux possibles.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ce que montre ce type d’événement
&lt;/h1&gt;

&lt;p&gt;Le point le plus intéressant de Sunday Labs #4 n’était probablement pas un projet précis.&lt;/p&gt;

&lt;p&gt;C’était plutôt le niveau d’ouverture dans les discussions :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;partage de problématiques réelles,&lt;/li&gt;
&lt;li&gt;retours directs,&lt;/li&gt;
&lt;li&gt;débats sur les modèles économiques,&lt;/li&gt;
&lt;li&gt;échanges très early-stage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On sent aussi une évolution du format des événements startup à Paris :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moins de conférences,&lt;/li&gt;
&lt;li&gt;plus de discussions,&lt;/li&gt;
&lt;li&gt;plus de petits groupes,&lt;/li&gt;
&lt;li&gt;plus de projets en construction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’écosystème parisien manque peut-être encore de structure et de capital comparé aux US, mais il y a clairement une génération de builders qui cherche à créer ses propres formats, ses propres communautés et ses propres réseaux.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🧩 Un agent IA aujourd’hui, c’est un stagiaire hypermotivé avec 400 onglets ouverts.</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sat, 23 May 2026 07:40:44 +0000</pubDate>
      <link>https://dev.to/matyo91/un-agent-ia-aujourdhui-cest-un-stagiaire-hypermotive-avec-400-onglets-ouverts-3ljk</link>
      <guid>https://dev.to/matyo91/un-agent-ia-aujourdhui-cest-un-stagiaire-hypermotive-avec-400-onglets-ouverts-3ljk</guid>
      <description>&lt;p&gt;Il répond vite.&lt;br&gt;
Il a confiance en lui.&lt;br&gt;
Il sait utiliser Gmail, Slack, Notion, GitHub, Linear, le terminal, et parfois même Docker.&lt;/p&gt;

&lt;p&gt;Et pourtant, dès qu’on lui donne une tâche un peu longue, tout commence à partir en vrille.&lt;/p&gt;

&lt;p&gt;Pas parce que le modèle est mauvais.&lt;/p&gt;

&lt;p&gt;Parce que le système autour est chaotique.&lt;/p&gt;


&lt;h2&gt;
  
  
  Le fantasme actuel des agents
&lt;/h2&gt;

&lt;p&gt;La démo est toujours la même :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Regarde, mon agent peut réserver un vol, envoyer un mail, créer un ticket Jira et déployer en production.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Techniquement, oui.&lt;/p&gt;

&lt;p&gt;Mais dans la réalité, la plupart des agents ressemblent à ça :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ils ouvrent trop d’outils&lt;/li&gt;
&lt;li&gt;oublient le contexte initial&lt;/li&gt;
&lt;li&gt;exécutent des actions dans le mauvais ordre&lt;/li&gt;
&lt;li&gt;hallucinent des états intermédiaires&lt;/li&gt;
&lt;li&gt;improvisent quand ils ne savent pas&lt;/li&gt;
&lt;li&gt;et surtout : ils ne savent pas quand s’arrêter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le problème n’est plus :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“est-ce que le modèle sait faire ?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le problème devient :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“comment est-ce qu’on orchestre proprement ses actions ?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Les LLM sont forts. Les systèmes autour beaucoup moins.
&lt;/h2&gt;

&lt;p&gt;ChatGPT, Claude, Gemini ou Qwen sont capables de :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;résumer des documents&lt;/li&gt;
&lt;li&gt;écrire du code&lt;/li&gt;
&lt;li&gt;comprendre du langage naturel&lt;/li&gt;
&lt;li&gt;raisonner sur plusieurs étapes&lt;/li&gt;
&lt;li&gt;manipuler des outils.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais un agent, ce n’est pas juste un LLM.&lt;/p&gt;

&lt;p&gt;C’est :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM
+ mémoire
+ outils
+ permissions
+ orchestration
+ validation
+ logs
+ contraintes
+ checkpoints humains
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et aujourd’hui, la plupart des stacks IA ressemblent encore à :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“brancher plein d’APIs ensemble et espérer que ça marche.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  L’orchestration est devenue le vrai problème
&lt;/h2&gt;

&lt;p&gt;Imagine un orchestre sans chef.&lt;/p&gt;

&lt;p&gt;Les musiciens sont excellents individuellement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;très bons violons&lt;/li&gt;
&lt;li&gt;très bonne batterie&lt;/li&gt;
&lt;li&gt;très bons cuivres.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais personne ne décide :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;du tempo&lt;/li&gt;
&lt;li&gt;des entrées&lt;/li&gt;
&lt;li&gt;des transitions&lt;/li&gt;
&lt;li&gt;des priorités&lt;/li&gt;
&lt;li&gt;de la fin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Résultat :&lt;br&gt;
ça fait du bruit.&lt;/p&gt;

&lt;p&gt;C’est exactement ce qui se passe quand on empile :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompts&lt;/li&gt;
&lt;li&gt;tools&lt;/li&gt;
&lt;li&gt;MCP servers&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;agents autonomes&lt;/li&gt;
&lt;li&gt;workflows&lt;/li&gt;
&lt;li&gt;memory systems
sans définir :&lt;/li&gt;
&lt;li&gt;qui décide quoi&lt;/li&gt;
&lt;li&gt;dans quel ordre&lt;/li&gt;
&lt;li&gt;avec quel droit de veto&lt;/li&gt;
&lt;li&gt;et avec quelles limites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  L’autonomie sans contraintes produit surtout du chaos
&lt;/h2&gt;

&lt;p&gt;Un agent IA sans garde-fous, c’est rarement “Jarvis”.&lt;/p&gt;

&lt;p&gt;C’est plutôt :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un alternant qui a accès à la prod&lt;/li&gt;
&lt;li&gt;sans checklist&lt;/li&gt;
&lt;li&gt;sans supervision&lt;/li&gt;
&lt;li&gt;sans notion du risque&lt;/li&gt;
&lt;li&gt;avec énormément de confiance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le plus dangereux n’est pas qu’il se trompe.&lt;/p&gt;

&lt;p&gt;Le plus dangereux, c’est que :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ses erreurs ont souvent l’air plausibles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il répond avec assurance.&lt;br&gt;
Il génère des plans crédibles.&lt;br&gt;
Il explique ses décisions.&lt;/p&gt;

&lt;p&gt;Même quand il invente complètement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qu’on appelle “agent”, aujourd’hui
&lt;/h2&gt;

&lt;p&gt;Beaucoup de systèmes “agents” actuels sont en réalité :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;des boucles de prompts&lt;/li&gt;
&lt;li&gt;des wrappers d’outils&lt;/li&gt;
&lt;li&gt;des routers&lt;/li&gt;
&lt;li&gt;des chaînes d’appels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Très peu possèdent réellement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;une mémoire stable&lt;/li&gt;
&lt;li&gt;une hiérarchie de décisions&lt;/li&gt;
&lt;li&gt;une stratégie&lt;/li&gt;
&lt;li&gt;une capacité d’arrêt&lt;/li&gt;
&lt;li&gt;une gestion claire des permissions&lt;/li&gt;
&lt;li&gt;une orchestration déterministe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On a énormément travaillé l’intelligence brute.&lt;/p&gt;

&lt;p&gt;Pas assez :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;le contrôle&lt;/li&gt;
&lt;li&gt;la coordination&lt;/li&gt;
&lt;li&gt;la supervision&lt;/li&gt;
&lt;li&gt;la traçabilité.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Le vrai scaling de l’IA n’est peut-être plus le modèle
&lt;/h2&gt;

&lt;p&gt;Pendant des années, le scaling de l’IA consistait surtout à :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;augmenter les paramètres&lt;/li&gt;
&lt;li&gt;augmenter le compute&lt;/li&gt;
&lt;li&gt;augmenter les datasets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais le prochain problème ressemble davantage à :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“comment coordonner correctement des systèmes probabilistes.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Autrement dit :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;runtime&lt;/li&gt;
&lt;li&gt;mémoire&lt;/li&gt;
&lt;li&gt;vérification&lt;/li&gt;
&lt;li&gt;hiérarchie&lt;/li&gt;
&lt;li&gt;contraintes&lt;/li&gt;
&lt;li&gt;auditabilité.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le modèle devient presque :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;un composant parmi d’autres.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Construire un agent utile ressemble plus à construire une organisation
&lt;/h2&gt;

&lt;p&gt;Un bon système agentique ressemble moins à :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“une IA omnisciente”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;et davantage à :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“une équipe bien encadrée”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rôles séparés&lt;/li&gt;
&lt;li&gt;limites claires&lt;/li&gt;
&lt;li&gt;validation humaine&lt;/li&gt;
&lt;li&gt;journaux d’actions&lt;/li&gt;
&lt;li&gt;budgets&lt;/li&gt;
&lt;li&gt;règles d’arrêt&lt;/li&gt;
&lt;li&gt;supervision&lt;/li&gt;
&lt;li&gt;retry contrôlé&lt;/li&gt;
&lt;li&gt;sandboxing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le problème n’est pas seulement cognitif.&lt;/p&gt;

&lt;p&gt;Il est organisationnel.&lt;/p&gt;

&lt;h2&gt;
  
  
  De la génération de texte à la génération de processus
&lt;/h2&gt;

&lt;p&gt;Le vrai shift est peut-être là.&lt;/p&gt;

&lt;p&gt;Les premiers LLM généraient :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;du texte&lt;/li&gt;
&lt;li&gt;du code&lt;/li&gt;
&lt;li&gt;des images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les prochains systèmes généreront :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;des workflows&lt;/li&gt;
&lt;li&gt;des plans&lt;/li&gt;
&lt;li&gt;des décisions&lt;/li&gt;
&lt;li&gt;des exécutions&lt;/li&gt;
&lt;li&gt;des pipelines complets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et plus ces systèmes deviennent autonomes, plus :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;l’orchestration&lt;/li&gt;
&lt;li&gt;les contraintes&lt;/li&gt;
&lt;li&gt;les garde-fous&lt;/li&gt;
&lt;li&gt;et la traçabilité&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;deviennent critiques.&lt;/p&gt;

&lt;h2&gt;
  
  
  Construire Toutouexplique
&lt;/h2&gt;

&lt;p&gt;Ce week-end, on a construit un moteur Symfony capable de transformer :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un sujet YAML&lt;/li&gt;
&lt;li&gt;une structure narrative&lt;/li&gt;
&lt;li&gt;une grammaire de style&lt;/li&gt;
&lt;li&gt;des contraintes de rendu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;en :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;voix&lt;/li&gt;
&lt;li&gt;images&lt;/li&gt;
&lt;li&gt;scènes&lt;/li&gt;
&lt;li&gt;vidéo finale&lt;/li&gt;
&lt;li&gt;article.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le plus intéressant n’était pas la génération elle-même.&lt;/p&gt;

&lt;p&gt;Le plus intéressant était :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;la formalisation de la structure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On ne cherchait pas à copier un créateur.&lt;/p&gt;

&lt;p&gt;On cherchait à comprendre :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;son rythme&lt;/li&gt;
&lt;li&gt;sa densité&lt;/li&gt;
&lt;li&gt;sa structure narrative&lt;/li&gt;
&lt;li&gt;sa compression d’information&lt;/li&gt;
&lt;li&gt;son pacing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Autrement dit :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;transformer une grammaire implicite en système exécutable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Le futur du contenu IA sera structurel
&lt;/h2&gt;

&lt;p&gt;Aujourd’hui, presque tous les outils IA savent générer du contenu.&lt;/p&gt;

&lt;p&gt;Le vrai différenciateur devient :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;le format&lt;/li&gt;
&lt;li&gt;le rythme&lt;/li&gt;
&lt;li&gt;l’orchestration&lt;/li&gt;
&lt;li&gt;la cohérence&lt;/li&gt;
&lt;li&gt;la structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pas seulement :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“est-ce que le modèle est intelligent ?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“est-ce que le système sait se coordonner ?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Et ça vaut autant pour :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;les agents IA&lt;/li&gt;
&lt;li&gt;les pipelines vidéo&lt;/li&gt;
&lt;li&gt;les systèmes autonomes&lt;/li&gt;
&lt;li&gt;que pour les organisations humaines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Faut doser
&lt;/h2&gt;

&lt;p&gt;Un agent utile n’est pas forcément le plus autonome.&lt;/p&gt;

&lt;p&gt;C’est souvent :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;celui qui possède les meilleures limites&lt;/li&gt;
&lt;li&gt;les meilleures validations&lt;/li&gt;
&lt;li&gt;la meilleure orchestration&lt;/li&gt;
&lt;li&gt;et le moins d’onglets ouverts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’intelligence brute aide.&lt;/p&gt;

&lt;p&gt;Mais sans structure :&lt;br&gt;
on ne scale pas l’intelligence.&lt;/p&gt;

&lt;p&gt;On scale juste le chaos plus vite.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>⬆️ Flowvox update : Symfony devient une plateforme d’agents vocaux temps réel</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 18 May 2026 07:21:52 +0000</pubDate>
      <link>https://dev.to/matyo91/flowvox-update-symfony-devient-une-plateforme-dagents-vocaux-temps-reel-1bc9</link>
      <guid>https://dev.to/matyo91/flowvox-update-symfony-devient-une-plateforme-dagents-vocaux-temps-reel-1bc9</guid>
      <description>&lt;p&gt;En février 2026, j’avais publié un premier prototype expérimental autour de la transcription vocale en PHP avec Whisper.cpp.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.darkwood.com/article/i-m-building-a-dictation-engine-in-php-flow-symfony-whisper-cpp" rel="noopener noreferrer"&gt;https://blog.darkwood.com/article/i-m-building-a-dictation-engine-in-php-flow-symfony-whisper-cpp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’objectif était simple :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;enregistrer sa voix, la retranscrire localement, puis exporter le résultat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Trois mois plus tard, le projet a énormément évolué.&lt;/p&gt;

&lt;p&gt;Flowvox n’est plus seulement un POC console.&lt;/p&gt;

&lt;p&gt;C’est désormais une plateforme de workers vocaux temps réel construite avec Symfony 8, Messenger, Mercure, Symfony UX, OpenAI Realtime et Hotwire Native. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi cette mise à jour maintenant ?
&lt;/h2&gt;

&lt;p&gt;La raison est très simple : OpenAI vient de faire évoluer massivement son API audio temps réel.&lt;/p&gt;

&lt;p&gt;Dans leur démonstration récente, plusieurs nouveautés ont été présentées :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;traduction multilingue temps réel&lt;/li&gt;
&lt;li&gt;transcription fluide en streaming&lt;/li&gt;
&lt;li&gt;agents vocaux capables d’appeler des tools&lt;/li&gt;
&lt;li&gt;raisonnement en arrière-plan&lt;/li&gt;
&lt;li&gt;conservation du contexte conversationnel. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce n’est plus simplement de la reconnaissance vocale.&lt;/p&gt;

&lt;p&gt;La voix devient une interface programmable.&lt;/p&gt;

&lt;p&gt;Et c’est précisément la direction dans laquelle Flowvox évolue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le prototype initial : Whisper.cpp + terminal
&lt;/h2&gt;

&lt;p&gt;La première version de Flowvox était extrêmement minimaliste.&lt;/p&gt;

&lt;p&gt;Architecture :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
→ ffmpeg
→ whisper.cpp
→ transcription locale
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le système fonctionnait entièrement en ligne de commande :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console voice:start
php bin/console voice:stop
php bin/console voice:worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il n’y avait :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aucune UI&lt;/li&gt;
&lt;li&gt;aucun temps réel&lt;/li&gt;
&lt;li&gt;aucune orchestration distribuée&lt;/li&gt;
&lt;li&gt;aucune notion de session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’objectif était uniquement de valider qu’il était possible de faire de la transcription locale en PHP avec Whisper.cpp. &lt;/p&gt;

&lt;h2&gt;
  
  
  Passage à une architecture distribuée
&lt;/h2&gt;

&lt;p&gt;La nouvelle version change complètement de philosophie.&lt;/p&gt;

&lt;p&gt;Le cœur du système repose maintenant sur :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony Messenger&lt;/li&gt;
&lt;li&gt;darkwood/flow&lt;/li&gt;
&lt;li&gt;Mercure&lt;/li&gt;
&lt;li&gt;Doctrine&lt;/li&gt;
&lt;li&gt;Symfony UX&lt;/li&gt;
&lt;li&gt;providers de transcription interchangeables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture simplifiée :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    UI["Symfony UX"]
    MQ["Messenger"]
    W["Voice Worker"]
    F["Flow Pipeline"]
    OAI["OpenAI Realtime"]
    WC["Whisper.cpp"]
    M["Mercure"]

    UI --&amp;gt; MQ
    MQ --&amp;gt; W
    W --&amp;gt; F
    F --&amp;gt; WC
    F --&amp;gt; OAI
    W --&amp;gt; M
    M --&amp;gt; UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le point important :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;le worker n’est pas l’interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;L’UI ne fait que piloter des workers vocaux indépendants. &lt;/p&gt;

&lt;p&gt;Chaque session possède sa propre queue Messenger :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;voice_demo
voice_mobile
voice_conference
voice_stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cela permet d’avoir :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;plusieurs workers&lt;/li&gt;
&lt;li&gt;plusieurs appareils&lt;/li&gt;
&lt;li&gt;plusieurs sessions simultanées&lt;/li&gt;
&lt;li&gt;une architecture distribuée.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Flow orchestration
&lt;/h2&gt;

&lt;p&gt;Le pipeline repose toujours sur Darkwood Flow.&lt;/p&gt;

&lt;p&gt;Trois étapes principales :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Étape&lt;/th&gt;
&lt;th&gt;Rôle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;InputProviderFlow&lt;/td&gt;
&lt;td&gt;Lecture des événements START / STOP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RecorderFlow&lt;/td&gt;
&lt;td&gt;Enregistrement audio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TranscribeFlow&lt;/td&gt;
&lt;td&gt;Transcription&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le worker reste long-running et écoute les événements Messenger.&lt;/p&gt;

&lt;p&gt;Lorsqu’un &lt;code&gt;START&lt;/code&gt; est reçu :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;le worker démarre l’enregistrement&lt;/li&gt;
&lt;li&gt;ffmpeg capture l’audio&lt;/li&gt;
&lt;li&gt;la session est suivie&lt;/li&gt;
&lt;li&gt;les événements sont publiés via Mercure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lorsqu’un &lt;code&gt;STOP&lt;/code&gt; est reçu :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;le fichier WAV est finalisé&lt;/li&gt;
&lt;li&gt;la transcription démarre&lt;/li&gt;
&lt;li&gt;l’UI reçoit les mises à jour.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Symfony UX + Mercure : le temps réel
&lt;/h2&gt;

&lt;p&gt;Une des plus grosses évolutions du projet est l’arrivée d’une vraie interface web temps réel.&lt;/p&gt;

&lt;p&gt;Stack utilisée :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Twig&lt;/li&gt;
&lt;li&gt;Symfony UX&lt;/li&gt;
&lt;li&gt;Turbo&lt;/li&gt;
&lt;li&gt;Stimulus&lt;/li&gt;
&lt;li&gt;Mercure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le dashboard permet maintenant :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;de voir les workers actifs&lt;/li&gt;
&lt;li&gt;de démarrer/arrêter une session&lt;/li&gt;
&lt;li&gt;de suivre les événements live&lt;/li&gt;
&lt;li&gt;d’afficher les transcriptions&lt;/li&gt;
&lt;li&gt;d’accéder à l’historique.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture temps réel :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sequenceDiagram
    participant Worker
    participant Mercure
    participant Browser

    Worker-&amp;gt;&amp;gt;Mercure: publish event
    Mercure-&amp;gt;&amp;gt;Browser: live update
    Browser-&amp;gt;&amp;gt;UI: refresh transcript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L’intérêt est énorme :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Symfony peut maintenant faire du temps réel moderne sans React ni frontend séparé.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Providers de transcription
&lt;/h2&gt;

&lt;p&gt;Une autre évolution importante est l’introduction d’une couche DDD avec providers interchangeables.&lt;/p&gt;

&lt;p&gt;Flowvox peut maintenant fonctionner avec plusieurs moteurs :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;whisper_cpp&lt;/td&gt;
&lt;td&gt;Local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;whisper_cpp_stream&lt;/td&gt;
&lt;td&gt;Local realtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openai_batch&lt;/td&gt;
&lt;td&gt;Cloud batch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openai_realtime_whisper&lt;/td&gt;
&lt;td&gt;Cloud realtime&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La sélection se fait via une variable d’environnement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FLOWVOX_TRANSCRIPTION_PROVIDER=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le moteur peut changer.&lt;/p&gt;

&lt;p&gt;L’UX reste identique. &lt;/p&gt;

&lt;h2&gt;
  
  
  OpenAI Realtime Whisper
&lt;/h2&gt;

&lt;p&gt;C’est probablement la nouveauté la plus importante.&lt;/p&gt;

&lt;p&gt;Avant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START
→ parler
→ STOP
→ transcription
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START
→ streaming audio
→ transcription live
→ partials
→ UI temps réel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le fonctionnement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    MIC["Micro"]
    FFMPEG["ffmpeg"]
    WS["WebSocket OpenAI"]
    WORKER["Worker"]
    MERCURE["Mercure"]
    UI["Symfony UX"]

    MIC --&amp;gt; FFMPEG
    FFMPEG --&amp;gt; WS
    WS --&amp;gt; WORKER
    WORKER --&amp;gt; MERCURE
    MERCURE --&amp;gt; UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le worker envoie les chunks audio à OpenAI Realtime via WebSocket.&lt;/p&gt;

&lt;p&gt;Le modèle retourne des transcriptions partielles.&lt;/p&gt;

&lt;p&gt;Le worker publie ensuite ces événements vers Mercure.&lt;/p&gt;

&lt;p&gt;Et Symfony UX met à jour l’interface en direct. &lt;/p&gt;

&lt;h2&gt;
  
  
  Traduction multilingue temps réel
&lt;/h2&gt;

&lt;p&gt;OpenAI introduit aussi GPT Realtime Translate.&lt;/p&gt;

&lt;p&gt;Cela permet :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;de parler en français&lt;/li&gt;
&lt;li&gt;de traduire en anglais&lt;/li&gt;
&lt;li&gt;ou même de changer dynamiquement de langue pendant la conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le modèle suit la structure de la phrase et attend parfois les verbes avant de traduire, ce qui rend le résultat beaucoup plus naturel. &lt;/p&gt;

&lt;p&gt;C’est extrêmement intéressant pour :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;conférences&lt;/li&gt;
&lt;li&gt;podcasts&lt;/li&gt;
&lt;li&gt;support client&lt;/li&gt;
&lt;li&gt;éducation&lt;/li&gt;
&lt;li&gt;médias.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Symfony UX Native + iOS
&lt;/h2&gt;

&lt;p&gt;Autre grosse évolution : l’intégration native mobile.&lt;/p&gt;

&lt;p&gt;Flowvox utilise maintenant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require symfony/ux-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L’idée est de conserver :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Twig&lt;/li&gt;
&lt;li&gt;Symfony UX&lt;/li&gt;
&lt;li&gt;Turbo&lt;/li&gt;
&lt;li&gt;Stimulus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tout en utilisant un shell mobile natif basé sur Hotwire Native.&lt;/p&gt;

&lt;p&gt;Architecture :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    Twig --&amp;gt; Turbo
    Turbo --&amp;gt; WebView
    WebView --&amp;gt; SwiftUI
    Stimulus --&amp;gt; NativeBridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L’application iOS repose sur une WebView connectée au serveur Symfony local. &lt;/p&gt;

&lt;p&gt;Le résultat :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;même application&lt;/li&gt;
&lt;li&gt;même backend&lt;/li&gt;
&lt;li&gt;même UI&lt;/li&gt;
&lt;li&gt;version web + version native.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Darkwood Navi : traçabilité des workflows
&lt;/h2&gt;

&lt;p&gt;Flowvox intègre aussi Darkwood Navi.&lt;/p&gt;

&lt;p&gt;L’objectif :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enregistrer les événements&lt;/li&gt;
&lt;li&gt;suivre les exécutions&lt;/li&gt;
&lt;li&gt;tracer les workflows&lt;/li&gt;
&lt;li&gt;rendre les traitements reproductibles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cela prépare surtout les prochaines étapes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;agents vocaux&lt;/li&gt;
&lt;li&gt;tool calling&lt;/li&gt;
&lt;li&gt;workflows déclaratifs&lt;/li&gt;
&lt;li&gt;orchestration IA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vision long terme
&lt;/h2&gt;

&lt;p&gt;Flowvox n’est plus seulement un moteur de transcription.&lt;/p&gt;

&lt;p&gt;La direction devient beaucoup plus ambitieuse :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;une plateforme vocale programmable pour Symfony.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Les prochaines étapes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPT Realtime Translate&lt;/li&gt;
&lt;li&gt;agents vocaux&lt;/li&gt;
&lt;li&gt;tool calling&lt;/li&gt;
&lt;li&gt;orchestration Flow&lt;/li&gt;
&lt;li&gt;workflows Navi&lt;/li&gt;
&lt;li&gt;intégration Uniflow&lt;/li&gt;
&lt;li&gt;automation pilotée par la voix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’objectif n’est plus simplement :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“parler à son application”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais plutôt :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“avoir une application qui réagit, raisonne et agit en temps réel à travers la voix”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;En quelques mois, Flowvox est passé :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;d’un POC terminal Whisper.cpp
→ à une plateforme vocale temps réel Symfony
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workers distribués&lt;/li&gt;
&lt;li&gt;orchestration Flow&lt;/li&gt;
&lt;li&gt;Symfony UX&lt;/li&gt;
&lt;li&gt;Mercure&lt;/li&gt;
&lt;li&gt;OpenAI Realtime&lt;/li&gt;
&lt;li&gt;Hotwire Native&lt;/li&gt;
&lt;li&gt;providers interchangeables&lt;/li&gt;
&lt;li&gt;traçabilité Navi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La voix devient progressivement une interface programmable.&lt;/p&gt;

&lt;p&gt;Et je pense que Symfony possède aujourd’hui toutes les briques nécessaires pour devenir une excellente plateforme pour ce type de systèmes.&lt;/p&gt;

&lt;p&gt;Flowvox continue d’évoluer comme terrain d’expérimentation autour :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;des workers vocaux&lt;/li&gt;
&lt;li&gt;de l’orchestration temps réel&lt;/li&gt;
&lt;li&gt;des agents pilotés par la voix&lt;/li&gt;
&lt;li&gt;de Symfony UX&lt;/li&gt;
&lt;li&gt;de Symfony AI&lt;/li&gt;
&lt;li&gt;et des workflows déclaratifs avec Flow et Navi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’objectif n’est plus simplement de retranscrire de l’audio.&lt;/p&gt;

&lt;p&gt;L’objectif est maintenant de construire des interfaces vocales programmables capables :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;d’écouter&lt;/li&gt;
&lt;li&gt;de raisonner&lt;/li&gt;
&lt;li&gt;de traduire&lt;/li&gt;
&lt;li&gt;et d’agir dans des systèmes externes en temps réel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ressources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.darkwood.com/article/i-m-building-a-dictation-engine-in-php-flow-symfony-whisper-cpp" rel="noopener noreferrer"&gt;Flowvox Announcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/darkwood-com/flowvox" rel="noopener noreferrer"&gt;Flowvox GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://symfony.com/bundles/ux-native/current/index.html" rel="noopener noreferrer"&gt;Symfony UX Native&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/realtime" rel="noopener noreferrer"&gt;OpenAI Realtime API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ggerganov/whisper.cpp" rel="noopener noreferrer"&gt;whisper.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tu peux ajouter cette section à la fin de l’article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ressources &amp;amp; projets
&lt;/h2&gt;

&lt;p&gt;Le code source et les expérimentations autour de Flowvox sont disponibles publiquement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/darkwood-com/flowvox" rel="noopener noreferrer"&gt;Flowvox (Symfony voice platform)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/flowvox-ios" rel="noopener noreferrer"&gt;Flowvox iOS (Hotwire Native)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/slidewire" rel="noopener noreferrer"&gt;Slides SlideWire de la présentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technologies utilisées :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ggml-org/whisper.cpp" rel="noopener noreferrer"&gt;Whisper.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ux.symfony.com/native" rel="noopener noreferrer"&gt;Symfony UX Native&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Annonces et documentation OpenAI :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=JOu8v6CBjkE" rel="noopener noreferrer"&gt;Annonce OpenAI Realtime Audio Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/guides/realtime-translation" rel="noopener noreferrer"&gt;Documentation OpenAI Realtime Translation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>⚙️ NoLife Models - Vers une infrastructure locale des runtimes IA avec Symfony</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Thu, 14 May 2026 07:14:53 +0000</pubDate>
      <link>https://dev.to/matyo91/nolife-models-vers-une-infrastructure-locale-des-runtimes-ia-avec-symfony-200a</link>
      <guid>https://dev.to/matyo91/nolife-models-vers-une-infrastructure-locale-des-runtimes-ia-avec-symfony-200a</guid>
      <description>&lt;p&gt;Pendant des années, utiliser un modèle IA voulait dire appeler une API distante.&lt;/p&gt;

&lt;p&gt;Le workflow était relativement simple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;envoyer un prompt&lt;/li&gt;
&lt;li&gt;attendre une réponse&lt;/li&gt;
&lt;li&gt;afficher du texte.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais depuis quelques mois, un nouvel écosystème est en train d’émerger autour des modèles locaux.&lt;/p&gt;

&lt;p&gt;Un écosystème composé de :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;catalogues de modèles&lt;/li&gt;
&lt;li&gt;runtimes locaux&lt;/li&gt;
&lt;li&gt;systèmes de benchmark&lt;/li&gt;
&lt;li&gt;exports structurés&lt;/li&gt;
&lt;li&gt;observabilité&lt;/li&gt;
&lt;li&gt;gouvernance&lt;/li&gt;
&lt;li&gt;orchestration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et progressivement, l’IA commence à ressembler davantage à une infrastructure logicielle qu’à un simple chatbot.&lt;/p&gt;

&lt;p&gt;C’est dans ce contexte qu’est né *&lt;em&gt;NoLife Models&lt;/em&gt;- :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/nolife-models" rel="noopener noreferrer"&gt;NoLife Models GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/slidewire" rel="noopener noreferrer"&gt;SlideWire presentation repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un projet Symfony 8 conçu pour explorer cette nouvelle couche d’infrastructure locale autour des modèles IA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le problème : les modèles locaux explosent
&lt;/h2&gt;

&lt;p&gt;Aujourd’hui, il existe une quantité gigantesque de modèles :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qwen&lt;/li&gt;
&lt;li&gt;Llama&lt;/li&gt;
&lt;li&gt;Granite&lt;/li&gt;
&lt;li&gt;Gemma&lt;/li&gt;
&lt;li&gt;Mistral&lt;/li&gt;
&lt;li&gt;Phi&lt;/li&gt;
&lt;li&gt;DeepSeek&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et chacun possède :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;des tailles différentes&lt;/li&gt;
&lt;li&gt;des quantizations différentes&lt;/li&gt;
&lt;li&gt;des capacités différentes&lt;/li&gt;
&lt;li&gt;des context windows différents&lt;/li&gt;
&lt;li&gt;des comportements différents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le problème n’est donc plus :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Comment utiliser un modèle ?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais plutôt :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Quel modèle utiliser, dans quel contexte, sur quel runtime, avec quelles performances ?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  models.dev : vers un catalogue standardisé des modèles
&lt;/h2&gt;

&lt;p&gt;Un projet particulièrement intéressant dans cette évolution est :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/anomalyco/models.dev" rel="noopener noreferrer"&gt;models.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L’idée est simple :&lt;br&gt;
transformer les modèles en objets structurés exploitables par des outils.&lt;/p&gt;

&lt;p&gt;On ne parle plus seulement d’un “nom de modèle”.&lt;/p&gt;

&lt;p&gt;On parle désormais de :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modalities&lt;/li&gt;
&lt;li&gt;reasoning flags&lt;/li&gt;
&lt;li&gt;pricing&lt;/li&gt;
&lt;li&gt;capabilities&lt;/li&gt;
&lt;li&gt;context windows&lt;/li&gt;
&lt;li&gt;providers&lt;/li&gt;
&lt;li&gt;compatibilité runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cela ressemble fortement à ce qu’a représenté Docker Hub pour les containers.&lt;/p&gt;
&lt;h2&gt;
  
  
  modles : explorer les modèles comme des artefacts logiciels
&lt;/h2&gt;

&lt;p&gt;Autour de cette idée émergent aussi des interfaces d’exploration comme :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dgageot/modles" rel="noopener noreferrer"&gt;modles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le sujet devient alors :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filtrer&lt;/li&gt;
&lt;li&gt;comparer&lt;/li&gt;
&lt;li&gt;explorer&lt;/li&gt;
&lt;li&gt;comprendre les capacités réelles des modèles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exactement comme nous avons commencé à le faire avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;containers&lt;/li&gt;
&lt;li&gt;packages&lt;/li&gt;
&lt;li&gt;runtimes cloud&lt;/li&gt;
&lt;li&gt;images OCI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Docker ecosystem ↔ AI runtime ecosystem
&lt;/h2&gt;

&lt;p&gt;L’analogie avec Docker devient de plus en plus pertinente.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Docker ecosystem&lt;/th&gt;
&lt;th&gt;AI runtime ecosystem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker Hub&lt;/td&gt;
&lt;td&gt;models.dev&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images&lt;/td&gt;
&lt;td&gt;GGUF / model weights&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dockerd&lt;/td&gt;
&lt;td&gt;Ollama / Kronk / vLLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes&lt;/td&gt;
&lt;td&gt;agent orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;inference tracing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OCI runtime&lt;/td&gt;
&lt;td&gt;runtime abstraction layers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le sujet n’est donc plus seulement :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“faire tourner un LLM”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le sujet devient :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“gouverner une infrastructure de modèles.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Ollama : le runtime HTTP local
&lt;/h2&gt;

&lt;p&gt;Le runtime qui a probablement démocratisé cette approche est :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ollama expose les modèles comme des services HTTP locaux.&lt;/p&gt;

&lt;p&gt;Quelques endpoints suffisent :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/api/tags
/api/generate
/api/chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et immédiatement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n’importe quelle application&lt;/li&gt;
&lt;li&gt;n’importe quel langage&lt;/li&gt;
&lt;li&gt;n’importe quel orchestrateur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;peut commencer à interagir avec des modèles locaux.&lt;/p&gt;

&lt;p&gt;Cette simplicité est extrêmement puissante.&lt;/p&gt;

&lt;h2&gt;
  
  
  NoLife Models
&lt;/h2&gt;

&lt;p&gt;C’est précisément ce constat qui a motivé la création de :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/nolife-models" rel="noopener noreferrer"&gt;NoLife Models&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NoLife Models est une application locale construite avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony 8&lt;/li&gt;
&lt;li&gt;Symfony UX&lt;/li&gt;
&lt;li&gt;Twig&lt;/li&gt;
&lt;li&gt;Live Components&lt;/li&gt;
&lt;li&gt;Turbo&lt;/li&gt;
&lt;li&gt;HttpClient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le projet permet :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;d’explorer un catalogue de modèles&lt;/li&gt;
&lt;li&gt;de lister les modèles Ollama installés&lt;/li&gt;
&lt;li&gt;de comparer plusieurs modèles&lt;/li&gt;
&lt;li&gt;de lancer des benchmarks&lt;/li&gt;
&lt;li&gt;d’exporter les résultats.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Une architecture orientée runtime
&lt;/h2&gt;

&lt;p&gt;Le point central du projet est probablement cette abstraction :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;LocalModelRuntimeInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/*- @return list&amp;lt;LocalModel&amp;gt; */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;listLocalModels&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;GeneratePromptCommand&lt;/span&gt; &lt;span class="nv"&gt;$command&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;ModelInferenceResult&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette décision transforme complètement l’architecture.&lt;/p&gt;

&lt;p&gt;Le domaine ne dépend plus :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;d’Ollama&lt;/li&gt;
&lt;li&gt;d’OpenAI&lt;/li&gt;
&lt;li&gt;d’un provider particulier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le domaine dépend uniquement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;d’un contrat d’inférence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et cela ouvre immédiatement la voie vers :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LM Studio&lt;/li&gt;
&lt;li&gt;vLLM&lt;/li&gt;
&lt;li&gt;OpenAI-compatible runtimes&lt;/li&gt;
&lt;li&gt;embedded runtimes&lt;/li&gt;
&lt;li&gt;futurs adapters.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Symfony 8 + Hexagonal Architecture
&lt;/h2&gt;

&lt;p&gt;Le projet suit une approche DDD / hexagonale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserInterface
    ↓
Application
    ↓
Domain ports
    ↓
Infrastructure adapters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les responsabilités sont séparées :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;td&gt;contracts + models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application&lt;/td&gt;
&lt;td&gt;orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Ollama adapter, exports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UserInterface&lt;/td&gt;
&lt;td&gt;Symfony UX + controllers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Le runtime devient alors une simple implémentation d’interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparer des modèles localement
&lt;/h2&gt;

&lt;p&gt;L’un des éléments les plus intéressants du projet est le moteur de comparaison.&lt;/p&gt;

&lt;p&gt;Même prompt.&lt;br&gt;
Même runtime surface.&lt;br&gt;
Même configuration.&lt;/p&gt;

&lt;p&gt;Mais plusieurs modèles.&lt;/p&gt;

&lt;p&gt;Cela permet de comparer :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;latence&lt;/li&gt;
&lt;li&gt;temps de chargement&lt;/li&gt;
&lt;li&gt;vitesse de génération&lt;/li&gt;
&lt;li&gt;raisonnement&lt;/li&gt;
&lt;li&gt;qualité des réponses&lt;/li&gt;
&lt;li&gt;hallucinations&lt;/li&gt;
&lt;li&gt;OCR&lt;/li&gt;
&lt;li&gt;vision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le plus important :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;les benchmarks mathématiques seuls ne suffisent pas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La qualité reste une lecture humaine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarks et reproductibilité
&lt;/h2&gt;

&lt;p&gt;Le projet permet également de lancer des benchmark suites.&lt;/p&gt;

&lt;p&gt;L’idée :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exécuter plusieurs prompts&lt;/li&gt;
&lt;li&gt;sur plusieurs modèles&lt;/li&gt;
&lt;li&gt;avec des paramètres contrôlés&lt;/li&gt;
&lt;li&gt;et produire des résultats structurés.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cela rapproche progressivement le projet :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;d’un système d’évaluation&lt;/li&gt;
&lt;li&gt;d’un observatoire runtime&lt;/li&gt;
&lt;li&gt;d’une couche d’observabilité.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exports et gouvernance
&lt;/h2&gt;

&lt;p&gt;Les exports jouent un rôle très important :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;CSV&lt;/li&gt;
&lt;li&gt;Markdown&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parce qu’une inférence sans artifact devient difficile à auditer.&lt;/p&gt;

&lt;p&gt;Les exports permettent :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;de tracer&lt;/li&gt;
&lt;li&gt;reproduire&lt;/li&gt;
&lt;li&gt;comparer&lt;/li&gt;
&lt;li&gt;archiver&lt;/li&gt;
&lt;li&gt;analyser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et c’est précisément à ce moment que l’on quitte le simple “prompt engineering”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kronk : une autre direction
&lt;/h2&gt;

&lt;p&gt;Un autre projet particulièrement intéressant est :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ardanlabs/kronk" rel="noopener noreferrer"&gt;Kronk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kronk ne doit pas être vu comme :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“un meilleur Ollama”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La philosophie est différente.&lt;/p&gt;

&lt;p&gt;Ollama expose les modèles comme des services HTTP locaux.&lt;/p&gt;

&lt;p&gt;Kronk pousse l’inférence directement dans le processus applicatif.&lt;/p&gt;

&lt;p&gt;L’inférence devient alors :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;embarquée&lt;/li&gt;
&lt;li&gt;programmable&lt;/li&gt;
&lt;li&gt;intégrée au runtime de l’application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GGUF&lt;/li&gt;
&lt;li&gt;llama.cpp&lt;/li&gt;
&lt;li&gt;Yzma&lt;/li&gt;
&lt;li&gt;streaming&lt;/li&gt;
&lt;li&gt;APIs compatibles OpenAI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le modèle cesse progressivement d’être un simple endpoint HTTP.&lt;/p&gt;

&lt;p&gt;Il devient :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;une dépendance logicielle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Vers une infrastructure IA locale
&lt;/h2&gt;

&lt;p&gt;Le plus intéressant dans cette évolution,&lt;br&gt;
c’est probablement que l’on voit réapparaître les mêmes patterns que dans le cloud :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;catalogues&lt;/li&gt;
&lt;li&gt;runtimes&lt;/li&gt;
&lt;li&gt;observabilité&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;policies&lt;/li&gt;
&lt;li&gt;exports&lt;/li&gt;
&lt;li&gt;traces&lt;/li&gt;
&lt;li&gt;gouvernance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais appliqués cette fois :&lt;br&gt;
à l’inférence locale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;NoLife Models n’est pas conçu comme :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un chatbot&lt;/li&gt;
&lt;li&gt;un wrapper OpenAI&lt;/li&gt;
&lt;li&gt;une simple UI Ollama.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le projet explore plutôt une question plus large :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;À quoi ressemble une infrastructure locale de runtimes IA ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Avec :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;catalogues&lt;/li&gt;
&lt;li&gt;runtimes&lt;/li&gt;
&lt;li&gt;benchmarks&lt;/li&gt;
&lt;li&gt;exports&lt;/li&gt;
&lt;li&gt;observabilité&lt;/li&gt;
&lt;li&gt;abstractions runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nous sommes probablement encore au début de cet écosystème.&lt;/p&gt;

&lt;p&gt;Mais les primitives commencent déjà à apparaître.&lt;/p&gt;

&lt;p&gt;Et cela devient extrêmement intéressant à observer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depots github
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🐙 An open-source database of AI models. : &lt;a href="https://github.com/anomalyco/models.dev" rel="noopener noreferrer"&gt;https://github.com/anomalyco/models.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;☺️ Your personal engine for running open source models locally : &lt;a href="https://github.com/ardanlabs/kronk" rel="noopener noreferrer"&gt;https://github.com/ardanlabs/kronk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🚀 J’ai créé une app pour comparer vos LLM en local avec Ollama. : &lt;a href="https://www.youtube.com/watch?v=YzxE3jQqItI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=YzxE3jQqItI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧩 Extract Insights from Videos with Docling + OpenRAG : &lt;a href="https://www.youtube.com/watch?v=Y0b1TANWZ-Y" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Y0b1TANWZ-Y&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤯 AI Model explorer based on models.dev : &lt;a href="https://github.com/dgageot/modles" rel="noopener noreferrer"&gt;https://github.com/dgageot/modles&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;😮 Baby steps with Kronk &lt;a href="https://k33g.hashnode.dev/baby-steps-with-kronk-1" rel="noopener noreferrer"&gt;https://k33g.hashnode.dev/baby-steps-with-kronk-1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;😋 How to cook a little coding agent with Docker Model Runner and Docker Agent (and sbx) &lt;a href="https://k33g.org/20260419-little-coder-agent.html" rel="noopener noreferrer"&gt;https://k33g.org/20260419-little-coder-agent.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;😍 fabpot Activity &lt;a href="https://github.com/symfony/models-dev/commits?author=fabpot" rel="noopener noreferrer"&gt;https://github.com/symfony/models-dev/commits?author=fabpot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Liens de la semaine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Symfony Level Up #9 Sylvain Blondeau : &lt;a href="https://symfonylevelup.substack.com/p/symfony-level-up-9" rel="noopener noreferrer"&gt;https://symfonylevelup.substack.com/p/symfony-level-up-9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Les géants US vont toujours plus loin (trop ?) et la Chine montre la voie : &lt;a href="https://www.youtube.com/watch?v=L4LCSXvA7LU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=L4LCSXvA7LU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Oussama Pour la suppression massive d’emplois ! &lt;a href="https://www.youtube.com/watch?v=GLfPVWRns-U" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=GLfPVWRns-U&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;De 0 à 10 000€/mois avec l'IA : la méthode exacte que j'aurais voulu avoir : &lt;a href="https://www.youtube.com/watch?v=sRtQmFEhlBE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=sRtQmFEhlBE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fouloscopie Comment discuter efficacement ? &lt;a href="https://www.youtube.com/watch?v=8J1opDS1otY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=8J1opDS1otY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MACI #158 - Découvrez CKE, notre Kubernetes managé - Avec Antoine Blondeau et Gilles Biannic : &lt;a href="https://www.youtube.com/watch?v=FtAF5kN_8pY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=FtAF5kN_8pY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github Open Source Friday with Spec-Kit : &lt;a href="https://www.youtube.com/watch?v=2IArMAhkJcE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=2IArMAhkJcE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Generate Images Locally with Docker Model Runner and Open WebUI &lt;a href="https://www.docker.com/blog/blog-generate-images-locally-dmr-open-webui/" rel="noopener noreferrer"&gt;https://www.docker.com/blog/blog-generate-images-locally-dmr-open-webui/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Commissariat au Numérique de Défense - DEF'LAN 2026 | LE DIRECT : &lt;a href="https://www.youtube.com/watch?v=OW4VCl6P-l4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=OW4VCl6P-l4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Why TTS Models Now Look Like LLMs — Samuel Humeau, Mistral : &lt;a href="https://www.youtube.com/watch?v=3jGAU2sbAyY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=3jGAU2sbAyY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Give Your Chat Agent a Voice — Luke Harries, ElevenLabs : &lt;a href="https://www.youtube.com/watch?v=DCZZ3AJKzuc" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=DCZZ3AJKzuc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Voice AI: when is the "Her" moment? — Neil Zeghidour, Gradium AI : &lt;a href="https://youtu.be/P_RI1kCkRbo?is=w2jQToL-6ua941SI" rel="noopener noreferrer"&gt;https://youtu.be/P_RI1kCkRbo?is=w2jQToL-6ua941SI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Context Is the New Code — Patrick Debois, Tessl : &lt;a href="https://www.youtube.com/watch?v=bSG9wUYaHWU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=bSG9wUYaHWU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Here’s one of the engineers explaining how they use LLMs to generate $30B+ every year : &lt;a href="https://x.com/thejayden/status/2052847766754250815?s=46" rel="noopener noreferrer"&gt;https://x.com/thejayden/status/2052847766754250815?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pourquoi même la logistique légendaire d’Apple ne résiste pas à la RAMpocalypse | OctogoneTech #8 : &lt;a href="https://www.youtube.com/watch?v=gjYbOViRy_k" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=gjYbOViRy_k&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;La France peut-elle encore créer des géants de la tech ? (Avec Carlos Diaz) : &lt;a href="https://www.youtube.com/watch?v=74TpWDkYpdE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=74TpWDkYpdE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Suraj vs The Future | With ChatGPT : &lt;a href="https://www.youtube.com/watch?v=bMmEEa8-6fU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=bMmEEa8-6fU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The 3 Most Important Claude Features Beginners Don’t Know About : &lt;a href="https://www.youtube.com/watch?v=tkpdPvx65A0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=tkpdPvx65A0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to Improve Video Streaming in Next.js - Adaptive Bitrate Streaming Tutorial | ImageKit : &lt;a href="https://www.youtube.com/watch?v=MKbdkWfVZ1w" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=MKbdkWfVZ1w&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Des skills pour agents IA spécialisés dans la bureaucratie française : &lt;a href="https://github.com/romainsimon/paperasse" rel="noopener noreferrer"&gt;https://github.com/romainsimon/paperasse&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building a Chess Coach — Anant Dole and Asbjorn Steinskog, Take Take Take : &lt;a href="https://www.youtube.com/watch?v=FlzpEGHNVKQ" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=FlzpEGHNVKQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Devenir Product Builder no code &amp;amp; IA avec Uncode School : &lt;a href="https://www.youtube.com/watch?v=8Ikwj_SNSNI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=8Ikwj_SNSNI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anthropic vient d'enterrer l'IA généraliste (et personne ne l'a vu) : &lt;a href="https://www.youtube.com/watch?v=qqhQDBClm1Y" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=qqhQDBClm1Y&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Your Agent Can Now Train Models — Merve Noyan, Hugging Face : &lt;a href="https://www.youtube.com/watch?v=OV56RddyFuU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=OV56RddyFuU&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎶 Music credit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A little footwork from New York New Jersey. ⚽ #FIFAWorldCup : &lt;a href="https://vm.tiktok.com/ZNRGDjFGx/" rel="noopener noreferrer"&gt;https://vm.tiktok.com/ZNRGDjFGx/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;  &lt;a title="@fifaworldcup" href="https://www.tiktok.com/@fifaworldcup?refer=embed" rel="noopener noreferrer"&gt;@fifaworldcup&lt;/a&gt; A little footwork from New York New Jersey. ⚽ &lt;a title="fifaworldcup" href="https://www.tiktok.com/tag/fifaworldcup?refer=embed" rel="noopener noreferrer"&gt;#FIFAWorldCup&lt;/a&gt; &lt;a title="♬ sonido original - FIFA World Cup" href="https://www.tiktok.com/music/sonido-original-7639391321183243030?refer=embed" rel="noopener noreferrer"&gt;♬ sonido original - FIFA World Cup&lt;/a&gt;  &lt;/blockquote&gt; 

&lt;ul&gt;
&lt;li&gt;Chinese students welcome President Trump to the Great Hall of the People in Beijing 💐 🎥: @MargoMartin47&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Chinese students welcome President Trump to the Great Hall of the People in Beijing 💐 &lt;br&gt;&lt;br&gt;🎥: &lt;a href="https://twitter.com/MargoMartin47?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;@MargoMartin47&lt;/a&gt; &lt;a href="https://t.co/wChlpVnphh" rel="noopener noreferrer"&gt;pic.twitter.com/wChlpVnphh&lt;/a&gt;&lt;/p&gt;— Rapid Response 47 (@RapidResponse47) &lt;a href="https://twitter.com/RapidResponse47/status/2054757875688292597?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;May 14, 2026&lt;/a&gt;
&lt;/blockquote&gt; 

</description>
      <category>ai</category>
      <category>infrastructure</category>
      <category>llm</category>
      <category>php</category>
    </item>
    <item>
      <title>💫 I forced 4 AIs to recreate Mario from scratch using Symfony AI and Godot</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sat, 09 May 2026 07:47:30 +0000</pubDate>
      <link>https://dev.to/matyo91/i-forced-4-ais-to-recreate-mario-from-scratch-using-symfony-ai-and-godot-kh2</link>
      <guid>https://dev.to/matyo91/i-forced-4-ais-to-recreate-mario-from-scratch-using-symfony-ai-and-godot-kh2</guid>
      <description>&lt;p&gt;Creating a video game with artificial intelligence has become almost commonplace.&lt;/p&gt;

&lt;p&gt;Today, all you need to do is open Cursor, Claude Code or ChatGPT and type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Create me a Mario.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And a few minutes later, something appears on the screen.&lt;/p&gt;

&lt;p&gt;But behind this apparent simplicity lies a much more interesting problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How ​​to properly orchestrate multiple AI agents to produce a coherent, playable, and maintainable result?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's precisely what I wanted to experiment with in this video:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;Grok&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even prompt.&lt;br&gt;
Same objective.&lt;br&gt;
Completely different results.&lt;/p&gt;

&lt;p&gt;But above all: a completely different architecture from what is called “vibe coding” today.&lt;/p&gt;
&lt;h2&gt;
  
  
  An inspiration from Playdate
&lt;/h2&gt;

&lt;p&gt;Before even talking about AI, we need to talk about video games.&lt;/p&gt;

&lt;p&gt;In the video, I quickly show the &lt;a href="https://play.date" rel="noopener noreferrer"&gt;Playdate&lt;/a&gt;, a small independent console developed by Panic with a black and white screen and a mechanical crank.&lt;/p&gt;

&lt;p&gt;What's interesting about the Playdate isn't the power.&lt;/p&gt;

&lt;p&gt;That's the philosophy.&lt;/p&gt;

&lt;p&gt;The equipment imposes constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;limited screen&lt;/li&gt;
&lt;li&gt;minimalist controls&lt;/li&gt;
&lt;li&gt;simple gameplay&lt;/li&gt;
&lt;li&gt;maximum creativity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And paradoxically, these constraints make the games more interesting.&lt;/p&gt;

&lt;p&gt;It's exactly the same phenomenon with AI agents.&lt;/p&gt;

&lt;p&gt;A vague prompt often results in a fragile system.&lt;/p&gt;

&lt;p&gt;Well-defined constraints produce much more consistent results.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Single Prompt Problem
&lt;/h2&gt;

&lt;p&gt;Most AI demonstrations work like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a Mario game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model then attempts to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate the gameplay&lt;/li&gt;
&lt;li&gt;handle collisions&lt;/li&gt;
&lt;li&gt;create the graphics&lt;/li&gt;
&lt;li&gt;balance the levels&lt;/li&gt;
&lt;li&gt;produce the mechanics&lt;/li&gt;
&lt;li&gt;organize the project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is often impressive for a few seconds.&lt;/p&gt;

&lt;p&gt;Then appear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;broken collisions&lt;/li&gt;
&lt;li&gt;impossible levels&lt;/li&gt;
&lt;li&gt;inconsistent rules&lt;/li&gt;
&lt;li&gt;contradictory mechanisms&lt;/li&gt;
&lt;li&gt;an immediate technical debt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is not necessarily AI.&lt;/p&gt;

&lt;p&gt;The problem is that he is being asked to do everything simultaneously without specialization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symfony AI + Godot
&lt;/h2&gt;

&lt;p&gt;For this experiment, I used two main technologies:&lt;/p&gt;

&lt;h3&gt;
  
  
  Symfony AI
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://ai.symfony.com" rel="noopener noreferrer"&gt;Symfony AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Symfony AI provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the agents&lt;/li&gt;
&lt;li&gt;the tools&lt;/li&gt;
&lt;li&gt;multimodal&lt;/li&gt;
&lt;li&gt;the RAG&lt;/li&gt;
&lt;li&gt;memory&lt;/li&gt;
&lt;li&gt;multi-agent orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework is divided into several specialized bundles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent&lt;/li&gt;
&lt;li&gt;Store&lt;/li&gt;
&lt;li&gt;AI Bundle&lt;/li&gt;
&lt;li&gt;Platform&lt;/li&gt;
&lt;li&gt;App&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to build a clean architecture around AI models rather than simply sending prompts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Godot
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://godotengine.org" rel="noopener noreferrer"&gt;Godot Engine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Godot is an open-source game engine extremely well-suited for rapid prototyping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2D&lt;/li&gt;
&lt;li&gt;3D&lt;/li&gt;
&lt;li&gt;scene system&lt;/li&gt;
&lt;li&gt;GDScript scripting&lt;/li&gt;
&lt;li&gt;nodal architecture&lt;/li&gt;
&lt;li&gt;multi-platform export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Orchestrate AI agents with Symfony AI to automatically generate a Godot game.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Multi-agent orchestration
&lt;/h2&gt;

&lt;p&gt;The core of the project is based on a multi-agent architecture.&lt;/p&gt;

&lt;p&gt;Instead of having a single AI that does everything, I separated the responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Orchestrator
&lt;/h2&gt;

&lt;p&gt;The orchestrator receives the main prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate a Mario-like platformer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it automatically delegates to the appropriate specialized agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specialized agents
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Layout Agent
&lt;/h2&gt;

&lt;p&gt;The “level designer”.&lt;/p&gt;

&lt;p&gt;It generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the platforms&lt;/li&gt;
&lt;li&gt;the holes&lt;/li&gt;
&lt;li&gt;the pipes&lt;/li&gt;
&lt;li&gt;the stairs&lt;/li&gt;
&lt;li&gt;the progression of the level&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gameplay Agent
&lt;/h2&gt;

&lt;p&gt;The mechanics specialist.&lt;/p&gt;

&lt;p&gt;He manages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collisions&lt;/li&gt;
&lt;li&gt;the enemies&lt;/li&gt;
&lt;li&gt;the bonuses&lt;/li&gt;
&lt;li&gt;the jumps&lt;/li&gt;
&lt;li&gt;the checkpoints&lt;/li&gt;
&lt;li&gt;the interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Godot Export Agent
&lt;/h2&gt;

&lt;p&gt;The role of this agent is to transform the generated data into structures compatible with Godot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scenes&lt;/li&gt;
&lt;li&gt;TileMaps&lt;/li&gt;
&lt;li&gt;objects&lt;/li&gt;
&lt;li&gt;JSON exports&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  QA Agent
&lt;/h2&gt;

&lt;p&gt;The most important thing.&lt;/p&gt;

&lt;p&gt;The QA Agent verifies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the gameplay&lt;/li&gt;
&lt;li&gt;collisions&lt;/li&gt;
&lt;li&gt;impossible jumps&lt;/li&gt;
&lt;li&gt;the consistency of the mechanics&lt;/li&gt;
&lt;li&gt;the rules of the level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is probably the element most lacking in “vibe coding” demos.&lt;/p&gt;

&lt;h2&gt;
  
  
  The orchestration with Darkwood Flow and Navi
&lt;/h2&gt;

&lt;p&gt;To orchestrate all of this, I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://flow.darkwood.com" rel="noopener noreferrer"&gt;Darkwood Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://navi.darkwood.com" rel="noopener noreferrer"&gt;Darkwood Navi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flow allows you to manage the execution of multi-agent workflows.&lt;/p&gt;

&lt;p&gt;Navi allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;traceability&lt;/li&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;monitoring of executions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pipeline looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Prompt
    ↓
Orchestrator
    ↓
Layout Agent
Gameplay Agent
Godot Export Agent
QA Agent
    ↓
Generated Game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The orchestrator automatically chooses which agent should intervene depending on the progress of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single Symfony command
&lt;/h2&gt;

&lt;p&gt;The entire generation process is launched with a simple Symfony command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console app:mario:orchestrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;calls the orchestrator&lt;/li&gt;
&lt;li&gt;Route to the specialist agents&lt;/li&gt;
&lt;li&gt;generates the result&lt;/li&gt;
&lt;li&gt;Automatically exports the game&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most interesting thing:&lt;br&gt;
The pipeline becomes reproducible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ChatGPT
&lt;/h2&gt;

&lt;p&gt;ChatGPT produces a very good database quickly.&lt;/p&gt;

&lt;p&gt;We find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a faithful structure&lt;/li&gt;
&lt;li&gt;consistent gameplay&lt;/li&gt;
&lt;li&gt;a rapid iteration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is strongly reminiscent of the old Mario Game Boy games.&lt;/p&gt;

&lt;p&gt;The main advantage:&lt;br&gt;
the speed of prototyping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude
&lt;/h2&gt;

&lt;p&gt;Claude produces something more graphically detailed.&lt;/p&gt;

&lt;p&gt;The activities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;are more fluid&lt;/li&gt;
&lt;li&gt;more modern&lt;/li&gt;
&lt;li&gt;sometimes more ambitious&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reasoning seems more structured.&lt;/p&gt;

&lt;p&gt;But we also feel more creative freedom compared to remaining faithful to the original.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gemini
&lt;/h2&gt;

&lt;p&gt;Gemini is probably the most visually interesting.&lt;/p&gt;

&lt;p&gt;We find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more modern graphics&lt;/li&gt;
&lt;li&gt;better art direction&lt;/li&gt;
&lt;li&gt;greater inventiveness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gameplay also seems more refined in certain aspects.&lt;/p&gt;

&lt;p&gt;There's a more "Nintendo-like" approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grok
&lt;/h2&gt;

&lt;p&gt;Grok is the most unpredictable.&lt;/p&gt;

&lt;p&gt;He takes more initiative:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;level selection&lt;/li&gt;
&lt;li&gt;scoring system&lt;/li&gt;
&lt;li&gt;graphic variations&lt;/li&gt;
&lt;li&gt;new gameplay approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it also deviates further from the original Mario.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real subject is not Mario
&lt;/h2&gt;

&lt;p&gt;This project was ultimately just a pretext.&lt;/p&gt;

&lt;p&gt;The real issue lies elsewhere:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The future of AI development lies in orchestration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A single agent can produce a prototype.&lt;/p&gt;

&lt;p&gt;But several specialized agents can produce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;systems&lt;/li&gt;
&lt;li&gt;pipelines&lt;/li&gt;
&lt;li&gt;workflows&lt;/li&gt;
&lt;li&gt;coherent architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly:&lt;br&gt;
reproducible results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The future of vibe coding
&lt;/h2&gt;

&lt;p&gt;Current “vibe coding” often relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a huge prompt&lt;/li&gt;
&lt;li&gt;a single AI&lt;/li&gt;
&lt;li&gt;many hallucinations&lt;/li&gt;
&lt;li&gt;little validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next step is probably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;specialized agents&lt;/li&gt;
&lt;li&gt;explicit constraints&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;QA loops&lt;/li&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;li&gt;of the orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;p&gt;The future of vibe coding is orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Matyo91: matyo91/mario-orquestration: &lt;a href="https://github.com/matyo91/mario-orquestration" rel="noopener noreferrer"&gt;https://github.com/matyo91/mario-orquestration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ChatGPT: yoloyee1/SMB-clone-made-by-Godot: &lt;a href="https://github.com/yoloyee1/SMB-clone-made-by-Godot" rel="noopener noreferrer"&gt;https://github.com/yoloyee1/SMB-clone-made-by-Godot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude: Axelrpg/Super-Mario-Bros-Godot: &lt;a href="https://github.com/Axelrpg/Super-Mario-Bros-Godot" rel="noopener noreferrer"&gt;https://github.com/Axelrpg/Super-Mario-Bros-Godot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gemini: charpurrr/SuperMarioSolarEngine: &lt;a href="https://github.com/charpurrr/SuperMarioSolarEngine" rel="noopener noreferrer"&gt;https://github.com/charpurrr/SuperMarioSolarEngine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Grok: wchen02/platformer: &lt;a href="https://github.com/wchen02/platformer" rel="noopener noreferrer"&gt;https://github.com/wchen02/platformer&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Presentation slides: &lt;a href="https://github.com/matyo91/slidewire" rel="noopener noreferrer"&gt;https://github.com/matyo91/slidewire&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Symfony Multiagent: &lt;a href="https://github.com/symfony/ai/blob/main/examples/multi-agent/orchestrator.php" rel="noopener noreferrer"&gt;https://github.com/symfony/ai/blob/main/examples/multi-agent/orchestrator.php&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai.symfony.com" rel="noopener noreferrer"&gt;Symfony AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://godotengine.org" rel="noopener noreferrer"&gt;Godot Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.date" rel="noopener noreferrer"&gt;Playdate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AgentCraft: The Orc at the Heart of the Orchestration — Ido Salomon: &lt;a href="https://www.youtube.com/watch?v=kR64LOqBBCU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=kR64LOqBBCU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn JavaScript by building Mario! (Super simple!): &lt;a href="https://www.youtube.com/watch?v=VNs96uQoetw" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=VNs96uQoetw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I created an AI that plays Mario all by itself: &lt;a href="https://m.youtube.com/watch?v=F63GNXGHVwM&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;https://m.youtube.com/watch?v=F63GNXGHVwM&amp;amp;feature=youtu.be&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;understand the code that the AI ​​produces for: &lt;a href="https://www.linkedin.com/posts/thierry-templier-7ba726_%C3%A0-l%C3%A8re-de-claude-code-g%C3%A9n%C3%A9rer-200-000-lignes-share-7457029437134512129-CSJb?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8" rel="noopener noreferrer"&gt;https://www.linkedin.com/posts/thierry-templier-7ba726_%C3%A0-l%C3%A8re-de-claude-code-g%C3%A9n%C3%A9rer-200-000-lignes-share-7457029437134512129-CSJb?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nakiros 0.9.0 — audit your entire .claude/ directory with specialized AI agents: &lt;a href="https://www.linkedin.com/posts/thomasailleaume_claudecode-ai-devtools-share-7457340449356144640-bWe6?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8" rel="noopener noreferrer"&gt;https://www.linkedin.com/posts/thomasailleaume_claudecode-ai-devtools-share-7457340449356144640-bWe6?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I Built a GAME OF KAREN with Genspark AI + GitHub (And Made Expensive Mistakes 😅): &lt;a href="https://www.youtube.com/watch?v=fI9Z1-SPfaI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=fI9Z1-SPfaI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Text-to-Level Diffusion Models With Various Text Encoders for Super Mario Bros: &lt;a href="https://arxiv.org/pdf/2507.00184" rel="noopener noreferrer"&gt;https://arxiv.org/pdf/2507.00184&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NVIDIA's New AI Turns One Photo Into A World That Never Breaks: &lt;a href="https://youtu.be/eCw33snvoNI?is=7KOOQzRpbPXPBtFl" rel="noopener noreferrer"&gt;https://youtu.be/eCw33snvoNI?is=7KOOQzRpbPXPBtFl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links of the week
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LIVE 1/5 LIBERTY WEBI OPEN HOUSE - THE AI SHORTCUT: &lt;a href="https://www.youtube.com/live/L0H-rgqf7zI?is=1mc0YgZAxwjABKay" rel="noopener noreferrer"&gt;https://www.youtube.com/live/L0H-rgqf7zI?is=1mc0YgZAxwjABKay&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Eve of the week of May 4, 2026 Guillaume Loulier: &lt;a href="https://guikingone.substack.com/p/veille-de-la-semaine-du-4-mai-2026" rel="noopener noreferrer"&gt;https://guikingone.substack.com/p/veille-de-la-semaine-du-4-mai-2026&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How MrBeast Works 18 Hours Per Day &lt;a href="https://youtu.be/wPeUb2SVmEc?is=psItbJ2YNJFjVHiq" rel="noopener noreferrer"&gt;https://youtu.be/wPeUb2SVmEc?is=psItbJ2YNJFjVHiq&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Richest People in the World (1900-2026) - From Rockefeller to Musk: &lt;a href="https://m.youtube.com/watch?v=5h_vKrHzRvg&amp;amp;is=M9gch9O_AuqDTiKe" rel="noopener noreferrer"&gt;https://m.youtube.com/watch?v=5h_vKrHzRvg&amp;amp;is=M9gch9O_AuqDTiKe&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Day 287 growing my SaaS startup to $1M: &lt;a href="https://m.youtube.com/watch?v=7aQ01ZKysl8&amp;amp;is=tdQGj8GddnmVH5sQ" rel="noopener noreferrer"&gt;https://m.youtube.com/watch?v=7aQ01ZKysl8&amp;amp;is=tdQGj8GddnmVH5sQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ANDREJ KARPATHY JUST DECLARED THE END OF PROGRAMMING AS YOU KNOW IT. &lt;a href="https://x.com/neil_xbt/status/2049687182336541013?s=46" rel="noopener noreferrer"&gt;https://x.com/neil_xbt/status/2049687182336541013?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How France's biggest pirate site was taken down: &lt;a href="https://youtu.be/ULTV6T6jRTw?is=F9k6GcMNll0IfjZo" rel="noopener noreferrer"&gt;https://youtu.be/ULTV6T6jRTw?is=F9k6GcMNll0IfjZo&lt;/a&gt;
Japan has just made a major decision: &lt;a href="https://youtu.be/n_Kfco-kuFY?is=TBrMM-XdMTeE0qGR" rel="noopener noreferrer"&gt;https://youtu.be/n_Kfco-kuFY?is=TBrMM-XdMTeE0qGR&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;check: Remove use of subtyping for monads: &lt;a href="https://github.com/Gabriella439/grace/pull/261" rel="noopener noreferrer"&gt;https://github.com/Gabriella439/grace/pull/261&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Agentic Search for Context Engineering — Leonie Monigatti, Elastic: &lt;a href="https://www.youtube.com/watch?v=ynJyIKwjonM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ynJyIKwjonM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;FLUX, open research and the future of visual AI — Stephen Batifol, Black Forest Labs: &lt;a href="https://www.youtube.com/watch?v=x8Yb4RidLgM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=x8Yb4RidLgM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How the Transformers finally devoured vision – Isaac Robinson, Roboflow: &lt;a href="https://www.youtube.com/watch?v=VhfAVA3BG2I" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=VhfAVA3BG2I&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;This 50-minute lecture by Jeff Bezos will teach you more about business than a 2-year MBA program: &lt;a href="https://x.com/Alokkumarzz/status/2049882855170588755?s=20" rel="noopener noreferrer"&gt;https://x.com/Alokkumarzz/status/2049882855170588755?s=20&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;This lecture from Massachusetts Institute of Technology breaks down wealth, compounding, and long-term thinking in a way most financial advice never does: &lt;a href="https://x.com/allen_explains/status/2049857599919825252?s=46" rel="noopener noreferrer"&gt;https://x.com/allen_explains/status/2049857599919825252?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Stanford just taught the entire thing in a 1-hour lecture. For Free. &lt;a href="https://x.com/codewithimanshu/status/2051240758125252872?s=46" rel="noopener noreferrer"&gt;https://x.com/codewithimanshu/status/2051240758125252872?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;this 2-hour Stanford lecture on AI careers. It will teach you more about winning in the AI ​​race than all the AI ​​content you've scrolled past this year. &lt;a href="https://x.com/radha_ai/status/2051617864617263397?s=46" rel="noopener noreferrer"&gt;https://x.com/radha_ai/status/2051617864617263397?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Peter Thiel gave a 1-hour class on how to create a monopoly starting from 0. &lt;a href="https://x.com/indutripat82427/status/2051709170618098065?s=12" rel="noopener noreferrer"&gt;https://x.com/indutripat82427/status/2051709170618098065?s=12&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In this 24-minute session, Cherny outlines a future that is already his daily reality: &lt;a href="https://x.com/datachaz/status/2051770066912379309?s=12" rel="noopener noreferrer"&gt;https://x.com/datachaz/status/2051770066912379309?s=12&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Radha Tripathi on X: "Claude FULL COURSE 1 HOUR (Build &amp;amp; Automate Anything) &lt;a href="https://t.co/gg81I06To0" rel="noopener noreferrer"&gt;https://t.co/gg81I06To0&lt;/a&gt;" /&lt;/li&gt;
&lt;li&gt;A Stanford University lecture taught the way engineers are actually trained to think about AI systems. You understand the why, every prompt you write, every system you design, and every agent you build operates from a completely different mental model. &lt;a href="https://x.com/cyrilxbt/status/2049690838972723503?s=46" rel="noopener noreferrer"&gt;https://x.com/cyrilxbt/status/2049690838972723503?s=46&lt;/a&gt;
-Sam Altman. Dustin Moskovitz. The first lecture of the most influential startup course ever recorded. &lt;a href="https://x.com/neil_xbt/status/2050411454830907898?s=46" rel="noopener noreferrer"&gt;https://x.com/neil_xbt/status/2050411454830907898?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI's own engineers just showed how to actually use OpenAI Codex properly. &lt;a href="https://x.com/heyzarakhan/status/2051357610222239745?s=46" rel="noopener noreferrer"&gt;https://x.com/heyzarakhan/status/2051357610222239745?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How much of your project code was written by #AI? Whether to track coding agent adoption in engineering teams or security risks introduced by vibe coding, it's time to track what Claude/Cursor/Copilot/Codex do. &lt;a href="https://usegitai.com/:" rel="noopener noreferrer"&gt;https://usegitai.com/:&lt;/a&gt; &lt;a href="https://www.linkedin.com/posts/fzaninotto_git-ai-track-ai-code-all-the-way-to-production-share-7450124640389263360-jhxu?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8" rel="noopener noreferrer"&gt;https://www.linkedin.com/posts/fzaninotto_git-ai-track-ai-code-all-the-way-to-production-share-7450124640389263360-jhxu?utm_source=share&amp;amp;utm_medium=member_ios&amp;amp;rcm=ACoAAA2M-8wBB-yYv6qd4pdeoz3fTBIAhu6HQH8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;practitioners' perspective: Takeaways based on a qualitative survey of 419 practitioners involved in workflow maintenance: &lt;a href="https://dl.acm.org/doi/10.1145/3806833" rel="noopener noreferrer"&gt;https://dl.acm.org/doi/10.1145/3806833&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In 14 minutes, this Anthropic engineer who created MCPs will teach you more about building them right than most developers figure out on their own in months &lt;a href="https://x.com/Av1dlive/status/2051967150894772609?s=20" rel="noopener noreferrer"&gt;https://x.com/Av1dlive/status/2051967150894772609?s=20&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Star Wars: Episode 1 - Racer (Podracing) 100% Speedrun in 1:17:33 [World Record]: &lt;a href="https://youtu.be/OWv69snqBFs?is=kNL8iJzzGVRL3hRl" rel="noopener noreferrer"&gt;https://youtu.be/OWv69snqBFs?is=kNL8iJzzGVRL3hRl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In 2007, Elon Musk Predicted Everything: &lt;a href="https://youtu.be/xyCOvT1Y5YQ?is=igUlB5wqAuX1qbRs" rel="noopener noreferrer"&gt;https://youtu.be/xyCOvT1Y5YQ?is=igUlB5wqAuX1qbRs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎶 Music credit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Questo trend è mio! ⭐️ : &lt;a href="https://www.tiktok.com/@maya_cianflone/video/7607524440364289302" rel="noopener noreferrer"&gt;https://www.tiktok.com/@maya_cianflone/video/7607524440364289302&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;  &lt;a title="@maya_cianflone" href="https://www.tiktok.com/@maya_cianflone?refer=embed" rel="noopener noreferrer"&gt;@maya_cianflone&lt;/a&gt; &lt;p&gt;Questo trend è mio! ⭐️&lt;/p&gt; &lt;a title="♬ original sound - smb.0685" href="https://www.tiktok.com/music/original-sound-7132887839133502214?refer=embed" rel="noopener noreferrer"&gt;♬ original sound - smb.0685&lt;/a&gt;  &lt;/blockquote&gt; 

</description>
    </item>
    <item>
      <title>⚡️ Screening of the film "My Extraordinary Life" - what living systems teach us about automation</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Wed, 06 May 2026 07:05:30 +0000</pubDate>
      <link>https://dev.to/matyo91/screening-of-the-film-my-extraordinary-life-what-living-systems-teach-us-about-automation-7om</link>
      <guid>https://dev.to/matyo91/screening-of-the-film-my-extraordinary-life-what-living-systems-teach-us-about-automation-7om</guid>
      <description>&lt;p&gt;On May 5th, at Pixelis in Paris, we screened &lt;a href="https://luma.com/7g7yl45y?tk=vVScFh" rel="noopener noreferrer"&gt;&lt;em&gt;Mon Extraordinaire&lt;/em&gt;&lt;/a&gt;, the film that follows &lt;a href="https://www.linkedin.com/in/guillaumelalu/" rel="noopener noreferrer"&gt;Guillaume Lalu&lt;/a&gt; on his 160km solo trek during the Marathon des Sables Ultra. No codes, no agents, no LLM. And yet, for two hours, everyone in the theater had the same feeling: this film speaks directly to what we are building at Darkwood.&lt;/p&gt;

&lt;p&gt;Because running 160 km in the sand is not about raw performance.&lt;br&gt;&lt;br&gt;
It's a masterclass in orchestration, resilience, and living systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4723.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4723.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Myth of the Perfect Sprint
&lt;/h2&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4724.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4724.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ultra-trail running is often imagined as a matter of steely resolve and pure willpower. Guillaume Lalu shows something else: he doesn't force the desert, he &lt;strong&gt;builds a system capable of surviving in it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Preparation, logistics, energy management, block-based approach, managing constant friction, recovery, rhythm, the team around him. Everything he talks about after the screening sounds exactly like a complex production pipeline.&lt;/p&gt;

&lt;p&gt;In automation and AI, we make the same mistake as at the beginning: we believe that everything depends on initial power (best model, perfect prompt, ultra-intelligent agent).&lt;br&gt;&lt;br&gt;
The reality on the ground is harsh: what matters is what still holds up after 40 hours… or after 6 months in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Friction is not a bug, it's the nature of matter
&lt;/h2&gt;

&lt;p&gt;The most telling moment in the film? The sand constantly getting into the shoes.&lt;/p&gt;

&lt;p&gt;A seemingly ridiculous detail.&lt;br&gt;&lt;br&gt;
It's actually a structural problem.&lt;/p&gt;

&lt;p&gt;Guillaume spends a huge part of his race emptying his shoes, managing irritation, losing rhythm, and expending mental energy. He can't eliminate the sand. He has to &lt;strong&gt;deal with it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is the exact metaphor for real-world workflows today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs that change without warning
&lt;/li&gt;
&lt;li&gt;Exploding tokens
&lt;/li&gt;
&lt;li&gt;Drifting agents
&lt;/li&gt;
&lt;li&gt;Contexts that become unusable
&lt;/li&gt;
&lt;li&gt;Humans who intervene at the wrong time
&lt;/li&gt;
&lt;li&gt;Dirty or incomplete data
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The systems that work aren't those that have eliminated all friction. They're the ones that have learned to move forward &lt;strong&gt;despite&lt;/strong&gt; it. This is precisely the spirit behind &lt;a href="https://flow.darkwood.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/a&gt;: data-oriented and event-driven architectures that don't strive for rigid perfection, but for the ability to keep going when things get tough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Endurance &amp;gt; Cutting-edge intelligence
&lt;/h2&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4725.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4725.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Guillaume isn't running to win. He's running to finish, remaining whole, fully experiencing the journey. He mentally breaks down the 160 km into four symbolic "marathons." He ticks off the blocks one by one.&lt;/p&gt;

&lt;p&gt;That's precisely the difference between an impressive AI demo and a system that lasts.&lt;/p&gt;

&lt;p&gt;Many automation tools shine on stage.&lt;br&gt;&lt;br&gt;
Few survive the night, the unforeseen events, the accumulation of small deviations.&lt;/p&gt;

&lt;p&gt;Sustainable systems are those that know how to slow down, observe, recover, and resume. Those that tolerate imperfection. Those that maintain a &lt;strong&gt;narrative continuity&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navi: The Memory of the Journey Through Chaos
&lt;/h2&gt;

&lt;p&gt;In the film, Guillaume explains how he survived mentally thanks to this breakdown and this ability to look back: "Where did I lose energy? Why did I slow down here? What allowed me to start again?"&lt;/p&gt;

&lt;p&gt;A memoryless AI agent system quickly becomes a ghost. We no longer know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did this officer make this decision?
&lt;/li&gt;
&lt;li&gt;What data triggered this branch?
&lt;/li&gt;
&lt;li&gt;At what point did the workflow deviate?
&lt;/li&gt;
&lt;li&gt;What actually created value
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://navi.darkwood.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Navi&lt;/strong&gt;&lt;/a&gt; was born from this need: to transform the chaotic trace of a distributed system (agents + workflows + human interventions) into a comprehensible, narrative, visual journey. Not just logs. A story that humans can reread and understand, even days later.&lt;/p&gt;

&lt;p&gt;Like Guillaume who, in the middle of the night, in the cold, still knows where he is in his own story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hybrid orchestration: the human element is not optional
&lt;/h2&gt;

&lt;p&gt;The film is also a beautiful lesson in humility: no one crosses 160 km alone. There are friends (François and Julien), the coach, the medical teams, the checkpoints, loved ones, the other runners.&lt;/p&gt;

&lt;p&gt;Ultra-trail running is becoming a &lt;strong&gt;collective system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is precisely what we observe with the best AI implementations today: the most powerful systems do not replace humans. They augment them. Humans become the immune system, the strategist, the one who sets safeguards and corrects the trajectory when the model goes astray.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uniflow: Building for the long term, not viral
&lt;/h2&gt;

&lt;p&gt;Guillaume didn't launch &lt;em&gt;Epic Race&lt;/em&gt; looking for a viral hit. He built it slowly: episode after episode, relationship after relationship, for years. 300 episodes later, the project still holds up because it's organic.&lt;/p&gt;

&lt;p&gt;This is the same trap that many fall into with creative automation: looking for the hack, the agent that generates 100 posts per day, explosive growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://uniflow.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Uniflow&lt;/strong&gt;&lt;/a&gt; is not a spam machine. It is a creative endurance infrastructure: recycling, enriching, reorchestrating, transforming a continuous flow into a living ecosystem that improves over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The desert as ultimate truth
&lt;/h2&gt;

&lt;p&gt;The Sahara in &lt;em&gt;My Extraordinary&lt;/em&gt; is the perfect metaphor for the environments in which we deploy our systems today: immense, unpredictable, energy-intensive, hostile at times, impossible to control totally.&lt;/p&gt;

&lt;p&gt;In this context, rigid architectures die.&lt;br&gt;&lt;br&gt;
Living systems survive.&lt;/p&gt;

&lt;p&gt;They learn to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dancing with friction
&lt;/li&gt;
&lt;li&gt;Maintaining a narrative memory
&lt;/li&gt;
&lt;li&gt;Human + AI orchestration
&lt;/li&gt;
&lt;li&gt;Moving forward despite the sand
&lt;/li&gt;
&lt;li&gt;Transforming chaos into continuous flow
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real automation is not magic. It is organic.&lt;/p&gt;

&lt;p&gt;Thanks to Guillaume Lalu, Pixelis, and everyone who was present on May 5th.  &lt;/p&gt;

&lt;p&gt;The desert didn't talk about technology.&lt;br&gt;&lt;br&gt;
Yet he told us everything about the future of AI and automation.&lt;/p&gt;

&lt;p&gt;And what he says is that the systems that will last will be those that know how to, like him, &lt;strong&gt;continue despite the sand&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4726.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-05-06-mon-extraordinaire/resized_IMG_4726.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>✨ Transformative design: no longer designing uses, but metamorphoses</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 01 May 2026 06:39:23 +0000</pubDate>
      <link>https://dev.to/matyo91/transformative-design-no-longer-designing-uses-but-metamorphoses-9i8</link>
      <guid>https://dev.to/matyo91/transformative-design-no-longer-designing-uses-but-metamorphoses-9i8</guid>
      <description>&lt;p&gt;On April 30th, at Le Laptop in Paris, an event took place that broke away from the beaten path of classic Product Design: &lt;strong&gt;“Transformative Design: Don't just create uses, transform users”&lt;/strong&gt;, presented by David Jeanne and organized by Jordan Thévenot.&lt;/p&gt;

&lt;p&gt;In a room filled with around forty participants—designers, developers, and product specialists—the promise was clear: to question the current limitations of UX and propose a new direction. A direction where design no longer simply optimizes interfaces, but seeks to produce profound transformations for users.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4665.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4665.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From Experience to Transformation&lt;/p&gt;

&lt;p&gt;Product design has long sought to make things simpler.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less friction.&lt;/li&gt;
&lt;li&gt;Less effort.&lt;/li&gt;
&lt;li&gt;Less complexity.&lt;/li&gt;
&lt;li&gt;Less waiting time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a powerful promise. But it also has a limitation: by smoothing everything over, we sometimes end up smoothing over meaning itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4666.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4666.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;David Jeanne starts from an idea from &lt;em&gt;The Experience Economy&lt;/em&gt;: the economy evolves in stages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We started by selling raw materials.&lt;/li&gt;
&lt;li&gt;Then products.&lt;/li&gt;
&lt;li&gt;Then services.&lt;/li&gt;
&lt;li&gt;Then experiments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But when the experience itself becomes commonplace, what remains to differentiate oneself?&lt;/p&gt;

&lt;p&gt;The proposed answer is powerful: &lt;strong&gt;transformation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's no longer just about selling a pleasant interface or a smooth user journey. It's about designing an experience that helps a person become someone else.&lt;/p&gt;

&lt;p&gt;For example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to go from “I am not sporty” to “I take care of my body”;&lt;/li&gt;
&lt;li&gt;moving from “I am at the mercy of my money” to “I am building my future”;&lt;/li&gt;
&lt;li&gt;to move from “I am just a resource” to “I am an active participant in the project”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4667.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4667.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where design becomes transformative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing a passage, not just a route
&lt;/h2&gt;

&lt;p&gt;Classical design often works with a persona: their needs, their pains, their motivations.&lt;/p&gt;

&lt;p&gt;Transformative design adds a deeper question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How ​​do we want to help this person to grow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This completely changes the nature of the work.&lt;/p&gt;

&lt;p&gt;We no longer just design a user journey.&lt;br&gt;
We design a passage.&lt;/p&gt;

&lt;p&gt;A passage between a current self and a possible self.&lt;/p&gt;

&lt;p&gt;This transition can follow the structure of initiation rites: a preparation phase, a turning point phase, and then an integration phase. The goal is not simply to create a "wow" effect, but to create an experience that leaves a lasting impression.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4674.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4674.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The role of rituals, symbols and objects
&lt;/h2&gt;

&lt;p&gt;One of the most interesting aspects of the conference is the importance given to symbols.&lt;/p&gt;

&lt;p&gt;A transformation does not happen solely through rational arguments. It also happens through forms, gestures, objects, places, words, and postures.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4679.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4679.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example presented, a simple, traditional meeting was transformed into a ritualistic moment. The chairs disappeared, a large strategic map was placed on the table, and the computer was put aside. The client was no longer simply someone who "gave a brief." They gradually became a strategist.&lt;/p&gt;

&lt;p&gt;And this change in physical posture can trigger a change in mental posture.&lt;/p&gt;

&lt;p&gt;This is a key idea: &lt;strong&gt;design transforms not only by what it explains, but by what it brings to life&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preserve, amplify, help, dissolve, transform
&lt;/h2&gt;

&lt;p&gt;David Jeanne presents an interesting matrix for deciding what to do with the existing elements in the experiment.&lt;/p&gt;

&lt;p&gt;Certain elements must be preserved, as they ensure the psychological safety of the user.&lt;br&gt;
Others need to be amplified, because they are already moving in the direction of the desired transformation.&lt;br&gt;
Others need help when they are simply irritants to be removed.&lt;/p&gt;

&lt;p&gt;Then come the deeper dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dissolve certain reference points;&lt;/li&gt;
&lt;li&gt;to transform certain identity-related blockages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where transformative design differs from traditional UX. It doesn't just aim to reduce problems; it seeks to identify what prevents a person from changing their perspective on themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  A central ethical question
&lt;/h2&gt;

&lt;p&gt;Such a design obviously raises a question: how far can we go?&lt;/p&gt;

&lt;p&gt;While design can transform, it can also manipulate.&lt;/p&gt;

&lt;p&gt;The conference emphasizes this point: the model presented aims for empowerment, not subjugation. But this imposes a strong requirement regarding consent, protection, and intent.&lt;/p&gt;

&lt;p&gt;Designing a transformation is not a neutral process.&lt;/p&gt;

&lt;p&gt;This is likely one of the major topics of the coming years, especially with the massive integration of AI into digital products. Interfaces will become more adaptive, more personalized, and more persuasive. The line between guidance and manipulation will become increasingly blurred.&lt;/p&gt;

&lt;h2&gt;
  
  
  My takeaway for Darkwood
&lt;/h2&gt;

&lt;p&gt;This conference resonates strongly with the topics I explore around Darkwood, Flow, and automation.&lt;/p&gt;

&lt;p&gt;Today, many tools aim to save time. But save time for what purpose?&lt;/p&gt;

&lt;p&gt;A good product shouldn't just automate a task. It should help its user change their approach.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To go from consumer to creator.&lt;/li&gt;
&lt;li&gt;To move from executor to architect.&lt;/li&gt;
&lt;li&gt;To go from spectator to player.&lt;/li&gt;
&lt;li&gt;To go from being overwhelmed to being able to orchestrate their own systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is probably where part of the value of future products lies: not in the total elimination of effort, but in the design of efforts that transform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Transformative design encourages us to move beyond a purely utilitarian view of the product.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A product can be more than just a tool.&lt;/li&gt;
&lt;li&gt;It can become a ritual.&lt;/li&gt;
&lt;li&gt;A passage.&lt;/li&gt;
&lt;li&gt;A mirror.&lt;/li&gt;
&lt;li&gt;A trigger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The question is therefore no longer simply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What use are we creating?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But rather:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What kind of person are we helping to emerge?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Going further&lt;/p&gt;

&lt;p&gt;David Jeanne has launched a campaign for his book dedicated to transformative design, which delves deeper into these concepts with concrete and operational methods.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://fr.ulule.com/design-transformatif-livre/" rel="noopener noreferrer"&gt;https://fr.ulule.com/design-transformatif-livre/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4664.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4664.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4668.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4668.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4669.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4669.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4670.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4670.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4671.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4671.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4673.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4673.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4675.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4675.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4676.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4676.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4677.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4677.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4678.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4678.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4680.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4680.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4681.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4681.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4682.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4682.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4683.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4683.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4684.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4684.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4685.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4685.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4686.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4686.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4687.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4687.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4688.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-30-le-design-transformatif/resized_IMG_4688.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>⚙️ Hermes X Paperclip - Building a Governed Multi-Agent Architecture with Symfony AI, Flow, and Navi</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Thu, 30 Apr 2026 12:19:19 +0000</pubDate>
      <link>https://dev.to/matyo91/hermes-x-paperclip-building-a-governed-multi-agent-architecture-with-symfony-ai-flow-and-navi-31jd</link>
      <guid>https://dev.to/matyo91/hermes-x-paperclip-building-a-governed-multi-agent-architecture-with-symfony-ai-flow-and-navi-31jd</guid>
      <description>&lt;p&gt;Multi-agent systems are everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestrated via Docker: &lt;a href="https://blog.darkwood.com/fr/article/ai-tinkerers-paris-agentic-workflows-avec-docker-vers-des-systemes-autonomes-securises-et-orchestres" rel="noopener noreferrer"&gt;https://blog.darkwood.com/fr/article/ai-tinkerers-paris-agentic-workflows-avec-docker-vers-des-systemes-autonomes-securises-et-orchestres&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Simulated using frameworks like Paperclip + Hermes: &lt;a href="https://www.youtube.com/watch?v=j7cKjTMjNLE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=j7cKjTMjNLE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;or integrated directly into products: &lt;a href="https://docs.langchain.com/oss/python/langchain/multi-agent" rel="noopener noreferrer"&gt;https://docs.langchain.com/oss/python/langchain/multi-agent&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in most cases, they remain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ collections of prompts&lt;br&gt;&lt;br&gt;
❌ without governance&lt;br&gt;&lt;br&gt;
❌ without traceability&lt;br&gt;&lt;br&gt;
❌ without clear responsibility&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we will build an alternative, not as a fictional startup, but as a concrete example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NoLife Agency - a digital agency entirely driven by a governed multi-agent architecture.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
a digital agency that produces client websites with specialized roles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🏢 NoLife Agency - a complete organization
&lt;/h2&gt;

&lt;p&gt;Unlike simplistic demos, NoLife Agency replicates a real organization:&lt;/p&gt;

&lt;h3&gt;
  
  
  Direction
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CEO&lt;/li&gt;
&lt;li&gt;CTO&lt;/li&gt;
&lt;li&gt;Governance Director Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Client &amp;amp; Delivery
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Account Manager&lt;/li&gt;
&lt;li&gt;Product Owner&lt;/li&gt;
&lt;li&gt;Delivery Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Architect&lt;/li&gt;
&lt;li&gt;Developer&lt;/li&gt;
&lt;li&gt;UX Designer&lt;/li&gt;
&lt;li&gt;UI Designer
Graphic Designer&lt;/li&gt;
&lt;li&gt;Motion Designer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Growth
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SEO / GEO&lt;/li&gt;
&lt;li&gt;Marketing&lt;/li&gt;
&lt;li&gt;Sales&lt;/li&gt;
&lt;li&gt;Web Analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Support &amp;amp; Reliability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;QA&lt;/li&gt;
&lt;li&gt;DevOps&lt;/li&gt;
&lt;li&gt;Security Officer&lt;/li&gt;
&lt;li&gt;Data Analyst&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internal Organization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Experience Officer&lt;/li&gt;
&lt;li&gt;Office Manager&lt;/li&gt;
&lt;li&gt;Happiness Chief Officer&lt;/li&gt;
&lt;li&gt;Nolife Resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Here, each role can be played by an agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ The trap of multi-agent architectures
&lt;/h2&gt;

&lt;p&gt;What many are building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt → LLM → résultat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is:&lt;/p&gt;

&lt;p&gt;*no guarantee&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no control&lt;/li&gt;
&lt;li&gt;no auditability&lt;/li&gt;
&lt;li&gt;no contract&lt;/li&gt;
&lt;li&gt;no governance&lt;/li&gt;
&lt;li&gt;no trace&lt;/li&gt;
&lt;li&gt;no trade-in&lt;/li&gt;
&lt;li&gt;no clear responsibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ The NoLife Agency Model
&lt;/h2&gt;

&lt;p&gt;We introduce a strict separation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;organization (Paperclip)&lt;/strong&gt; → who does what&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;specialization (Hermes)&lt;/strong&gt; → how to think&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;orchestration (Flow)&lt;/strong&gt; → when to execute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;traceability (Navi)&lt;/strong&gt; → observe and audit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;intelligence (Symfony AI)&lt;/strong&gt; → produce content&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧱 Technical architecture
&lt;/h2&gt;

&lt;p&gt;The application is based on a &lt;strong&gt;ports &amp;amp; adapters&lt;/strong&gt; architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Ports
&lt;/h3&gt;

&lt;p&gt;NoLife Agency uses ports and adapters to ensure that orchestration and governance remain decoupled from vendor/runtime specifics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI → &lt;code&gt;AiAgentClient&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Workflow → &lt;code&gt;FlowWorkflowClient&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Trace → &lt;code&gt;NaviTraceClient&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Media → &lt;code&gt;MediaGenerationClient&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Each external dependency is isolated.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AgentRunner&lt;/code&gt; is the single boundary for execution and governance. Adapters provide functionality, but they do not enforce policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
demoCommand[DemoClientWebsiteCommand] --&amp;gt; workflowLoader[WorkflowDefinitionLoader]
workflowLoader --&amp;gt; workflowValidator[WorkflowDefinitionValidator]
workflowValidator --&amp;gt; flowPort[FlowWorkflowClient]
flowPort --&amp;gt; agentRunner[AgentRunner]
agentRunner --&amp;gt; aiPort[AiAgentClient]
agentRunner --&amp;gt; naviPort[NaviTraceClient]
agentRunner --&amp;gt; mediaPort[MediaGenerationClient]
agentRunner --&amp;gt; auditJsonl[Audit JSONL]
agentRunner --&amp;gt; runArtifacts[Run Artifacts]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Symfony AI
  ↓
Agent Contracts + Registry
  ↓
AgentRunner + Governance
  ↓
Flow Workflow Runner
  ↓
Navi Trace Client
  ↓
Operational Reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Key principle
&lt;/h2&gt;

&lt;p&gt;Agents are not dependent on tools. They are dependent on contracts.&lt;/p&gt;

&lt;p&gt;Result :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;testability&lt;/li&gt;
&lt;li&gt;interchangeability&lt;/li&gt;
&lt;li&gt;robustness&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚙️ The heart of the system: AgentRunner
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;AgentRunner&lt;/code&gt; is &lt;strong&gt;the central point&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execution&lt;/li&gt;
&lt;li&gt;governance&lt;/li&gt;
&lt;li&gt;audit&lt;/li&gt;
&lt;li&gt;trace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 No agent can circumvent this point.&lt;/p&gt;

&lt;p&gt;Main guarantees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checks of the &lt;code&gt;pre-flight&lt;/code&gt; and &lt;code&gt;post-flight&lt;/code&gt; policy&lt;/li&gt;
&lt;li&gt;Application of approval for high-risk states/final delivery&lt;/li&gt;
&lt;li&gt;Workflow status security checks&lt;/li&gt;
&lt;li&gt;confining the artifact path to the execution directory&lt;/li&gt;
&lt;li&gt;Trace the correlation between the lifecycle and audit events&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔐 Integrated IT Governance
&lt;/h2&gt;

&lt;p&gt;Each action is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validated&lt;/li&gt;
&lt;li&gt;traced&lt;/li&gt;
&lt;li&gt;audited&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSONL logs&lt;/li&gt;
&lt;li&gt;trace per run&lt;/li&gt;
&lt;li&gt;validation rules&lt;/li&gt;
&lt;li&gt;mandatory approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is not a blind, autonomous system.&lt;br&gt;&lt;br&gt;
👉 It's a &lt;strong&gt;controlled&lt;/strong&gt; system.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AgentRunner&lt;/code&gt; is the single point of application for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;policy checks&lt;/li&gt;
&lt;li&gt;trace the life cycle&lt;/li&gt;
&lt;li&gt;Issuance of audit events&lt;/li&gt;
&lt;li&gt;approval requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;separation of responsibilities&lt;/li&gt;
&lt;li&gt;auditability&lt;/li&gt;
&lt;li&gt;human validation&lt;/li&gt;
&lt;li&gt;limitation of risky actions&lt;/li&gt;
&lt;li&gt;typed interfaces&lt;/li&gt;
&lt;li&gt;policy tests&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🔌 Phase 3 - Typed Ports
&lt;/h2&gt;

&lt;p&gt;The dependencies become ports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony AI → intelligence&lt;/li&gt;
&lt;li&gt;Flow → orchestration&lt;/li&gt;
&lt;li&gt;Navi → traceability&lt;/li&gt;
&lt;li&gt;media-bundle → media generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With one critical point:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The adapters are interchangeable via configuration&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Environment variables made available on the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NOLIFE_AI_ADAPTER&lt;/code&gt; (&lt;code&gt;null|symfony_ai&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NOLIFE_FLOW_ADAPTER&lt;/code&gt; (&lt;code&gt;null|darkwood_flow&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NOLIFE_NAVI_ADAPTER&lt;/code&gt; (&lt;code&gt;null|darkwood_navi&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NOLIFE_MEDIA_ADAPTER&lt;/code&gt; (&lt;code&gt;null|media_bundle&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOLIFE_FLOW_ROOT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOLIFE_NAVI_ROOT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOLIFE_MEDIA_BUNDLE_ROOT&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🧪 Use Case - Creating a Client Website
&lt;/h2&gt;

&lt;p&gt;Use case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client: Acme SaaS
Contact: John Do
Need: landing page + blog + SEO + short launch video
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Order :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console nolife:demo:client-website acme-saas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lead_qualified&lt;/li&gt;
&lt;li&gt;brief_created&lt;/li&gt;
&lt;li&gt;architecture_defined&lt;/li&gt;
&lt;li&gt;ux_ready&lt;/li&gt;
&lt;li&gt;content_generated&lt;/li&gt;
&lt;li&gt;development_ready&lt;/li&gt;
&lt;li&gt;SEO optimized&lt;/li&gt;
&lt;li&gt;qa_validated&lt;/li&gt;
&lt;li&gt;media_brief_created&lt;/li&gt;
&lt;li&gt;delivery_reviewed&lt;/li&gt;
&lt;li&gt;human_approval_required&lt;/li&gt;
&lt;li&gt;published&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 We are intentionally stopping before publication.&lt;/p&gt;

&lt;p&gt;Paperclip is modeled as an organizational concept.&lt;br&gt;&lt;br&gt;
Hermès is modeled as a concept of specialization.&lt;br&gt;&lt;br&gt;
Neither is coupled as an execution service.&lt;/p&gt;
&lt;h2&gt;
  
  
  📂 Generated Outputs
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var/nolife-agency/runs/{run_id}/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;brief.json&lt;/li&gt;
&lt;li&gt;landing-page.md&lt;/li&gt;
&lt;li&gt;article-draft.md&lt;/li&gt;
&lt;li&gt;seo-geo.md&lt;/li&gt;
&lt;li&gt;media-brief.yaml&lt;/li&gt;
&lt;li&gt;delivery-report.md&lt;/li&gt;
&lt;li&gt;trace.json&lt;/li&gt;
&lt;li&gt;audit.jsonl&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Expected final state: &lt;code&gt;human_approval_required&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔁 Multi-agent at all levels
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker / isolated services&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Organization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Paperclip → role structure&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Intelligence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hermes → agent specialization&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. Application
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Symfony → concrete orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 NoLife Agency is a &lt;strong&gt;point of convergence&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️ Real problem encountered
&lt;/h2&gt;

&lt;p&gt;Today :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI adapter: null
Using Null AI adapter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 The system is correct… but not yet connected.&lt;/p&gt;

&lt;p&gt;That's normal.&lt;/p&gt;

&lt;p&gt;Because :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ports are in place&lt;/li&gt;
&lt;li&gt;but the actual implementations are not enabled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 What this reveals
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Building a multi-agent architecture is not the same as calling an LLM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define contracts&lt;/li&gt;
&lt;li&gt;Isolate the dependencies&lt;/li&gt;
&lt;li&gt;Centralize governance&lt;/li&gt;
&lt;li&gt;Make the system testable&lt;/li&gt;
&lt;li&gt;Gradually activate the integrations&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🚀 Next step
&lt;/h2&gt;

&lt;p&gt;Enable :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony AI (real intelligence)&lt;/li&gt;
&lt;li&gt;Flow (actual workflow)&lt;/li&gt;
&lt;li&gt;Navi (actual track)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Without breaking anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the tests&lt;/li&gt;
&lt;li&gt;governance&lt;/li&gt;
&lt;li&gt;the ports&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;Multi-agent architectures are not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;magical autonomous systems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These are :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;governed, orchestrated, and traceable software organizations&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💡 Darkwood Positioning
&lt;/h2&gt;

&lt;p&gt;NoLife Agency is showing a clear direction:&lt;/p&gt;

&lt;p&gt;The future of AI systems is not only autonomous.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is &lt;strong&gt;governed&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🕵 Project source code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;nolife-agency: &lt;a href="https://github.com/matyo91/nolife-agency" rel="noopener noreferrer"&gt;https://github.com/matyo91/nolife-agency&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multi-Agent Architectures: &lt;a href="https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026?slide=46" rel="noopener noreferrer"&gt;https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026?slide=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;What is a multi-agent system? &lt;a href="https://www.ibm.com/fr-fr/think/topics/multiagent-system" rel="noopener noreferrer"&gt;https://www.ibm.com/fr-fr/think/topics/multiagent-system&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Multi-Agent Orchestration: How to Build Agent Teams That Actually Work: &lt;a href="https://www.mindstudio.ai/blog/multi-agent-orchestration-patterns" rel="noopener noreferrer"&gt;https://www.mindstudio.ai/blog/multi-agent-orchestration-patterns&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building AI Teams: How Docker Sandboxes and Docker Agent Transform Development: &lt;a href="https://www.docker.com/blog/building-ai-teams-docker-sandboxes-agent/" rel="noopener noreferrer"&gt;https://www.docker.com/blog/building-ai-teams-docker-sandboxes-agent/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How To Build a Multi-Agent AI System with Docker Agent: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-build-multi-agent-ai-system-docker-agent-digitalocean" rel="noopener noreferrer"&gt;https://www.digitalocean.com/community/tutorials/how-to-build-multi-agent-ai-system-docker-agent-digitalocean&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Langchain Multi-agent: &lt;a href="https://docs.langchain.com/oss/python/langchain/multi-agent" rel="noopener noreferrer"&gt;https://docs.langchain.com/oss/python/langchain/multi-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github NousResearch/hermes-paperclip-adapter: &lt;a href="https://github.com/NousResearch/hermes-paperclip-adapter" rel="noopener noreferrer"&gt;https://github.com/NousResearch/hermes-paperclip-adapter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hermes Agent, how to take advantage of the OpenClaw killer: &lt;a href="https://www.youtube.com/watch?v=j7cKjTMjNLE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=j7cKjTMjNLE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The A-Team - AI Agents for SaaS Development: &lt;a href="https://github.com/gmoigneu/the-a-team" rel="noopener noreferrer"&gt;https://github.com/gmoigneu/the-a-team&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;New Tech Role Emerging: Product Managers might evolve to “Product CEOs” (Paul Teyssier | Front): &lt;a href="https://www.youtube.com/watch?v=J3vCkWbSYI0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=J3vCkWbSYI0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Openai/symphony: &lt;a href="https://github.com/openai/symphony" rel="noopener noreferrer"&gt;https://github.com/openai/symphony&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎶 Music credit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keine Freunde bleiben (feat. Mia Julia) - Matthias Reim: &lt;a href="https://vm.tiktok.com/ZNRgyxKkE/" rel="noopener noreferrer"&gt;https://vm.tiktok.com/ZNRgyxKkE/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt; &lt;a title="@reim.matthias" href="https://www.tiktok.com/@reim.matthias?refer=embed" rel="noopener noreferrer"&gt;@reim.matthias&lt;/a&gt; Wenn Freundschaft keinen Sinn mehr macht… Wer fühlt den Song? &lt;a title="miajulia" href="https://www.tiktok.com/tag/miajulia?refer=embed" rel="noopener noreferrer"&gt;#miajulia&lt;/a&gt; &lt;a title="matthiasreim" href="https://www.tiktok.com/tag/matthiasreim?refer=embed" rel="noopener noreferrer"&gt;#matthiasreim&lt;/a&gt; &lt;a title="keinefreundebleben" href="https://www.tiktok.com/tag/keinefreundebleben?refer=embed" rel="noopener noreferrer"&gt;#keinefreundebleben&lt;/a&gt; &lt;a title="♬ Keine Freunde bleiben (feat. Mia Julia) - Matthias Reim" href="https://www.tiktok.com/music/Keine-Freunde-bleiben-feat-Mia-Julia-7628279460525115408?refer=embed" rel="noopener noreferrer"&gt;♬ Keine Freunde bleiben (feat. Mia Julia) - Matthias Reim&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;"That way I eat more!" 😂 #nico #byilhanntwitch: &lt;a href="https://vm.tiktok.com/ZNRg5Rsh1/" rel="noopener noreferrer"&gt;https://vm.tiktok.com/ZNRg5Rsh1/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt; &lt;a title="@leclippeurrapide" href="https://www.tiktok.com/@leclippeurrapide?refer=embed" rel="noopener noreferrer"&gt;@leclippeurrapide&lt;/a&gt; "That way I eat more!" 😂 &lt;a title="Nico" href="https://www.tiktok.com/tag/nico?refer=embed" rel="noopener noreferrer"&gt;#nico&lt;/a&gt; &lt;a title="byilhanntwitch" href="https://www.tiktok.com/tag/byilhanntwitch?refer=embed" rel="noopener noreferrer"&gt;#byilhanntwitch&lt;/a&gt; &lt;a title="♬ Original sound - The Fast Clipper" href="https://www.tiktok.com/music/son-original-7552578191062453014?refer=embed" rel="noopener noreferrer"&gt;♬ original sound - Le Clippeur Rapide&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📖 Selection of the week
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DeepSeek-R1 evolving a Game of Life pattern really feels like a breakthrough: &lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1icqzcz/deepseekr1_evolving_a_game_of_life_pattern_really/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/LocalLLaMA/comments/1icqzcz/deepseekr1_evolving_a_game_of_life_pattern_really/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Unbounded: A Generative Infinite Game of Character Life Simulation: &lt;a href="https://arxiv.org/html/2410.18975v1" rel="noopener noreferrer"&gt;https://arxiv.org/html/2410.18975v1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LLM Interactive Story Game Architecture: &lt;a href="https://montreal.aitinkerers.org/talks/rsvp_c82tFBRQJ9A" rel="noopener noreferrer"&gt;https://montreal.aitinkerers.org/talks/rsvp_c82tFBRQJ9A&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Can an LLM Make a Video Game? &lt;a href="https://www.codemag.com/Article/2411061/Can-an-LLM-Make-a-Video-Game" rel="noopener noreferrer"&gt;https://www.codemag.com/Article/2411061/Can-an-LLM-Make-a-Video-Game&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Harness design for long-running application development: &lt;a href="https://www.anthropic.com/engineering/harness-design-long-running-apps" rel="noopener noreferrer"&gt;https://www.anthropic.com/engineering/harness-design-long-running-apps&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elon Musk explains his 5-step algorithm for running companies: &lt;a href="https://youtu.be/tdf3luOCNks?is=L6MRoXTHzvFVIUR8" rel="noopener noreferrer"&gt;https://youtu.be/tdf3luOCNks?is=L6MRoXTHzvFVIUR8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;when you have vibe coder in your office: &lt;a href="https://x.com/javinpaul/status/2048425733694124211/video/1?s=46" rel="noopener noreferrer"&gt;https://x.com/javinpaul/status/2048425733694124211/video/1?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sunday morning science: &lt;a href="https://x.com/Soph_astro/status/2048333972615111050/video/1?s=46" rel="noopener noreferrer"&gt;https://x.com/Soph_astro/status/2048333972615111050/video/1?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Native at Cdiscount with Ludwig Vantours: &lt;a href="https://www.youtube.com/watch?v=C3toh628KJE&amp;amp;list=PLmewDYeBL3XIx7Lnga-jO3eRjOsKQ-HW0&amp;amp;index=31" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=C3toh628KJE&amp;amp;list=PLmewDYeBL3XIx7Lnga-jO3eRjOsKQ-HW0&amp;amp;index=31&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Getgaal - docs(mcp): re-sync with agents/global registry resolution: &lt;a href="https://github.com/getgaal/docs/pull/16" rel="noopener noreferrer"&gt;https://github.com/getgaal/docs/pull/16&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Arize Phoenix: &lt;a href="https://arize.com/docs/phoenix" rel="noopener noreferrer"&gt;https://arize.com/docs/phoenix&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Design a new professional future with no-code and AI: &lt;a href="https://www.youtube.com/watch?v=p-sHtOut884" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=p-sHtOut884&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The bullshit of open-source AI models: &lt;a href="https://www.youtube.com/watch?v=jpg9lvtqrF8" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=jpg9lvtqrF8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A former spy uses AI to learn everything about you (Claude Code demonstration): &lt;a href="https://www.youtube.com/watch?v=eQXMEvGRld4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=eQXMEvGRld4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Automate your information monitoring for free and easily: &lt;a href="https://www.youtube.com/watch?v=6n_xwJ6YAj0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6n_xwJ6YAj0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A man spent 50 years teaching at MIT. The most important hour you'll watch this week. &lt;a href="https://x.com/suryanshti777/status/2049187998936482069?s=46" rel="noopener noreferrer"&gt;https://x.com/suryanshti777/status/2049187998936482069?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Fastest AI Infrastructure: &lt;a href="https://www.cerebras.ai" rel="noopener noreferrer"&gt;https://www.cerebras.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Diablo® IV: Lord of Hatred: &lt;a href="https://eu.shop.battle.net/fr-fr/product/diablo-iv-lord-of-hatred" rel="noopener noreferrer"&gt;https://eu.shop.battle.net/fr-fr/product/diablo-iv-lord-of-hatred&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>🚀 Fundraising vs. Bootstrap: Two paths to building a company</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Wed, 29 Apr 2026 07:22:46 +0000</pubDate>
      <link>https://dev.to/matyo91/fundraising-vs-bootstrap-two-paths-to-building-a-company-4787</link>
      <guid>https://dev.to/matyo91/fundraising-vs-bootstrap-two-paths-to-building-a-company-4787</guid>
      <description>&lt;p&gt;On April 28th, Builders Factory and NextGen VC organized a discussion in Paris around a seemingly simple question: &lt;strong&gt;Should you raise funds or build using bootstrapping?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Face to face: &lt;strong&gt;Étienne Genvrin&lt;/strong&gt;, founder of Emma, ​​which has raised several million euros, and &lt;strong&gt;Wilfried Granier&lt;/strong&gt;, founder of Superprof, which claims impressive growth without raising funds.&lt;/p&gt;

&lt;p&gt;Two opposing paths. Two visions of entrepreneurship. And above all, one central idea: &lt;strong&gt;there is no single right way to build a business.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4659.HEIC.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4659.HEIC.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The bootstrap: building a company that reflects you
&lt;/h2&gt;

&lt;p&gt;Wilfried Granier defends a very personal vision of the company.&lt;/p&gt;

&lt;p&gt;Superprof wasn't conceived as a startup to be sold, but as a company to be held onto. This difference changes everything. When you don't raise capital, you retain the freedom to decide, to experiment, to take your time, to make choices that may not seem rational on paper, but are consistent with your intuition.&lt;/p&gt;

&lt;p&gt;The bootstrap also forces you to focus on the essentials: revenue.&lt;/p&gt;

&lt;p&gt;No artificial runway. No growth financed by successive rounds of funding. The market responds directly. If customers pay, the company moves forward. If not, it must correct course.&lt;/p&gt;

&lt;p&gt;This constraint can become a strength: it encourages creativity, efficiency, the building of a solid culture, and the search for sustainable organic levers such as SEO, community, user reviews, or gradual internationalization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fundraising: Accelerate, learn, iterate faster
&lt;/h2&gt;

&lt;p&gt;Étienne Genvrin offers another interpretation.&lt;/p&gt;

&lt;p&gt;For certain markets, particularly consumer applications or products requiring high execution speeds, raising funds can be almost essential. Funding allows for faster recruitment, more testing, and the ability to make more mistakes in less time.&lt;/p&gt;

&lt;p&gt;But he insists on one important point: raising funds is a game.&lt;/p&gt;

&lt;p&gt;This game has its rules, its codes, its expectations, its language. Many entrepreneurs fail to raise funds not because their project is bad, but because they don't yet understand how this game works.&lt;/p&gt;

&lt;p&gt;Raising funds is therefore not just a question of business model. It is also a question of narrative, timing, network, perceived ambition, and the ability to embody a credible trajectory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real issue: alignment
&lt;/h2&gt;

&lt;p&gt;The debate could have been reduced to “raise or not raise”. But the real question is deeper:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What type of business do you really want to build?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your goal is to remain in control, to build for twenty years, to preserve maximum freedom, then the bootstrap may be the best path.&lt;/p&gt;

&lt;p&gt;If your goal is to quickly capture a market, recruit expensive profiles, and move very fast in a sector where speed counts, then fundraising can become a strategic tool.&lt;/p&gt;

&lt;p&gt;In both cases, the danger is misalignment.&lt;/p&gt;

&lt;p&gt;Raising capital when you want a flexible structure can create ongoing problems. Bootstrapping when you're operating in a market where speed is vital can condemn the project to remain too small.&lt;/p&gt;

&lt;p&gt;Advice is no substitute for instinct.&lt;/p&gt;

&lt;p&gt;One of the strongest messages of the evening: &lt;strong&gt;entrepreneurship is learned through practice&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Listening to podcasts, reading threads, or attending conferences can be inspiring. But it doesn't replace being on the ground.&lt;/p&gt;

&lt;p&gt;Entrepreneurial instinct is built by talking to customers, selling, recruiting, making mistakes, wasting time, correcting, and starting again.&lt;/p&gt;

&lt;p&gt;This is also why we must be wary of absolute advice. Advice that's true for Superprof isn't necessarily true for Emma. A strategy that works in 2013 isn't necessarily effective in 2026. A tactic that works in France might fail in the United States.&lt;/p&gt;

&lt;p&gt;The entrepreneur should not seek a universal rule. He must develop his own judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Barriers to entry are built as you move forward
&lt;/h2&gt;

&lt;p&gt;Another interesting point: at the beginning, it is often unnecessary to over-theorize about barriers to entry.&lt;/p&gt;

&lt;p&gt;When you start out, you don't yet have 39 million teachers, millions of user reviews, a well-known brand, or an international database. These advantages aren't prerequisites. They're the result of years of operation.&lt;/p&gt;

&lt;p&gt;The real initial barrier to entry is often the ability to continue when others give up.&lt;/p&gt;

&lt;p&gt;Create a first version. Find a first client. Solve a first problem. Move from level 0 to level 1.&lt;/p&gt;

&lt;p&gt;It's less spectacular than an ambitious pitch deck, but this is where the real building begins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Fundraising and bootstrapping are not two opposing camps.&lt;/p&gt;

&lt;p&gt;These are two different tools.&lt;/p&gt;

&lt;p&gt;The fundraising buys time, speed, and visible ambition.&lt;br&gt;
Bootstrapping buys freedom, patience, and mastery.&lt;/p&gt;

&lt;p&gt;The real issue, therefore, is not which model is superior.&lt;/p&gt;

&lt;p&gt;The real question is which one allows you to build the right business, at the right time, with the right level of alignment.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4657.HEIC.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4657.HEIC.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4658.HEIC.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4658.HEIC.jpg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4661.HEIC.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/2026-04-29-builder-factory/resized_IMG_4661.HEIC.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🚀 I rebuilt an LLM… with pixels.</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 26 Apr 2026 15:59:27 +0000</pubDate>
      <link>https://dev.to/matyo91/i-rebuilt-an-llm-with-pixels-aoe</link>
      <guid>https://dev.to/matyo91/i-rebuilt-an-llm-with-pixels-aoe</guid>
      <description>&lt;p&gt;Large Language Models (LLMs) are based on abstract concepts:&lt;br&gt;
probability distribution, autoregressive generation, large-scale optimization.&lt;/p&gt;

&lt;p&gt;These mechanisms are difficult to observe directly.&lt;/p&gt;

&lt;p&gt;An alternative approach is to &lt;strong&gt;project these concepts into a visual and deterministic system&lt;/strong&gt;, allowing us to study their dynamics.&lt;/p&gt;

&lt;p&gt;This work is inspired by an initial demonstration shared on Twitter:&lt;br&gt;
Allen Explains thread&lt;/p&gt;

&lt;p&gt;The goal is to build an educational prototype that will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;represent a sequential generation&lt;/li&gt;
&lt;li&gt;observe an optimization process&lt;/li&gt;
&lt;li&gt;compare different training regimens&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The prototype is implemented in PHP (Symfony 8) and is based on four main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cellular Automaton (Game of Life)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lambda language (AST JSON)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Genetic Algorithm&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streaming pipeline (NDJSON + SSE)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Full source code:&lt;br&gt;
llm-game-of-life&lt;/p&gt;
&lt;h2&gt;
  
  
  Representation: from text to grid
&lt;/h2&gt;

&lt;p&gt;An LLM models a distribution:&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
P(x_1, x_2, ..., x_n)&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;broken down into:&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
\prod_{t=1}^{n} P(x_t \mid x_{&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;In this prototype, this structure is transposed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LLM&lt;/th&gt;
&lt;th&gt;Prototype&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;td&gt;Cell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sequence&lt;/td&gt;
&lt;td&gt;Grid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generation&lt;/td&gt;
&lt;td&gt;Frame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;Program&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference loop&lt;/td&gt;
&lt;td&gt;Simulation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each frame corresponds to a generation step.&lt;/p&gt;

&lt;p&gt;The SSE flow produces a sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frame₀ → frame₁ → frame₂ → …
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;equivalent to a self-regressive generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model: program rather than network
&lt;/h2&gt;

&lt;p&gt;Unlike traditional LLMs, no neural networks are used.&lt;/p&gt;

&lt;p&gt;The model is defined as a &lt;strong&gt;program in a mini lambda language&lt;/strong&gt;, represented as an AST JSON file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sequence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"birth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program acts as a transition function on the grid.&lt;/p&gt;

&lt;p&gt;This approach replaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the weights of a model → by instructions&lt;/li&gt;
&lt;li&gt;the layers → through explicit transformations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Optimization: Genetic Algorithm
&lt;/h2&gt;

&lt;p&gt;The training is based on a population of programs.&lt;/p&gt;

&lt;p&gt;Each generation follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fitness Assessment&lt;/li&gt;
&lt;li&gt;Selection&lt;/li&gt;
&lt;li&gt;Crossover&lt;/li&gt;
&lt;li&gt;Mutation&lt;/li&gt;
&lt;li&gt;Elitism&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process replaces gradient descent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unsupervised training
&lt;/h2&gt;

&lt;p&gt;Unsupervised mode maximizes a fitness function based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;entropy (diversity)&lt;/li&gt;
&lt;li&gt;movement (variation between frames)&lt;/li&gt;
&lt;li&gt;lifetime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Objective :&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
\text{fitness} = f(\text{entropy}, \text{motion}, \text{lifetime})&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;This regimen is analogous to &lt;strong&gt;pretraining&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;absence of target&lt;/li&gt;
&lt;li&gt;exploration of the solutions space&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supervised Training
&lt;/h2&gt;

&lt;p&gt;The supervised mode introduces a target:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;glider&lt;/li&gt;
&lt;li&gt;blinker&lt;/li&gt;
&lt;li&gt;block&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fitness is becoming:&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
\text{fitness} = -d(\text{frame}, \text{target}) + \lambda \cdot \text{penalty}&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;Or :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(d) is a distance between grids&lt;/li&gt;
&lt;li&gt;the penalty limits the size of the programs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mode corresponds to &lt;strong&gt;fine-tuning&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preferences and selection
&lt;/h2&gt;

&lt;p&gt;A comparison mechanism can be introduced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two programs produce two sequences&lt;/li&gt;
&lt;li&gt;a preference is applied&lt;/li&gt;
&lt;li&gt;The selection favors the best&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This diagram represents a simplification of &lt;strong&gt;RLHF / DPO&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
\max \log P(\text{preferred}) - \log P(\text{rejected})&lt;br&gt;
]&lt;/p&gt;

&lt;h2&gt;
  
  
  Generation and streaming
&lt;/h2&gt;

&lt;p&gt;The results are produced in NDJSON and disseminated via SSE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each chunk = one frame&lt;/li&gt;
&lt;li&gt;Each stream = one generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Canvas-based visualization interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;matrix rendering&lt;/li&gt;
&lt;li&gt;real-time display&lt;/li&gt;
&lt;li&gt;metrics (fitness, generation, seed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Presentation slides:&lt;br&gt;
Slidewire presentation&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark and reproducibility
&lt;/h2&gt;

&lt;p&gt;The system includes a benchmark pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deterministic seed&lt;/li&gt;
&lt;li&gt;double execution&lt;/li&gt;
&lt;li&gt;sequence hash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Metrics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;duration (&lt;code&gt;duration_ms&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;memory (&lt;code&gt;peak_memory_mb&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;final fitness&lt;/li&gt;
&lt;li&gt;reproducibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Boundaries
&lt;/h2&gt;

&lt;p&gt;This prototype is not intended to reproduce a real LLM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no transformer&lt;/li&gt;
&lt;li&gt;no tokenization&lt;/li&gt;
&lt;li&gt;no probabilistic model&lt;/li&gt;
&lt;li&gt;no gradient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a &lt;strong&gt;computational analogy&lt;/strong&gt;, useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observe an optimization dynamic&lt;/li&gt;
&lt;li&gt;visualize a sequential generation&lt;/li&gt;
&lt;li&gt;compare different learning regimes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Modern LLMs rely on mechanisms that are difficult to grasp directly.&lt;/p&gt;

&lt;p&gt;Transposing this into a visual system allows us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;make generation observable&lt;/li&gt;
&lt;li&gt;to materialize the optimization&lt;/li&gt;
&lt;li&gt;isolate the fundamental concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach does not replace existing models, but offers a &lt;strong&gt;conceptual exploration tool&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source of the Twitter post: &lt;a href="https://x.com/allen_explains/status/2044757995549319172?s=12" rel="noopener noreferrer"&gt;https://x.com/allen_explains/status/2044757995549319172?s=12&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The project's source code: &lt;a href="https://github.com/matyo91/llm-game-of-life" rel="noopener noreferrer"&gt;https://github.com/matyo91/llm-game-of-life&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The presentation slides: &lt;a href="https://github.com/matyo91/slidewire" rel="noopener noreferrer"&gt;https://github.com/matyo91/slidewire&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What are the principles we can use to build LLM-powered software that is actually good enough to put in the hands of production customers? &lt;a href="https://github.com/humanlayer/12-factor-agents" rel="noopener noreferrer"&gt;https://github.com/humanlayer/12-factor-agents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AIE Miami Keynote &amp;amp; Talks ft. OpenCode. Google Deepmind, OpenAI, and more! : &lt;a href="https://www.youtube.com/watch?v=6IxSbMhT7v4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6IxSbMhT7v4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AIE Miami Day 2 ft. Cerebras, OpenCode, Cursor, Arize AI, and more! : &lt;a href="https://www.youtube.com/watch?v=DeM_u2Ik0sk" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=DeM_u2Ik0sk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How AI is transforming software engineering: a conversation with Gergely Orosz, @pragmaticengineer: &lt;a href="https://www.youtube.com/watch?v=CS5Cmz5FssI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=CS5Cmz5FssI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft at ICLR 2026: Deep Learning, LLM Reasoning, Generative Models: &lt;a href="https://www.linkedin.com/pulse/microsoft-iclr-2026-deep-learning-llm-reasoning-generative-h74se/" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/microsoft-iclr-2026-deep-learning-llm-reasoning-generative-h74se/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ASUS DGX Spark: KI auf dem Schreibtisch – Nie wieder Token‑Kosten! | Live Modellvergleich: &lt;a href="https://www.youtube.com/watch?v=dP4zE-DTWAg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=dP4zE-DTWAg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🟣 [VIRTUAL SUMMIT DAY 1/5] How to outperform 99% of people using AI: &lt;a href="https://www.youtube.com/watch?v=yzhg9Ks859I" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=yzhg9Ks859I&lt;/a&gt;
Ready to launch your own agent? : &lt;a href="https://hermes-agent.org/fr/" rel="noopener noreferrer"&gt;https://hermes-agent.org/fr/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PaperClip + Agent Hermès, it's insane! : &lt;a href="https://www.youtube.com/watch?v=PUaZ5o8u0wY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=PUaZ5o8u0wY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;30-minute workshop by the creator of Claude Code that will teach you more about vibe-coding: &lt;a href="https://x.com/heyamit_/status/2046489651775713498?s=46" rel="noopener noreferrer"&gt;https://x.com/heyamit_/status/2046489651775713498?s=46&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;What Young People Expect from HR: Why the Generational Approach is a Misleading Concept: &lt;a href="https://www.insign.fr/en/insights/young-workforce-expectations-generational-approach-an-intellectual-scam" rel="noopener noreferrer"&gt;https://www.insign.fr/en/insights/young-workforce-expectations-generational-approach-an-intellectual-scam&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>🤖 Symfony AI in Action - Building real AI systems with Symfony</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 24 Apr 2026 14:25:23 +0000</pubDate>
      <link>https://dev.to/matyo91/symfony-ai-in-action-building-real-ai-systems-with-symfony-47nm</link>
      <guid>https://dev.to/matyo91/symfony-ai-in-action-building-real-ai-systems-with-symfony-47nm</guid>
      <description>&lt;p&gt;For two days, on April 23 and 24, 2026, the &lt;strong&gt;SymfonyLive Berlin&lt;/strong&gt; conference brought the community together around the major developments of the Symfony ecosystem.&lt;/p&gt;

&lt;p&gt;Among the talks, one in particular marks a turning point:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Symfony AI in Action&lt;/strong&gt;, presented by Christopher Hertel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎥 Slides: &lt;a href="https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026" rel="noopener noreferrer"&gt;https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧠 Symfony AI: &lt;a href="https://ai.symfony.com" rel="noopener noreferrer"&gt;https://ai.symfony.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🛠️ Platform used for this article: &lt;a href="https://slidewire.dev" rel="noopener noreferrer"&gt;https://slidewire.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article does not summarize the conference.&lt;br&gt;
He offers a &lt;strong&gt;Darkwood&lt;/strong&gt; interpretation of what is happening.&lt;/p&gt;
&lt;h2&gt;
  
  
  The real issue: stop thinking “chatbot”
&lt;/h2&gt;

&lt;p&gt;Today, many AI integrations are limited to this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;write a prompt → call a template → display a response&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's insufficient.&lt;/p&gt;

&lt;p&gt;The real problem, in production, lies elsewhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestrate multiple models&lt;/li&gt;
&lt;li&gt;manage context and memory&lt;/li&gt;
&lt;li&gt;Expose actions (tools)&lt;/li&gt;
&lt;li&gt;monitor costs and logs&lt;/li&gt;
&lt;li&gt;integrate everything into a business architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Symfony AI does not offer a chatbot.&lt;br&gt;
👉 Symfony AI offers a &lt;strong&gt;complete stack&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Symfony AI: a stack, not a feature
&lt;/h2&gt;

&lt;p&gt;The objective is clear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Enable AI features, not only LLMs.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Symfony AI introduces several fundamental building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform&lt;/strong&gt; → model abstraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt; → LLM loop + tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store&lt;/strong&gt; → embeddings &amp;amp; RAG&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Bundle&lt;/strong&gt; → Symfony integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Bundle / SDK&lt;/strong&gt; → tools exhibition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 We're moving from an API call… to a &lt;strong&gt;complete AI architecture&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Platform: Model abstraction
&lt;/h2&gt;

&lt;p&gt;First classic problem:&lt;/p&gt;

&lt;p&gt;OpenAI, Claude, Gemini, Mistral → Different APIs&lt;/p&gt;

&lt;p&gt;Symfony AI introduces a unique abstraction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$platform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'gpt-5-mini'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same code, different providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this is key
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;change model without refactoring&lt;/li&gt;
&lt;li&gt;optimize costs&lt;/li&gt;
&lt;li&gt;fallback multi-provider&lt;/li&gt;
&lt;li&gt;Integrate local and remote&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Symfony becomes a &lt;strong&gt;model orchestration layer&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming &amp;amp; multimodal
&lt;/h2&gt;

&lt;p&gt;Symfony AI goes beyond simple text:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time token streaming&lt;/li&gt;
&lt;li&gt;audio, image, PDF&lt;/li&gt;
&lt;li&gt;binary output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analyze a PDF&lt;/li&gt;
&lt;li&gt;Describe an image&lt;/li&gt;
&lt;li&gt;process an audio&lt;/li&gt;
&lt;li&gt;generate files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 AI is becoming a &lt;strong&gt;multimodal application building block&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured Output: regaining control
&lt;/h2&gt;

&lt;p&gt;Classic problem:&lt;/p&gt;

&lt;p&gt;LLMs return text… not reliable data&lt;/p&gt;

&lt;p&gt;Symfony AI introduces typed responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$response_format&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;MyDTO&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;usable PHP objects&lt;/li&gt;
&lt;li&gt;strict validation&lt;/li&gt;
&lt;li&gt;Direct integration into the profession&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 We are moving from “generated text” to &lt;strong&gt;controlled data&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent: Connect the LLM to your application
&lt;/h2&gt;

&lt;p&gt;An agent is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a model that can call your code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With Symfony AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[AsTool('create_recipe')]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You present your profession as a tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  What this changes
&lt;/h3&gt;

&lt;p&gt;Before :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolated LLM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM + access to your system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 AI becomes &lt;strong&gt;executable&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human in the loop: security
&lt;/h2&gt;

&lt;p&gt;A critical point that is often overlooked:&lt;/p&gt;

&lt;p&gt;An AI shouldn't do everything automatically.&lt;/p&gt;

&lt;p&gt;Symfony AI allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;intercept a tool call&lt;/li&gt;
&lt;li&gt;request validation&lt;/li&gt;
&lt;li&gt;block or allow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;publish an article&lt;/li&gt;
&lt;li&gt;trigger critical action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You remain in control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory: contextualize
&lt;/h2&gt;

&lt;p&gt;Agents do not function without context.&lt;/p&gt;

&lt;p&gt;Symfony AI allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inject user data&lt;/li&gt;
&lt;li&gt;manage profiles&lt;/li&gt;
&lt;li&gt;store history&lt;/li&gt;
&lt;li&gt;control permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 AI is becoming &lt;strong&gt;contextual and personalized&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store &amp;amp; RAG: Connect your data
&lt;/h2&gt;

&lt;p&gt;Pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;loading&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;transforming&lt;/li&gt;
&lt;li&gt;Vectorizing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 You are building a vector basis.&lt;/p&gt;

&lt;p&gt;Afterwards :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user request&lt;/li&gt;
&lt;li&gt;search in the store&lt;/li&gt;
&lt;li&gt;enrichment of the prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is &lt;strong&gt;RAG (Retrieval Augmented Generation)&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Smart FAQ&lt;/li&gt;
&lt;li&gt;industry search engine&lt;/li&gt;
&lt;li&gt;internal co-pilot&lt;/li&gt;
&lt;li&gt;documented assistant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You connect the AI ​​to &lt;strong&gt;your business knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-agent: specialization
&lt;/h2&gt;

&lt;p&gt;Advanced architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;senior agent&lt;/li&gt;
&lt;li&gt;specialized sub-agents&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;sharing or isolation of context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;support agent&lt;/li&gt;
&lt;li&gt;technical agent&lt;/li&gt;
&lt;li&gt;billing agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Each agent has a role.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP: Expose your system
&lt;/h2&gt;

&lt;p&gt;Symfony AI is part of a broader movement:&lt;/p&gt;

&lt;p&gt;👉 the MCP protocol&lt;/p&gt;

&lt;p&gt;Objective :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Showcase your tools&lt;/li&gt;
&lt;li&gt;make your system queryable&lt;/li&gt;
&lt;li&gt;standardize AI interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Your application becomes an &lt;strong&gt;intelligence server&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real turning point: orchestration
&lt;/h2&gt;

&lt;p&gt;The most important point is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the models&lt;/li&gt;
&lt;li&gt;the prompts&lt;/li&gt;
&lt;li&gt;the agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The real issue is &lt;strong&gt;orchestration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Key questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who calls what?&lt;/li&gt;
&lt;li&gt;In what context?&lt;/li&gt;
&lt;li&gt;Under what permissions?&lt;/li&gt;
&lt;li&gt;With what traceability?&lt;/li&gt;
&lt;li&gt;How to regain control?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Darkwood Approach
&lt;/h2&gt;

&lt;p&gt;At Darkwood, the answer is clear:&lt;/p&gt;

&lt;h3&gt;
  
  
  Suggested Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Symfony AI&lt;/strong&gt; → AI building blocks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; → tools exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flow&lt;/strong&gt; → orchestration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navi&lt;/strong&gt; → execution + tracing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uniflow&lt;/strong&gt; → interface&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why this stack
&lt;/h3&gt;

&lt;p&gt;Symfony AI provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the models&lt;/li&gt;
&lt;li&gt;the agents&lt;/li&gt;
&lt;li&gt;the tools&lt;/li&gt;
&lt;li&gt;the RAG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But something is missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business orchestration&lt;/li&gt;
&lt;li&gt;overall control&lt;/li&gt;
&lt;li&gt;full visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is where Flow and Navi come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this changes in practice
&lt;/h2&gt;

&lt;p&gt;Before :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;isolated AI scripts&lt;/li&gt;
&lt;li&gt;fragile prompts&lt;/li&gt;
&lt;li&gt;little control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestrated system&lt;/li&gt;
&lt;li&gt;traceable execution&lt;/li&gt;
&lt;li&gt;integrated business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 We are moving from “playing with AI” to &lt;strong&gt;building reliable systems&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Symfony AI marks a major evolution:&lt;/p&gt;

&lt;p&gt;You're no longer building a chatbot&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you build a &lt;strong&gt;complete AI feature&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Today you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an abstraction of models&lt;/li&gt;
&lt;li&gt;agents connected to your code&lt;/li&gt;
&lt;li&gt;a memory system&lt;/li&gt;
&lt;li&gt;of the integrated RAG&lt;/li&gt;
&lt;li&gt;a basis for orchestrating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You have no more excuses.&lt;/p&gt;

&lt;h2&gt;
  
  
  To go further
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Symfony AI: &lt;a href="https://ai.symfony.com" rel="noopener noreferrer"&gt;https://ai.symfony.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Slides by Christopher Hertel: &lt;a href="https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026" rel="noopener noreferrer"&gt;https://speakerdeck.com/chr_hertel/symfony-ai-in-action-symfonylive-berlin-2026&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The technical support that allowed me to generate the slides - Slidewire: &lt;a href="https://slidewire.dev" rel="noopener noreferrer"&gt;https://slidewire.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Darkwood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://navi.darkwood.com" rel="noopener noreferrer"&gt;Navi&lt;/a&gt; → execution &amp;amp; tracing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://flow.darkwood.com" rel="noopener noreferrer"&gt;Flow&lt;/a&gt; → orchestration&lt;/li&gt;
&lt;li&gt;Uniflow → interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Articles coming soon with concrete implementations.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
