<?xml
version="1.0" encoding="utf-8"?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>

<channel xml:lang="fr">
	<title>Les services IA de DnC</title>
	<link>https://ia.dnc.global/</link>
	<description>En mati&#232;re d'intelligence artificielle (IA), DnC met l'accent sur la s&#233;curit&#233; en offrant aux entreprises le moyen de conserver leurs donn&#233;es et les traitements &#224; l'int&#233;rieur de leur r&#233;seau d'entreprise plut&#244;t que dans le Cloud.</description>
	<language>fr</language>
	<generator>SPIP - www.spip.net</generator>
	<atom:link href="https://ia.dnc.global/spip.php?id_rubrique=13&amp;page=backend" rel="self" type="application/rss+xml" />




<item xml:lang="fr">
		<title>Les modes de synth&#232;se</title>
		<link>https://ia.dnc.global/Les-modes-de-synthese.html</link>
		<guid isPermaLink="true">https://ia.dnc.global/Les-modes-de-synthese.html</guid>
		<dc:date>2026-07-28T15:02:23Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Bertrand Degoy</dc:creator>



		<description>
&lt;p&gt;Le Moteur RAG de la v200 (RagRuntime) offre diff&#233;rents modes de synth&#232;se des passages extraits de la documentation : &#034;condense&#034;, &#034;tree summarize&#034;, &#034;node summarize, &#034;tool&#034;.
&lt;br class='autobr' /&gt;
Donnant des r&#233;sultats tr&#232;s diff&#233;rents, il doivent &#234;tre choisis en fonction de l'application et de la qualit&#233; de la documentation. &lt;br class='autobr' /&gt;
La pertinance du Reranker est mise en question. R&#233;sum&#233; de la probl&#233;matique &lt;br class='autobr' /&gt;
Le mode condense produit des r&#233;ponses plus pertinentes et plus &#8220;intelligentes&#8221; que les modes stricts (tree summarize, node (...)&lt;/p&gt;


