<?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>Forem: Mathieu Ledru</title>
    <description>The latest articles on Forem by Mathieu Ledru (@matyo91).</description>
    <link>https://forem.com/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>Forem: Mathieu Ledru</title>
      <link>https://forem.com/matyo91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/matyo91"/>
    <language>en</language>
    <item>
      <title>👨‍💻 Benchmarking Small Language Models in the Real World</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Tue, 21 Apr 2026 07:55:27 +0000</pubDate>
      <link>https://forem.com/matyo91/benchmarking-small-language-models-in-the-real-world-2l45</link>
      <guid>https://forem.com/matyo91/benchmarking-small-language-models-in-the-real-world-2l45</guid>
      <description>&lt;p&gt;On Saturday, April 18th, I participated in a hackathon that invites machine learning engineers, data engineers and researchers to Paris for an in-depth study of the evaluation of small language models (SLM).&lt;/p&gt;

&lt;p&gt;This hackathon, organized by &lt;a href="https://paris.aitinkerers.org/p/hackathon-benchmarking-small-language-models-in-the-real-world" rel="noopener noreferrer"&gt;AI Tinkerers Paris&lt;/a&gt;, addresses a very concrete problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;test the actual ability of language models to produce &lt;strong&gt;production-ready&lt;/strong&gt; executable code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The theme - &lt;em&gt;"Benchmarking Small Language Models in the Real World"&lt;/em&gt; - sets a clear framework: moving beyond impressive demos to confront models with real-world constraints (execution, performance, resources). &lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Objective
&lt;/h2&gt;

&lt;p&gt;The challenge is to automatically generate &lt;strong&gt;Polars&lt;/strong&gt; queries from natural language, with a strong requirement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;produce &lt;strong&gt;correct&lt;/strong&gt; code&lt;/li&gt;
&lt;li&gt;ensure that it is &lt;strong&gt;executable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Optimize &lt;strong&gt;execution time&lt;/strong&gt; and &lt;strong&gt;memory consumption&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scoring reflects this reality:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Score = N / (T × VRAM^0.1 × RAM^0.01)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 In other words: accuracy alone is not enough - &lt;strong&gt;system efficiency becomes a central constraint&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Technical Context
&lt;/h2&gt;

&lt;p&gt;Each team works in a standardized environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execution under Docker&lt;/li&gt;
&lt;li&gt;Use of &lt;strong&gt;Polars&lt;/strong&gt; for data processing&lt;/li&gt;
&lt;li&gt;GPU/memory constraints&lt;/li&gt;
&lt;li&gt;evaluation dataset provided&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to create "the best prompt", but to build a system capable of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;withstand real data&lt;/li&gt;
&lt;li&gt;produce robust code&lt;/li&gt;
&lt;li&gt;run an automated benchmark&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧩 Positioning
&lt;/h2&gt;

&lt;p&gt;This hackathon stands out because of its approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no marketing demo&lt;/li&gt;
&lt;li&gt;no "impressive but fragile" generation&lt;/li&gt;
&lt;li&gt;focus on &lt;strong&gt;what really works&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is an environment that directly exposes the current limitations of LLM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hallucinations&lt;/li&gt;
&lt;li&gt;syntax errors&lt;/li&gt;
&lt;li&gt;Misunderstanding of the data schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it forces you to build around it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompt structured engineering&lt;/li&gt;
&lt;li&gt;systematic validation&lt;/li&gt;
&lt;li&gt;fast iteration loop&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📊 Reading
&lt;/h2&gt;

&lt;p&gt;This is not a "creative" hackathon, but an &lt;strong&gt;engineering benchmark&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The final deliverable is not an idea, but:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a measurable, reproducible, and comparable system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🏗️ Day's Organization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Morning - framing and initialization
&lt;/h3&gt;

&lt;p&gt;The morning is dedicated to setting up the technical and organizational framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Team formation via the event portal &lt;/li&gt;
&lt;li&gt;Presentation of the problem by the organizers and mentors &lt;/li&gt;
&lt;li&gt;Clarification of expectations (generation of executable Polars code + scoring)&lt;/li&gt;
&lt;li&gt;Initial setup of the work environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;Darkwood&lt;/strong&gt; team is formed around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/matyo91" rel="noopener noreferrer"&gt;Mathieu Ledru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/vej333" rel="noopener noreferrer"&gt;Victor-eliejah Garnier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/mirza-andriamanamisoa-marotsaha-891926b1/" rel="noopener noreferrer"&gt;Mirza Marotsaha&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The objective of this phase is to &lt;strong&gt;reduce uncertainty&lt;/strong&gt; and align everyone on an executable pipeline from the very first hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Midday - Forced Break
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lunch provided on site&lt;/li&gt;
&lt;li&gt;informal exchanges between teams&lt;/li&gt;
&lt;li&gt;Consultation of the message center (general questions, clarifications from the jury)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Short phase, without real decoupling: the project remains in iteration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Afternoon - Implementation and Iterations
&lt;/h3&gt;