-
&lt;a href="https://ia.dnc.global/-Architecture-v200-.html" rel="directory"&gt;Architecture v200&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;Le Moteur RAG de la v200 (&lt;a href='https://ia.dnc.global/RagRuntime.html' class='spip_in'&gt;RagRuntime&lt;/a&gt;) offre diff&#233;rents modes de synth&#232;se des passages extraits de la documentation : &#034;condense&#034;, &#034;tree summarize&#034;, &#034;node summarize, &#034;tool&#034;.&lt;br class='autobr' /&gt;
Donnant des r&#233;sultats tr&#232;s diff&#233;rents, il doivent &#234;tre choisis en fonction de l'application et de la qualit&#233; de la documentation. &lt;br class='autobr' /&gt;
La pertinance du Reranker est mise en question.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;h2&gt;R&#233;sum&#233; de la probl&#233;matique&lt;/h2&gt;
&lt;p&gt;Le mode &lt;strong&gt;condense&lt;/strong&gt; produit des r&#233;ponses plus pertinentes et plus &#8220;intelligentes&#8221; que les modes stricts (&lt;strong&gt;tree summarize&lt;/strong&gt;, &lt;strong&gt;node summarize&lt;/strong&gt;, &lt;strong&gt;tool&lt;/strong&gt;), notamment lorsqu'il faut r&#233;pondre &#224; une question sans correspondance documentaire directe. La raison principale est que &lt;strong&gt;condense pr&#233;serve davantage de mati&#232;re textuelle et laisse au mod&#232;le une latitude d'inf&#233;rence plus large&lt;/strong&gt;, alors que les modes stricts r&#233;duisent fortement la richesse du contexte.&lt;/p&gt;
&lt;h3&gt;1. Diff&#233;rence de traitement du contexte&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;condense&lt;/strong&gt; : concat&#232;ne les passages et g&#233;n&#232;re un r&#233;sum&#233; global. &lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Pr&#233;serve les redondances. &lt;/li&gt;
&lt;li&gt;Conserve les signaux faibles. &lt;/li&gt;
&lt;li&gt;Maintient les ambigu&#239;t&#233;s utiles. &lt;/li&gt;
&lt;li&gt;Offre un espace d'inf&#233;rence large.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De plus, ce mode est rapide et &#233;conomique en token.&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;tree_summarize / node_summarize / tool&lt;/strong&gt; : imposent une structure pr&#233;coce. &lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Compression agressive. &lt;/li&gt;
&lt;li&gt;Hi&#233;rarchisation ou segmentation. &lt;/li&gt;
&lt;li&gt;Normalisation du contenu. &lt;/li&gt;
&lt;li&gt;R&#233;duction des co&#8209;occurrences latentes. &lt;/li&gt;
&lt;li&gt;Perte d'informations implicites.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Impact sur les capacit&#233;s du mod&#232;le&lt;/h3&gt;
&lt;p&gt;Les mod&#232;les modernes exploitent efficacement :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;les corr&#233;lations faibles, &lt;/li&gt;
&lt;li&gt;les ambigu&#239;t&#233;s, &lt;/li&gt;
&lt;li&gt;les patterns latents, &lt;/li&gt;
&lt;li&gt;les fragments d'information dispers&#233;s.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le mode &lt;strong&gt;condense&lt;/strong&gt; leur fournit un contexte riche permettant :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;l'inf&#233;rence, &lt;/li&gt;
&lt;li&gt;la reconstruction de sens, &lt;/li&gt;
&lt;li&gt;la r&#233;ponse indirecte &#224; des questions non couvertes explicitement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les modes stricts limitent ces m&#233;canismes en r&#233;duisant la mati&#232;re disponible.&lt;/p&gt;
&lt;h3&gt;3. Cas d'usage des modes stricts&lt;/h3&gt;
&lt;p&gt;Les modes stricts restent adapt&#233;s lorsque :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;le contexte est tr&#232;s volumineux (n&#233;cessit&#233; de structuration), &lt;/li&gt;
&lt;li&gt;la t&#226;che exige une r&#233;ponse d&#233;terministe, &lt;/li&gt;
&lt;li&gt;l'application impose une tra&#231;abilit&#233; stricte, &lt;/li&gt;
&lt;li&gt;un agent ReAct doit consommer un format compact et non ambigu.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. Cons&#233;quence architecturale&lt;/h3&gt;
&lt;p&gt;Le mode &lt;strong&gt;condense&lt;/strong&gt; se comporte comme un pr&#233;&#8209;RAG g&#233;n&#233;ratif :&lt;br /&gt;
il agr&#232;ge et densifie le contexte sans le contraindre, ce qui maximise la capacit&#233; du mod&#232;le &#224; produire une r&#233;ponse pertinente m&#234;me en absence de support documentaire direct.&lt;/p&gt;
&lt;h3&gt;Recommandation d'usage&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Mode par d&#233;faut : &lt;strong&gt;condense&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Contextes tr&#232;s longs : &lt;strong&gt;tree_summarize&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Analyse par chunk : &lt;strong&gt;node_summarize&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Agents ReAct : &lt;strong&gt;tool&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Pertinence du reranker&lt;/h2&gt;
&lt;p&gt;L'effet du &lt;strong&gt;reranker&lt;/strong&gt; d&#233;pend fortement du mode de post&#8209;traitement utilis&#233;.&lt;br /&gt;
Dans les modes stricts, il est souvent redondant ou contre&#8209;productif.&lt;br /&gt;
Dans le mode &lt;strong&gt;condense&lt;/strong&gt;, il peut &#234;tre utile, mais pas toujours n&#233;cessaire, car ce mode exploite d&#233;j&#224; la capacit&#233; du mod&#232;le &#224; combiner des signaux faibles.&lt;/p&gt;
&lt;h3&gt;1. Interaction g&#233;n&#233;rale entre reranker et modes&lt;/h3&gt;
&lt;p&gt;Le reranker agit avant la phase de summarization.&lt;br /&gt;
Il modifie :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;l'ordre des passages, &lt;/li&gt;
&lt;li&gt;la s&#233;lection des passages (top&#8209;k / top&#8209;n), &lt;/li&gt;
&lt;li&gt;la distribution des signaux faibles.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Son impact d&#233;pend donc de la mani&#232;re dont le mode consomme les passages.&lt;/p&gt;
&lt;h2&gt;2. Effet par mode&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;Mode condense&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Le mod&#232;le re&#231;oit un bloc textuel riche. &lt;/li&gt;
&lt;li&gt;Le reranker peut am&#233;liorer la pertinence en mettant les passages les plus utiles en t&#234;te. &lt;/li&gt;
&lt;li&gt;Cependant, condense exploite aussi les signaux faibles et les co&#8209;occurrences. &lt;/li&gt;
&lt;li&gt;Un reranker trop strict peut &lt;strong&gt;r&#233;duire la diversit&#233;&lt;/strong&gt; des passages et donc diminuer la capacit&#233; d'inf&#233;rence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Effet :&lt;/strong&gt; utile mais non indispensable.&lt;br /&gt;
&lt;strong&gt;Risque :&lt;/strong&gt; perte de mati&#232;re latente si le reranker est trop agressif.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Mode tree_summarize&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Ce mode structure le contenu en niveaux hi&#233;rarchiques. &lt;/li&gt;
&lt;li&gt;Il d&#233;pend moins de l'ordre initial des passages. &lt;/li&gt;
&lt;li&gt;Le reranker apporte peu de valeur, car la hi&#233;rarchie reconstruit d&#233;j&#224; une importance relative.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Effet :&lt;/strong&gt; faible.&lt;br /&gt;
&lt;strong&gt;Risque :&lt;/strong&gt; compression excessive si le reranker filtre trop.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Mode node_summarize&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Chaque passage est r&#233;sum&#233; individuellement. &lt;/li&gt;
&lt;li&gt;L'ordre n'a presque aucune importance. &lt;/li&gt;
&lt;li&gt;Le reranker n'am&#233;liore pas la qualit&#233; du r&#233;sum&#233; par passage. &lt;/li&gt;
&lt;li&gt;Il peut m&#234;me r&#233;duire la couverture documentaire.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Effet :&lt;/strong&gt; marginal.&lt;br /&gt;
&lt;strong&gt;Risque :&lt;/strong&gt; perte de diversit&#233; des chunks.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Mode tool&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Format strict, compact, destin&#233; aux agents. &lt;/li&gt;
&lt;li&gt;Le reranker peut aider &#224; s&#233;lectionner les passages les plus factuels. &lt;/li&gt;
&lt;li&gt;Mais l'objectif est le &lt;strong&gt;d&#233;terminisme&lt;/strong&gt;, pas l'inf&#233;rence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Effet :&lt;/strong&gt; mod&#233;r&#233;.&lt;br /&gt;
&lt;strong&gt;Risque :&lt;/strong&gt; suppression de passages utiles pour les actions de l'agent.&lt;/p&gt;
&lt;h2&gt;3. Utilit&#233; r&#233;elle du reranker&lt;/h2&gt;
&lt;p&gt;Le reranker est utile lorsque :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;le corpus est tr&#232;s bruit&#233;, &lt;/li&gt;
&lt;li&gt;les chunks sont h&#233;t&#233;rog&#232;nes, &lt;/li&gt;
&lt;li&gt;le retriever renvoie trop de passages non pertinents, &lt;/li&gt;
&lt;li&gt;la question est tr&#232;s cibl&#233;e.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il est moins utile lorsque :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;les chunks sont propres et homog&#232;nes, &lt;/li&gt;
&lt;li&gt;les modes stricts restructurent d&#233;j&#224; le contenu, &lt;/li&gt;
&lt;li&gt;le mod&#232;le doit combiner des signaux faibles (cas du mode condense).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. Synth&#232;se&lt;/h2&gt;&lt;spip&gt;
&lt;table class=&#034;spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Mode&lt;/td&gt;
&lt;td&gt;Utilit&#233; du reranker&lt;/td&gt;
&lt;td&gt;Commentaire&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;condense&lt;/td&gt;
&lt;td&gt;moyenne&lt;/td&gt;
&lt;td&gt;am&#233;liore la pertinence mais peut r&#233;duire la diversit&#233; utile&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;tree_summarize&lt;/td&gt;
&lt;td&gt;faible&lt;/td&gt;
&lt;td&gt;la hi&#233;rarchie interne remplace le tri&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;node_summarize&lt;/td&gt;
&lt;td&gt;tr&#232;s faible&lt;/td&gt;
&lt;td&gt;r&#233;sum&#233;s ind&#233;pendants, ordre peu important&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;tool&lt;/td&gt;
&lt;td&gt;mod&#233;r&#233;e&lt;/td&gt;
&lt;td&gt;utile pour filtrer, mais risque de perte d'information&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/spip&gt;
&lt;h2&gt;Recommandation&lt;/h2&gt;
&lt;p&gt;Le reranker doit &#234;tre activ&#233; uniquement dans les cas o&#249; la diversit&#233; des passages nuit &#224; la pertinence.&lt;br /&gt;
Pour un pipeline moderne, la strat&#233;gie optimale est :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;condense sans reranker&lt;/strong&gt; par d&#233;faut, &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;condense avec reranker&lt;/strong&gt; si le corpus est bruit&#233;, &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;modes stricts sans reranker&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Le Daemon Pyro5</title>
		<link>https://ia.dnc.global/Le-Daemon-Pyro5.html</link>
		<guid isPermaLink="true">https://ia.dnc.global/Le-Daemon-Pyro5.html</guid>
		<dc:date>2026-07-07T09:30:51Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Bertrand Degoy</dc:creator>



		<description>
&lt;p&gt;Dans une architecture multi&#8209;processus et multi&#8209;utilisateur, on ne peut charger un m&#234;me mod&#232;le dans chaque composant (NSOrchestrator, ReActEngine, workers, tests, scripts). Pour cette raison, les mod&#232;les doivent &#234;tre servis via un daemon. &lt;br class='autobr' /&gt;
##Position du probl&#232;me &lt;br class='autobr' /&gt;
Un LLM ou un SLM repr&#233;sente plusieurs gigaoctets en m&#233;moire, et leur rechargement dans chaque processus provoquerait une explosion de la consommation RAM, une fragmentation CUDA, des temps de d&#233;marrage prohibitifs et une instabilit&#233; g&#233;n&#233;rale (...)&lt;/p&gt;


-
&lt;a href="https://ia.dnc.global/-Architecture-v200-.html" rel="directory"&gt;Architecture v200&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;Dans une architecture multi&#8209;processus et multi&#8209;utilisateur, on ne peut charger un m&#234;me mod&#232;le dans chaque composant (NSOrchestrator, ReActEngine, workers, tests, scripts).&lt;br class='autobr' /&gt;
Pour cette raison, les mod&#232;les doivent &#234;tre servis via un daemon.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;h2&gt;Position du probl&#232;me&lt;/h2&gt;
&lt;p&gt;Un LLM ou un SLM repr&#233;sente plusieurs gigaoctets en m&#233;moire, et leur rechargement dans chaque processus provoquerait une explosion de la consommation RAM, une fragmentation CUDA, des temps de d&#233;marrage prohibitifs et une instabilit&#233; g&#233;n&#233;rale du syst&#232;me. Le &lt;strong&gt;mode daemon&lt;/strong&gt; r&#233;sout ce probl&#232;me en garantissant qu'&lt;strong&gt;un mod&#232;le n'est charg&#233; en m&#233;moire qu'une seule fois dans un processus d&#233;di&#233;, puis partag&#233; entre tous les autres via RPC&lt;/strong&gt;. Cela permet un fonctionnement r&#233;ellement concurrent, une gestion propre du streaming token&#8209;par&#8209;token, une isolation des erreurs, et une stabilit&#233; m&#233;moire indispensable en production.&lt;/p&gt;
&lt;p&gt;Pour cette raison, le LLM et le SLM doivent &#234;tre servis via un daemon. Les deux mod&#232;les sont sollicit&#233;s par plusieurs utilisateurs, plusieurs sessions et plusieurs moteurs internes, parfois simultan&#233;ment. Les Thought et les r&#233;ponses finales de ReAct doivent &#234;tre g&#233;n&#233;r&#233;es sans jamais recharger les poids des mod&#232;les, sans bloquer les autres processus, et sans d&#233;pendre de l'environnement local de chaque composant. En les ex&#233;cutant tous deux en daemon, l'architecture v200 devient coh&#233;rente, d&#233;terministe et scalable : un seul chargement, un seul point d'acc&#232;s, un comportement identique pour tous les clients, et une capacit&#233; &#224; monter en charge sans modifier le code des orchestrateurs ou des moteurs internes.&lt;/p&gt;
&lt;p&gt;Ce raisonnement vaut &#233;galement pour les index.&lt;/p&gt;
&lt;h2&gt;R&#244;le du daemon&lt;/h2&gt;
&lt;p&gt;Le daemon Pyro5 est un fournisseur multi-services.&lt;/p&gt;
&lt;p&gt;Via ModelsConfigurator, il :&lt;/p&gt;
&lt;ol class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;Charge les mod&#232;les d&#233;finis dans &lt;code&gt;models.json&lt;/code&gt;,
ce qui initialise AppSettings et les mod&#232;les globaux (embedding, LLM, SLM).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Charge les services d&#233;clar&#233;s dans &lt;code&gt;services.json&lt;/code&gt; et les instancie dynamiquement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enregistre chaque service dans Pyro5 sous un nom stable :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;llm.server&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;slm.server&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;embedding.server&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;rag.reader&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Puis : Lance la boucle d'&#233;v&#233;nements Pyro5.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exemple : chargement d'un index par RagRuntime :&lt;/strong&gt;&lt;/p&gt;
&lt;dl class='spip_document_56 spip_documents'&gt; &lt;dt&gt; &lt;a href='https://ia.dnc.global/IMG/png/in_daemon_rag_reader_workflow-2026-07-07-091503.png' class=&#034;mediabox&#034; title=&#034;PNG - 737.1 ko&#034; &gt; &lt;img src='https://ia.dnc.global/local/cache-vignettes/L500xH320/in_daemon_rag_reader_workflow-2026-07-07-091503-2f088.png?1783416584' width='500' height='320' alt=&#034;PNG - 737.1&#160;ko&#034; /&gt; &lt;/a&gt; &lt;/dt&gt; &lt;/dl&gt;
&lt;h2&gt;Composants principaux&lt;/h2&gt;
&lt;h3&gt;1. MemoryManager&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;Arbitre global de la RAM.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Suit les allocations d'objets persistants.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Applique une politique d'&#233;viction (LRU locale).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fournit un &#233;tat m&#233;moire complet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thread-safe.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. InDaemonRagReader (service rag.reader)&lt;/h3&gt;
&lt;p&gt;Module de recherche RAG, interne au daemon.
Une architecture qui s&#233;parerait le mod&#232;le d'embedding et l'index dans des services distincts du daemon conduirait &#224; un grand nombre d'&#233;changes RCP et &#224; des temps de traitement prohibitifs. InDaemonRagReader permet d'&#233;viter cela :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;Encode les requ&#234;tes via le mod&#232;le d'embedding global.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Interroge le backend vectoriel (FAISS, LlamaIndex ...).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Renvoie des &lt;code&gt;RichNode&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fournit un mode streaming (&lt;code&gt;astream&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class='spip_document_57 spip_documents'&gt; &lt;dt&gt; &lt;a href='https://ia.dnc.global/IMG/png/rag-reader_workflow_2026-08-08.png' class=&#034;mediabox&#034; title=&#034;PNG - 641.4 ko&#034; &gt; &lt;img src='https://ia.dnc.global/local/cache-vignettes/L500xH259/rag-reader_workflow_2026-08-08-1a022.png?1786220821' width='500' height='259' alt=&#034;PNG - 641.4&#160;ko&#034; /&gt; &lt;/a&gt; &lt;/dt&gt; &lt;/dl&gt;
&lt;h2&gt;Interaction avec le client&lt;/h2&gt;
&lt;p&gt;Le client utilise &lt;strong&gt;InDaemonRagReaderProxy&lt;/strong&gt; pour contacter le service &lt;code&gt;rag.reader&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Flux typique :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RagRuntime.retrieve() &#8594; InDaemonRagReaderProxy(&#034;rag.reader&#034;).retrieve(theme, query, top_k) &#8594; InDaemonRagReader.retrieve() &#8594; encode la requ&#234;te &#8594; interroge le backend vectoriel &#8594; renvoie des RichNode&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le client ne voit jamais MemoryManager : tout est encapsul&#233; dans le daemon.&lt;/p&gt;
&lt;h2&gt;Avantages de cette architecture&lt;/h2&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;Un seul daemon &#8594; coh&#233;rence m&#233;moire.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Plusieurs services &#8594; modularit&#233;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MemoryManager central &#8594; contr&#244;le RAM industriel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;InDaemonRagReader &#8594; moteur RAG unifi&#233;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Structure simple &#8594; facile &#224; &#233;tendre.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>v200 : Introduction, RagRuntime</title>
		<link>https://ia.dnc.global/v200-Introduction-RagRuntime.html</link>
		<guid isPermaLink="true">https://ia.dnc.global/v200-Introduction-RagRuntime.html</guid>
		<dc:date>2026-07-04T08:16:29Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Bertrand Degoy</dc:creator>



		<description>