&lt;p&gt;The afternoon is entirely production-oriented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;implementation of the benchmark (&lt;code&gt;polars-bench&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;integration of the model via &lt;code&gt;ai-harness&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;experimentation on prompts (structure, format, constraints)&lt;/li&gt;
&lt;li&gt;Adjusting model behavior via dataset and prompt engineering&lt;/li&gt;
&lt;li&gt;progressive validation via actual execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The iterations focus on three areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hallucination reduction&lt;/strong&gt; (schema-aware prompting)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;improved executable code rate&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;score optimization (time / memory / accuracy)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The logic is not to add features, but to &lt;strong&gt;tighten the system around real constraints&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Benchmark Architecture
&lt;/h2&gt;

&lt;p&gt;The system relies on a clear separation of responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ai-harness&lt;/code&gt; → pattern orchestration layer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;polars-bench&lt;/code&gt; → execution and evaluation engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This breakdown allows us to isolate the generation (LLM) from the execution reality (runtime), which is precisely the objective of the benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Sponsors, Mentors &amp;amp; Organizers, Teams
&lt;/h2&gt;

&lt;p&gt;This hackathon is made possible thanks to an ecosystem of complementary players: sponsors, mentors and organizers, each playing a key role in the overall experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏢 Organizers
&lt;/h3&gt;

&lt;p&gt;The event is organized by the AI ​​Tinkerers Paris community, a collective active in experimenting with and sharing AI technologies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Official website: &lt;a href="https://paris.aitinkerers.org" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📅 Hackathon page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👥 Organizers: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/organizers" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/organizers&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Their positioning is clear: to promote concrete experimentation around AI models, with a focus on real engineering rather than demonstration.&lt;/p&gt;

&lt;h3&gt;
  
  
  💼 Sponsors
&lt;/h3&gt;

&lt;p&gt;Sponsors support the event by providing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical resources (GPU, infrastructure, tools)&lt;/li&gt;
&lt;li&gt;funding&lt;/li&gt;
&lt;li&gt;visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Their role is critical to enabling a realistic environment (compute constraints, Docker execution, etc.).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mistral&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: &lt;a href="https://www.linkedin.com/in/matthieu-dinot-022378222/" rel="noopener noreferrer"&gt;Matthieu Dinot&lt;/a&gt; — AI Scientist at Mistral&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Alpic&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: &lt;a href="https://www.linkedin.com/in/nikolayrodionov/" rel="noopener noreferrer"&gt;Nikolay Rodionov&lt;/a&gt; — COO at Alpic&lt;/li&gt;
&lt;li&gt;Other links:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/jeanroudy" rel="noopener noreferrer"&gt;X / Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rodincave" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Cloudfare&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: &lt;a href="https://www.linkedin.com/in/cyril-bouissou" rel="noopener noreferrer"&gt;Nans Cyril Bouissou&lt;/a&gt; — Account executive at Cloudfare&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Fold&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: &lt;a href="https://linkedin.com/in/raoufchebri" rel="noopener noreferrer"&gt;Raouf Chebri&lt;/a&gt; — Developer Relations Engineer at Replit&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Microsoft&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: &lt;a href="https://www.linkedin.com/in/jubichon/" rel="noopener noreferrer"&gt;Julien Bichon&lt;/a&gt; — Developer Experience | GTM Manager at Microsoft&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;ESGI&lt;/strong&gt; &lt;em&gt;(venue partner mentioned alongside sponsors)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sponsor / venue page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/sponsors" rel="noopener noreferrer"&gt;Hackathon Sponsors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Representative: Astrid Beaucourt — Communications Officer at ESGI&lt;/li&gt;
&lt;li&gt;School links:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/school/esgi/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/esgi" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧑‍🏫 Mentors
&lt;/h3&gt;

&lt;p&gt;Mentors support participants throughout the hackathon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assistance in structuring approaches&lt;/li&gt;
&lt;li&gt;Feedback on templates and prompts&lt;/li&gt;
&lt;li&gt;tips on performance and optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 They help avoid common dead ends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;over-optimization of the prompt&lt;/li&gt;
&lt;li&gt;lack of validation&lt;/li&gt;
&lt;li&gt;&lt;p&gt;errors in data interpretation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Arthur Mensch&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mentor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/mentors" rel="noopener noreferrer"&gt;Hackathon Mentors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Role: Co-founder and CEO of Mistral AI&lt;/li&gt;
&lt;li&gt;Public profile link: not visible in the provided data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Leo Arsenin&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mentor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/mentors" rel="noopener noreferrer"&gt;Hackathon Mentors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/leoarsenin" rel="noopener noreferrer"&gt;Léo Arsenin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Role: Solutions engineer at Cloudfare&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Matthieu Dinot&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mentor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/mentors" rel="noopener noreferrer"&gt;Hackathon Mentors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/matthieu-dinot-022378222/" rel="noopener noreferrer"&gt;Matthieu Dinot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Role: AI Scientist at Mistral&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Preetham Kaukuntla&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mentor page: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/mentors" rel="noopener noreferrer"&gt;Hackathon Mentors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/preetham-kaukuntla-a43841105" rel="noopener noreferrer"&gt;Preetham Kaukuntla&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Role: Staff Data Scientist at Glassdoor&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Mentors Message Board&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/chat?channel=hackathon_team_ht_gW9Xg0G3S44#hackathon_team_ht_gW9Xg0G3S44" rel="noopener noreferrer"&gt;Mentors Message Board&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  👥 Teams
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_qFVxlREukLQ"&gt;Darkwood&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;1st Place&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_qFVxlREukLQ"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_qFVxlREukLQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_qFVxlREukLQ"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_qFVxlREukLQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo video: &lt;a href="https://youtu.be/sUq5Z_jNtKc?is=3Omo4O1sErux6_ds" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_qFVxlREukLQ"&gt;Mathieu Ledru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_qFVxlREukLQ"&gt;Mirza Marotsaha&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_qFVxlREukLQ"&gt;Victor-eliejah GARNIER&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_-p8xvdGl-oA"&gt;bluebull&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Best Startup&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_-p8xvdGl-oA"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_-p8xvdGl-oA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_-p8xvdGl-oA"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_-p8xvdGl-oA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_-p8xvdGl-oA"&gt;Vasiliki Doropoulou&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_ub4tDzlrft0"&gt;Muon&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;10x Data Scientist&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_ub4tDzlrft0"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_ub4tDzlrft0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_ub4tDzlrft0"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_ub4tDzlrft0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_ub4tDzlrft0"&gt;Imane Momayiz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_y4_Yz6P5BZE"&gt;Polaris&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Finalist&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_y4_Yz6P5BZE"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_y4_Yz6P5BZE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_y4_Yz6P5BZE"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_y4_Yz6P5BZE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_y4_Yz6P5BZE"&gt;Hippolyte Dupont&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_y4_Yz6P5BZE"&gt;Ghaith ABDESSALEM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_y4_Yz6P5BZE"&gt;Jacques Dumora&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_njEtwEBAmUE"&gt;Training Expert&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Finalist&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_njEtwEBAmUE"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_njEtwEBAmUE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_njEtwEBAmUE"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_njEtwEBAmUE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_njEtwEBAmUE"&gt;Eva Useros Marugan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_njEtwEBAmUE"&gt;Paul-Louis Fouesnant&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_wRj-nEG24zE"&gt;CodeMind&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Submitted&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_wRj-nEG24zE"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_wRj-nEG24zE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE"&gt;Amelie Smith&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE"&gt;Damien Frechou&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE"&gt;Anis Kaci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_wRj-nEG24zE"&gt;Choutri Adel Djalil&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_RFBTGYYwbm4"&gt;Coffe is life&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Submitted&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_RFBTGYYwbm4"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_RFBTGYYwbm4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_RFBTGYYwbm4"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_RFBTGYYwbm4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_RFBTGYYwbm4"&gt;Pierre Lepagnol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_RFBTGYYwbm4"&gt;Filipp Trigub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_Gc4SneBV2D4"&gt;PiLLM&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status: &lt;strong&gt;Submitted&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Entry: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/entries/ht_Gc4SneBV2D4"&gt;/hackathons/h_sj1ca_J4Hdk/entries/ht_Gc4SneBV2D4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Team: &lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_Gc4SneBV2D4"&gt;/hackathons/h_sj1ca_J4Hdk/teams/ht_Gc4SneBV2D4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Members:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_Gc4SneBV2D4"&gt;Din Sokheng&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackathons/h_sj1ca_J4Hdk/teams/ht_Gc4SneBV2D4"&gt;Ahmed Abdelaziz Mokeddem&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔗 Useful Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🏠 Home: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👥 Teams: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/teams" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/teams&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📩 Message Center: &lt;a href="https://paris.aitinkerers.org/message_center?board_key=meetup_mu_eZJ5tCXlA2A" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/message_center?board_key=meetup_mu_eZJ5tCXlA2A&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🏆 Submissions: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/entries" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/entries&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📊 Results: &lt;a href="https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/results" rel="noopener noreferrer"&gt;https://paris.aitinkerers.org/hackathons/h_sj1ca_J4Hdk/results&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧱 Technical Stack
&lt;/h2&gt;

&lt;p&gt;The architecture is intentionally simple, but constrained by real-world conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; for execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polars&lt;/strong&gt; as a search engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quinn 2.5&lt;/strong&gt; as a generation model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; for the interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local sandbox (CPU)&lt;/strong&gt; with memory constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core of the system is an API that transforms a natural request into &lt;strong&gt;directly executable Polars code&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Execution Pipeline
&lt;/h2&gt;

&lt;p&gt;The benchmark requires a complete chain, without shortcuts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Query (NL)
    ↓
Prompt enrichi (schema + règles)
    ↓
LLM
    ↓
Code Polars généré
    ↓
Exécution réelle
    ↓
Validation
    ↓
Scoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 The model is not evaluated on what it "says", but on what its code &lt;strong&gt;actually produces&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Generation Strategy
&lt;/h2&gt;

&lt;p&gt;The key choice is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ train the model&lt;br&gt;
✅ to constrain one's behavior&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rather than heavy-handed fine-tuning, the system is based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;structured prompt&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;dataset of targeted examples&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Required Format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System:
- règles Polars
- contraintes strictes

User:
- schéma
- requête

Assistant:
- code uniquement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 The model learns an &lt;strong&gt;execution pattern&lt;/strong&gt;, not general knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗂️ Dataset
&lt;/h2&gt;

&lt;p&gt;The dataset is not massive, it is &lt;strong&gt;intentional&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15 to 500 examples&lt;/li&gt;
&lt;li&gt;focused on critical patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cutlery:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;selection&lt;/li&gt;
&lt;li&gt;filters&lt;/li&gt;
&lt;li&gt;aggregations&lt;/li&gt;
&lt;li&gt;joins&lt;/li&gt;
&lt;li&gt;window functions&lt;/li&gt;
&lt;li&gt;nulls&lt;/li&gt;
&lt;li&gt;edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Coverage is more important than volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Schema injection
&lt;/h2&gt;

&lt;p&gt;The model doesn't guess anything.&lt;br&gt;
The scheme is injected systematically:&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;"columns"&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="s2"&gt;"card_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mana_cost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"frequency"&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;Direct effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer hallucinations&lt;/li&gt;
&lt;li&gt;Valid queries on the first try&lt;/li&gt;
&lt;li&gt;strong dependence on the provided context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Without a diagram, the system collapses.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Inference Constraints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;~6GB model&lt;/li&gt;
&lt;li&gt;CPU only&lt;/li&gt;
&lt;li&gt;high latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consequence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every call counts&lt;/li&gt;
&lt;li&gt;Re-sorting is expensive&lt;/li&gt;
&lt;li&gt;The prompt must be precise from the outset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The cost of error is included in the score.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Validation &amp;amp; scoring
&lt;/h2&gt;

&lt;p&gt;The benchmark validates a &lt;strong&gt;complete behavior&lt;/strong&gt;, not a raw output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Levels
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Valid code&lt;/li&gt;
&lt;li&gt;Successful execution&lt;/li&gt;
&lt;li&gt;Correct result&lt;/li&gt;
&lt;li&gt;Acceptable performance&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Score
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Score = N / (T * VRAM^0.1 * RAM^0.01)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 We measure a constrained system, not an abstract model.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔁 Architectural choices
&lt;/h2&gt;

&lt;p&gt;Three options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fine-tuning → too heavy&lt;/li&gt;
&lt;li&gt;multi-models → too complex&lt;/li&gt;
&lt;li&gt;prompt + dataset → chosen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Decision: &lt;strong&gt;encode the behavior in the data&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Implementation
&lt;/h2&gt;

&lt;p&gt;The API exposes a simple stream:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;input:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request&lt;/li&gt;
&lt;li&gt;metadata&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Polars code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;builds the prompt&lt;/li&gt;
&lt;li&gt;calls the model&lt;/li&gt;
&lt;li&gt;returns the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Voluntary simplicity: the real difficulty lies elsewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Positioning
&lt;/h2&gt;

&lt;p&gt;The project is not presented as an LLM wrapper, but as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;a secure analytical copilot for tabular data&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;guided prompts&lt;/li&gt;
&lt;li&gt;structured context&lt;/li&gt;
&lt;li&gt;execution verified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The product is defined by its constraints, not by the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 System reading
&lt;/h2&gt;

&lt;p&gt;This benchmark shows one thing:&lt;/p&gt;

&lt;p&gt;The performance of a small model is a property of the system, not of the model alone.&lt;/p&gt;

&lt;p&gt;The real levers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structure of the prompt&lt;/li&gt;
&lt;li&gt;dataset&lt;/li&gt;
&lt;li&gt;Context injection&lt;/li&gt;
&lt;li&gt;runtime validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 We're going from an ML problem to an engineering problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Harness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;abstraction of models&lt;/li&gt;
&lt;li&gt;standardization of inputs/outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Executor
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;isolated execution&lt;/li&gt;
&lt;li&gt;error capture&lt;/li&gt;
&lt;li&gt;runtime metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scoring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;validity&lt;/li&gt;
&lt;li&gt;performance&lt;/li&gt;
&lt;li&gt;stability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📊 What is measured
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Execution&lt;/strong&gt; → Is it running?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correction&lt;/strong&gt; → Is this correct?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polars Quality&lt;/strong&gt; → correct use of the motor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; → actual cost&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍 Real-life case
&lt;/h2&gt;

&lt;p&gt;Input:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Find the top 10 most frequent cards with mana cost ≤ 3"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filter correct&lt;/li&gt;
&lt;li&gt;correct aggregation&lt;/li&gt;
&lt;li&gt;sorting + limit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;valid but incorrect code&lt;/li&gt;
&lt;li&gt;Python fallback&lt;/li&gt;
&lt;li&gt;silent errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The benchmark reveals the gap between &lt;strong&gt;generation&lt;/strong&gt; and &lt;strong&gt;execution&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Real stakes
&lt;/h2&gt;

&lt;p&gt;An LLM generates plausible code, not reliable code&lt;/p&gt;

&lt;p&gt;So, in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sandbox required&lt;/li&gt;
&lt;li&gt;systematic validation&lt;/li&gt;
&lt;li&gt;controlled retrievals&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Without this, the system is unstable by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Project Contribution
&lt;/h2&gt;

&lt;p&gt;This benchmark introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an end-to-end executable pipeline&lt;/li&gt;
&lt;li&gt;a multi-criteria assessment&lt;/li&gt;
&lt;li&gt;a reproducible approach&lt;/li&gt;
&lt;li&gt;a production-friendly environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rest :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mrzdevcore/ai-harness" rel="noopener noreferrer"&gt;&lt;code&gt;ai-harness&lt;/code&gt;&lt;/a&gt; → orchestration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mrzdevcore/polars-bench" rel="noopener noreferrer"&gt;&lt;code&gt;polars-bench&lt;/code&gt;&lt;/a&gt; → evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is no longer a model test, it's a &lt;strong&gt;complete system test&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  📹 Demo
&lt;/h2&gt;

&lt;p&gt;Submission video:&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Hackathon Deliverables
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Full benchmark code&lt;/li&gt;
&lt;li&gt;Test set&lt;/li&gt;
&lt;li&gt;Reproducible pipeline&lt;/li&gt;
&lt;li&gt;Comparative results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of a provided structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Nisseya/submission_example" rel="noopener noreferrer"&gt;submission_example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;main benchmark code&lt;/li&gt;
&lt;li&gt;datasets&lt;/li&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This hackathon is not intended to demonstrate that LLMs work.&lt;/p&gt;

&lt;p&gt;It shows &lt;strong&gt;where they break&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;A useful benchmark does not measure generation.&lt;br&gt;
It measures performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 Darkwood Perspective
&lt;/h2&gt;

&lt;p&gt;This type of benchmark fits directly into a broader vision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestration of AI pipelines&lt;/li&gt;
&lt;li&gt;systematic validation&lt;/li&gt;
&lt;li&gt;generation/execution separation&lt;/li&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is not a demo tool.&lt;br&gt;
It's a building block for constructing reliable systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/hackathon_ia_thinker_2026-04-18/resized_IMG_4563.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/hackathon_ia_thinker_2026-04-18/resized_IMG_4563.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/hackathon_ia_thinker_2026-04-18/resized_IMG_4564.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/hackathon_ia_thinker_2026-04-18/resized_IMG_4564.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🚀 Sundays Lab #3 - When AI becomes a collective playground</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 20 Apr 2026 12:15:35 +0000</pubDate>
      <link>https://forem.com/matyo91/sundays-lab-3-when-ai-becomes-a-collective-playground-bpl</link>
      <guid>https://forem.com/matyo91/sundays-lab-3-when-ai-becomes-a-collective-playground-bpl</guid>
      <description>&lt;p&gt;On &lt;strong&gt;Sunday, April 19, 2026&lt;/strong&gt;, at Hexa (eFounders) in Paris, a new edition of &lt;a href="https://luma.com/62yzcu08?tk=zddnOx" rel="noopener noreferrer"&gt;&lt;strong&gt;Sundays Lab&lt;/strong&gt;&lt;/a&gt; was held.&lt;br&gt;
A seemingly simple format: coworking, AI workshop, exchange session.&lt;/p&gt;

&lt;p&gt;But in practice:&lt;br&gt;
👉 a concrete demonstration of what &lt;strong&gt;the builder ecosystem will become in 2026&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ A paradigm shift: from conference to interactive system
&lt;/h2&gt;

&lt;p&gt;The first strong signal of the event is not technical.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;the format&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are no longer sure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;top-down talks&lt;/li&gt;
&lt;li&gt;“Inspiring” speakers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;real-time construction&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;an ongoing interaction**&lt;/li&gt;
&lt;li&gt;a system where &lt;strong&gt;the audience becomes a co-creator&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“We didn’t want a traditional workshop. We wanted everyone to participate.” &lt;/p&gt;

&lt;p&gt;Here's a section ready to integrate into your Darkwood article 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🧑‍🚀 Speakers &amp;amp; Participants - Projects and Weak Signals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  👤 Pato - AI &amp;amp; Automated Go-To-Market
&lt;/h3&gt;

&lt;p&gt;As the founder of &lt;strong&gt;Cluently&lt;/strong&gt;, he embodies the “builder + sales” profile.&lt;br&gt;
His presentation shows how AI can &lt;strong&gt;replace entire business functions&lt;/strong&gt; (prospecting, matching, CRM).&lt;/p&gt;

&lt;p&gt;👉 Project presented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agent for automated prospecting&lt;/li&gt;
&lt;li&gt;Intelligent matching between profiles / opportunities&lt;/li&gt;
&lt;li&gt;Build Society community app generated live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Key signal:&lt;/p&gt;

&lt;p&gt;The future of SaaS = &lt;strong&gt;agent + distribution&lt;/strong&gt;, not just product&lt;/p&gt;

&lt;h3&gt;
  
  
  👤 Jules - Growth &amp;amp; Creative AI
&lt;/h3&gt;

&lt;p&gt;Founder of &lt;strong&gt;Loops&lt;/strong&gt;, focused on performance marketing.&lt;/p&gt;

&lt;p&gt;👉 Project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaS for generating high-performing ads&lt;/li&gt;
&lt;li&gt;Focus on &lt;strong&gt;creativity as the main driver of growth&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Growth no longer comes from targeting&lt;/li&gt;
&lt;li&gt;but &lt;strong&gt;large-scale content creation via AI&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 Tom - Personal branding &amp;amp; distribution
&lt;/h3&gt;

&lt;p&gt;Content creator (philosophy + tech), rapid growth on Instagram.&lt;/p&gt;

&lt;p&gt;👉 Positioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build an audience before a product&lt;/li&gt;
&lt;li&gt;Transforming complex ideas into viral content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;p&gt;Distribution is becoming a stronger asset than tech.&lt;/p&gt;

&lt;h3&gt;
  
  
  👤 Lucas Lefner - Startup advisory &amp;amp; network
&lt;/h3&gt;

&lt;p&gt;Provides support to early-stage startups (strategy, sales, equity).&lt;/p&gt;

&lt;p&gt;👉 Model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;support in exchange for equity or mission&lt;/li&gt;
&lt;li&gt;creation of a business club (Startup Hunters)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Key insight:&lt;/p&gt;

&lt;p&gt;“90% of business is networking”&lt;/p&gt;

&lt;p&gt;👉 Signal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;return of &lt;strong&gt;network-driven business&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Importance of private circles / clubs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 Enzo - Iomaris
&lt;/h3&gt;

&lt;p&gt;Real estate startup (beta phase).&lt;/p&gt;

&lt;p&gt;👉 Product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Platform for managing a real estate project from start to finish&lt;/li&gt;
&lt;li&gt;Profitability analysis, taxation, market&lt;/li&gt;
&lt;li&gt;collaboration between individuals and professionals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Business model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free for individuals&lt;/li&gt;
&lt;li&gt;Monetization via professionals (leads)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extreme simplification of a complex domain via AI&lt;/li&gt;
&lt;li&gt;trend “vertically integrated business assistant”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 Eli - Gamified Education App
&lt;/h3&gt;

&lt;p&gt;Student (HEC), project focused on academic productivity.&lt;/p&gt;

&lt;p&gt;👉 Product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collaborative work app&lt;/li&gt;
&lt;li&gt;Strava-type logic applied to the study&lt;/li&gt;
&lt;li&gt;comparison between students / classes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gamification + social = strong engagement lever&lt;/li&gt;
&lt;li&gt;“public progress tracking” logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 Romain - Automated Pentest with AI
&lt;/h3&gt;

&lt;p&gt;Profile not an expert in cybersecurity.&lt;/p&gt;

&lt;p&gt;👉 Product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated penetration testing service via AI&lt;/li&gt;
&lt;li&gt;Use of scripts + LLM to detect vulnerabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one-off service (audit)&lt;/li&gt;
&lt;li&gt;no ongoing maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Key insight:&lt;/p&gt;

&lt;p&gt;AI makes it possible to create expert services without initial expertise.&lt;/p&gt;

&lt;p&gt;👉 Signal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explosion of &lt;strong&gt;AI-augmented agencies&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 Laurent (Startup Hunters) - Ecosystem &amp;amp; Support
&lt;/h3&gt;

&lt;p&gt;Supports startups and young entrepreneurs.&lt;/p&gt;

&lt;p&gt;👉 Activity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business structuring&lt;/li&gt;
&lt;li&gt;Connecting investors and founders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lack of operational support for early founders&lt;/li&gt;
&lt;li&gt;growing need for &lt;strong&gt;on-the-ground guidance&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👤 GEO Project (AI Search Optimization)
&lt;/h3&gt;

&lt;p&gt;E-commerce consultant / Advanced SEO.&lt;/p&gt;

&lt;p&gt;👉 Product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;optimization tool to appear in LLM responses&lt;/li&gt;
&lt;li&gt;alternative to traditional SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analysis of the sources used by AI&lt;/li&gt;
&lt;li&gt;Content optimization + ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Key insight:&lt;/p&gt;

&lt;p&gt;AI traffic will surpass traditional SEO&lt;/p&gt;

&lt;h3&gt;
  
  
  👤 Social Matching Project (anonymous)
&lt;/h3&gt;

&lt;p&gt;Next generation social network concept.&lt;/p&gt;

&lt;p&gt;👉 Product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weekly matching based on deep interests&lt;/li&gt;
&lt;li&gt;No profile, no swipe&lt;/li&gt;
&lt;li&gt;authentic interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Insight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reaction to the saturation of social networks&lt;/li&gt;
&lt;li&gt;back to &lt;strong&gt;qualitative interactions&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧭 Overall reading
&lt;/h2&gt;

&lt;p&gt;These profiles show a clear convergence:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. All projects use AI
&lt;/h3&gt;

&lt;p&gt;But at different levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automation (sales, penetration testing)&lt;/li&gt;
&lt;li&gt;product (ads, real estate)&lt;/li&gt;
&lt;li&gt;distribution (content, GEO)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The technical barrier disappears
&lt;/h3&gt;

&lt;p&gt;➡️ Everyone can build&lt;br&gt;
➡️ so the difference lies elsewhere&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The real weapons become:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;network&lt;/li&gt;
&lt;li&gt;distribution&lt;/li&gt;
&lt;li&gt;branding&lt;/li&gt;
&lt;li&gt;niche&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In concrete terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an app generated live&lt;/li&gt;
&lt;li&gt;decisions made via vote&lt;/li&gt;
&lt;li&gt;a product built in front of the audience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The event itself becomes a &lt;strong&gt;product prototype&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 AI is no longer a tool, it's a production interface
&lt;/h2&gt;

&lt;p&gt;The workshop highlighted a key point:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Software creation is now iterative, public, and assisted.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A concrete example observed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app scenario generation&lt;/li&gt;
&lt;li&gt;code generation with LLM (Claude)&lt;/li&gt;
&lt;li&gt;Automatic error correction&lt;/li&gt;
&lt;li&gt;near-immediate deployment (Cloudflare)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Claude generates the code, corrects his errors, and we build the app as we go.” &lt;/p&gt;

&lt;h3&gt;
  
  
  What it actually changes
&lt;/h3&gt;

&lt;p&gt;Before :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;design → dev → test → deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOW :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;intention → generation → feedback → correction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 The cycle becomes &lt;strong&gt;continuous and conversational&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The real issue: distribution &amp;gt; technology
&lt;/h2&gt;

&lt;p&gt;One point came up several times during the exchange session:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Technology is no longer the barrier to entry.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What remains difficult:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find customers&lt;/li&gt;
&lt;li&gt;distribute a product&lt;/li&gt;
&lt;li&gt;create an audience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Code is becoming commoditized. The real barrier is distribution.” &lt;/p&gt;

&lt;h3&gt;
  
  
  Direct consequence
&lt;/h3&gt;

&lt;p&gt;We observe a shift:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;Now&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Build a product&lt;/td&gt;
&lt;td&gt;Build an audience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optimize tech&lt;/td&gt;
&lt;td&gt;Optimize acquisition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Be a developer&lt;/td&gt;
&lt;td&gt;Be a full operator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  📈 Acquisition: Organized Chaos
&lt;/h2&gt;

&lt;p&gt;The discussions highlighted a reality:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;There is no longer a single dominant channel.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Canals mentioned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;LinkedIn (B2B, decision-makers)&lt;/li&gt;
&lt;li&gt;Instagram (creation + virality)&lt;/li&gt;
&lt;li&gt;Twitter/X (monitoring + opportunities)&lt;/li&gt;
&lt;li&gt;Email (still extremely effective)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Insight
&lt;/h3&gt;

&lt;p&gt;👉 Efficiency comes from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repetition&lt;/li&gt;
&lt;li&gt;multi-channel presence&lt;/li&gt;
&lt;li&gt;the transformation of content into multiple formats&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“A video → shorts → reels → LinkedIn post → newsletter” &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧩 The emergence of “hybrid builders”
&lt;/h2&gt;

&lt;p&gt;One profile keeps recurring:&lt;/p&gt;

&lt;p&gt;👉 people &lt;strong&gt;not technically expert&lt;/strong&gt;&lt;br&gt;
→ capable of creating products using AI&lt;/p&gt;

&lt;p&gt;A striking example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;creation of an automated penetration testing service&lt;/li&gt;
&lt;li&gt;without advanced cybersecurity expertise&lt;/li&gt;
&lt;li&gt;based on tool orchestration + LLM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“I don’t have strong technical skills, but it works.” &lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The underlying problem: cognitive overload
&lt;/h2&gt;

&lt;p&gt;Everyone shares the same feeling:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;AI is going too fast&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Symptoms :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;permanent FOMO&lt;/li&gt;
&lt;li&gt;too many tools&lt;/li&gt;
&lt;li&gt;too many new things&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observed response:&lt;/p&gt;

&lt;p&gt;👉 Return to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task structuring (SOP)&lt;/li&gt;
&lt;li&gt;simplification&lt;/li&gt;
&lt;li&gt;focus&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Write down your tasks one by one, then see what AI can optimize.” &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧬 AI amplifies… but does not replace
&lt;/h2&gt;

&lt;p&gt;A central question was raised:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Will AI kill products?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Overall response from the group:&lt;/p&gt;

&lt;p&gt;❌ No&lt;br&gt;
✅ It filters&lt;/p&gt;

&lt;h3&gt;
  
  
  What disappears
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;low-quality products&lt;/li&gt;
&lt;li&gt;SaaS without distribution&lt;/li&gt;
&lt;li&gt;worthless clones&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What remains
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;branding&lt;/li&gt;
&lt;li&gt;network&lt;/li&gt;
&lt;li&gt;human relationship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“AI amplifies both the good and the bad.” &lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Towards a new layer: GEO (AI Search)
&lt;/h2&gt;

&lt;p&gt;An advanced topic has emerged:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;GEO (Generative Engine Optimization)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Objective :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;appear in LLM responses (ChatGPT, etc.)&lt;/li&gt;
&lt;li&gt;not just in Google&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Figures mentioned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;18x growth in AI traffic&lt;/li&gt;
&lt;li&gt;4x conversion on this traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Users coming from ChatGPT convert 4x more.” &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 This is probably the equivalent of SEO… AI version.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 The heart of the model: connecting people
&lt;/h2&gt;

&lt;p&gt;The product built during the event is revealing:&lt;/p&gt;

&lt;p&gt;👉 a matching app for participants&lt;/p&gt;

&lt;p&gt;Aim :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect problems ↔ solutions&lt;/li&gt;
&lt;li&gt;create real synergies&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Matching problems with solutions.” &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧭 Darkwood Reading
&lt;/h2&gt;

&lt;p&gt;This meetup confirms several major trends:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The technical stack becomes secondary
&lt;/h3&gt;

&lt;p&gt;Symfony, Node, etc. → important&lt;br&gt;
But more differentiating on its own&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Orchestration becomes key
&lt;/h3&gt;

&lt;p&gt;What you do with Flow → totally aligned&lt;/p&gt;

&lt;p&gt;👉 Connect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data&lt;/li&gt;
&lt;li&gt;agents&lt;/li&gt;
&lt;li&gt;workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. The product = system + distribution
&lt;/h3&gt;

&lt;p&gt;Not just code&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The future is hybrid
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AI → execution&lt;/li&gt;
&lt;li&gt;human → direction&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;Sundays Lab #3 is not a meetup.&lt;/strong&gt;&lt;br&gt;
This is a prototype of what the tech ecosystem is becoming.&lt;/p&gt;

&lt;p&gt;👉 A space where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on build live&lt;/li&gt;
&lt;li&gt;we learn by doing&lt;/li&gt;
&lt;li&gt;we connect in real time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;👉 where the real skill is no longer coding&lt;br&gt;
but to &lt;strong&gt;transform an intention into a functional system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4568.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4568.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4569.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4569.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4590.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4590.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4583.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4583.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4582.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4582.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="/blog/images/articles/sundays-lab-3/resized_IMG_4584.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="/blog/images/articles/sundays-lab-3/resized_IMG_4584.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>⚙️ Message-oriented vs. Data-oriented orchestration - from data to knowledge</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 17 Apr 2026 15:37:26 +0000</pubDate>
      <link>https://forem.com/matyo91/message-oriented-vs-data-oriented-orchestration-from-data-to-knowledge-1pmd</link>
      <guid>https://forem.com/matyo91/message-oriented-vs-data-oriented-orchestration-from-data-to-knowledge-1pmd</guid>
      <description>&lt;p&gt;For intellectual property reasons, the subject chosen for the application of this article will not be the one discussed, although it is closely related. For any further information, please contact &lt;a href="https://www.linkedin.com/in/omer-lakraa" rel="noopener noreferrer"&gt;Omer&lt;/a&gt; who will be happy to answer, and apologize for any potential inconvenience.&lt;/p&gt;

&lt;p&gt;In this article, we explore two fundamental approaches to software orchestration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Message-Oriented Orchestration&lt;/strong&gt;: via &lt;a href="https://symfony.com/doc/current/messenger.html" rel="noopener noreferrer"&gt;Symfony Messenger&lt;/a&gt; synchronous respectively asynchronous&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data-Oriented Orchestration&lt;/strong&gt;: via &lt;a href="https://navi.darkwood.com" rel="noopener noreferrer"&gt;Navi&lt;/a&gt; for synchronous and &lt;a href="https://flow.darkwood.com" rel="noopener noreferrer"&gt;Flow&lt;/a&gt; for asynchronous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The case study is based on a classic but structuring problem: &lt;strong&gt;text mining applied to a set of Git repositories&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
For the practical demonstration, I will take the EIT tutorial from 2007/2008 carried out at the time on classification with &lt;a href="https://www.linkedin.com/in/matthieu-beyou-9a425a32/" rel="noopener noreferrer"&gt;Matthieu Beyou&lt;/a&gt; during computer science class tutorials.&lt;br&gt;&lt;br&gt;
For the data, we use those of &lt;a href="https://www.linkedin.com/in/omer-lakraa" rel="noopener noreferrer"&gt;Omer&lt;/a&gt; (former work colleague) available on his site &lt;a href="https://git.arkalo.ovh" rel="noopener noreferrer"&gt;https://git.arkalo.ovh&lt;/a&gt; (via the api).&lt;/p&gt;

&lt;p&gt;The goal is not to produce the best machine learning model, but to understand &lt;strong&gt;how the form of orchestration influences the complexity, readability, and scalability of the system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The problem: transforming repositories into usable knowledge&lt;/p&gt;

&lt;p&gt;The dataset consists of a list of Git repositories defined in a &lt;code&gt;repos.json&lt;/code&gt; file, the data of the directories listed on &lt;a href="https://git.arkalo.ovh/explore/repos" rel="noopener noreferrer"&gt;https://git.arkalo.ovh/explore/repos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For your information, you can extract the information using the Composio connector for &lt;a href="https://composio.dev/toolkits/gitea" rel="noopener noreferrer"&gt;https://composio.dev/toolkits/gitea&lt;/a&gt;. Refer to my previous article for the implementation: &lt;a href="https://blog.darkwood.com/fr/article/relacher-les-connecteurs-des-outils-au-langage" rel="noopener noreferrer"&gt;https://blog.darkwood.com/fr/article/relacher-les-connecteurs-des-outils-au-langage&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each deposit becomes a &lt;strong&gt;canonical document&lt;/strong&gt; constructed from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repository name&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;README&lt;/li&gt;
&lt;li&gt;metadata (owner, topics…)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This document is then transformed via a classic text mining pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pretreatment (cleaning, tokenization)&lt;/li&gt;
&lt;li&gt;Feature Extraction&lt;/li&gt;
&lt;li&gt;TF-IDF Weighting&lt;/li&gt;
&lt;li&gt;Similarity between documents&lt;/li&gt;
&lt;li&gt;Classification / clustering&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pipeline is directly inspired by historical approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TF-IDF: &lt;code&gt;weight = tf * log(N / df)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cosine similarity between documents&lt;/li&gt;
&lt;li&gt;Supervised Naive Bayes Classification&lt;/li&gt;
&lt;li&gt;Unsupervised k-means clustering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What interests us here is not the algorithm, but &lt;strong&gt;the way to orchestrate it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note that if you are fond of documentation, you can refer to the Resources section at the bottom of the article which lists a number of topics concerning data mining applied in computer science.&lt;/p&gt;
&lt;h2&gt;
  
  
  Business pipeline (independent of orchestration)
&lt;/h2&gt;

&lt;p&gt;First and foremost, the core business needs to be isolated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repository → Document → Tokens → Features → TF-IDF → Similarity → Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pipeline represents a &lt;strong&gt;data transformation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;takes a piece of data&lt;/li&gt;
&lt;li&gt;produces new data&lt;/li&gt;
&lt;li&gt;without strong dependence on an external context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is precisely where the two approaches diverge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach 1 Message-Oriented - Orchestration via Symfony Messenger
&lt;/h2&gt;

&lt;p&gt;In the Message-Oriented implementation, the pipeline is not expressed as a continuous data transformation.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;encapsulated in a message&lt;/strong&gt;, then executed via the Symfony bus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Execution Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command → Message Bus → Handler → PipelineService → Stages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In concrete terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a CLI command triggers the execution&lt;/li&gt;
&lt;li&gt;A message is sent&lt;/li&gt;
&lt;li&gt;a handler takes care of the execution&lt;/li&gt;
&lt;li&gt;the core business remains centralized in a shared service
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RunMessengerPipelineMessage
→ RunMessengerPipelineHandler
→ PipelineService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Separation of responsibilities
&lt;/h2&gt;

&lt;p&gt;This implementation adheres to a key project constraint:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The core business is strictly shared between the two approaches&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Messenger contains &lt;strong&gt;no business logic&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;he only orchestrates the execution&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Actual Pipeline Executed
&lt;/h2&gt;

&lt;p&gt;The handler triggers a deterministic pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. ingest
2. preprocess
3. feature build
4. classification
5. clustering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step is executed in a common application service (&lt;code&gt;PipelineService&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Concepts introduced by Messenger
&lt;/h2&gt;

&lt;p&gt;The orchestration explicitly introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a message class&lt;/li&gt;
&lt;li&gt;a dedicated handler&lt;/li&gt;
&lt;li&gt;a dependence on the bus&lt;/li&gt;
&lt;li&gt;a dispatch layer
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command → Message → Handler → Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These elements are &lt;strong&gt;specific to Messenger&lt;/strong&gt; and do not exist in the data-oriented model&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability and debugging
&lt;/h2&gt;

&lt;p&gt;Messenger offers a natural debugging model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;message inspection&lt;/li&gt;
&lt;li&gt;middleware&lt;/li&gt;
&lt;li&gt;bus logging&lt;/li&gt;
&lt;li&gt;Extensibility towards async / queue
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Debug = niveau message + middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nature of the overhead
&lt;/h2&gt;

&lt;p&gt;In this MVP, the overhead is conceptually measurable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;introduction of an artificial message&lt;/li&gt;
&lt;li&gt;Indirection via handler&lt;/li&gt;
&lt;li&gt;the need to structure the execution around the bus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this overhead is &lt;strong&gt;located in the orchestration adapter&lt;/strong&gt;, not in the hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This approach transforms the pipeline into:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a &lt;strong&gt;distributed work unit&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She favors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony standardization&lt;/li&gt;
&lt;li&gt;extensibility towards async&lt;/li&gt;
&lt;li&gt;integration with the ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the cost of an additional layer of indirection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conceptual Example
&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;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ComputeTfIdfMessage&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;DocumentId&lt;/span&gt; &lt;span class="nv"&gt;$id&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="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ComputeTfIdfHandler&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;ComputeTfIdfMessage&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tfidf&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dispatch&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;ComputeSimilarityMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$vector&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;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;strong decoupling&lt;/li&gt;
&lt;li&gt;resilience (retry, queue)&lt;/li&gt;
&lt;li&gt;native parallelization&lt;/li&gt;
&lt;li&gt;Symfony standard&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Structural Limitations
&lt;/h3&gt;

&lt;p&gt;The problem quickly becomes apparent:&lt;/p&gt;

&lt;p&gt;➡️ &lt;strong&gt;the message becomes an artificial envelope&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;IDs&lt;/li&gt;
&lt;li&gt;persistent states&lt;/li&gt;
&lt;li&gt;indirect transitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data → transformation → data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;the boilerplate&lt;/li&gt;
&lt;li&gt;implicit dependencies&lt;/li&gt;
&lt;li&gt;a loss of overall readability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Approach 2 Data-Oriented - Orchestration via Navi (synchronous) and Flow (asynchronous)
&lt;/h2&gt;

&lt;p&gt;In the Data-Oriented implementation, the pipeline is expressed as an &lt;strong&gt;ordered sequence of actions applied to a context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There is no message.&lt;/p&gt;

&lt;p&gt;There is no dispatch.&lt;/p&gt;

&lt;p&gt;There is only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a piece of data&lt;/li&gt;
&lt;li&gt;a context&lt;/li&gt;
&lt;li&gt;a sequential transformation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Execution Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command → WorkflowRunner → Actions → PipelineService → Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In concrete terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a command triggers a workflow&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;WorkflowRunner&lt;/code&gt; executes a list of actions&lt;/li&gt;
&lt;li&gt;each action transforms a &lt;code&gt;Context&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The business services are identical to Messenger
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WorkflowRunner
→ PipelineStageAction[]
→ Context
→ PipelineService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pipeline Structure
&lt;/h2&gt;

&lt;p&gt;The pipeline is explicitly defined as 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;[IngestAction,
 PreprocessAction,
 FeatureBuildAction,
 ClassificationAction,
 ClusteringAction]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;takes a &lt;code&gt;Context&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;applies a transformation&lt;/li&gt;
&lt;li&gt;returns a new &lt;code&gt;Context&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nature of the Context
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Context&lt;/code&gt; becomes the central object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it contains the pipeline status&lt;/li&gt;
&lt;li&gt;it evolves at each stage&lt;/li&gt;
&lt;li&gt;it is inspectable
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context₀ → Context₁ → Context₂ → ... → Contextₙ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Concepts introduced by Flow
&lt;/h2&gt;

&lt;p&gt;This approach introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explicit actions&lt;/li&gt;
&lt;li&gt;a runner&lt;/li&gt;
&lt;li&gt;an evolving context
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data → Action → Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike Messenger:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no message&lt;/li&gt;
&lt;li&gt;no handler&lt;/li&gt;
&lt;li&gt;no bus&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Observability and debugging
&lt;/h2&gt;

&lt;p&gt;The debugging process changes completely in nature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Debug = suite d’actions + snapshots de contexte
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visible execution order&lt;/li&gt;
&lt;li&gt;inspectable intermediate state&lt;/li&gt;
&lt;li&gt;deterministic pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nature of readability
&lt;/h2&gt;

&lt;p&gt;The pipeline can be directly read as a stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ingest → preprocess → features → classification → clustering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without structural transformation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structural Overhead
&lt;/h2&gt;

&lt;p&gt;The cost introduced is different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;need for a Context&lt;/li&gt;
&lt;li&gt;abstraction via actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no envelope&lt;/li&gt;
&lt;li&gt;no bus detours&lt;/li&gt;
&lt;li&gt;no break in the data flow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This approach transforms the pipeline into:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a &lt;strong&gt;series of data transformations&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She favors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;immediate readability&lt;/li&gt;
&lt;li&gt;direct transformation of data&lt;/li&gt;
&lt;li&gt;absence of envelope&lt;/li&gt;
&lt;li&gt;deterministic pipeline&lt;/li&gt;
&lt;li&gt;ease of testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Boundaries
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;less suitable for complex distributed systems&lt;/li&gt;
&lt;li&gt;requires strict discipline regarding the purity of the transformations&lt;/li&gt;
&lt;li&gt;Tooling less standard than Messenger&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Direct Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Message-Oriented&lt;/th&gt;
&lt;th&gt;Data-Oriented&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mental model&lt;/td&gt;
&lt;td&gt;Events / Messages&lt;/td&gt;
&lt;td&gt;Data streams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Readability&lt;/td&gt;
&lt;td&gt;fragmented&lt;/td&gt;
&lt;td&gt;linear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overhead&lt;/td&gt;
&lt;td&gt;high (messages, handlers)&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;excellent&lt;/td&gt;
&lt;td&gt;depends on the design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debug&lt;/td&gt;
&lt;td&gt;indirect&lt;/td&gt;
&lt;td&gt;direct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business coupling&lt;/td&gt;
&lt;td&gt;weak but diffuse&lt;/td&gt;
&lt;td&gt;strong but explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Appearance&lt;/th&gt;
&lt;th&gt;Messenger&lt;/th&gt;
&lt;th&gt;NaviFlow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Central unit&lt;/td&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;Bus + Handler&lt;/td&gt;
&lt;td&gt;Runner + Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flow&lt;/td&gt;
&lt;td&gt;indirect&lt;/td&gt;
&lt;td&gt;direct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debug&lt;/td&gt;
&lt;td&gt;message-centric&lt;/td&gt;
&lt;td&gt;data-centric&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overhead&lt;/td&gt;
&lt;td&gt;message + handler&lt;/td&gt;
&lt;td&gt;action + context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline&lt;/td&gt;
&lt;td&gt;encapsulated&lt;/td&gt;
&lt;td&gt;explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key point: the illusion of complexity
&lt;/h2&gt;

&lt;p&gt;In the case of text mining, each step is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pure&lt;/li&gt;
&lt;li&gt;determinist&lt;/li&gt;
&lt;li&gt;functional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TF-IDF → simple mathematical formula&lt;/li&gt;
&lt;li&gt;Similarity cosine → normalized dot product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is &lt;strong&gt;no natural need for messages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The introduction of Messenger is therefore an &lt;strong&gt;architectural decision&lt;/strong&gt;, not a business necessity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Insight
&lt;/h2&gt;

&lt;p&gt;Message-oriented transforms data into events.&lt;br&gt;&lt;br&gt;
Data-oriented technology transforms data into data.**&lt;/p&gt;

&lt;p&gt;In a system like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message-Oriented adds a layer&lt;/li&gt;
&lt;li&gt;Data-Oriented reveals the model&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implications for Symfony
&lt;/h2&gt;

&lt;p&gt;Symfony is evolving towards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;async&lt;/li&gt;
&lt;li&gt;workers&lt;/li&gt;
&lt;li&gt;sidekicks (FrankenPHP)&lt;/li&gt;
&lt;li&gt;distributed orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this raises a fundamental question:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Does everything have to be orchestrated via messages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer depends on the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use each approach
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Message-Oriented
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;distributed workflows&lt;/li&gt;
&lt;li&gt;long tasks&lt;/li&gt;
&lt;li&gt;resilient systems&lt;/li&gt;
&lt;li&gt;industry events&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data-Oriented
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;analytical pipelines&lt;/li&gt;
&lt;li&gt;data transformations&lt;/li&gt;
&lt;li&gt;deterministic systems&lt;/li&gt;
&lt;li&gt;intensive calculations&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The project's source code is free and can be viewed here: &lt;a href="https://github.com/matyo91/omer-quotes" rel="noopener noreferrer"&gt;https://github.com/matyo91/omer-quotes&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This project demonstrates one simple thing:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Orchestration is not neutral&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two functionally identical implementations can produce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;radically different systems&lt;/li&gt;
&lt;li&gt;opposing cognitive costs&lt;/li&gt;
&lt;li&gt;divergent evolutionary capacities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the case of text mining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message-Oriented makes things more complex&lt;/li&gt;
&lt;li&gt;Data-Oriented clarifie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Symfony Messenger orchestrates a pipeline as a unit of work.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Darkwood Flow orchestrates a pipeline as a data transformation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;The next step in the project is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extend the pipeline (clustering, classification)&lt;/li&gt;
&lt;li&gt;to integrate more advanced models&lt;/li&gt;
&lt;li&gt;expose an API&lt;/li&gt;
&lt;li&gt;compare actual performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most importantly:&lt;/p&gt;

&lt;p&gt;👉 continue to question the form of the orchestration.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Thank you for writing the article
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Omer's git repository for data and inspiration: &lt;a href="https://git.arkalo.ovh" rel="noopener noreferrer"&gt;https://git.arkalo.ovh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Leverage Messenger to Improve Your Architecture - Tugdual Saunier for the article outline: &lt;a href="https://speakerdeck.com/tucksaun/tirez-profit-de-messenger-pour-ameliorer-votre-architecture" rel="noopener noreferrer"&gt;https://speakerdeck.com/tucksaun/tirez-profit-de-messenger-pour-ameliorer-votre-architecture&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Polytech Paris Sud (formerly IFIPS) 2008: Information Extraction from Texts Project - Document Classification by François Yvon and Alexandre Allauzen, carried out as a tutorial during the 2007/2008 academic year using the Perl language with Matthieu Beyou &lt;a href="https://www.linkedin.com/in/matthieu-beyou-9a425a32/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/matthieu-beyou-9a425a32/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples from friends on EIT topics and mathematical models applied to AI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Claude just changed sales calls forever! (free skill) - Alexandra Spalato | AI Automation: &lt;a href="https://www.youtube.com/watch?v=FuVIGGWwYKY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=FuVIGGWwYKY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demystifying AI: A practical guide for PHP developers - Iana IATSUN - PHP Forum 2024: &lt;a href="https://www.youtube.com/watch?v=u-yrK_-%5C_p9g" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=u-yrK_-\_p9g&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Embeddings in PHP: Symfony AI in practice: &lt;a href="https://speakerdeck.com/lyrixx/embeddings-symfony-ai-en-pratique" rel="noopener noreferrer"&gt;https://speakerdeck.com/lyrixx/embeddings-symfony-ai-en-pratique&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Stack Overflow tags - automatic prediction using machine learning algorithms - Marco Berta: &lt;a href="https://www.youtube.com/watch?v=fFKXFDDjEJU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=fFKXFDDjEJU&lt;/a&gt;
Help! I'm being asked to use AI! - Drupal Camp Grenoble 2026 - Alexandre Balmes: &lt;a href="https://speakerdeck.com/pocky/au-secours-on-me-demande-dutiliser-de-lia-drupal-camp-grenoble-2026" rel="noopener noreferrer"&gt;https://speakerdeck.com/pocky/au-secours-on-me-demande-dutiliser-de-lia-drupal-camp-grenoble-2026&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DeepMind's New AI Just Changed Science Forever - Two Minute Papers: &lt;a href="https://www.youtube.com/watch?v=Io_GqmbNBbY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Io_GqmbNBbY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Langflow Models Are Smart. Data Is Everything. Building Context-Rich AI Systems with Unstructured: &lt;a href="https://www.youtube.com/watch?v=fNLUv6Pvc6w" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=fNLUv6Pvc6w&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I am a legend: hacking hearthstone with machine learning - Elie Bursztein, Celine Bursztein: &lt;a href="https://elie.net/talk/i-am-a-legend" rel="noopener noreferrer"&gt;https://elie.net/talk/i-am-a-legend&lt;/a&gt;
Tell me something about myself that I don't yet know by Nathalie | A Voice That Carries: &lt;a href="https://x.com/Bonzai_Star/status/2031432381471797589" rel="noopener noreferrer"&gt;https://x.com/Bonzai_Star/status/2031432381471797589&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Future of AI as Seen by Yann LeCun
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nobody realizes what Yann LeCun has just created - Grand Angle Nova: &lt;a href="https://www.youtube.com/watch?v=P-wAr687qxg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=P-wAr687qxg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For those who are curious: Inaugural lecture by Yann LeCun - Deep Learning and Beyond: The New Challenges of AI - École nationale des ponts et chaussées: &lt;a href="https://www.youtube.com/watch?v=Z208NMP7_-0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Z208NMP7_-0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;What is knowledge made of? From Arthur Sarrazin &lt;a href="https://www.linkedin.com/in/arthursarazin" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/arthursarazin&lt;/a&gt; in &lt;a href="https://srzarthur.substack.com/p/what-is-knowledge-made-of" rel="noopener noreferrer"&gt;https://srzarthur.substack.com/p/what-is-knowledge-made-of&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>data</category>
      <category>distributedsystems</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>🤩 Unleach connectors - From Tools to Language</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Tue, 14 Apr 2026 07:17:40 +0000</pubDate>
      <link>https://forem.com/matyo91/unleach-connectors-from-tools-to-language-3lab</link>
      <guid>https://forem.com/matyo91/unleach-connectors-from-tools-to-language-3lab</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Automation has reached a paradox.&lt;/p&gt;

&lt;p&gt;We have never had so many tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;connectors&lt;/li&gt;
&lt;li&gt;workflows&lt;/li&gt;
&lt;li&gt;orchestration engines&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet, something fundamental is still missing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We don’t have a language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article revisits a previous experiment around Composio and MCP, and introduces a new direction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Automation should not be a workflow. It should be a language.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Revisiting the First Approach
&lt;/h2&gt;

&lt;p&gt;A year ago, an implementation was proposed to automate Gmail and Google Calendar using PHP agents, MCP, and Composio.&lt;/p&gt;

&lt;p&gt;The system relied on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool exposure via MCP&lt;/li&gt;
&lt;li&gt;connector orchestration&lt;/li&gt;
&lt;li&gt;agent-driven execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While functional, this approach had structural limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tight coupling to specific providers (Composio)&lt;/li&gt;
&lt;li&gt;workflow-centric design&lt;/li&gt;
&lt;li&gt;lack of composability&lt;/li&gt;
&lt;li&gt;no abstraction of intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This led to the archival of the original project:&lt;br&gt;
→ &lt;code&gt;composio-mcp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The problem was not the tools.&lt;/p&gt;

&lt;p&gt;The problem was the model.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Limits of Connectors
&lt;/h2&gt;

&lt;p&gt;Modern automation platforms provide access to hundreds of integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Composio&lt;/li&gt;
&lt;li&gt;Symfony Mate&lt;/li&gt;
&lt;li&gt;Kestra&lt;/li&gt;
&lt;li&gt;n8n&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each exposes capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send email&lt;/li&gt;
&lt;li&gt;fetch data&lt;/li&gt;
&lt;li&gt;trigger workflows&lt;/li&gt;
&lt;li&gt;call APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, these systems share a common limitation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They define &lt;strong&gt;how to connect&lt;/strong&gt;, not &lt;strong&gt;how to compute&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They operate as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pipelines&lt;/li&gt;
&lt;li&gt;graphs&lt;/li&gt;
&lt;li&gt;sequences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But not as a formal system.&lt;/p&gt;
&lt;h2&gt;
  
  
  Back to First Principles
&lt;/h2&gt;

&lt;p&gt;To redefine automation, we revisit two foundational models:&lt;/p&gt;
&lt;h3&gt;
  
  
  Church - The Language
&lt;/h3&gt;

&lt;p&gt;Lambda calculus defines computation as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function abstraction&lt;/li&gt;
&lt;li&gt;function application&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λx.x + 1
(λx.x + 1)(5) = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functions are first-class&lt;/li&gt;
&lt;li&gt;no mutable state&lt;/li&gt;
&lt;li&gt;computation = evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Turing - The Execution
&lt;/h3&gt;

&lt;p&gt;The Turing machine defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how computation is executed&lt;/li&gt;
&lt;li&gt;how state evolves&lt;/li&gt;
&lt;li&gt;how instructions are processed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Equivalence
&lt;/h3&gt;

&lt;p&gt;The Church–Turing thesis states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any computation expressed as a Turing machine can be expressed in lambda calculus.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A New Model for Automation
&lt;/h2&gt;

&lt;p&gt;Applying this equivalence:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&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;Lambda&lt;/td&gt;
&lt;td&gt;Language (intent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flow&lt;/td&gt;
&lt;td&gt;Execution (runtime)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connectors&lt;/td&gt;
&lt;td&gt;External primitives&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This leads to a new architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent → Lambda → Execution → Connector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connect Flow
&lt;/h2&gt;

&lt;p&gt;A new system, &lt;strong&gt;connect-flow&lt;/strong&gt;, implements this model.&lt;/p&gt;

&lt;p&gt;It introduces three core domains:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. LambdaCapability
&lt;/h3&gt;

&lt;p&gt;Represents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a computation&lt;/li&gt;
&lt;li&gt;a composable expression&lt;/li&gt;
&lt;li&gt;a formal structure&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λfetchemails.λuserId.fetchemails(userId)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Execution (Flow)
&lt;/h3&gt;

&lt;p&gt;Execution is delegated to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an orchestration engine&lt;/li&gt;
&lt;li&gt;supporting async and parallel computation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flow acts as the &lt;strong&gt;Turing machine&lt;/strong&gt; of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. LanguageCapability
&lt;/h3&gt;

&lt;p&gt;A higher-level abstraction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transforms natural language into lambda expressions&lt;/li&gt;
&lt;li&gt;uses a local LLM (Ollama + Mistral)&lt;/li&gt;
&lt;li&gt;preserves privacy (RGPD-compliant)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From Tools to Primitives
&lt;/h2&gt;

&lt;p&gt;In this model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Composio&lt;/li&gt;
&lt;li&gt;Symfony Mate&lt;/li&gt;
&lt;li&gt;n8n&lt;/li&gt;
&lt;li&gt;Kestra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are no longer central systems.&lt;/p&gt;

&lt;p&gt;They become:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;execution backends&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each tool becomes a primitive callable within lambda.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lambda Execution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/console connect-flow:lambda:run &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;"λfetchemails.λuserId.fetchemails(userId)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="s2"&gt;"[5]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;a function taking &lt;code&gt;fetchemails&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;then &lt;code&gt;userId&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;applying &lt;code&gt;fetchemails(userId)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Natural Language → Lambda
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/console &lt;span class="nt"&gt;-vvv&lt;/span&gt; connect-flow:language:to-lambda &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;"fetch emails you have the tool 'fetchemails'"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λfetchemails.fetchemails()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Traditional automation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Workflow → Tools → Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent → Lambda → Flow → Connector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Differences
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional&lt;/th&gt;
&lt;th&gt;Lambda-based&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Static workflows&lt;/td&gt;
&lt;td&gt;Dynamic composition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool-driven&lt;/td&gt;
&lt;td&gt;Language-driven&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provider-dependent&lt;/td&gt;
&lt;td&gt;Provider-agnostic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard to scale&lt;/td&gt;
&lt;td&gt;Composable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Extending the Language
&lt;/h2&gt;

&lt;p&gt;Future iterations will introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data mappers&lt;/li&gt;
&lt;li&gt;conditional logic&lt;/li&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;li&gt;HTTP primitives&lt;/li&gt;
&lt;li&gt;process execution&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;fetch_emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;filter_important&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;send_email&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Relationship with Functional Programming
&lt;/h2&gt;

&lt;p&gt;This approach builds upon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lambda calculus&lt;/li&gt;
&lt;li&gt;combinatory logic&lt;/li&gt;
&lt;li&gt;functional composition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As previously explored in:&lt;/p&gt;

&lt;p&gt;→ Lambda interpreter in PHP&lt;br&gt;
→ Y combinator implementations&lt;br&gt;
→ Flow execution model&lt;/p&gt;

&lt;h2&gt;
  
  
  Toward a Universal Execution Layer
&lt;/h2&gt;

&lt;p&gt;This architecture suggests a new category of systems:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Capability Composition Engines&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;connectors are interchangeable&lt;/li&gt;
&lt;li&gt;execution is abstracted&lt;/li&gt;
&lt;li&gt;intent is formalized&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Projet sources
&lt;/h2&gt;

&lt;p&gt;You can find sources of the project here : &lt;a href="https://github.com/matyo91/connect-flow" rel="noopener noreferrer"&gt;https://github.com/matyo91/connect-flow&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Automation has evolved from scripts to workflows.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;From workflows to language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda (Church)&lt;/li&gt;
&lt;li&gt;Flow (Turing)&lt;/li&gt;
&lt;li&gt;Connectors (primitives)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we obtain a system that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;composable&lt;/li&gt;
&lt;li&gt;extensible&lt;/li&gt;
&lt;li&gt;formally grounded&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Automation is not a sequence of steps.&lt;br&gt;
It is a computation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And computation deserves a language.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents" rel="noopener noreferrer"&gt;https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/matyo91/composio-mcp" rel="noopener noreferrer"&gt;https://github.com/matyo91/composio-mcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://composio.dev/" rel="noopener noreferrer"&gt;https://composio.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://symfony.com/doc/current/ai/components/platform.html" rel="noopener noreferrer"&gt;https://symfony.com/doc/current/ai/components/platform.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kestra.io/plugins" rel="noopener noreferrer"&gt;https://kestra.io/plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://n8n.io/integrations/" rel="noopener noreferrer"&gt;https://n8n.io/integrations/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://navi.darkwood.com/" rel="noopener noreferrer"&gt;https://navi.darkwood.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flow.darkwood.com/" rel="noopener noreferrer"&gt;https://flow.darkwood.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>💡 I created a GDPR-compliant AI app in 1 hour with Symfony</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 03 Apr 2026 06:41:54 +0000</pubDate>
      <link>https://forem.com/matyo91/i-created-a-gdpr-compliant-ai-app-in-1-hour-with-symfony-3dpl</link>
      <guid>https://forem.com/matyo91/i-created-a-gdpr-compliant-ai-app-in-1-hour-with-symfony-3dpl</guid>
      <description>&lt;p&gt;Today, many developers use AI to generate code.&lt;/p&gt;

&lt;p&gt;The question we are addressing here is the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;How ​​to transform an idea into an executable system?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's normal.&lt;/p&gt;

&lt;p&gt;Because we learned to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;coding features&lt;/li&gt;
&lt;li&gt;write functions&lt;/li&gt;
&lt;li&gt;connect APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But not to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;structuring an idea so that it can be executed&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At Darkwood, we never start with the code.&lt;/p&gt;

&lt;p&gt;We begin with a much more fundamental step:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;the reasoning&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we will look at the following in concrete terms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to transform an idea into a usable unit&lt;/li&gt;
&lt;li&gt;How to use AI to execute this idea&lt;/li&gt;
&lt;li&gt;How to apply this in a real project: &lt;strong&gt;SketchUp Shape&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🧠 1. An idea is not code
&lt;/h2&gt;

&lt;p&gt;When you think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Créer une application”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your reflex as a developer is often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Okay, I’m going to code an API, a database, etc.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 Bad starting point.&lt;/p&gt;

&lt;p&gt;An idea is not yet something you can execute.&lt;/p&gt;

&lt;p&gt;That's right:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 a &lt;strong&gt;vague intention&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💡 The right mental model
&lt;/h2&gt;

&lt;p&gt;At Darkwood, we believe that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;one idea = one task&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No more, no less.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Créer une application”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task: create_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may seem trivial.&lt;/p&gt;

&lt;p&gt;But this is a significant change:&lt;/p&gt;

&lt;p&gt;👉 You no longer think in terms of “projects”&lt;br&gt;
👉 You think in &lt;strong&gt;executable units&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  ⚙️ Why this method works: Church, Turing, and the idea as an executable unit
&lt;/h1&gt;

&lt;p&gt;One might think that “prompting an AI” is a recent, almost purely practical topic, linked to current LLM news.&lt;/p&gt;

&lt;p&gt;In reality, the problem is much older.&lt;/p&gt;

&lt;p&gt;When a developer takes an idea and tries to turn it into an executable system, they always encounter the same question:&lt;/p&gt;

&lt;p&gt;How do we move from an abstract intention to a form that the machine can actually process?&lt;/p&gt;

&lt;p&gt;This is exactly the type of question that lies at the root of theoretical computer science.&lt;/p&gt;

&lt;p&gt;In a previous Darkwood article - &lt;a href="https://blog.darkwood.com/index.php/fr/article/create-a-lambda-interpreter-in-php-1" rel="noopener noreferrer"&gt;&lt;em&gt;Create a Lambda Interpreter in PHP&lt;/em&gt;&lt;/a&gt; - we already explored this boundary between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;the idea of ​​a calculation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;its actual execution by a machine&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article started with Alonzo Church's λ-calculus, then linked it to the Turing machine, recalling a fundamental point:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The λ-calculus and the Turing machine are two equivalent models of computation&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;Church provides a &lt;strong&gt;conceptual model&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Turing provides a &lt;strong&gt;model of execution&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's exactly what interests us here.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Church: before execution, a conceivable form is necessary
&lt;/h2&gt;

&lt;p&gt;Alonzo Church does not start from a machine.&lt;br&gt;
It stems from a much deeper problem:&lt;/p&gt;

&lt;p&gt;What is a function?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;and more broadly:&lt;/p&gt;

&lt;p&gt;What is a calculation?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The λ-calculus responds to this with a radical idea:&lt;/p&gt;

&lt;p&gt;Any calculation can be expressed as an abstraction and application of functions.&lt;/p&gt;

&lt;p&gt;In this model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A function is a transformation&lt;/li&gt;
&lt;li&gt;a value can be passed to another function&lt;/li&gt;
&lt;li&gt;and evaluation consists of applying functions to one another&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the theoretical root of many things we use today without thinking about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functional programming&lt;/li&gt;
&lt;li&gt;the currying&lt;/li&gt;
&lt;li&gt;closures&lt;/li&gt;
&lt;li&gt;the combinators&lt;/li&gt;
&lt;li&gt;pure transformations&lt;/li&gt;
&lt;li&gt;DSLs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the article on the lambda interpreter in PHP, this idea was presented in a very concrete way:&lt;br&gt;
We started with an expression, tokenized it, parsed it, built an AST, and then evaluated it.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;before a system executes something,&lt;br&gt;
First, it must &lt;strong&gt;understand a form&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is exactly the point that interests us regarding AI.&lt;/p&gt;

&lt;p&gt;When you give an LLM a sentence like:&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 house
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You haven't given it an execution yet.&lt;br&gt;
You give it an &lt;strong&gt;abstract form&lt;/strong&gt;, an intention, a request that is still insufficiently structured.&lt;/p&gt;

&lt;p&gt;And that's where Church's intuition becomes useful to us.&lt;/p&gt;
&lt;h3&gt;
  
  
  Developer translation
&lt;/h3&gt;

&lt;p&gt;When we talk about ideas in this article, we are not talking about vague inspiration or brainstorming.&lt;/p&gt;

&lt;p&gt;We are already talking about a &lt;strong&gt;manipulable abstraction&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;An idea must become a unit upon which a system can reason.&lt;/p&gt;

&lt;p&gt;That's why, at Darkwood, we make an initial mental shift:&lt;/p&gt;

&lt;p&gt;An idea is not yet code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An idea is already a transformation in progress.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or, to put it another way:&lt;/p&gt;

&lt;p&gt;An idea is a potential task&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ Turing: once the form is defined, it must be executed
&lt;/h2&gt;

&lt;p&gt;Church formalizes calculation on the side of abstraction.&lt;br&gt;
Turing, however, answers a different question:&lt;/p&gt;

&lt;p&gt;What does a machine capable of performing this calculation look like?&lt;/p&gt;

&lt;p&gt;His answer is famous:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a memory strip&lt;/li&gt;
&lt;li&gt;a reading head&lt;/li&gt;
&lt;li&gt;a current state&lt;/li&gt;
&lt;li&gt;transition rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The power of the model does not come from its complexity, but rather from its simplicity.&lt;/p&gt;

&lt;p&gt;A Turing machine reads a cell, takes its state into account, applies a rule, possibly writes something, and then moves on.&lt;/p&gt;

&lt;p&gt;It's an extremely simple model, but sufficient to reason about what a machine can do.&lt;/p&gt;

&lt;p&gt;What interests us here is not teaching the entire theory of automata.&lt;br&gt;
It's about recovering a very concrete intuition:&lt;/p&gt;

&lt;p&gt;An executable system needs readable units.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;and a clear mechanism for switching from one state to the other&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where the link with modern work on ideas, tasks, and AI agents becomes very concrete.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔁 What Church and Turing teach us about working with AI
&lt;/h2&gt;

&lt;p&gt;The essential point is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Church teaches us to think of calculation as &lt;strong&gt;transformation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Turing teaches us to think of computation as &lt;strong&gt;structured execution&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you combine the two, you get a much healthier way of working with AI.&lt;/p&gt;

&lt;p&gt;We stop thinking:&lt;/p&gt;

&lt;p&gt;“I’m going to ask the model for some code”&lt;/p&gt;

&lt;p&gt;And we start to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m going to give him a structured unit of work,&lt;br&gt;
that he will be able to transform,&lt;br&gt;
then another system can execute”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's exactly what we do at Darkwood.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧩 Darkwood translation: an idea becomes a task
&lt;/h2&gt;

&lt;p&gt;At this stage, we can simplify the model without betraying it.&lt;/p&gt;

&lt;p&gt;Here is the translation we are using as a basis:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Theoretical concept&lt;/th&gt;
&lt;th&gt;Darkwood interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Abstraction&lt;/td&gt;
&lt;td&gt;Structured idea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;td&gt;Transformation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory slot&lt;/td&gt;
&lt;td&gt;Task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strip&lt;/td&gt;
&lt;td&gt;To-do list / stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;Execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transition&lt;/td&gt;
&lt;td&gt;Change from one state to another&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This gives us a simple rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;an idea becomes a task&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a task becomes a readable unit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A readable unit can be executed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is this change of perspective that matters.&lt;/p&gt;

&lt;p&gt;Because as long as an idea remains only in your head, it is unusable by the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nor your terminal&lt;/li&gt;
&lt;li&gt;nor your IDE&lt;/li&gt;
&lt;li&gt;nor your LLM&lt;/li&gt;
&lt;li&gt;nor your orchestrator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;cannot work on it properly.&lt;/p&gt;

&lt;p&gt;It therefore needs to be given a form.&lt;/p&gt;
&lt;h2&gt;
  
  
  💡 The idea as a unit of calculation
&lt;/h2&gt;

&lt;p&gt;This is where our method becomes truly meaningful.&lt;/p&gt;

&lt;p&gt;When we say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Créer une application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not a system yet.&lt;br&gt;
This is not yet architecture.&lt;br&gt;
This is not yet a usable prompt.&lt;/p&gt;

&lt;p&gt;But it's not "nothing" either.&lt;/p&gt;

&lt;p&gt;That's already it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a unit of calculation to be specified&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At Darkwood, we put it through a nomination and reduction stage.&lt;/p&gt;

&lt;p&gt;For example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task: create_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task: generate_sketchup_shape
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this point on, the machine - or the system of agents - no longer manipulates just a human sentence.&lt;br&gt;
She is manipulating an identifiable task.&lt;/p&gt;

&lt;p&gt;And once you can identify a task, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store it&lt;/li&gt;
&lt;li&gt;reread it&lt;/li&gt;
&lt;li&gt;reproduce it&lt;/li&gt;
&lt;li&gt;transmit it&lt;/li&gt;
&lt;li&gt;cut it&lt;/li&gt;
&lt;li&gt;parallelize it&lt;/li&gt;
&lt;li&gt;to orchestrate it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, that's the real change.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Why this is so useful for a developer
&lt;/h2&gt;

&lt;p&gt;A developer often tends to jump directly to implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a folder&lt;/li&gt;
&lt;li&gt;Install Symfony&lt;/li&gt;
&lt;li&gt;connect an API&lt;/li&gt;
&lt;li&gt;write an order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But if the initial idea has not been modeled correctly, everything else becomes unstable.&lt;/p&gt;

&lt;p&gt;This leads to what many people experience with LLMs today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vague prompts&lt;/li&gt;
&lt;li&gt;unclear outputs&lt;/li&gt;
&lt;li&gt;fragile structures&lt;/li&gt;
&lt;li&gt;projects that “work”, but lack coherence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The theory of Church and Turing reminds us of something very simple:&lt;/p&gt;

&lt;p&gt;The quality of the execution depends on the quality of the initial representation.&lt;/p&gt;

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

&lt;p&gt;If you want to improve the performance of an AI,&lt;br&gt;
First, you need to represent your idea better.&lt;/p&gt;

&lt;p&gt;And that's precisely what we're going to do next with SketchUp Shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;starting from an intention&lt;/li&gt;
&lt;li&gt;convert it into a task&lt;/li&gt;
&lt;li&gt;to structure it&lt;/li&gt;
&lt;li&gt;transform it into a design&lt;/li&gt;
&lt;li&gt;then only in code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🧭 The rule to remember
&lt;/h2&gt;

&lt;p&gt;If this entire section had to be condensed into a single sentence, it would be this:&lt;/p&gt;

&lt;p&gt;A useful idea for AI is not an inspiration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It's a sufficiently clear abstraction to become an executable task&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's where Church and Turing cease to be distant theory.&lt;/p&gt;

&lt;p&gt;They become a practical model for the modern developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Church helps you think about form&lt;/li&gt;
&lt;li&gt;Turing helps you think about execution&lt;/li&gt;
&lt;li&gt;Darkwood helps you connect the two&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  📚 Concrete example
&lt;/h1&gt;

&lt;p&gt;You have several ideas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- créer une app
- construire une API
- générer un modèle 3D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 You can represent them as a stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stack:
- create_app
- build_api
- generate_model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, everything becomes simpler:&lt;/p&gt;

&lt;p&gt;You can handle each task &lt;strong&gt;one by one&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;in parallel&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  ⚡ 2. Your brain already works like this
&lt;/h1&gt;

&lt;p&gt;You don't need to learn a new system.&lt;/p&gt;

&lt;p&gt;👉 You're already using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Simple case: different tasks
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task A: répondre à un message
Task B: installer un package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 No link&lt;br&gt;
👉 You can easily switch between them&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️ Complicated case: similar tasks
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task A: coder une API
Task B: refactor la même API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;👉 Now, things are getting tough&lt;/p&gt;

&lt;p&gt;For what ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;same context&lt;/li&gt;
&lt;li&gt;same mental variables&lt;/li&gt;
&lt;li&gt;same files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;confusion&lt;/li&gt;
&lt;li&gt;errors&lt;/li&gt;
&lt;li&gt;fatigue&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  💥 What this implies
&lt;/h2&gt;

&lt;p&gt;Your brain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;has limited memory&lt;/li&gt;
&lt;li&gt;handles too much context poorly&lt;/li&gt;
&lt;li&gt;saturates quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 So:&lt;/p&gt;

&lt;p&gt;You can't manage many complex tasks at the same time.&lt;/p&gt;
&lt;h1&gt;
  
  
  🧩 3. The real problem: reproducibility
&lt;/h1&gt;

&lt;p&gt;A task is only valuable if you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find her&lt;/li&gt;
&lt;li&gt;to revive it&lt;/li&gt;
&lt;li&gt;share it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Otherwise, it stays in your head&lt;br&gt;
👉 and she disappears&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Darkwood Approach
&lt;/h2&gt;

&lt;p&gt;We introduce a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;one task = one pointer&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  In concrete terms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You write your task in Joplin&lt;/li&gt;
&lt;li&gt;she has an ID&lt;/li&gt;
&lt;li&gt;This ID becomes your “pointer”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in your terminal → you are referencing this task&lt;/li&gt;
&lt;li&gt;in your IDE → same&lt;/li&gt;
&lt;li&gt;in your AI → same&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you manipulate &lt;strong&gt;the same object&lt;/strong&gt;, everywhere&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  💡 What this changes
&lt;/h2&gt;

&lt;p&gt;You no longer say:&lt;/p&gt;

&lt;p&gt;“I’m going to work on my idea.”&lt;/p&gt;

&lt;p&gt;You say:&lt;/p&gt;

&lt;p&gt;“I will carry out this task”&lt;/p&gt;

&lt;p&gt;And that's much more powerful.&lt;/p&gt;
&lt;h1&gt;
  
  
  ⚙️ 4. AI: not a magic tool, an execution system
&lt;/h1&gt;

&lt;p&gt;Today, many developers use AI like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“generate a function for me”&lt;/li&gt;
&lt;li&gt;“write me a class”&lt;/li&gt;
&lt;li&gt;“Fixes this bug”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 It works.&lt;/p&gt;

&lt;p&gt;But you remain within a certain logic:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;responsive&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  🧠 Darkwood Approach
&lt;/h2&gt;

&lt;p&gt;We completely change the perspective:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 AI is becoming an &lt;strong&gt;execution system&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  🏗 We model like a business
&lt;/h2&gt;

&lt;p&gt;Rather than “magical agents”, a simple structure is used:&lt;/p&gt;
&lt;h3&gt;
  
  
  👤 You (human)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;you define the intention&lt;/li&gt;
&lt;li&gt;you pose the problem&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧠 AI Architect
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;he understands your intention&lt;/li&gt;
&lt;li&gt;he breaks it down into tasks&lt;/li&gt;
&lt;li&gt;he decides how to organize the system&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ⚙️ Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;they execute&lt;/li&gt;
&lt;li&gt;they produce code&lt;/li&gt;
&lt;li&gt;they transform the data&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  💡 Key Rule
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;The prompt = your intention&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your prompt is unclear:&lt;/p&gt;

&lt;p&gt;👉 the system is unclear&lt;/p&gt;

&lt;p&gt;If your prompt is structured:&lt;/p&gt;

&lt;p&gt;👉 the system becomes structured&lt;/p&gt;
&lt;h2&gt;
  
  
  🔥 Example
&lt;/h2&gt;

&lt;p&gt;❌ Bad 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 house”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Good prompt:&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 structured architectural design of a house,
with walls, roof, proportions and constraints,
then generate SketchUp Ruby code from it”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Here, you give:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a direction&lt;/li&gt;
&lt;li&gt;a structure&lt;/li&gt;
&lt;li&gt;a clear objective&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🧠 What you need to remember
&lt;/h1&gt;

&lt;p&gt;👉 You don't need to be better at coding&lt;/p&gt;

&lt;p&gt;👉 You need to get better at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structuring&lt;/li&gt;
&lt;li&gt;intention&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's exactly what we're going to apply now with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;SketchUp Shape&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  🚀 5. Practical application: SketchUp Shape
&lt;/h1&gt;

&lt;p&gt;Project :&lt;br&gt;
👉 &lt;a href="https://github.com/matyo91/sketchup-shape" rel="noopener noreferrer"&gt;https://github.com/matyo91/sketchup-shape&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 Objective
&lt;/h2&gt;

&lt;p&gt;Transformer:&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 house”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in:&lt;/p&gt;

&lt;p&gt;👉 Ruby script executable in &lt;a href="https://sketchup.trimble.com/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Why SketchUp?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;3D modeling tool&lt;/li&gt;
&lt;li&gt;Documented Ruby API:
→ &lt;a href="https://ruby.sketchup.com/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp Ruby API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;extensible (plugins, scripts)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎓 Context
&lt;/h2&gt;

&lt;p&gt;I personally learned SketchUp with&lt;br&gt;
&lt;a href="https://www.youtube.com/@sebastienmaison?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Sébastien Maison (YouTube)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Here, the goal is not to use their AI:&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://sketchup.trimble.com/fr/ai-in-sketchup?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Official SketchUp AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 But to build &lt;strong&gt;our own system&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  ⚙️ 6. Pipeline: from idea to (concrete) 3D model
&lt;/h1&gt;

&lt;p&gt;Before going any further, let's take a real-life example.&lt;/p&gt;

&lt;p&gt;👉 Here, we're not talking about an abstract API&lt;br&gt;
👉 We're talking about &lt;strong&gt;generating a 3D object in SketchUp&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🧱 A little background: why SketchUp?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://sketchup.trimble.com/fr?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp&lt;/a&gt; is a widely used 3D modeling tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;design&lt;/li&gt;
&lt;li&gt;prototyping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personally, I discovered SketchUp thanks to &lt;a href="https://www.youtube.com/@sebastienmaison?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Sébastien Maison&lt;/a&gt;, with whom I took a course.&lt;/p&gt;

&lt;p&gt;👉 I modeled a house there “by hand”&lt;/p&gt;

&lt;p&gt;And that's where the idea came from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 “What if I could generate that directly with code?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  ⚠️ Why not use SketchUp's native AI?
&lt;/h2&gt;

&lt;p&gt;SketchUp already offers AI:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://sketchup.trimble.com/fr/ai-in-sketchup?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that's not the point here.&lt;/p&gt;

&lt;p&gt;👉 We are developers.&lt;/p&gt;

&lt;p&gt;👉 We want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to understand&lt;/li&gt;
&lt;li&gt;control&lt;/li&gt;
&lt;li&gt;automate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we go through:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;SketchUp Ruby API&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  🧠 The technical entrance
&lt;/h2&gt;

&lt;p&gt;To do this, SketchUp explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.sketchup.com/learn?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Developer documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ruby.sketchup.com/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Ruby API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 In concrete terms:&lt;/p&gt;

&lt;p&gt;You write Ruby like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Sketchup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;active_model&lt;/span&gt;
&lt;span class="n"&gt;entities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entities&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;faces&lt;/li&gt;
&lt;li&gt;volumes&lt;/li&gt;
&lt;li&gt;groups&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧩 Resources used
&lt;/h2&gt;

&lt;p&gt;To make the AI ​​more reliable, I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/SketchUp/ruby-api-stubs?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Ruby API Stubs&lt;/a&gt;&lt;br&gt;
👉 to give the LLM a clear view of the available objects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/SketchUp/sketchup-ruby-api-tutorials/tree/main/examples?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Official examples&lt;/a&gt;&lt;br&gt;
👉 to understand the real patterns&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you want to go further:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://extensions.sketchup.com/extension/add?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp Extensions&lt;/a&gt;&lt;br&gt;
→ You can package your code as a plugin&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️ Important prerequisite
&lt;/h2&gt;

&lt;p&gt;To run Ruby:&lt;/p&gt;

&lt;p&gt;👉 You must use the desktop version:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sketchup.trimble.com/fr/products/sketchup-pro/trial?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;SketchUp Pro Trial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 The web version does not allow this (or only in very limited ways)&lt;/p&gt;
&lt;h1&gt;
  
  
  🔁 Pipeline Darkwood (applied)
&lt;/h1&gt;

&lt;p&gt;Now that we have the context, here is the actual pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intention
   ↓
Design (LLM #1)
   ↓
Code (LLM #2)
   ↓
SketchUp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Step 1: Intention
&lt;/h2&gt;

&lt;p&gt;You start with a simple idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/console app:generate-shape &lt;span class="s2"&gt;"Create a house"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Nothing more.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Step 2: Design (LLM #1)
&lt;/h2&gt;

&lt;p&gt;Here, AI does not code.&lt;/p&gt;

&lt;p&gt;👉 She &lt;strong&gt;thinks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;She acts like an architect:&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;"house"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"structure"&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;"walls"&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="err"&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;"roof"&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="err"&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;👉 She decides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;proportions&lt;/li&gt;
&lt;li&gt;elements&lt;/li&gt;
&lt;li&gt;of the structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚙️ Step 3: Code (LLM #2)
&lt;/h2&gt;

&lt;p&gt;Only then:&lt;/p&gt;

&lt;p&gt;👉 a second AI transforms this plan into code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'House'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit_operation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 She acts like a developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It uses the SketchUp API&lt;/li&gt;
&lt;li&gt;she constructs the geometry&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  ⚠️ 7. Why 2 LLMs (and not 1)
&lt;/h1&gt;

&lt;p&gt;This is one of the most important parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ Naive approach
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idée → code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inconsistent&lt;/li&gt;
&lt;li&gt;unpredictable&lt;/li&gt;
&lt;li&gt;difficult to correct&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Darkwood Approach
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idée → design → code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 You separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 the &lt;strong&gt;what&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚙️ the &lt;strong&gt;comment&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 It's exactly like in a team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architect → decides&lt;/li&gt;
&lt;li&gt;developer → implements&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🧠 8. The real problem encountered
&lt;/h1&gt;

&lt;p&gt;When I launched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Create a house
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technically valid&lt;/li&gt;
&lt;li&gt;but visually… false&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 It wasn't a house&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ Why?
&lt;/h2&gt;

&lt;p&gt;Because AI did this:&lt;/p&gt;

&lt;p&gt;“A house = shapes”&lt;/p&gt;

&lt;p&gt;👉 She stacked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cubes&lt;/li&gt;
&lt;li&gt;a roof&lt;/li&gt;
&lt;li&gt;without logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💥 The real problem
&lt;/h2&gt;

&lt;p&gt;AI doesn't understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gravity&lt;/li&gt;
&lt;li&gt;the proportions&lt;/li&gt;
&lt;li&gt;actual usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 She doesn't understand:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;what a house is&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧠 Correction made
&lt;/h2&gt;

&lt;p&gt;A layer was introduced:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;structured design&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of :&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;"parts"&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="err"&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;We force:&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;"house"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"foundation"&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="err"&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;"walls"&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="err"&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;"roof"&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="err"&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;"constraints"&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;"symmetry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alignment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"centered"&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;👉 Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;consistency&lt;/li&gt;
&lt;li&gt;stability&lt;/li&gt;
&lt;li&gt;made credible&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  ⚙️ 10. Technical Stack
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🧱 Backend
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Symfony 8&lt;/li&gt;
&lt;li&gt;Symfony AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;darkwood/navi&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Installation:&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 darkwood/navi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Local AI (GDPR)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mistral.ai/news/mistral-3" rel="noopener noreferrer"&gt;Mistral 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ollama.com/library/ministral-3" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 everything runs locally&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚖️ Why this is important
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;no external API&lt;/li&gt;
&lt;li&gt;no data leak&lt;/li&gt;
&lt;li&gt;total control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You build a system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GDPR compliant by design&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  ⚙️ 11. Orders
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🧠 Local LLM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull ministral-3:8b
ollama serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚙️ Generation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/console app:generate-shape &lt;span class="s2"&gt;"Create a house"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Useful Options
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-o&lt;/span&gt; house.rb        &lt;span class="c"&gt;# sauvegarde du script&lt;/span&gt;
&lt;span class="nt"&gt;--spec&lt;/span&gt; design.json &lt;span class="c"&gt;# sauvegarde du design&lt;/span&gt;
&lt;span class="nt"&gt;-v&lt;/span&gt;                 &lt;span class="c"&gt;# debug complet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🧠 12. What you really need to remember
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ❌ This is not:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;“How to use AI”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ It is:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;How ​​to structure an idea so that an AI can execute it&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  🔁 Final Model
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idée
 → tâche
 → design
 → code
 → exécution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🚀 Conclusion
&lt;/h1&gt;

&lt;p&gt;The future of development is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;write more code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;structuring ideas&lt;br&gt;
and orchestrate their execution&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 At Darkwood:&lt;/p&gt;

&lt;p&gt;we are not trying to go faster&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;we are trying to be fairer&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>php</category>
      <category>privacy</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🎨 Darkwood v1.0.4 - Présentation du design V4</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 16 Mar 2026 12:29:36 +0000</pubDate>
      <link>https://forem.com/matyo91/darkwood-v104-presentation-du-design-v4-3f4m</link>
      <guid>https://forem.com/matyo91/darkwood-v104-presentation-du-design-v4-3f4m</guid>
      <description>&lt;p&gt;Darkwood v1.0.4 est maintenant disponible.&lt;/p&gt;

&lt;p&gt;Cette version introduit Design V4, la quatrième itération visuelle majeure de Darkwood.&lt;/p&gt;

&lt;p&gt;Pour les nouveaux lecteurs, voici deux idées de versionnage différentes :&lt;/p&gt;

&lt;p&gt;v1.0.4 est la version du logiciel&lt;br&gt;
Design V4 est la quatrième évolution de l'interface de Darkwood&lt;br&gt;
Au fil des ans, Darkwood a connu plusieurs itérations de conception :&lt;/p&gt;

&lt;p&gt;V1 se concentrait sur la première identité visuelle&lt;br&gt;
V2 a exploré de nouvelles orientations de mise en page&lt;br&gt;
V3 a affiné la marque et la structure globale&lt;br&gt;
V4 remanie la navigation sur l'ensemble du site&lt;br&gt;
Cette version n'est donc pas « Darkwood version 4 » au sens du terme. Il s'agit de la version 1.0.4, qui introduit Darkwood Design V4.&lt;/p&gt;

&lt;p&gt;Et c'est important, car cette mise à jour ne se limite pas à une simple amélioration visuelle. Elle modernise également l'infrastructure technique et ouvre Darkwood aux flux de travail basés sur l'IA.&lt;/p&gt;

&lt;p&gt;Notes de version : &lt;a href="https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qu'est-ce que Darkwood ?&lt;br&gt;
Darkwood est un jeu tactique axé sur les API.&lt;/p&gt;

&lt;p&gt;Il est conçu comme les deux :&lt;/p&gt;

&lt;p&gt;un système de jeu jouable&lt;br&gt;
un terrain de jeu technique&lt;br&gt;
une application Symfony conçue pour l'expérimentation à long terme&lt;br&gt;
L'idée de base est simple : le gameplay ne doit pas dépendre entièrement de l'interface graphique.&lt;/p&gt;

&lt;p&gt;L'interface utilisateur est importante, mais la logique du jeu réside avant tout dans l'API.&lt;/p&gt;

&lt;p&gt;Cette approche a été décrite précédemment ici : &lt;a href="https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game" rel="noopener noreferrer"&gt;https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette version s'inscrit dans cette continuité.&lt;/p&gt;

&lt;p&gt;Darkwood combine désormais :&lt;/p&gt;

&lt;p&gt;une interface repensée&lt;br&gt;
une pile PHP mise à jour&lt;br&gt;
et intégration MCP pour les agents d'IA&lt;br&gt;
Pourquoi concevoir V4 ?&lt;br&gt;
Au fil du temps, Darkwood a accumulé des couches.&lt;/p&gt;

&lt;p&gt;Des pages ont été ajoutées. Les expériences ont été intégrées. Navigation étendue.&lt;/p&gt;

&lt;p&gt;Le résultat était fonctionnel, mais pas toujours clair.&lt;/p&gt;

&lt;p&gt;La version 4 de Design se concentre sur un objectif principal :&lt;/p&gt;

&lt;p&gt;Redonner au navigateur un aspect naturel.&lt;/p&gt;

&lt;p&gt;Le changement le plus important entre la version V3 et la version V4 ne réside pas dans la marque elle-même. Il s'agit de la manière dont les utilisateurs naviguent sur le site.&lt;/p&gt;

&lt;p&gt;Les versions précédentes portaient principalement sur la mise en page et l'identité visuelle. Celui-ci concerne l'architecture de navigation.&lt;/p&gt;

&lt;p&gt;La nouvelle conception a d'abord été explorée avec Pencil, ce qui a permis d'accélérer les études d'interface et les décisions de mise en page avant la mise en œuvre.&lt;/p&gt;

&lt;p&gt;Elle bénéficie également directement des leçons apprises lors de la construction d'Uniflow.&lt;/p&gt;

&lt;p&gt;Chez Uniflow, un travail considérable a été consacré à l'amélioration de la clarté des menus sur ordinateur et mobile. Cette expérience a contribué à façonner le nouveau modèle de navigation de Darkwood.&lt;/p&gt;

&lt;p&gt;Une bonne façon de résumer cet état d'esprit est :&lt;/p&gt;

&lt;p&gt;Penser macro, agir micro.&lt;/p&gt;

&lt;p&gt;Au niveau macro, la plateforme a besoin d'une structure claire. Au niveau micro, chaque interaction doit rester simple.&lt;/p&gt;

&lt;p&gt;Voilà l’esprit qui anime le design V4.&lt;/p&gt;

&lt;p&gt;Qu'est-ce qui a changé dans l'interface ?&lt;br&gt;
Une nouvelle structure de navigation&lt;br&gt;
Le changement le plus visible concerne la navigation.&lt;/p&gt;

&lt;p&gt;Darkwood utilise désormais une navigation centrée en haut au lieu de l'ancienne structure latérale.&lt;/p&gt;

&lt;p&gt;Le site est organisé autour de quatre sections principales :&lt;/p&gt;

&lt;p&gt;Jouer - accéder au jeu tactique&lt;br&gt;
Monde - explorez l'univers et son contexte&lt;br&gt;
Journal - Consultez les articles techniques et les notes de développement&lt;br&gt;
Projets - Découvrez des expériences et des travaux connexes&lt;br&gt;
Cela rend la plateforme plus facile à comprendre au premier coup d'œil.&lt;/p&gt;

&lt;p&gt;Au lieu d'être fragmentée, l'expérience est désormais organisée autour de quatre points d'entrée clairement définis.&lt;/p&gt;

&lt;p&gt;La même logique est utilisée sur ordinateur et mobile, la navigation reste donc cohérente quel que soit l'appareil.&lt;/p&gt;

&lt;p&gt;Une tête plus légère&lt;br&gt;
L'en-tête a été repensé pour paraître plus léger et plus réfléchi.&lt;/p&gt;

&lt;p&gt;Elle reste disponible pendant le défilement, mais avec un poids visuel réduit.&lt;/p&gt;

&lt;p&gt;Le but n'était pas de le rendre plus décoratif. L'objectif était de le rendre plus utile.&lt;/p&gt;

&lt;p&gt;Un pied de page remanié&lt;br&gt;
Le pied de page a également été restructuré.&lt;/p&gt;

&lt;p&gt;Elle permet désormais de regrouper le contenu plus clairement tout en restant secondaire par rapport à la page elle-même.&lt;/p&gt;

&lt;p&gt;L'objectif était d'améliorer l'orientation sans que le pied de page ne domine l'expérience de lecture.&lt;/p&gt;

&lt;p&gt;Un système visuel plus cohérent&lt;br&gt;
La version 4 de Design introduit également un nettoyage plus global du site :&lt;/p&gt;

&lt;p&gt;espacement amélioré&lt;br&gt;
Hiérarchie de boutons plus claire&lt;br&gt;
meilleure navigation mobile&lt;br&gt;
Expérience de connexion améliorée&lt;br&gt;
Comportement de mise en page plus cohérent&lt;br&gt;
Il ne s'agit pas d'une refonte radicale. Il s'agit d'un passage de cohérence à travers l'expérience complète.&lt;/p&gt;

&lt;p&gt;Construit avec une pile mise à jour&lt;br&gt;
Cette version met également à jour les fondements techniques de Darkwood.&lt;/p&gt;

&lt;p&gt;Darkwood fonctionne désormais avec :&lt;/p&gt;

&lt;p&gt;PHP 8.5&lt;br&gt;
Symfony 8&lt;br&gt;
FrankenPHP v1.12.1&lt;br&gt;
Il comprend également :&lt;/p&gt;

&lt;p&gt;Migration des contrôleurs des annotations vers les attributs PHP&lt;br&gt;
Configuration Nix et CI mise à jour&lt;br&gt;
Mise à jour des recettes et de la configuration du framework&lt;br&gt;
Corrections de dépréciation concernant le groupe d'exceptions Darkwood IA&lt;br&gt;
Renforcement de la sécurité en production sur plusieurs points, notamment le référencement naturel, Castor, la sérialisation des utilisateurs, reCAPTCHA et l'intégration optionnelle de Baserow&lt;br&gt;
L'objectif est simple :&lt;/p&gt;

&lt;p&gt;Maintenir la plateforme à jour, rapide et facile à maintenir.&lt;/p&gt;

&lt;p&gt;Pas par mode. Pour sa durabilité.&lt;/p&gt;

&lt;p&gt;Darkwood devrait pouvoir se développer sans rencontrer de difficultés techniques évitables.&lt;/p&gt;

&lt;p&gt;Intégration MCP pour les flux de travail d'IA&lt;br&gt;
Cette version ajoute également l'intégration de l'outil MCP grâce aux nouvelles capacités d'IA de la plateforme API.&lt;/p&gt;

&lt;p&gt;Référence: &lt;a href="https://les-tilleuls.coop/blog/sortie-dapi-platform-4-3-rencontre-avec-lia" rel="noopener noreferrer"&gt;https://les-tilleuls.coop/blog/sortie-dapi-platform-4-3-rencontre-avec-lia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cela correspond naturellement à l'approche « API-first » de Darkwood.&lt;/p&gt;

&lt;p&gt;Si la logique du jeu existe déjà sous forme d'API, l'exposer à des agents d'IA devient une extension de la même philosophie.&lt;/p&gt;

&lt;p&gt;Autrement dit, le jeu tactique était déjà programmable. Il est désormais également prêt pour les agents.&lt;/p&gt;

&lt;p&gt;Outils MCP de DarkwoodGame&lt;br&gt;
La ressource API DarkwoodGame expose désormais quatre outils MCP :&lt;/p&gt;

&lt;p&gt;get_darkwood_state Renvoie l'état actuel du jeu&lt;/p&gt;

&lt;p&gt;darkwood_action Exécute une action de jeu à partir d'une entrée&lt;/p&gt;

&lt;p&gt;list_darkwood_archives Liste des captures d'écran archivées des puzzles pour les utilisateurs premium&lt;/p&gt;

&lt;p&gt;get_darkwood_archive Récupère une archive par identifiant pour les utilisateurs premium&lt;/p&gt;

&lt;p&gt;Tous utilisent une sortie de contenu structuré, ce qui signifie que la réponse de l'API est directement renvoyée sous forme de sortie de l'outil MCP.&lt;/p&gt;

&lt;p&gt;Aucune nouvelle route HTTP n'a été introduite pour cela.&lt;/p&gt;

&lt;p&gt;La couche MCP expose simplement les capacités API existantes de manière à ce que les agents d'IA puissent les exploiter sans problème.&lt;/p&gt;

&lt;p&gt;Outils MCP de l'article&lt;br&gt;
Les articles de Darkwood sont désormais également accessibles via MCP.&lt;/p&gt;

&lt;p&gt;Deux outils ont été ajoutés :&lt;/p&gt;

&lt;p&gt;list_articles&lt;br&gt;
get_article&lt;br&gt;
Cela permet aux agents d'IA de récupérer des données structurées d'articles tout en conservant les mêmes règles de sécurité que la ressource API elle-même.&lt;/p&gt;

&lt;p&gt;Là encore, l'objectif n'est pas de dupliquer l'application. Il s'agit de rendre le système existant accessible via une nouvelle couche d'interaction.&lt;/p&gt;

&lt;p&gt;Gratuit vs Premium&lt;br&gt;
Darkwood est actuellement en cours de développement en Bêta Saison 0.&lt;/p&gt;

&lt;p&gt;La proposition commerciale reste inchangée.&lt;/p&gt;

&lt;p&gt;Deux types de clés d'accès sont disponibles.&lt;/p&gt;

&lt;p&gt;🎟 Accès bêta (gratuit)&lt;br&gt;
Clé API personnelle&lt;br&gt;
Actions quotidiennes limitées&lt;br&gt;
Accès à l'état jouable actuel&lt;br&gt;
Accès aux archives impossible&lt;br&gt;
💎 Fondateur Premium&lt;br&gt;
Clé API personnelle&lt;br&gt;
Actions quotidiennes illimitées&lt;br&gt;
Accès aux instantanés archivés des puzzles&lt;br&gt;
Statut de soutien précoce&lt;br&gt;
Les archives sont des instantanés en lecture seule des états jouables antérieurs. Ils permettent de révéler l'état historique du jeu sans affecter la partie en cours.&lt;/p&gt;

&lt;p&gt;Édition limitée pour les fondateurs&lt;br&gt;
Cette version reste volontairement confidentielle.&lt;/p&gt;

&lt;p&gt;Disponible dès maintenant :&lt;/p&gt;

&lt;p&gt;5 clés d'accès bêta&lt;br&gt;
5 clés Fondateur Premium&lt;br&gt;
C'est tout.&lt;/p&gt;

&lt;p&gt;Il ne s'agit pas d'un lancement destiné au marché de masse. Il s'agit d'une version contrôlée destinée à valider le modèle.&lt;/p&gt;

&lt;p&gt;L'accès est géré par Bonzai :&lt;/p&gt;

&lt;p&gt;Accès bêta (gratuit) &lt;a href="https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fondateur Premium &lt;a href="https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chaque clé est personnelle et peut être changée si nécessaire.&lt;/p&gt;

&lt;p&gt;Ce que cette publication signifie réellement&lt;br&gt;
Darkwood v1.0.4 est une version qui poursuit trois objectifs :&lt;/p&gt;

&lt;p&gt;rendre l'interface plus facile à naviguer&lt;br&gt;
Mettre à jour l'architecture technique selon les normes modernes&lt;br&gt;
Étendre le modèle de jeu basé sur les API aux agents d'IA via MCP&lt;br&gt;
Le design V4 correspond à la partie visible.&lt;/p&gt;

&lt;p&gt;Mais en coulisses, le projet se consolide et s'ouvre également.&lt;/p&gt;

&lt;p&gt;On peut désormais aborder ce même jeu tactique par le biais de :&lt;/p&gt;

&lt;p&gt;le site web&lt;br&gt;
l'API&lt;br&gt;
et les flux de travail pilotés par l'IA&lt;br&gt;
Cette continuité est importante.&lt;/p&gt;

&lt;p&gt;Darkwood ne se divise pas en idées distinctes. Cela devient plus cohérent.&lt;/p&gt;

&lt;p&gt;Découvrez la version&lt;br&gt;
Darkwood v1.0.4 est disponible.&lt;/p&gt;

&lt;p&gt;Il apporte Design V4, une pile Symfony et PHP modernisée, et une intégration MCP pour le jeu tactique axé sur les API.&lt;/p&gt;

&lt;p&gt;Explorez l'interface. Lisez le journal. Accédez à l'API. Ou commencez à jouer.&lt;/p&gt;

&lt;p&gt;Libérer: &lt;a href="https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>👾 Darkwood : Créer un jeu tactique axé sur les API</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 08 Mar 2026 09:31:07 +0000</pubDate>
      <link>https://forem.com/matyo91/darkwood-creer-un-jeu-tactique-axe-sur-les-api-4fo9</link>
      <guid>https://forem.com/matyo91/darkwood-creer-un-jeu-tactique-axe-sur-les-api-4fo9</guid>
      <description>&lt;p&gt;Darkwood est désormais jouable entièrement via API.&lt;/p&gt;

&lt;p&gt;Il n'y a pas d'interface utilisateur dédiée. Aucune interface utilisateur requise. Pas de client graphique.&lt;/p&gt;

&lt;p&gt;Vous interagissez avec le jeu via HTTP.&lt;/p&gt;

&lt;p&gt;Que signifie réellement « API-First » ?&lt;br&gt;
Dans Darkwood, la boucle de jeu est simple et explicite :&lt;/p&gt;

&lt;p&gt;GET /api/darkwood/state → observer la situation actuelle&lt;br&gt;
Interpréter la réponse JSON&lt;br&gt;
POST /api/darkwood/action → décider de l'action à effectuer&lt;br&gt;
Recevoir l'état mis à jour&lt;br&gt;
Répéter&lt;br&gt;
Le jeu se comporte comme une machine à états via HTTP.&lt;/p&gt;

&lt;p&gt;Chaque réponse comprend :&lt;/p&gt;

&lt;p&gt;état — où vous vous trouvez (principal, combat, infos, boutique, etc.)&lt;br&gt;
mode — sous-phase (combat, victoire, mort, etc.)&lt;br&gt;
data — détails contextuels (vie, ennemi, statistiques, session de combat)&lt;br&gt;
Votre client — qu'il s'agisse de curl, d'un outil en ligne de commande, d'un script ou d'un agent d'IA — lit l'état et décide de la prochaine action.&lt;/p&gt;

&lt;p&gt;Il n'y a pas de logique d'interface utilisateur cachée.&lt;/p&gt;

&lt;p&gt;Le protocole est la clé du jeu.&lt;/p&gt;

&lt;p&gt;Deux niveaux d'accès&lt;br&gt;
Darkwood divise l'accès en deux niveaux :&lt;/p&gt;

&lt;p&gt;1️⃣ Accès API&lt;br&gt;
Chaque demande doit inclure :&lt;/p&gt;

&lt;p&gt;X-API-Key: &lt;br&gt;
La clé API contrôle :&lt;/p&gt;

&lt;p&gt;Si vous pouvez appeler l'API&lt;br&gt;
Que vous fassiez partie de la saison bêta 0&lt;br&gt;
Que vous ayez un accès premium&lt;br&gt;
Votre quota d'actions quotidien (pour les clés gratuites)&lt;br&gt;
2️⃣ Identité du joueur&lt;br&gt;
Pour jouer avec un personnage spécifique (progression persistante, combats, statistiques), vous vous authentifiez avec :&lt;/p&gt;

&lt;p&gt;Authorization: Bearer &lt;br&gt;
Le JWT identifie le compte du joueur. La clé API contrôle l'accès et la monétisation.&lt;/p&gt;

&lt;p&gt;Ils sont séparés par conception.&lt;/p&gt;

&lt;p&gt;La documentation complète est disponible sur GitHub : &lt;a href="https://github.com/darkwood-com/darkwood-com/blob/main/docs/" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/darkwood-com/blob/main/docs/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gratuit vs Premium&lt;br&gt;
Darkwood est actuellement en cours de développement en Bêta Saison 0.&lt;/p&gt;

&lt;p&gt;Il existe deux types de clés :&lt;/p&gt;

&lt;p&gt;🎟 Accès bêta (gratuit)&lt;br&gt;
Clé API personnelle&lt;br&gt;
Actions quotidiennes limitées&lt;br&gt;
Accès à l'état jouable actuel&lt;br&gt;
Accès aux archives impossible&lt;br&gt;
💎 Fondateur Premium&lt;br&gt;
Clé API personnelle&lt;br&gt;
Actions quotidiennes illimitées&lt;br&gt;
Accès aux instantanés archivés des puzzles&lt;br&gt;
Statut de soutien précoce&lt;br&gt;
Les archives sont des instantanés en lecture seule des états jouables antérieurs. Ils permettent de révéler l'état historique du jeu sans modifier le déroulement en direct.&lt;/p&gt;

&lt;p&gt;Édition limitée pour les fondateurs&lt;br&gt;
Pour que ce lancement reste sous contrôle :&lt;/p&gt;

&lt;p&gt;5 clés d'accès bêta&lt;br&gt;
5 clés Fondateur Premium&lt;br&gt;
C'est ça.&lt;/p&gt;

&lt;p&gt;Il ne s'agit pas d'un lancement à grande échelle. Il s'agit d'une version ciblée visant à valider le modèle.&lt;/p&gt;

&lt;p&gt;Les ventes sont gérées par Bonzai :&lt;/p&gt;

&lt;p&gt;Accès bêta (gratuit) : &lt;a href="https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Premium Fondateur : &lt;a href="https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chaque clé est personnelle. Les touches peuvent être pivotées si nécessaire.&lt;/p&gt;

&lt;p&gt;Pourquoi pas d'interface utilisateur ?&lt;br&gt;
Parce que l'interface est optionnelle.&lt;/p&gt;

&lt;p&gt;Vous pouvez jouer à Darkwood avec :&lt;/p&gt;

&lt;p&gt;curl&lt;br&gt;
Postman&lt;br&gt;
une interface de ligne de commande personnalisée&lt;br&gt;
un petit client web&lt;br&gt;
un script&lt;br&gt;
un agent d'IA&lt;br&gt;
L'API définit le contrat du jeu.&lt;/p&gt;

&lt;p&gt;Le client n'est qu'un interprète.&lt;/p&gt;

&lt;p&gt;Saison bêta 0&lt;br&gt;
La logique du jeu reste inchangée.&lt;/p&gt;

&lt;p&gt;L'objectif de cette phase est :&lt;/p&gt;

&lt;p&gt;Stabilité de l'API&lt;br&gt;
Modèle de monétisation propre (clé API uniquement)&lt;br&gt;
Flux d'état déterministe&lt;br&gt;
Clarté de la documentation&lt;br&gt;
Pas de sur-ingénierie. Aucune fonctionnalité superflue.&lt;/p&gt;

&lt;p&gt;Un simple jeu tactique déguisé en protocole.&lt;/p&gt;

&lt;p&gt;Darkwood n'est pas qu'un simple projet backend.&lt;/p&gt;

&lt;p&gt;C'est un jeu qui fonctionne entièrement via HTTP.&lt;/p&gt;

&lt;p&gt;Et la saison 0 de la bêta est maintenant disponible.&lt;/p&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>gamedev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>🚀 Création d'une application PHP MCP pour publier des articles Darkwood</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 01 Mar 2026 20:09:22 +0000</pubDate>
      <link>https://forem.com/matyo91/creation-dune-application-php-mcp-pour-publier-des-articles-darkwood-2pcm</link>
      <guid>https://forem.com/matyo91/creation-dune-application-php-mcp-pour-publier-des-articles-darkwood-2pcm</guid>
      <description>&lt;p&gt;Les grands modèles de langage sont déjà performants pour la génération de texte. Ce qui manque encore, dans de nombreux projets, c'est une méthode simple pour transformer cette génération de texte en un véritable flux de travail : rédiger un brouillon, le relire, le corriger, le publier et l'intégrer de manière intuitive dans une application cliente d'IA.&lt;/p&gt;

&lt;p&gt;C’est précisément là que les applications MCP deviennent intéressantes.&lt;/p&gt;

&lt;p&gt;Dans ce projet, l'objectif n'était pas de créer « une énième intégration de chatbot ». L'objectif était de développer une véritable application MCP en PHP permettant de publier un article de blog Darkwood via un flux de travail éditorial simplifié :&lt;/p&gt;

&lt;p&gt;générer un brouillon,&lt;br&gt;
le réviser ou le corriger,&lt;br&gt;
le publier,&lt;br&gt;
et, si nécessaire, revenir en arrière avant la publication.&lt;br&gt;
Le résultat est un serveur PHP MCP qui peut fonctionner sur stdio ou HTTP, exposer des outils, exposer des ressources d'interface utilisateur et être conditionné comme une extension Claude Desktop.&lt;/p&gt;

&lt;p&gt;Pourquoi les applications MCP sont importantes&lt;br&gt;
Un serveur MCP classique peut exposer des outils et des ressources. C'est déjà utile : un LLM peut appeler un outil, obtenir une sortie structurée et poursuivre son raisonnement.&lt;/p&gt;

&lt;p&gt;Mais les applications MCP ajoutent quelque chose de plus pratique : elles permettent à un outil d’intégrer sa propre interface utilisateur embarquée.&lt;/p&gt;

&lt;p&gt;Cela modifie considérablement le modèle d'interaction.&lt;/p&gt;

&lt;p&gt;Au lieu de se contenter de renvoyer du texte, un outil peut désormais ouvrir une interface dédiée au sein du système hôte. Cette interface peut afficher l'état des entrées, présenter les résultats, guider l'utilisateur tout au long d'un flux et déclencher des appels d'outils supplémentaires. Autrement dit, l'outil cesse d'être une simple fonction distante et se comporte davantage comme une interface d'application à part entière.&lt;/p&gt;

&lt;p&gt;Dans un flux de travail éditorial, c'est beaucoup plus adapté que le simple texte brut.&lt;/p&gt;

&lt;p&gt;Générer un brouillon n'est pas le plus difficile. La difficulté réside dans la gestion de la transition entre le texte généré et le contenu prêt à être publié. C'est là qu'une interface utilisateur d'application MCP s'avère utile : elle structure le processus.&lt;/p&gt;

&lt;p&gt;Le cas d'utilisation de Darkwood&lt;br&gt;
Le cas d'utilisation concret est ici simple à expliquer.&lt;/p&gt;

&lt;p&gt;Cette application MCP est utilisée pour faciliter la publication d'un article de blog sur Darkwood.&lt;/p&gt;

&lt;p&gt;Le flux de travail commence par une première étape, GenerateDraft, qui produit une ébauche initiale à partir d'un sujet ou d'un contexte.&lt;/p&gt;

&lt;p&gt;Vient ensuite la deuxième étape, PublishDraft, qui gère le processus de publication. Si le brouillon n'est pas encore satisfaisant, le processus peut se poursuivre. Il est possible de revenir en arrière et de procéder à une correction ou une révision avant de tenter une nouvelle publication.&lt;/p&gt;

&lt;p&gt;Cette boucle est importante.&lt;/p&gt;

&lt;p&gt;En pratique, le processus de publication est rarement linéaire. Une première ébauche peut être trop brouillonne, trop générique, trop longue, ou tout simplement ne pas correspondre à l'intention éditoriale. C'est pourquoi l'application MCP est conçue autour d'une idée réaliste : la publication est l'objectif final, mais l'itération fait partie intégrante du cheminement.&lt;/p&gt;

&lt;p&gt;Un serveur MCP, plusieurs façons de l'utiliser&lt;br&gt;
Un aspect utile de ce projet est que la même logique MCP est réutilisée dans plusieurs modes d'exécution.&lt;/p&gt;

&lt;p&gt;Le serveur peut être utilisé :&lt;/p&gt;

&lt;p&gt;via stdio, généralement pour les intégrations locales et le packaging Claude Desktop,&lt;br&gt;
via HTTP, pour les hôtes basés sur un navigateur ou les points de terminaison MCP locaux,&lt;br&gt;
via le serveur Symfony, lorsque vous souhaitez une configuration HTTP plus standard autour de public/index.php,&lt;br&gt;
via une extension Claude Desktop, conditionnée sous forme de .mcpb,&lt;br&gt;
et, dans tous ces cas, en tant qu'outil compatible avec l'application MCP lorsque l'hôte prend en charge l'interface utilisateur intégrée.&lt;br&gt;
C'est important du point de vue de l'architecture : la logique métier n'est pas liée à un seul client ni à un seul protocole de transport. Le protocole de transport change, le modèle d'orchestration évolue légèrement, mais l'interface MCP reste la même.&lt;/p&gt;

&lt;p&gt;Architecture&lt;br&gt;
La manière la plus simple de comprendre le projet est de le diviser en quatre rôles : l’hôte, le serveur PHP MCP, l’interface utilisateur de l’application MCP et la couche d’orchestration.&lt;/p&gt;

&lt;p&gt;Vue d'ensemble&lt;br&gt;
De manière générale, le système fonctionne comme suit :&lt;/p&gt;

&lt;p&gt;schema-architecture&lt;/p&gt;

&lt;p&gt;un hôte MCP se connecte au serveur PHP,&lt;br&gt;
l'hôte découvre les outils et ressources disponibles,&lt;br&gt;
l'hôte appelle un outil tel que GenerateDraft ou PublishDraft,&lt;br&gt;
si l'outil déclare une ressource d'interface utilisateur, l'hôte charge également la vue d'application MCP correspondante.&lt;br&gt;
l'interface utilisateur et l'hôte communiquent entre eux via JSON-RPC sur postMessage,&lt;br&gt;
et l'outil de transfert d'appels de l'hôte renvoie les appels au serveur PHP.&lt;br&gt;
Voici l'idée clé : l'interface utilisateur ne communique pas directement avec le serveur. L'hôte fait office d'intermédiaire.&lt;/p&gt;

&lt;p&gt;Cette séparation est utile car elle permet de conserver l'interface utilisateur portable sur les hôtes compatibles tout en préservant un contrat MCP propre côté serveur.&lt;/p&gt;

&lt;p&gt;Transports&lt;br&gt;
Le projet soutient deux principaux modes de transport.&lt;/p&gt;

&lt;p&gt;Stdio&lt;br&gt;
En mode stdio, l'hôte démarre le serveur PHP en tant que sous-processus et communique via STDIN et STDOUT.&lt;/p&gt;

&lt;p&gt;C'est le cas idéal pour les extensions Claude Desktop. L'hôte lance le serveur, envoie des messages JSON-RPC via l'entrée standard et lit les réponses depuis la sortie standard.&lt;/p&gt;

&lt;p&gt;Ce mode est simple, local et efficace lorsque le client est responsable de la gestion des processus.&lt;/p&gt;

&lt;p&gt;HTTP&lt;br&gt;
En mode HTTP, le serveur expose un point de terminaison MCP tel que POST /mcp.&lt;/p&gt;

&lt;p&gt;Ce mode est utile pour les hôtes orientés navigateur, les tests locaux ou toute configuration où une limite HTTP est plus pratique qu'un processus enfant.&lt;/p&gt;

&lt;p&gt;Dans ce projet, le protocole HTTP peut être servi de deux manières :&lt;/p&gt;

&lt;p&gt;grâce à un processus dédié et durable tel que le flow worker,&lt;br&gt;
ou via un point d'entrée web plus traditionnel tel que public/index.php.&lt;br&gt;
Messagerie&lt;br&gt;
Une fois connectés, l'hôte et le serveur communiquent avec JSON-RPC 2.0.&lt;/p&gt;

&lt;p&gt;Cela signifie que le modèle d'interaction reste clair et explicite :&lt;/p&gt;

&lt;p&gt;l'hôte envoie des requêtes,&lt;br&gt;
le serveur renvoie des réponses, Des notifications peuvent être échangées lorsqu'aucune réponse n'est attendue.&lt;br&gt;
Cela reste vrai, que le transport soit stdio ou HTTP. Le transport change, mais le contrat du protocole demeure le même.&lt;/p&gt;

&lt;p&gt;De plus, lorsque des applications MCP sont impliquées, l'interface utilisateur communique avec l'hôte via un autre canal JSON-RPC, cette fois via postMessage.&lt;/p&gt;

&lt;p&gt;Il y a donc en réalité deux niveaux de communication :&lt;/p&gt;

&lt;p&gt;hôte ↔ serveur via MCP,&lt;br&gt;
Interface utilisateur ↔ hôte via le pont MCP Apps.&lt;br&gt;
C’est cette séparation qui rend possible l’intégration d’une interface utilisateur sans coupler directement le front-end à l’environnement d’exécution PHP.&lt;/p&gt;

&lt;p&gt;Cycle de vie&lt;br&gt;
Une interaction typique se déroule en quelques étapes prévisibles.&lt;/p&gt;

&lt;p&gt;Tout d'abord, l'hôte initialise la connexion et découvre les capacités du serveur.&lt;/p&gt;

&lt;p&gt;Ensuite, il liste les outils et les ressources.&lt;/p&gt;

&lt;p&gt;Lorsqu'un utilisateur déclenche un outil, l'hôte appelle cet outil sur le serveur. Si cet outil est associé à une ressource d'interface utilisateur, l'hôte lit également la ressource ui://... correspondante et l'affiche dans une iframe isolée.&lt;/p&gt;

&lt;p&gt;À ce stade, l'application MCP devient interactive. Elle peut recevoir les données saisies par l'outil, afficher le résultat et déclencher des actions complémentaires via l'hôte.&lt;/p&gt;

&lt;p&gt;Dans le flux de travail Darkwood, cela signifie que l'utilisateur ou l'assistant peut passer de la génération d'ébauches à la publication, et éventuellement revenir dans une boucle de correction, sans quitter le modèle d'interaction MCP.&lt;/p&gt;

&lt;p&gt;Ce qui se passe où&lt;br&gt;
Le serveur PHP MCP possède la surface de protocole :&lt;/p&gt;

&lt;p&gt;initialiser&lt;br&gt;
tools/list&lt;br&gt;
outils/appel&lt;br&gt;
ressources/liste&lt;br&gt;
ressources/lire&lt;br&gt;
L’interface utilisateur de l’application MCP est responsable de l’expérience interactive.&lt;/p&gt;

&lt;p&gt;L'hôte gère le transport, le rendu et la liaison entre l'interface utilisateur et le serveur.&lt;/p&gt;

&lt;p&gt;La couche Flow gère l'orchestration des flux de travail lorsque celle-ci est nécessaire.&lt;/p&gt;

&lt;p&gt;Ce dernier point est important car les flux éditoriaux impliquent souvent plus d'une action et plus d'une transition d'état.&lt;/p&gt;

&lt;p&gt;Stdio, HTTP et le serveur Symfony ne sont pas la même chose&lt;br&gt;
Même si la logique métier reste la même, le modèle d'exécution n'est pas identique d'un mode à l'autre.&lt;/p&gt;

&lt;p&gt;Avec stdio et un worker HTTP persistant, vous pouvez envisager un processus persistant. Cela ouvre la voie à des fonctionnalités asynchrones, des boucles d'événements et une orchestration continue au sein du même environnement d'exécution.&lt;/p&gt;

&lt;p&gt;Avec Symfony Server, le modèle est plus classique. Chaque requête est traitée dans un cycle HTTP synchrone. C'est généralement plus simple à mettre en œuvre, mais cela implique une orchestration différente : la couche HTTP reste synchronisée, tandis que la logique de workflow est déléguée à Flow ou à une coordination externe.&lt;/p&gt;

&lt;p&gt;Il est important de faire explicitement cette distinction, car « prend en charge HTTP » ne signifie pas automatiquement « prend en charge le même modèle d'exécution partout ».&lt;/p&gt;

&lt;p&gt;Pourquoi cette conception est-elle efficace pour les flux de travail de publication ?&lt;br&gt;
Le flux de publication d'un blog se trouve dans une situation délicate.&lt;/p&gt;

&lt;p&gt;Il ne s'agit pas d'un simple appel de fonction, ni d'une application back-office complète. Elle nécessite une structure suffisante pour gérer l'état et les décisions, tout en restant assez légère pour être déclenchée par une conversation avec une IA.&lt;/p&gt;

&lt;p&gt;C’est précisément pourquoi les applications MCP sont parfaitement adaptées ici.&lt;/p&gt;

&lt;p&gt;L'interface de l'outil confère au modèle une surface d'interaction. L'interface utilisateur offre à l'utilisateur ou au client une vue contrôlée du flux de travail. Enfin, l'orchestration du flux permet au système de gérer les transitions en plusieurs étapes.&lt;/p&gt;

&lt;p&gt;Cette combinaison est efficace car chaque couche reste ciblée :&lt;/p&gt;

&lt;p&gt;le modèle décide quand utiliser l'outil,&lt;br&gt;
l'outil expose le flux de travail,&lt;br&gt;
l'interface utilisateur rend le flux de travail visible,&lt;br&gt;
le serveur l'exécute sans problème.&lt;br&gt;
Utilisation de l'application MCP dans Claude&lt;br&gt;
L'un des résultats pratiques de ce projet est que le même serveur MCP peut être intégré sous forme d'extension Claude Desktop.&lt;/p&gt;

&lt;p&gt;Cela signifie que le projet n'est pas seulement un prototype local ou une démo pour navigateur. Il peut être installé dans Claude et utilisé comme une véritable intégration d'outil.&lt;/p&gt;

&lt;p&gt;Dans cette configuration :&lt;/p&gt;

&lt;p&gt;le manifeste de l'extension définit comment Claude lance le serveur,&lt;br&gt;
le serveur fonctionne via stdio,&lt;br&gt;
Claude fait office d'hôte du MCP,&lt;br&gt;
et l'application MCP devient disponible en tant qu'outil au sein du client.&lt;br&gt;
Voilà un bon exemple qui illustre l'importance de séparer les protocoles de transport de la logique métier. Un même serveur PHP MCP peut ainsi gérer le développement local, les expérimentations HTTP et l'utilisation de Claude Desktop sans qu'il soit nécessaire de réécrire son fonctionnement de base.&lt;/p&gt;

&lt;p&gt;De la démo aux outils éditoriaux réels&lt;br&gt;
Ce qui rend ce projet intéressant, ce n'est pas l'existence d'un énième générateur de brouillons.&lt;/p&gt;

&lt;p&gt;C’est le fait que le projet définit déjà une forme réutilisable pour les outils éditoriaux :&lt;/p&gt;

&lt;p&gt;un outil pour produire un brouillon,&lt;br&gt;
un outil pour publier,&lt;br&gt;
un endroit pour gérer les révisions,&lt;br&gt;
une couche d'interface utilisateur pour prendre en charge l'interaction,&lt;br&gt;
et un serveur MCP indépendant du transport en dessous.&lt;br&gt;
C'est une base beaucoup plus durable qu'une chaîne de distribution ponctuelle.&lt;/p&gt;

&lt;p&gt;Une fois cette structure en place, l'amélioration du flux de travail devient beaucoup plus simple. Vous pouvez optimiser la qualité de la génération, enrichir les métadonnées de publication, ajouter des validations ou intégrer un véritable CMS. Le contrat entre l'hébergeur, l'interface utilisateur et le serveur reste stable.&lt;/p&gt;

&lt;p&gt;Open source&lt;br&gt;
Le projet complet est disponible en tant que dépôt open-source sur GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/darkwood-com/darkwood-publish-article-mcp-apps" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/darkwood-publish-article-mcp-apps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Ce projet démontre que les applications MCP ne se limitent pas à proposer des outils aux titulaires d'un LLM. Elles visent également à proposer des flux de travail utilisables.&lt;/p&gt;

&lt;p&gt;Dans le cas de Darkwood, le plus intéressant n'est pas que PHP puisse communiquer avec MCP. Le plus intéressant est qu'un serveur PHP MCP puisse désormais servir de backend à une petite application éditoriale, accessible depuis un client d'IA, avec à la fois la sémantique de l'outil et une interface utilisateur intégrée.&lt;/p&gt;

&lt;p&gt;Cela fait passer l'intégration de « le modèle peut appeler une fonction » à « le modèle peut participer à un flux de travail de publication contrôlé ».&lt;/p&gt;

&lt;p&gt;Et c'est un endroit bien plus utile.&lt;/p&gt;

&lt;p&gt;Sources Démarrage rapide des applications MCP&lt;br&gt;
README.md&lt;br&gt;
php-mcp-apps-mvp-architecture.md&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>mcp</category>
      <category>php</category>
    </item>
    <item>
      <title>🚀 Je construis un moteur de dictée en PHP (Flow + Symfony + Whisper.cpp)</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 22 Feb 2026 22:24:27 +0000</pubDate>
      <link>https://forem.com/matyo91/je-construis-un-moteur-de-dictee-en-php-flow-symfony-whispercpp-48e2</link>
      <guid>https://forem.com/matyo91/je-construis-un-moteur-de-dictee-en-php-flow-symfony-whispercpp-48e2</guid>
      <description>&lt;p&gt;Construire un moteur de dictée en 2026 est trivial.&lt;/p&gt;

&lt;p&gt;Construire une architecture propre autour d’un moteur de dictée est plus intéressant.&lt;/p&gt;

&lt;p&gt;Cet article présente Flowvox, un MVP de moteur de transcription audio développé en PHP, en s’appuyant sur :&lt;/p&gt;

&lt;p&gt;Symfony&lt;br&gt;
Symfony Messenger&lt;br&gt;
Flow : orchestrateur maison&lt;br&gt;
ffmpeg&lt;br&gt;
whisper.cpp&lt;br&gt;
Le code source est disponible en open source : 👉 &lt;a href="https://github.com/darkwood-com/flowvox" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/flowvox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’objectif n’était pas simplement d’utiliser Whisper. L’objectif était de structurer correctement le pipeline.&lt;/p&gt;

&lt;p&gt;Le problème : la transcription n’est qu’une étape&lt;br&gt;
Un moteur vocal minimal peut se résumer à :&lt;/p&gt;

&lt;p&gt;Audio → Texte&lt;br&gt;
Mais dans un système réel, plusieurs contraintes apparaissent :&lt;/p&gt;

&lt;p&gt;Déclenchement start / stop&lt;br&gt;
Finalisation propre du fichier audio&lt;br&gt;
Gestion d’état du recorder&lt;br&gt;
Orchestration des étapes&lt;br&gt;
Extension vers post-traitement (résumé, LLM, analyse)&lt;br&gt;
La question devient alors :&lt;/p&gt;

&lt;p&gt;Comment modéliser un pipeline audio propre, extensible et maîtrisé ?&lt;/p&gt;

&lt;p&gt;Stack technique&lt;br&gt;
Le MVP repose sur :&lt;/p&gt;

&lt;p&gt;PHP 8+&lt;br&gt;
Symfony&lt;br&gt;
Symfony Messenger&lt;br&gt;
Flow (orchestrateur)&lt;br&gt;
ffmpeg (captation audio locale)&lt;br&gt;
whisper.cpp (transcription open source locale)&lt;br&gt;
Aucune API distante. Aucun service cloud. Transcription 100% locale.&lt;/p&gt;

&lt;p&gt;Architecture générale&lt;br&gt;
L’architecture est organisée en trois flows :&lt;/p&gt;

&lt;p&gt;InputProvider → Recorder → Transcribe&lt;br&gt;
Chaque étape est isolée et responsable d’un rôle précis.&lt;/p&gt;

&lt;p&gt;InputProviderFlow&lt;br&gt;
Responsabilité :&lt;/p&gt;

&lt;p&gt;Écouter les commandes voice:start et voice:stop&lt;br&gt;
Émettre un VoiceControlEvent&lt;br&gt;
Les commandes CLI déclenchent des messages via Symfony Messenger.&lt;/p&gt;

&lt;p&gt;Le worker, en arrière-plan, reçoit ces événements et les injecte dans Flow.&lt;/p&gt;

&lt;p&gt;Ce découplage permet :&lt;/p&gt;

&lt;p&gt;Un contrôle granulaire&lt;br&gt;
Une gestion multi-session&lt;br&gt;
Une séparation claire des responsabilités&lt;br&gt;
RecorderFlow&lt;br&gt;
Responsabilité :&lt;/p&gt;

&lt;p&gt;Piloter une instance de VoiceRecorder&lt;br&gt;
Gérer le cycle de vie d’un processus ffmpeg&lt;br&gt;
Le VoiceRecorder encapsule un processus système lancé via :&lt;/p&gt;

&lt;p&gt;Symfony\Component\Process\Process&lt;br&gt;
Problème central :&lt;/p&gt;

&lt;p&gt;Comment gérer proprement start / stop sans corrompre le fichier audio ?&lt;/p&gt;

&lt;p&gt;Trois états sont explicitement modélisés :&lt;/p&gt;

&lt;p&gt;idle&lt;br&gt;
recording&lt;br&gt;
stopping&lt;br&gt;
Lors d’un stop, un SIGINT est envoyé à ffmpeg afin de finaliser correctement le header WAV.&lt;/p&gt;

&lt;p&gt;L’état stopping évite :&lt;/p&gt;

&lt;p&gt;Les double-start&lt;br&gt;
Les conflits concurrents&lt;br&gt;
Les fichiers incomplets&lt;br&gt;
Le processus est maîtrisé, pas subi.&lt;/p&gt;

&lt;p&gt;TranscribeFlow&lt;br&gt;
Responsabilité :&lt;/p&gt;

&lt;p&gt;Recevoir un fichier WAV finalisé&lt;br&gt;
Lancer whisper.cpp&lt;br&gt;
Produire un texte transcrit&lt;br&gt;
Whisper est exécuté localement via CLI.&lt;/p&gt;

&lt;p&gt;Le MVP reste volontairement simple :&lt;/p&gt;

&lt;p&gt;Pas de streaming&lt;br&gt;
Pas de chunking temps réel&lt;br&gt;
Une transcription synchrone&lt;br&gt;
L’objectif est de valider l’intégration et l’orchestration.&lt;/p&gt;

&lt;p&gt;Worker et orchestration&lt;br&gt;
Le moteur fonctionne via un worker Symfony :&lt;/p&gt;

&lt;p&gt;php bin/console voice:worker&lt;br&gt;
Ce worker :&lt;/p&gt;

&lt;p&gt;Instancie Flow&lt;br&gt;
Enregistre les flows&lt;br&gt;
Écoute Symfony Messenger&lt;br&gt;
Ordonne l’exécution des étapes&lt;br&gt;
Commandes disponibles :&lt;/p&gt;

&lt;p&gt;voice:start&lt;br&gt;
voice:stop&lt;br&gt;
voice:worker-list&lt;br&gt;
Le flux complet devient :&lt;/p&gt;

&lt;p&gt;voice:start&lt;br&gt;
→ Recorder démarre&lt;br&gt;
→ voice:stop&lt;br&gt;
→ Recorder finalise&lt;br&gt;
→ TranscribeFlow s’exécute&lt;br&gt;
→ Texte produit&lt;br&gt;
Sans état global externe.&lt;/p&gt;

&lt;p&gt;Pourquoi Flow ?&lt;br&gt;
Flow permet :&lt;/p&gt;

&lt;p&gt;Une architecture orientée pipeline&lt;br&gt;
Des stratégies d’Input Processing (IP Strategy)&lt;br&gt;
Une gestion explicite des événements&lt;br&gt;
Une séparation nette entre orchestration et logique métier&lt;br&gt;
Le système n’est pas couplé à Whisper.&lt;/p&gt;

&lt;p&gt;Whisper est une implémentation. Flow est la structure.&lt;/p&gt;

&lt;p&gt;Ce que valide le MVP&lt;br&gt;
Gestion propre d’un processus système&lt;br&gt;
Modélisation explicite des états&lt;br&gt;
Orchestration événementielle&lt;br&gt;
Extensibilité du pipeline&lt;br&gt;
Ce n’est pas un produit.&lt;/p&gt;

&lt;p&gt;C’est une base architecturale.&lt;/p&gt;

&lt;p&gt;Évolutions possibles&lt;br&gt;
Les prochaines itérations naturelles :&lt;/p&gt;

&lt;p&gt;Streaming par chunk audio&lt;br&gt;
Transcription parallèle&lt;br&gt;
Post-traitement LLM&lt;br&gt;
Intégration NativePHP (desktop)&lt;br&gt;
Support mobile&lt;br&gt;
Batching multi-modèles&lt;br&gt;
Mais ces évolutions ne changent pas le cœur :&lt;/p&gt;

&lt;p&gt;Une architecture claire. Une orchestration maîtrisée. Un pipeline extensible.&lt;/p&gt;

&lt;p&gt;Code source&lt;br&gt;
Le dépôt open source est disponible ici :&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/darkwood-com/flowvox" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/flowvox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contributions, suggestions et retours sont les bienvenus.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Construire un moteur vocal en PHP est simple.&lt;/p&gt;

&lt;p&gt;Construire une architecture propre autour d’un moteur vocal est plus intéressant.&lt;/p&gt;

&lt;p&gt;Flowvox valide un principe :&lt;/p&gt;

&lt;p&gt;La transcription n’est qu’un composant. L’orchestration est la véritable structure.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>opensource</category>
      <category>php</category>
    </item>
    <item>
      <title>⚔️ Découverte de l'extension cataclysme Hearthstone</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 20 Feb 2026 22:06:20 +0000</pubDate>
      <link>https://forem.com/matyo91/decouverte-de-lextension-cataclysme-hearthstone-5441</link>
      <guid>https://forem.com/matyo91/decouverte-de-lextension-cataclysme-hearthstone-5441</guid>
      <description>&lt;p&gt;La nouvelle ère destructrice arrive le 17 mars 2026&lt;/p&gt;

&lt;p&gt;L’auberge est sur le point d’être secouée comme jamais. L’extension Cataclysme s’inspire d’une version alternative de l’univers de World of Warcraft, où Aile de mort n’a jamais été battu et règne en maître sur Azeroth.&lt;/p&gt;

&lt;p&gt;🌋 Une intrigue sombre : la menace d’Aile de mort&lt;br&gt;
À la fin de Par-delà les voies temporelles, Chromie déclenche par erreur une ligne temporelle cauchemardesque dans laquelle Aile de mort triomphe et envahit Azeroth avec ses six terribles lieutenants colossaux.&lt;/p&gt;

&lt;p&gt;Dans Cataclysme :&lt;/p&gt;

&lt;p&gt;Le ciel est rougeoyant&lt;br&gt;
Azeroth doit à nouveau se défendre&lt;br&gt;
Les héros et héroïnes doivent rallier les Vols draconiques&lt;br&gt;
De nouvelles cartes et mécaniques sont là pour faire pencher la balance&lt;br&gt;
💥 Nouvelle carte héroïque : Aile de Mort le Brise-monde&lt;br&gt;
L’une des grandes nouveautés de Cataclysme est la première carte héroïque Deathwing jouable dans Hearthstone :&lt;/p&gt;

&lt;p&gt;En la jouant, votre héros se transforme en Aile de Mort le Brise-monde&lt;br&gt;
Son Cri de guerre vous permet de choisir un Cataclysme&lt;br&gt;
Vous pouvez déclencher différentes actions destructrices selon vos choix et ressources&lt;br&gt;
Plus vous utilisez le mot-clé Convocation avant de la jouer, plus vous pouvez déclencher de Cataclysmes simultanément&lt;br&gt;
🧱 Mécaniques clés de Cataclysme&lt;br&gt;
🔹 Convocation&lt;br&gt;
Ce mot-clé est au cœur de l’extension :&lt;/p&gt;

&lt;p&gt;Jouer un serviteur avec Convocation invoque un soldat colosse sur le plateau&lt;br&gt;
Plus vous utilisez Convocation, plus votre serviteur colossal devient puissant&lt;br&gt;
Convocation renforce aussi Aile de Mort le Brise-monde pour déclencher davantage de Cataclysmes&lt;br&gt;
🔹 Retour des serviteurs Colossaux&lt;br&gt;
Géants qui occupent plusieurs cases du plateau&lt;br&gt;
Sont accompagnés d’appendices (bras, têtes) qui ont leurs propres effets&lt;br&gt;
Une nouvelle légendaire colossale est disponible pour chaque classe fidélisée à Aile de mort (ex : Ragnaros le Grand Feu pour les guerriers)&lt;br&gt;
🔹 Scission&lt;br&gt;
Ce mot-clé innovant affecte certaines cartes de type défense des Vols draconiques :&lt;/p&gt;

&lt;p&gt;Quand vous piochez une carte Scission, elle se sépare en deux morceaux&lt;br&gt;
Ces morceaux se placent aux extrémités de votre main&lt;br&gt;
Si vous les réunissez en jouant les cartes entre eux, ils se recombinent pour déclencher deux effets pour le prix d’un seul&lt;br&gt;
🌀 Autres effets innovants&lt;br&gt;
Cataclysme ajoute également des cartes qui permettent de :&lt;/p&gt;

&lt;p&gt;Cibler des cartes spécifiques dans votre main&lt;br&gt;
Manipuler la main à des fins tactiques&lt;br&gt;
Renforcer votre deck pour des stratégies plus dynamiques&lt;br&gt;
🛡️ Les Vols draconiques en renfort&lt;br&gt;
Pour contrer la puissance d’Aile de mort :&lt;/p&gt;

&lt;p&gt;🌟 Les classes mage, prêtre, druide, chasseur, paladin bénéficient d’un nouvel Aspect draconique légendaire. Par exemple, le chasseur obtient Ébyssian du Vol noir, capable de se transformer en puissant dragon.&lt;/p&gt;

&lt;p&gt;🎁 Récompenses gratuites et événements&lt;br&gt;
Blizzard a prévu un flot de récompenses pour préparer votre aventure :&lt;/p&gt;

&lt;p&gt;🎉 Avant la sortie :&lt;br&gt;
Paquets gratuits à gagner durant les diffusions Twitch&lt;br&gt;
Accès temporaire aux cartes des extensions Au cœur du Rêve d’émeraude et La cité perdue d’Un’Goro du 10 mars jusqu’à la sortie de Cataclysme&lt;br&gt;
Carte légendaire Maître de guerre Corne-Noire offerte au bonus de connexion&lt;br&gt;
Drops Twitch jusqu’à plusieurs paquets gratuits&lt;br&gt;
Récompenses pour événements en jeu (quêtes, vagues, hauts faits)&lt;br&gt;
📅 Pendant et après le lancement :&lt;br&gt;
Carte légendaire colossale gratuite au parcours de récompenses de la taverne&lt;br&gt;
Récompenses hebdomadaires en connexion (paquets, cartes signature)&lt;br&gt;
Récompenses liées aux quêtes de l’événement de lancement&lt;br&gt;
Dos de carte spécial si vous terminez certains exploits en Bras de fer&lt;br&gt;
👉 Bref : beaucoup de contenu gratuit à récupérer sans dépenser un centime si tu joues régulièrement.&lt;/p&gt;

&lt;p&gt;📆 Calendrier important&lt;br&gt;
🗓️ 10-17 mars : Bras de fer de prélancement – essayez la carte Aile de Mort et gagnez des récompenses 🗓️ 17 mars 2026 : Lancement de l’extension Cataclysme 📆 Du 10 mars au lancement : Accès temporaire aux cartes d’anciennes extensions pour tester des decks&lt;/p&gt;

&lt;p&gt;💡 En résumé : qu’est-ce qui change ?&lt;br&gt;
Cataclysme apporte une histoire alternative intense&lt;br&gt;
Aile de mort est jouable et destructrice&lt;br&gt;
De puissants mots-clés : Convocation, Scission&lt;br&gt;
Retour des serviteurs colossaux&lt;br&gt;
Beaucoup de récompenses gratuites&lt;br&gt;
Un gameplay plus tactique et stratégique&lt;br&gt;
💬 Mon avis Darkwood : Cette extension promet une expérience plus riche tactiquement, avec des decks qui récompensent la planification et la gestion de main. Elle offre aussi de nombreuses opportunités gratuites pour les joueurs Free-to-Play.&lt;/p&gt;

&lt;p&gt;Références :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hearthstone.blizzard.com/fr-fr/expansions-adventures/cataclysm" rel="noopener noreferrer"&gt;https://hearthstone.blizzard.com/fr-fr/expansions-adventures/cataclysm&lt;/a&gt; "Cataclysme"&lt;br&gt;
&lt;a href="https://hearthstone.blizzard.com/fr-fr/news/24245219/aile-de-mort-contre-attaque-dans-cataclysme-la-nouvelle-extension-de-hearthstone" rel="noopener noreferrer"&gt;https://hearthstone.blizzard.com/fr-fr/news/24245219/aile-de-mort-contre-attaque-dans-cataclysme-la-nouvelle-extension-de-hearthstone&lt;/a&gt; "Aile de mort contre-attaque dans CATACLYSME, la nouvelle extension de Hearthstone - Hearthstone"&lt;br&gt;
&lt;a href="https://hearthstone.blizzard.com/fr-fr/news/24242864/votre-guide-pour-decouvrir-les-cartes-de-cataclysme-et-obtenir-des-recompenses-gratuites" rel="noopener noreferrer"&gt;https://hearthstone.blizzard.com/fr-fr/news/24242864/votre-guide-pour-decouvrir-les-cartes-de-cataclysme-et-obtenir-des-recompenses-gratuites&lt;/a&gt; "Votre guide pour découvrir les cartes de CATACLYSME et obtenir des récompenses gratuites - Hearthstone"&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖 Développement parallèle d'IA avec Cursor et Git Worktrees</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 15 Feb 2026 22:28:07 +0000</pubDate>
      <link>https://forem.com/matyo91/developpement-parallele-dia-avec-cursor-et-git-worktrees-3480</link>
      <guid>https://forem.com/matyo91/developpement-parallele-dia-avec-cursor-et-git-worktrees-3480</guid>
      <description>&lt;p&gt;Dans cet article, je souhaite présenter un exemple concret de parallélisation du développement à l'aide de Cursor, Git worktrees et d'un véritable bundle Symfony :&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/darkwood-com/ia-exception-bundle" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/ia-exception-bundle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’objectif est simple : améliorer le produit en travaillant simultanément sur deux fonctionnalités indépendantes sans conflit, grâce à des agents d’IA.&lt;/p&gt;

&lt;p&gt;Contexte&lt;br&gt;
Je travaille actuellement sur un bundle Symfony appelé :&lt;/p&gt;

&lt;p&gt;Pack d'exceptions Darkwood IA Dépôt : &lt;a href="https://github.com/darkwood-com/ia-exception-bundle" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/ia-exception-bundle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Son objectif est d'améliorer la gestion des exceptions Symfony grâce à l'IA : lorsqu'une erreur 500 se produit, le module analyse l'exception et génère des diagnostics structurés (causes probables, solutions suggérées, score de confiance, etc.).&lt;/p&gt;

&lt;p&gt;Cependant, en travaillant dessus en local, j'ai identifié deux améliorations.&lt;/p&gt;

&lt;p&gt;🟥 Problème 1 Améliorer l'icône d'erreur&lt;br&gt;
L'icône actuelle est une icône de « danger » standard de Bootstrap. Cela fonctionne, mais cela ne communique pas visuellement que l'exception est augmentée par l'IA.&lt;/p&gt;

&lt;p&gt;L'idée : Remplacez-la par une icône de danger sur le thème de l'IA plus appropriée.&lt;/p&gt;

&lt;p&gt;🟦 Problème 2 : Rendu asynchrone de l’analyse IA&lt;br&gt;
Actuellement:&lt;/p&gt;

&lt;p&gt;Une exception se produit.&lt;br&gt;
L'appel à l'IA est déclenché.&lt;br&gt;
La réponse HTTP attend l'IA.&lt;br&gt;
La page complète n'est affichée qu'une fois que l'IA a terminé.&lt;br&gt;
Cela introduit une latence.&lt;/p&gt;

&lt;p&gt;Nous voulons plutôt :&lt;/p&gt;

&lt;p&gt;Rendu immédiat des exceptions.&lt;br&gt;
L'analyse IA est chargée de manière asynchrone. La page sera mise à jour dès réception de la réponse de l'IA.&lt;br&gt;
Pour cela, nous utilisons Symfony UX.&lt;/p&gt;

&lt;p&gt;Le Défi&lt;br&gt;
Comment pouvons-nous travailler sur les deux problèmes en parallèle en utilisant Cursor sans créer de conflits de fichiers ?&lt;/p&gt;

&lt;p&gt;La réponse provient d'une idée popularisée dans des articles récents sur les agents de codage IA :&lt;/p&gt;

&lt;p&gt;Utilisez les répertoires de travail Git pour l'isolation du contexte.&lt;/p&gt;

&lt;p&gt;Petit rappel concernant les arbres de travail Git&lt;br&gt;
Un répertoire de travail Git vous permet de créer un nouveau répertoire de travail rattaché au même dépôt.&lt;/p&gt;

&lt;p&gt;Ce n'est pas un clone parfait.&lt;/p&gt;

&lt;p&gt;Il partage l'historique Git mais réside dans un répertoire physique distinct.&lt;/p&gt;

&lt;p&gt;Exemple:&lt;/p&gt;

&lt;p&gt;git worktree add ../feature-ai-icon feature/ai-icon&lt;br&gt;
git worktree add ../feature-async-render feature/async-render&lt;br&gt;
Vous avez maintenant :&lt;/p&gt;

&lt;p&gt;Dépôt principal&lt;br&gt;
Arborescence de travail A → Fonctionnalité 1&lt;br&gt;
Arborescence de travail B → Fonctionnalité 2&lt;br&gt;
Chacun peut évoluer indépendamment.&lt;/p&gt;

&lt;p&gt;Aucun conflit de fichiers. Pollution sans contexte.&lt;/p&gt;

&lt;p&gt;Pourquoi c'est important pour les agents IA&lt;br&gt;
Avec Cursor, vous pouvez affecter un agent d'IA à chaque arbre de travail.&lt;/p&gt;

&lt;p&gt;L'agent 1 travaille uniquement à l'intérieur :&lt;/p&gt;

&lt;p&gt;feature/ai-icon&lt;br&gt;
L'agent 2 travaille uniquement à l'intérieur :&lt;/p&gt;

&lt;p&gt;feature/async-render&lt;br&gt;
Chaque agent opère de manière isolée.&lt;/p&gt;

&lt;p&gt;C’est ce que nous appelons :&lt;/p&gt;

&lt;p&gt;Isolation du contexte&lt;/p&gt;

&lt;p&gt;Et c'est essentiel pour paralléliser le développement piloté par l'IA.&lt;/p&gt;

&lt;p&gt;Mise en œuvre pratique&lt;br&gt;
Étape 1 Créer deux arbres de travail&lt;br&gt;
J'ai créé manuellement deux arborescences de travail correspondant aux deux problèmes.&lt;/p&gt;

&lt;p&gt;Ensuite, pour chaque arbre de travail, je :&lt;/p&gt;

&lt;p&gt;Ouvert dans le curseur&lt;br&gt;
J'ai collé la description du problème GitHub&lt;br&gt;
Laisser l'agent IA implémenter la fonctionnalité&lt;br&gt;
Étape 2 Rendu asynchrone des exceptions&lt;br&gt;
Pour la fonctionnalité asynchrone, l'IA a implémenté :&lt;/p&gt;

&lt;p&gt;Un chargeur de route dédié&lt;br&gt;
Un IAExceptionController&lt;br&gt;
Un système de stockage de contexte&lt;br&gt;
Un service d'analyse différée de l'IA Comportement conditionnel lorsque le mode asynchrone est activé&lt;br&gt;
Le flux de travail est maintenant le suivant :&lt;/p&gt;

&lt;p&gt;L'exception est générée instantanément.&lt;br&gt;
Symfony UX charge l'analyse IA de manière asynchrone.&lt;br&gt;
La page se met à jour dynamiquement dès réception de la réponse de l'IA.&lt;br&gt;
Cela améliore considérablement la performance perçue.&lt;/p&gt;

&lt;p&gt;Amélioration de l'icône de l'étape 3&lt;br&gt;
Dans le deuxième arbre de travail, l'agent :&lt;/p&gt;

&lt;p&gt;Icône de danger Bootstrap remplacée&lt;br&gt;
Introduction d'un SVG plus épuré sur le thème de l'IA&lt;br&gt;
Compatibilité de mise en page maintenue&lt;br&gt;
Style Bootstrap préservé&lt;br&gt;
Cela était totalement indépendant de la fonctionnalité asynchrone.&lt;/p&gt;

&lt;p&gt;Pas de code qui se chevauche.&lt;/p&gt;

&lt;p&gt;Basculement entre les fonctionnalités&lt;br&gt;
Comme il s'agit d'arborescences de travail, changer de contexte est facile.&lt;/p&gt;

&lt;p&gt;Dans mon application Darkwood locale :&lt;/p&gt;

&lt;p&gt;Le paquet est normalement chargé via Composer.&lt;br&gt;
J'ai temporairement lié le paquet à l'arborescence de travail correspondante.&lt;br&gt;
Cache vidé.&lt;br&gt;
Une exception contrôlée a été déclenchée.&lt;br&gt;
Je pourrais alors tester chaque fonctionnalité indépendamment.&lt;/p&gt;

&lt;p&gt;Passer de la fonctionnalité A à la fonctionnalité B est uniquement nécessaire :&lt;/p&gt;

&lt;p&gt;Modification du lien symbolique&lt;br&gt;
Nettoyage du cache&lt;br&gt;
Rafraîchissant&lt;br&gt;
Pas de fusion. Pas de rebasage. Aucun conflit.&lt;/p&gt;

&lt;p&gt;Nos réalisations&lt;br&gt;
Nous avons maintenant :&lt;/p&gt;

&lt;p&gt;Deux demandes de fusion indépendantes&lt;br&gt;
Deux agents d'IA isolés Aucun conflit de fichiers&lt;br&gt;
Séparation claire des préoccupations&lt;br&gt;
Ces modifications ont été publiées dans :&lt;/p&gt;

&lt;p&gt;👉 v1.0.2 &lt;a href="https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette version introduit :&lt;/p&gt;

&lt;p&gt;Améliorations de l'interface utilisateur pour le rendu des exceptions d'IA&lt;br&gt;
Chargement de l'analyse IA asynchrone&lt;br&gt;
Séparation architecturale améliorée pour les développements futurs&lt;br&gt;
Quand cela va-t-il se rompre ?&lt;br&gt;
Le développement parallèle fonctionne mieux lorsque les problèmes sont :&lt;/p&gt;

&lt;p&gt;Clairement séparés&lt;br&gt;
Cibler différentes couches&lt;br&gt;
Ne pas modifier les mêmes fichiers&lt;br&gt;
Si deux problèmes se modifient :&lt;/p&gt;

&lt;p&gt;Le même service&lt;br&gt;
Le même modèle Twig&lt;br&gt;
La même manette&lt;br&gt;
Vous rencontrerez des conflits de fusion plus tard.&lt;/p&gt;

&lt;p&gt;Le développement parallèle de l'IA nécessite une décomposition adéquate des tâches.&lt;/p&gt;

&lt;p&gt;Considérations relatives à la production&lt;br&gt;
Si vous poussez plusieurs branches :&lt;/p&gt;

&lt;p&gt;Vous pourriez rencontrer des conflits de ports au niveau local.&lt;br&gt;
Les environnements de prévisualisation peuvent nécessiter une configuration.&lt;br&gt;
Les fonctionnalités asynchrones peuvent nécessiter la persistance du contexte.&lt;br&gt;
Ces problèmes sont gérables, mais doivent être pris en compte.&lt;/p&gt;

&lt;p&gt;Pourquoi c'est puissant&lt;br&gt;
La véritable valeur ne réside pas dans le modèle d'IA.&lt;/p&gt;

&lt;p&gt;C'est:&lt;/p&gt;

&lt;p&gt;Isolement&lt;br&gt;
Orchestration&lt;br&gt;
Contrôle du contexte&lt;br&gt;
Les arborescences de travail Git nous permettent de faire évoluer les sessions de codage IA sans chaos.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Le développement parallèle de l'IA ne consiste pas à exécuter davantage de modèles.&lt;/p&gt;

&lt;p&gt;Il s'agit d'isoler correctement le contexte.&lt;/p&gt;

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

&lt;p&gt;Arbres de travail Git&lt;br&gt;
Agents de curseur&lt;br&gt;
Expérience utilisateur Symfony&lt;br&gt;
Décomposition propre des problèmes&lt;br&gt;
Vous pouvez faire évoluer en toute sécurité des systèmes complexes sans compromettre vos propres modifications.&lt;/p&gt;

&lt;p&gt;Références&lt;br&gt;
Ensemble d'exceptions IA du référentiel &lt;a href="https://github.com/darkwood-com/ia-exception-bundle" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/ia-exception-bundle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Version 1.0.2 &lt;a href="https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arbres de travail Git pour agents de codage IA parallèles Upsun &lt;a href="https://devcenter.upsun.com/posts/git-worktrees-for-parallel-ai-coding-agents/" rel="noopener noreferrer"&gt;https://devcenter.upsun.com/posts/git-worktrees-for-parallel-ai-coding-agents/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arbres de travail Git : La puissance des agents parallèles de Cursor DEV.to &lt;a href="https://dev.to/arifszn/git-worktrees-the-power-behind-cursors-parallel-agents-19j1"&gt;https://dev.to/arifszn/git-worktrees-the-power-behind-cursors-parallel-agents-19j1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuration des arborescences de travail de la documentation du curseur &lt;a href="https://cursor.com/fr/docs/configuration/worktrees" rel="noopener noreferrer"&gt;https://cursor.com/fr/docs/configuration/worktrees&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>git</category>
      <category>php</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🤖 Comment rendre Darkwood prêt pour les agents</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Thu, 12 Feb 2026 07:55:32 +0000</pubDate>
      <link>https://forem.com/matyo91/comment-rendre-darkwood-pret-pour-les-agents-3ial</link>
      <guid>https://forem.com/matyo91/comment-rendre-darkwood-pret-pour-les-agents-3ial</guid>
      <description>&lt;p&gt;Les sites web ne sont plus seulement consommés par les humains.&lt;/p&gt;

&lt;p&gt;Elles sont analysées, résumées, classées et interprétées par des agents d'IA.&lt;/p&gt;

&lt;p&gt;Les moteurs de recherche ont constitué la première vague. Les agents utilisant LLM représentent la seconde.&lt;/p&gt;

&lt;p&gt;Récemment, j'ai décidé d'auditer darkwood.com et d'y apporter des améliorations concrètes afin de le rendre plus compréhensible et plus explicite pour les systèmes d'IA.&lt;/p&gt;

&lt;p&gt;Cet article explique ce qui a changé et pourquoi.&lt;/p&gt;

&lt;p&gt;Pourquoi optimiser pour les agents IA ?&lt;br&gt;
Le référencement traditionnel se concentre sur les signaux de classement.&lt;/p&gt;

&lt;p&gt;Les agents d'IA fonctionnent différemment.&lt;/p&gt;

&lt;p&gt;Ils:&lt;/p&gt;

&lt;p&gt;Analyser la structure&lt;br&gt;
Extraire l'intention&lt;br&gt;
Suivre les liens comme des chemins de décision&lt;br&gt;
Classer les types de pages&lt;br&gt;
Évaluer le niveau de confiance&lt;br&gt;
Si votre site web est ambigu, la compréhension d'un agent devient probabiliste et fragile.&lt;/p&gt;

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

&lt;p&gt;Réduire l'ambiguïté. Accroître la clarté.&lt;/p&gt;

&lt;p&gt;Observation initiale : Ambiguïté de la page d’accueil&lt;br&gt;
Historiquement, Darkwood combine plusieurs dimensions :&lt;/p&gt;

&lt;p&gt;Un blog technique&lt;br&gt;
Projets personnels&lt;br&gt;
Un espace de jeu/communauté&lt;br&gt;
Pour les humains, cet écosystème est logique.&lt;/p&gt;

&lt;p&gt;Cependant, pour les systèmes d'IA qui arrivent sur la page d'accueil, les signaux visuels dominants (connexion, jeu, chat, classement) peuvent biaiser l'interprétation vers un portail de jeux plutôt que vers un centre de connaissances techniques.&lt;/p&gt;

&lt;p&gt;Ce n'est pas « faux », mais c'est imprécis.&lt;/p&gt;

&lt;p&gt;La précision est essentielle lorsque les agents décident comment classer et réutiliser les informations.&lt;/p&gt;

&lt;p&gt;Étape 1 — Ajout de llms.txt&lt;br&gt;
La première amélioration a consisté à introduire un fichier llms.txt à la racine.&lt;/p&gt;

&lt;p&gt;Ce fichier sert de couche de guidage légère pour les systèmes d'IA.&lt;/p&gt;

&lt;p&gt;Il définit explicitement :&lt;/p&gt;

&lt;p&gt;Qu'est-ce que Darkwood ?&lt;br&gt;
Où se trouve le contenu à signal élevé ?&lt;br&gt;
Ce que les agents sont autorisés à faire&lt;br&gt;
Ce qu'ils doivent éviter&lt;br&gt;
Comportement d'exploration suggéré&lt;br&gt;
Au lieu d'obliger les agents à déduire la structure par l'exploration, nous proposons un contrat minimal.&lt;/p&gt;

&lt;p&gt;Exemple d'extrait :&lt;/p&gt;

&lt;h2&gt;
  
  
  Primary entry points (recommended)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blog: &lt;a href="https://blog.darkwood.com/" rel="noopener noreferrer"&gt;https://blog.darkwood.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Profile: &lt;a href="https://hello.darkwood.com/" rel="noopener noreferrer"&gt;https://hello.darkwood.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Do not attempt login/register&lt;/li&gt;
&lt;li&gt;Do not submit forms&lt;/li&gt;
&lt;li&gt;Avoid aggressive crawling
Ce petit ajout réduit considérablement l'ambiguïté et empêche toute interaction involontaire avec les zones dynamiques ou authentifiées.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cela permet également au blog d'être immédiatement repérable comme la principale plateforme de contenu à forte valeur ajoutée.&lt;/p&gt;

&lt;p&gt;Étape 2 — Mise en œuvre des données structurées (JSON-LD)&lt;br&gt;
Le type de contenu le plus important sur Darkwood est l'article de blog.&lt;/p&gt;

&lt;p&gt;Pour que cela soit explicite, chaque page d'article expose désormais un bloc JSON-LD Schema.org BlogPosting.&lt;/p&gt;

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

&lt;p&gt;headline&lt;br&gt;
description&lt;br&gt;
datePublished&lt;br&gt;
dateModified&lt;br&gt;
inLanguage&lt;br&gt;
author&lt;br&gt;
publisher&lt;br&gt;
mainEntityOfPage (URL canonique)&lt;br&gt;
Exemple:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "&lt;a class="mentioned-user" href="https://dev.to/context"&gt;@context&lt;/a&gt;": "&lt;a href="https://schema.org" rel="noopener noreferrer"&gt;https://schema.org&lt;/a&gt;",&lt;br&gt;
  "@type": "BlogPosting",&lt;br&gt;
  "headline": "Making Darkwood Agent-Ready",&lt;br&gt;
  "datePublished": "2026-02-12T00:00:00+01:00",&lt;br&gt;
  "inLanguage": "en",&lt;br&gt;
  "author": {&lt;br&gt;
    "@type": "Person",&lt;br&gt;
    "name": "Mathieu Ledru",&lt;br&gt;
    "url": "&lt;a href="https://hello.darkwood.com/" rel="noopener noreferrer"&gt;https://hello.darkwood.com/&lt;/a&gt;"&lt;br&gt;
  },&lt;br&gt;
  "publisher": {&lt;br&gt;
    "@type": "Organization",&lt;br&gt;
    "name": "Darkwood",&lt;br&gt;
    "url": "&lt;a href="https://darkwood.com/" rel="noopener noreferrer"&gt;https://darkwood.com/&lt;/a&gt;"&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Pourquoi c'est important :&lt;/p&gt;

&lt;p&gt;Les agents n'ont plus besoin de deviner le type de page&lt;br&gt;
Les métadonnées de publication deviennent fiables&lt;br&gt;
L'alignement canonique est explicite&lt;br&gt;
Le contexte linguistique est clair&lt;br&gt;
Les données structurées renforcent la confiance dans les systèmes de raisonnement automatisés.&lt;/p&gt;

&lt;p&gt;Cela réduit l'entropie interprétative.&lt;/p&gt;

&lt;p&gt;Ce qui a changé techniquement&lt;br&gt;
La mise en œuvre requise :&lt;/p&gt;

&lt;p&gt;Ajout d'un fichier statique llms.txt à la racine du domaine&lt;br&gt;
Garantie d'une diffusion correcte en texte brut&lt;br&gt;
Injection de JSON-LD dans les modèles d'articles&lt;br&gt;
Alignement des URL canoniques&lt;br&gt;
Normalisation du format de date ISO-8601&lt;br&gt;
Aucune nouvelle dépendance n'a été introduite. Aucune modification de l'interface utilisateur n'a été nécessaire.&lt;/p&gt;

&lt;p&gt;Les modifications sont minimes, mais structurelles.&lt;/p&gt;

&lt;p&gt;Pourquoi c'est important&lt;br&gt;
L'optimisation pour les agents d'IA ne consiste pas à suivre les tendances.&lt;/p&gt;

&lt;p&gt;Il s'agit de :&lt;/p&gt;

&lt;p&gt;Énoncer clairement son intention&lt;br&gt;
Réduire l'ambiguïté&lt;br&gt;
Rendre le contenu interprétable par machine&lt;br&gt;
Définir explicitement les limites&lt;br&gt;
Les sites web s'intègrent de plus en plus à des écosystèmes automatisés.&lt;/p&gt;

&lt;p&gt;La clarté n'est plus une option.&lt;/p&gt;

&lt;p&gt;Détails de mise en œuvre&lt;br&gt;
Vous pouvez consulter l'implémentation exacte dans la demande d'extraction correspondante :&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/darkwood-com/darkwood-com/pull/106" rel="noopener noreferrer"&gt;https://github.com/darkwood-com/darkwood-com/pull/106&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