&lt;p&gt;La v200 introduit une architecture RAG enti&#232;rement refondue, centr&#233;e sur la modularit&#233;, la performance et la robustesse. Elle s'appuie sur l'&#233;criture de services d&#233;di&#233;s pour les mod&#232;les et les index, un daemon Pyro5 pour l'acc&#232;s rapide aux index en m&#233;moire, et une API interne unifi&#233;e permettant d'abstraire totalement les backends. L'ensemble garantit un moteur RAG &#034;RagRuntime&#034; totalement ind&#233;pendant de toute biblioth&#232;que (LlamaIndex, LangChain ...) . Cette version fournit ainsi une base industrielle, (...)&lt;/p&gt;


-
&lt;a href="https://ia.dnc.global/-Architecture-v200-.html" rel="directory"&gt;Architecture v200&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;La v200 introduit une architecture RAG enti&#232;rement refondue, centr&#233;e sur la modularit&#233;, la performance et la robustesse. Elle s'appuie sur l'&#233;criture de services d&#233;di&#233;s pour les mod&#232;les et les index, un daemon Pyro5 pour l'acc&#232;s rapide aux index en m&#233;moire, et une API interne unifi&#233;e permettant d'abstraire totalement les backends. &lt;br class='autobr' /&gt;
L'ensemble garantit un moteur RAG &#034;RagRuntime&#034; totalement ind&#233;pendant de toute biblioth&#232;que (LlamaIndex, LangChain ...) . &lt;br class='autobr' /&gt;
Cette version fournit ainsi une base industrielle, stable et extensible pour un pipeline RAG totalement propri&#233;taire.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;hr /&gt;
&lt;p&gt;La &lt;strong&gt;v200&lt;/strong&gt; constitue une r&#233;architecture compl&#232;te du pipeline RAG, con&#231;ue pour offrir une modularit&#233; stricte, une ind&#233;pendance vis&#8209;&#224;&#8209;vis de LlamaIndex ou de toute autre biblioth&#232;que, et une performance accrue gr&#226;ce &#224; un daemon g&#233;rant les index en m&#233;moire persistante. Elle introduit une s&#233;paration nette des responsabilit&#233;s, une normalisation des API internes, et un mod&#232;le d'ex&#233;cution coh&#233;rent pour tous les types d'index et de mod&#232;les.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;1. Objectif : Modularit&#233; syst&#233;mique&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1.1. Modularit&#233; des mod&#232;les&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;La v200 d&#233;finit des services d&#233;di&#233;s pour les mod&#232;les :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;services/llm/&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;services/embeddings/&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque service expose une API normalis&#233;e :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;generate()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;astream()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;embed()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cette abstraction permet de remplacer un mod&#232;le (OpenAI, Ollama, HF, local) sans impact sur le reste du pipeline.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1.2. Modularit&#233; des index&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Les index sont encapsul&#233;s dans des backends interchangeables :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;FaissBackend&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;LlamaIndexBackend&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;DummyBackend&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tous impl&#233;mentent une &lt;strong&gt;API unifi&#233;e&lt;/strong&gt; :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;retrieve(query, top_k)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;query(query)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;astream(query)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ping()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cette normalisation garantit que le RAG ne d&#233;pend plus du type d'index sous&#8209;jacent.&lt;/p&gt;
&lt;dl class='spip_document_51 spip_documents'&gt; &lt;dt&gt; &lt;a href='https://ia.dnc.global/IMG/png/ragruntime_retrieve-2026-07-04-105144.png' class=&#034;mediabox&#034; title=&#034;PNG - 2.1 Mo&#034; &gt; &lt;img src='https://ia.dnc.global/local/cache-vignettes/L500xH320/ragruntime_retrieve-2026-07-04-105144-63cf4.png?1783163163' width='500' height='320' alt=&#034;PNG - 2.1&#160;Mo&#034; /&gt; &lt;/a&gt; &lt;/dt&gt; &lt;/dl&gt;
&lt;h3&gt;&lt;strong&gt;1.3. Rapidit&#233; via daemon Pyro5&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;La v200 introduit un daemon Pyro5 :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;charg&#233; de maintenir les index en m&#233;moire,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;exposant une API RPC homog&#232;ne,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;permettant un acc&#232;s rapide depuis n'importe quel worker.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le client est minimal :&lt;/p&gt;
&lt;p&gt;IndexesManager &#8594; IndexService &#8594; RemoteIndexBackend&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Un m&#233;canisme de **fallback local** assure la continuit&#233; de service en cas d'indisponibilit&#233; du daemon. &lt;p&gt;### **1.4. Couche interne de normalisation**
Une couche interne (`internal/`) garantit :&lt;/p&gt;
&lt;p&gt;- la normalisation des r&#233;sultats des backends,
- la conversion des formats h&#233;t&#233;rog&#232;nes en structures standardis&#233;es,
- la coh&#233;rence des donn&#233;es consomm&#233;es par RagRuntime.&lt;/p&gt;
&lt;p&gt;Tous les r&#233;sultats sont convertis en dictionnaires homog&#232;nes :&lt;/p&gt;
&lt;p&gt;```python
{ &#034;text&#034;: &#034;...&#034;, &#034;score&#034;: None, &#034;metadata&#034;: {}
}&lt;/code&gt;&lt;/p&gt;
&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;2. Objectif : un RAG Engine ind&#233;pendant d'API externes&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;2.1. Suppression des d&#233;pendances structurelles&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;La v200 &#233;limine toute d&#233;pendance directe &#224; LlamaIndex ( ou autre) dans le moteur RAG.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2.2. un RAG Engine bas&#233; sur une API interne stable&lt;/strong&gt; :&lt;/h3&gt;
&lt;p&gt;Le moteur RAG (RagRuntime) ne d&#233;pend plus :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;du type d'index,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;du type de mod&#232;le,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;de LlamaIndex ou FAISS.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il consomme uniquement l'API unifi&#233;e :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;retrieve()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;query()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;astream()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;2.3. Normalisation syst&#233;matique des r&#233;sultats&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Les r&#233;sultats bruts des backends (souvent des cha&#238;nes de caract&#232;res) sont syst&#233;matiquement convertis en objets structur&#233;s avant traitement par RagRuntime.&lt;/p&gt;
&lt;p&gt;Cela garantit :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;la stabilit&#233; du pipeline,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;la compatibilit&#233; avec les hooks,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;l'absence d'erreurs li&#233;es &#224; des formats h&#233;t&#233;rog&#232;nes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;2.4. Fallback local coh&#233;rent&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;En cas d'indisponibilit&#233; du daemon :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IndexService.connect() &#8594; RemoteIndexBackend (si daemon disponible) &#8594; LocalIndexBackend (si daemon indisponible)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;LocalIndexBackend&lt;/code&gt; est un proxy thread&#8209;safe, totalement ind&#233;pendant du type d'index.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Synth&#232;se&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;La &lt;strong&gt;v200&lt;/strong&gt; est une architecture RAG :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;modulaire&lt;/strong&gt;, gr&#226;ce &#224; des services d&#233;di&#233;s pour les mod&#232;les et les index,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;performante&lt;/strong&gt;, via un daemon Pyro5 servant les index en m&#233;moire,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;normalis&#233;e&lt;/strong&gt;, gr&#226;ce &#224; une API interne unifi&#233;e pour tous les backends,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;r&#233;siliente&lt;/strong&gt;, via un fallback local automatique,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ind&#233;pendante de LlamaIndex&lt;/strong&gt;, gr&#226;ce &#224; l'encapsulation compl&#232;te dans &lt;code&gt;LlamaIndexBackend&lt;/code&gt;,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;stable&lt;/strong&gt;, gr&#226;ce &#224; une couche de normalisation syst&#233;matique pour RagRuntime.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Elle constitue une base industrielle, coh&#233;rente, et extensible pour un pipeline RAG moderne.&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Politique LRU/MRU</title>
		<link>https://ia.dnc.global/Politique-LRU-MRU.html</link>
		<guid isPermaLink="true">https://ia.dnc.global/Politique-LRU-MRU.html</guid>
		<dc:date>2026-06-29T09:04:20Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Bertrand Degoy</dc:creator>



		<description>
&lt;p&gt;Dans l'architecture Pyro5, les index ( et certains mod&#232;les ) sont charg&#233;s depuis le disque puis conserv&#233;s en RAM pour &#234;tre accessibles rapidement par les services distants. Le daemon joue le r&#244;le de processus ma&#238;tre. &lt;br class='autobr' /&gt;
Pour les index par exemple, il les expose via IndexServer, et sert de point d'acc&#232;s unique pour tous les RemoteIndexService. Comme ces index peuvent &#234;tre volumineux et que le daemon est con&#231;u pour rester actif longtemps, il doit g&#233;rer sa m&#233;moire de mani&#232;re autonome et efficace. C'est (...)&lt;/p&gt;


-
&lt;a href="https://ia.dnc.global/-Architecture-v200-.html" rel="directory"&gt;Architecture v200&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;Dans l'architecture Pyro5, les index ( et certains mod&#232;les ) sont charg&#233;s depuis le disque puis conserv&#233;s en RAM pour &#234;tre accessibles rapidement par les services distants. Le daemon joue le r&#244;le de processus ma&#238;tre.&lt;/p&gt;
&lt;p&gt;Pour les index par exemple, il les expose via IndexServer, et sert de point d'acc&#232;s unique pour tous les RemoteIndexService.&lt;/p&gt;
&lt;p&gt;Comme ces index peuvent &#234;tre volumineux et que le daemon est con&#231;u pour rester actif longtemps, il doit g&#233;rer sa m&#233;moire de mani&#232;re autonome et efficace. C'est pr&#233;cis&#233;ment pour cela qu'une politique LRU/MRU est indispensable : elle permet de conserver en RAM les index les plus r&#233;cemment utilis&#233;s (MRU), tout en &#233;vin&#231;ant automatiquement ceux qui ne sont plus sollicit&#233;s (LRU).&lt;/p&gt;
&lt;p&gt;Cette strat&#233;gie garantit que le flowchart Pyro5 fonctionne de mani&#232;re fluide, sans surcharge m&#233;moire, et que les services distants acc&#232;dent toujours aux index pertinents sans rechargement inutile depuis le disque.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;hr /&gt;
&lt;h1&gt;Politique LRU/MRU&lt;/h1&gt;
&lt;p&gt;La politique &lt;strong&gt;LRU/MRU&lt;/strong&gt; (Least Recently Used / Most Recently Used) est un m&#233;canisme de gestion de la m&#233;moire qui permet de d&#233;cider &lt;strong&gt;quel objet doit &#234;tre &#233;vinc&#233;&lt;/strong&gt; lorsque la RAM atteint sa capacit&#233; maximale. Elle repose sur un principe simple : &lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;MRU&lt;/strong&gt; = objets r&#233;cemment utilis&#233;s &#8594; &#224; conserver &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LRU&lt;/strong&gt; = objets peu utilis&#233;s r&#233;cemment &#8594; candidats &#224; l'&#233;viction &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans notre syst&#232;me, cette politique est appliqu&#233;e par le &lt;strong&gt;MemoryManager&lt;/strong&gt;, qui maintient un ordre strict des objets en RAM gr&#226;ce &#224; un &lt;code&gt;OrderedDict&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;MRU &#8212; Most Recently Used&lt;/h2&gt;
&lt;p&gt;Un objet devient &lt;strong&gt;MRU&lt;/strong&gt; lorsqu'il est :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;charg&#233; en RAM,&lt;/li&gt;
&lt;li&gt;acc&#233;d&#233; via &lt;code&gt;get()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;marqu&#233; via &lt;code&gt;touch()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le MemoryManager d&#233;place alors la cl&#233; &lt;strong&gt;&#224; la fin&lt;/strong&gt; de l'OrderedDict :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ LRU ... &#8594; ... MRU ]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela signifie :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;cet index est actif,&lt;/li&gt;
&lt;li&gt;il doit &#234;tre conserv&#233; en priorit&#233;,&lt;/li&gt;
&lt;li&gt;il ne doit pas &#234;tre &#233;vinc&#233; tant que d'autres objets moins utilis&#233;s existent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;LRU &#8212; Least Recently Used&lt;/h2&gt;
&lt;p&gt;L'objet &lt;strong&gt;LRU&lt;/strong&gt; est celui qui :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;n'a pas &#233;t&#233; utilis&#233; depuis le plus longtemps,&lt;/li&gt;
&lt;li&gt;n'a pas &#233;t&#233; touch&#233; r&#233;cemment,&lt;/li&gt;
&lt;li&gt;se trouve &lt;strong&gt;au d&#233;but&lt;/strong&gt; de l'OrderedDict.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lorsqu'une &#233;viction est n&#233;cessaire (ex : &lt;code&gt;len(store) &gt; max_items&lt;/code&gt;), le MemoryManager fait :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#034;language-python&#034;&gt;key, _ = self._store.popitem(last=False)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ce qui retire &lt;strong&gt;le premier &#233;l&#233;ment&lt;/strong&gt;, donc le LRU.&lt;/p&gt;
&lt;h2&gt;Pourquoi LRU/MRU est id&#233;al dans notre architecture&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;Les index sont lourds&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ils peuvent peser plusieurs centaines de Mo.&lt;br /&gt;
Il est donc crucial d'&#233;viter de recharger inutilement depuis le disque.&lt;/p&gt;
&lt;h3&gt;2. &lt;strong&gt;Les RemoteIndexService sont stateless&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ils ne conservent rien : tout repose sur la RAM du daemon.&lt;br /&gt;
LRU/MRU garantit que les index r&#233;ellement utilis&#233;s restent disponibles.&lt;/p&gt;
&lt;h3&gt;3. &lt;strong&gt;Le daemon est long-lived&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Il doit s'auto-r&#233;guler sans intervention humaine.&lt;br /&gt;
LRU/MRU fournit une politique simple, d&#233;terministe et efficace.&lt;/p&gt;
&lt;h3&gt;4. &lt;strong&gt;Les th&#232;mes ont chacun leur fr&#233;quence d'acc&#232;s&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Certains th&#232;mes sont consult&#233;s souvent (MRU), d'autres rarement (LRU).&lt;br /&gt;
La politique s'adapte automatiquement &#224; ces usages.&lt;/p&gt;
&lt;h2&gt;R&#233;sultat : une m&#233;moire auto-optimis&#233;e&lt;/h2&gt;
&lt;p&gt;Gr&#226;ce &#224; LRU/MRU :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;Les index actifs restent en RAM &#8594; &lt;strong&gt;latence minimale&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Les index inactifs sont &#233;vinc&#233;s &#8594; &lt;strong&gt;RAM ma&#238;tris&#233;e&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Le daemon ne recharge que si n&#233;cessaire &#8594; &lt;strong&gt;I/O minimis&#233;es&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Le syst&#232;me reste stable m&#234;me sous forte charge &#8594; &lt;strong&gt;robustesse&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Construction des mod&#232;les : models.json et services.json</title>
		<link>https://ia.dnc.global/Construction-des-modeles-models-json-et-services-json.html</link>
		<guid isPermaLink="true">https://ia.dnc.global/Construction-des-modeles-models-json-et-services-json.html</guid>
		<dc:date>2026-06-23T08:51:00Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Bertrand Degoy</dc:creator>



		<description>
&lt;p&gt;L'architecture v200 repose sur une s&#233;paration stricte entre la d&#233;finition des mod&#232;les, leur construction centralis&#233;e, et la d&#233;claration des services qui les consomment. &lt;br class='autobr' /&gt;
Les mod&#232;les sont d&#233;crits dans un fichier unique (`models.json`), puis construits une seule fois au d&#233;marrage par le `ModelsConfigurator`, avant d'&#234;tre stock&#233;s dans `AppSettings` pour &#234;tre partag&#233;s par l'ensemble du runtime. &lt;br class='autobr' /&gt;
Les services Pyro5, d&#233;clar&#233;s dans `services.json`, ne chargent jamais de mod&#232;les eux&#8209;m&#234;mes : ils se contentent (...)&lt;/p&gt;


-
&lt;a href="https://ia.dnc.global/-Architecture-v200-.html" rel="directory"&gt;Architecture v200&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;L'architecture v200 repose sur une s&#233;paration stricte entre la d&#233;finition des mod&#232;les, leur &lt;a href='https://ia.dnc.global/Trois-modes-de-chargement-des-modeles.html' class='spip_in'&gt;construction centralis&#233;e&lt;/a&gt;, et la d&#233;claration des services qui les consomment. &lt;br class='autobr' /&gt;
Les mod&#232;les sont d&#233;crits dans un fichier unique (`models.json`), puis construits une seule fois au d&#233;marrage par le `ModelsConfigurator`, avant d'&#234;tre stock&#233;s dans `AppSettings` pour &#234;tre partag&#233;s par l'ensemble du runtime. &lt;br class='autobr' /&gt;
Les services Pyro5, d&#233;clar&#233;s dans `services.json`, ne chargent jamais de mod&#232;les eux&#8209;m&#234;mes : ils se contentent d'exposer des capacit&#233;s en s'appuyant sur les objets d&#233;j&#224; initialis&#233;s, garantissant ainsi coh&#233;rence, performance et isolation des responsabilit&#233;s.&lt;/p&gt;&lt;/div&gt;
		&lt;hr /&gt;
		&lt;div &lt;div class='rss_ps'&gt;&lt;hr /&gt;
&lt;h1&gt;Construction des mod&#232;les : &lt;code&gt;models.json&lt;/code&gt; et &lt;code&gt;services.json&lt;/code&gt;&lt;/h1&gt;
&lt;h2&gt;1. Pr&#233;sentation g&#233;n&#233;rale : comment les mod&#232;les sont construits dans v200&lt;/h2&gt;
&lt;p&gt;L'architecture v200 repose sur une s&#233;paration stricte des responsabilit&#233;s :&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1. &lt;code&gt;models.json&lt;/code&gt; d&#233;crit les mod&#232;les&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ce fichier d&#233;clare &lt;em&gt;uniquement&lt;/em&gt; les mod&#232;les utilis&#233;s par le runtime :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;embedding &lt;/li&gt;
&lt;li&gt;slm &lt;/li&gt;
&lt;li&gt;tokenizer &lt;/li&gt;
&lt;li&gt;llm &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque entr&#233;e d&#233;crit :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;code&gt;model_name&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;model_path&lt;/code&gt; (optionnel) &lt;/li&gt;
&lt;li&gt;&lt;code&gt;backend&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;device&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;api_key_env&lt;/code&gt; (si backend = API)
etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;2. ModelsConfigurator construit les mod&#232;les&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Le composant &lt;code&gt;ModelsConfigurator&lt;/code&gt; :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;lit &lt;code&gt;models.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;instancie les mod&#232;les (HF, API, local, etc.)&lt;/li&gt;
&lt;li&gt;cr&#233;e les objets Python correspondants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il ne conna&#238;t pas les services Pyro5.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3. AppSettingsManager stocke les mod&#232;les&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Une fois construits, les mod&#232;les sont transmis &#224; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AppSettingsManager.load_models(...)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ce composant :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;cr&#233;e un objet &lt;code&gt;AppSettings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;stocke les mod&#232;les dans des attributs statiques&lt;/li&gt;
&lt;li&gt;verrouille la configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;4. Les services Pyro5 consomment les mod&#232;les&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Les services (EmbeddingServer, SLMServer, IndexServer, MemoryManager, RagReader) :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;ne chargent pas de mod&#232;les&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ne re&#231;oivent pas de param&#232;tres de mod&#232;le&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;r&#233;cup&#232;rent les mod&#232;les via :&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&#034;language-python&#034;&gt;from runtime_v2.settings.app_settings import AppSettings self.embedding = AppSettings.embedding
self.slm = AppSettings.slm
self.tokenizer = AppSettings.tokenizer
self.llm = AppSettings.llm&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;5. &lt;code&gt;services.json&lt;/code&gt; d&#233;crit uniquement les services&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ce fichier :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;d&#233;clare les services Pyro5&lt;/li&gt;
&lt;li&gt;indique leur classe Python&lt;/li&gt;
&lt;li&gt;fournit uniquement les param&#232;tres n&#233;cessaires aux RPC (ex : nom d'un autre service)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il &lt;strong&gt;ne doit jamais contenir de param&#232;tres de mod&#232;le&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. Comment &#233;crire &lt;code&gt;models.json&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Voici la structure de base :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#034;language-json&#034;&gt;{ &#034;__comment&#034;: &#034;Source de ModelsConfigurator pour la configuration des mod&#232;les du runtime v200.&#034;, &#034;embedding&#034;: { &#034;__comment&#034;: &#034;Embedding local bas&#233; sur SentenceTransformers (ST). Utilise BGE-small en mode l&#233;ger, sans AutoModel/AutoTokenizer, pour &#233;viter la surcharge m&#233;moire des mod&#232;les HF.&#034;, &#034;model_type&#034;: &#034;embedding&#034;, &#034;model_name&#034;: &#034;BAAI/bge-small-en-v1.5&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/bge-small&#034;, &#034;backend&#034;: &#034;st&#034;, &#034;device&#034;: &#034;cpu&#034; }, &#034;slm&#034;: { &#034;__comment&#034;: &#034;SLM local optionnel (TinyLlama, Phi, etc.). Null = d&#233;sactiv&#233;.&#034;, &#034;model_type&#034;: &#034;causal_lm&#034;, &#034;model_name&#034;: null, &#034;model_path&#034;: null, &#034;backend&#034;: null, &#034;device&#034;: null }, &#034;tokenizer&#034;: { &#034;__comment&#034;: &#034;Tokenizer HF externe (Mixtral), t&#233;l&#233;charg&#233; via HF.&#034;, &#034;model_type&#034;: &#034;tokenizer&#034;, &#034;model_name&#034;: &#034;mistralai/Mixtral-8x7B-Instruct-v0.1&#034;, &#034;model_path&#034;: null, &#034;backend&#034;: &#034;hf&#034;, &#034;device&#034;: null }, &#034;llm&#034;: { &#034;__comment&#034;: &#034;LLM principal via Daemon.&#034;, &#034;model_type&#034;: &#034;causal_lm&#034;, &#034;backend&#034;: &#034;mistral_daemon&#034;, &#034;model_name&#034;: &#034;mistral-medium-latest&#034;, &#034;api_key_env&#034;: &#034;MISTRAL_API_KEY&#034;, &#034;daemon_host&#034;: &#034;127.0.0.1&#034;, &#034;daemon_port&#034;: 50050 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ou, plus ambitieux ( &#224; condition que les backends aient &#233;t&#233; &#233;crits) :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#034;language-json&#034;&gt;{ &#034;__comment&#034;: &#034;Configuration canonique v200 &#8212; aucun champ implicite, aucun type d&#233;duit automatiquement.&#034;, &#034;llm_api&#034;: { &#034;model_name&#034;: &#034;mistral-medium-latest&#034;, &#034;backend&#034;: &#034;mistral_api&#034;, &#034;model_type&#034;: &#034;causal_lm&#034;, &#034;api_key_env&#034;: &#034;MISTRAL_API_KEY&#034;, &#034;max_new_tokens&#034;: 2048, &#034;temperature&#034;: 0.2 }, &#034;llm_daemon&#034;: { &#034;model_name&#034;: &#034;mistral-medium-latest&#034;, &#034;backend&#034;: &#034;mistral_daemon&#034;, &#034;model_type&#034;: &#034;causal_lm&#034;, &#034;api_key&#034;: &#034;env:MISTRAL_API_KEY&#034;, &#034;daemon_host&#034;: &#034;127.0.0.1&#034;, &#034;daemon_port&#034;: 50050, &#034;max_new_tokens&#034;: 2048, &#034;temperature&#034;: 0.0 }, &#034;slm&#034;: { &#034;model_name&#034;: &#034;TinyLlama/TinyLlama-1.1B-Chat-v1.0&#034;, &#034;backend&#034;: &#034;hf_local&#034;, &#034;model_type&#034;: &#034;hf_causal_lm&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/TinyLlama-1.1B-Chat-v1.0&#034;, &#034;device&#034;: &#034;cpu&#034;, &#034;dtype&#034;: &#034;float16&#034;, &#034;max_new_tokens&#034;: 512, &#034;temperature&#034;: 0.0 }, &#034;embedding&#034;: { &#034;model_name&#034;: &#034;BAAI/bge-small-en-v1.5&#034;, &#034;backend&#034;: &#034;st&#034;, &#034;model_type&#034;: &#034;embedding&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/bge-small&#034;, &#034;device&#034;: &#034;cpu&#034; }, &#034;tokenizer&#034;: { &#034;model_name&#034;: &#034;mistralai/Mixtral-8x7B-Instruct-v0.1&#034;, &#034;backend&#034;: &#034;hf&#034;, &#034;model_type&#034;: &#034;tokenizer&#034;, &#034;device&#034;: &#034;cpu&#034; }, &#034;service_router&#034;: { &#034;model_name&#034;: &#034;router-v1&#034;, &#034;backend&#034;: &#034;internal&#034;, &#034;model_type&#034;: &#034;router&#034;, &#034;strategy&#034;: &#034;round_robin&#034;, &#034;targets&#034;: [&#034;llm_api&#034;, &#034;llm_daemon&#034;, &#034;slm&#034;] }, &#034;reranker&#034;: { &#034;model_name&#034;: &#034;colbertv2&#034;, &#034;backend&#034;: &#034;hf_local&#034;, &#034;model_type&#034;: &#034;reranker&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/colbertv2&#034;, &#034;device&#034;: &#034;cuda&#034;, &#034;dtype&#034;: &#034;float16&#034; }, &#034;vision_encoder&#034;: { &#034;model_name&#034;: &#034;openai/clip-vit-base-patch32&#034;, &#034;backend&#034;: &#034;hf_local&#034;, &#034;model_type&#034;: &#034;vision_encoder&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/clip-vit-base-patch32&#034;, &#034;device&#034;: &#034;cuda&#034; }, &#034;audio_encoder&#034;: { &#034;model_name&#034;: &#034;facebook/wav2vec2-base-960h&#034;, &#034;backend&#034;: &#034;hf_local&#034;, &#034;model_type&#034;: &#034;audio_encoder&#034;, &#034;model_path&#034;: &#034;/home/iadnc/.models/wav2vec2&#034;, &#034;device&#034;: &#034;cpu&#034; }, &#034;http_service&#034;: { &#034;model_name&#034;: &#034;custom-service&#034;, &#034;backend&#034;: &#034;http&#034;, &#034;model_type&#034;: &#034;service&#034;, &#034;service_url&#034;: &#034;http://127.0.0.1:8080/infer&#034;, &#034;timeout&#034;: 30 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;R&#232;gles :&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;&lt;strong&gt;Chaque mod&#232;le doit avoir un &lt;code&gt;model_name&lt;/code&gt;&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;model_path&lt;/code&gt; peut &#234;tre &lt;code&gt;null&lt;/code&gt; si HF doit t&#233;l&#233;charger automatiquement &lt;/li&gt;
&lt;li&gt;&lt;code&gt;backend&lt;/code&gt; d&#233;termine le loader (hf, hf_local, mistral_api, etc.) &lt;/li&gt;
&lt;li&gt;&lt;code&gt;device&lt;/code&gt; peut &#234;tre &lt;code&gt;cpu&lt;/code&gt;, &lt;code&gt;cuda&lt;/code&gt;, ou &lt;code&gt;null&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;api_key&lt;/code&gt; est utilis&#233; uniquement pour les backends API &lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Comment &#233;crire &lt;code&gt;services.json&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Voici la version minimale, conforme &#224; v200 :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#034;language-json&#034;&gt;{ &#034;daemon&#034;: { &#034;host&#034;: &#034;127.0.0.1&#034;, &#034;port&#034;: XXX }, &#034;services&#034;: [ { &#034;name&#034;: &#034;llm.server&#034;, &#034;class&#034;: &#034;runtime_v21.services.llm.llm_server.LlmServer&#034;, &#034;params&#034;: {} }, { &#034;name&#034;: &#034;slm.server&#034;, &#034;class&#034;: &#034;runtime_v21.services.llm.slm_server.SlmServer&#034;, &#034;params&#034;: {} }, { &#034;name&#034;: &#034;memory.server&#034;, &#034;class&#034;: &#034;runtime_v21.services.memory_manager.MemoryManager&#034;, &#034;params&#034;: {} } ], &#034;index&#034;: { &#034;loader&#034;: { &#034;class&#034;: &#034;runtime_v21.services.index.loaders.loader_manager.ThemeIndexLoaderManager&#034;, &#034;params&#034;: {} }, &#034;reserved_ram&#034;: 100000000 }
}, &#034;tokenizer&#034;: { &#034;model_name&#034;: &#034;mistralai/Mixtral-8x7B-Instruct-v0.1&#034;, &#034;backend&#034;: &#034;hf&#034;, &#034;model_type&#034;: &#034;tokenizer&#034;, &#034;device&#034;: &#034;cpu&#034; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;R&#232;gles :&lt;/h3&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aucun service ne doit recevoir de mod&#232;le&lt;/strong&gt;&lt;br /&gt;
&#8594; pas de &lt;code&gt;model&lt;/code&gt;, &lt;code&gt;model_name&lt;/code&gt;, &lt;code&gt;backend&lt;/code&gt;, &lt;code&gt;device&lt;/code&gt;, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Les services doivent recevoir uniquement :&lt;/p&gt;
&lt;ul class=&#034;spip&#034;&gt;
&lt;li&gt;des noms de services Pyro5 (pour RPC)&lt;/li&gt;
&lt;li&gt;des param&#232;tres m&#233;tier (rare)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Les services doivent r&#233;cup&#233;rer les mod&#232;les via &lt;code&gt;AppSettings&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. R&#233;sum&#233;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&#201;l&#233;ment&lt;/th&gt;
&lt;th&gt;R&#244;le&lt;/th&gt;
&lt;th&gt;Contenu&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;models.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;D&#233;crit les mod&#232;les&lt;/td&gt;
&lt;td&gt;model_name, backend, device, path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ModelsConfigurator&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Construit les mod&#232;les&lt;/td&gt;
&lt;td&gt;HF, API, local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AppSettingsManager&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stocke les mod&#232;les&lt;/td&gt;
&lt;td&gt;AppSettings.embedding, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;services.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;D&#233;crit les services&lt;/td&gt;
&lt;td&gt;classes, RPC, d&#233;pendances&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Services Pyro5&lt;/td&gt;
&lt;td&gt;Consomment les mod&#232;les&lt;/td&gt;
&lt;td&gt;via AppSettings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>



</channel>

</rss>
