<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Node.js on kenji.blog</title><link>http://kenji.blog/fr/tags/node.js/</link><description>Recent content in Node.js on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 02:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/node.js/index.xml" rel="self" type="application/rss+xml"/><item><title>Mise en place facile d'un LLM local et intégration API avec Ollama</title><link>http://kenji.blog/fr/p/ollama-local-llm-api-guide/</link><pubDate>Fri, 11 Sep 2026 02:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/ollama-local-llm-api-guide/</guid><description>&lt;img src="http://kenji.blog/p/ollama-local-llm-api-guide/img/eyecatch.jpg" alt="Featured image of post Mise en place facile d'un LLM local et intégration API avec Ollama" />&lt;h1 id="introduction--pourquoi-avons-nous-besoin-dun-llm-local-">Introduction : Pourquoi avons-nous besoin d&amp;rsquo;un LLM local ?
&lt;/h1>&lt;p>Avec l&amp;rsquo;essor des grands modèles de langage (LLM), nos modes de vie et nos méthodes de développement ont subi des changements radicaux. Les puissants services d&amp;rsquo;IA basés sur le cloud, tels que ChatGPT, Claude et Gemini, continuent d&amp;rsquo;évoluer chaque jour, offrant des capacités de raisonnement extrêmement avancées. Cependant, les LLM basés sur le cloud ne sont pas toujours optimaux pour tous les cas d&amp;rsquo;utilisation. Les LLM cloud présentent les défis suivants :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Problèmes de confidentialité et de sécurité&lt;/strong> : L&amp;rsquo;envoi de données contenant des informations confidentielles ou personnelles vers des serveurs externes est souvent inacceptable du point de vue de la conformité de l&amp;rsquo;entreprise et de la sécurité.&lt;/li>
&lt;li>&lt;strong>Incertitude des coûts&lt;/strong> : Comme les frais d&amp;rsquo;utilisation de l&amp;rsquo;API dépendent du nombre de jetons, les systèmes effectuant des traitements de données à grande échelle ou des requêtes fréquentes courent le risque de voir leurs coûts de fonctionnement exploser.&lt;/li>
&lt;li>&lt;strong>Latence et dépendance au réseau&lt;/strong> : Pour une utilisation dans des environnements hors ligne ou pour une exécution sur des appareils de pointe (edge devices) nécessitant une latence extrêmement faible, la communication réseau devient un goulot d&amp;rsquo;étranglement.&lt;/li>
&lt;li>&lt;strong>Enfermement propriétaire (Vendor lock-in)&lt;/strong> : La dépendance au modèle d&amp;rsquo;un fournisseur spécifique peut vous exposer à des risques tels que l&amp;rsquo;arrêt futur du service, des modifications des conditions d&amp;rsquo;utilisation, ou des changements de comportement inattendus dus aux mises à jour du modèle.&lt;/li>
&lt;/ol>
&lt;p>Pour résoudre ces défis, le &amp;ldquo;LLM local&amp;rdquo; attire de plus en plus l&amp;rsquo;attention. En exécutant des modèles sur votre propre matériel, vous pouvez utiliser librement l&amp;rsquo;IA sans envoyer aucune donnée à l&amp;rsquo;extérieur ni vous soucier des frais mensuels.&lt;/p>
&lt;p>Dans cet article, nous expliquerons en détail &amp;ldquo;&lt;strong>Ollama&lt;/strong>&amp;rdquo;, un outil qui permet d&amp;rsquo;introduire, de gérer et d&amp;rsquo;intégrer des API de LLM locaux avec une facilité surprenante. Nous couvrirons tout, de ses bases et de son architecture interne, à l&amp;rsquo;intégration avancée d&amp;rsquo;API en utilisant Python et Node.js, jusqu&amp;rsquo;aux formules mathématiques d&amp;rsquo;optimisation des performances.&lt;/p>
&lt;hr>
&lt;h1 id="quest-ce-quollama--son-architecture-interne">Qu&amp;rsquo;est-ce qu&amp;rsquo;Ollama ? Son architecture interne
&lt;/h1>&lt;p>Ollama est une plateforme qui permet d&amp;rsquo;exécuter et de gérer facilement de grands modèles de langage open-source (Llama 3, Phi-3, Mistral, Gemma, etc.) dans un environnement local. Auparavant, la configuration d&amp;rsquo;un environnement LLM local nécessitait des procédures très fastidieuses, telles que la configuration de l&amp;rsquo;environnement Python, l&amp;rsquo;installation du kit d&amp;rsquo;outils CUDA, la résolution des dépendances PyTorch, le téléchargement d&amp;rsquo;énormes fichiers de modèles depuis Hugging Face et la conversion de formats (par exemple de Safetensors à GGUF).&lt;/p>
&lt;p>Ollama masque ces complexités et permet de manipuler les LLM avec une facilité d&amp;rsquo;utilisation similaire à Docker. Avec une seule commande, vous pouvez télécharger un modèle (&lt;code>pull&lt;/code>), l&amp;rsquo;exécuter (&lt;code>run&lt;/code>) et le lancer en tant que serveur HTTP.&lt;/p>
&lt;h2 id="technologie-de-base--un-wrapper-pour-llamacpp">Technologie de base : un wrapper pour llama.cpp
&lt;/h2>&lt;p>L&amp;rsquo;arrière-plan du moteur d&amp;rsquo;inférence d&amp;rsquo;Ollama est propulsé par &amp;ldquo;&lt;strong>llama.cpp&lt;/strong>&amp;rdquo;, une bibliothèque d&amp;rsquo;inférence de LLM rapide implémentée en C/C++. llama.cpp a la capacité d&amp;rsquo;exécuter des modèles en tirant parti au maximum des performances matérielles, que ce soit sur Apple Silicon (Metal), NVIDIA GPU (CUDA), AMD GPU (ROCm) ou même dans des environnements limités au CPU.&lt;/p>
&lt;p>Ollama intègre llama.cpp et adopte une architecture où un processus serveur écrit en langage Go fournit une API REST et appelle le moteur d&amp;rsquo;inférence de llama.cpp en arrière-plan.&lt;/p>
&lt;p>Le diagramme Mermaid ci-dessous montre l&amp;rsquo;architecture globale d&amp;rsquo;Ollama.&lt;/p>
&lt;div class="mermaid">graph TD
A["Applications clientes (Python / Node.js)"] -- "API HTTP/REST" --> B["Serveur Ollama (Go)"]
B --> C["Gestionnaire de modèles (manipulation GGUF)"]
B --> D["Moteur d'inférence (llama.cpp)"]
D --> E["Accélération GPU (CUDA / Metal / ROCm)"]
D --> F["Repli CPU (AVX2 / AVX-512)"]
C --> G["Stockage local de modèles"]&lt;/div>
&lt;p>Grâce à cette architecture, les développeurs peuvent utiliser des capacités d&amp;rsquo;inférence avancées via des requêtes HTTP standard sans se soucier des compilations C++ ou de la configuration complexe des pilotes GPU.&lt;/p>
&lt;hr>
&lt;h1 id="installation-et-configuration-initiale-dollama">Installation et configuration initiale d&amp;rsquo;Ollama
&lt;/h1>&lt;p>L&amp;rsquo;installation d&amp;rsquo;Ollama est extrêmement simple. Des binaires optimisés pour chaque système d&amp;rsquo;exploitation sont fournis.&lt;/p>
&lt;h2 id="macos--windows">macOS / Windows
&lt;/h2>&lt;p>Il vous suffit de télécharger l&amp;rsquo;installateur depuis le site officiel (&lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>https://ollama.com/&lt;/a>) et de l&amp;rsquo;exécuter. La version macOS reconnaît automatiquement l&amp;rsquo;API Metal d&amp;rsquo;Apple Silicon, et la version Windows reconnaît les GPU NVIDIA (CUDA), activant l&amp;rsquo;accélération matérielle lorsque c&amp;rsquo;est possible.&lt;/p>
&lt;h2 id="linux">Linux
&lt;/h2>&lt;p>Dans les environnements Linux (comme Ubuntu), il suffit d&amp;rsquo;exécuter la commande d&amp;rsquo;une ligne suivante pour installer les composants nécessaires et démarrer le serveur Ollama en tant que service systemd.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -fsSL https://ollama.com/install.sh &lt;span class="p">|&lt;/span> sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Une fois l&amp;rsquo;installation terminée, vérifions la version dans le terminal.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Si les informations de version s&amp;rsquo;affichent, l&amp;rsquo;installation a réussi.&lt;/p>
&lt;h2 id="exécution-avec-docker">Exécution avec Docker
&lt;/h2>&lt;p>Si vous ne souhaitez pas altérer votre environnement existant ou si vous voulez l&amp;rsquo;intégrer à une infrastructure basée sur des conteneurs, vous pouvez également utiliser l&amp;rsquo;image Docker officielle. Si vous utilisez un GPU, l&amp;rsquo;installation du NVIDIA Container Toolkit est requise.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># En cas d&amp;#39;exécution sur le CPU uniquement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># En cas d&amp;#39;utilisation d&amp;#39;un GPU NVIDIA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker run -d --gpus&lt;span class="o">=&lt;/span>all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Par défaut, le serveur Ollama écoute sur &lt;code>http://localhost:11434&lt;/code>.&lt;/p>
&lt;hr>
&lt;h1 id="gestion-des-modèles-et-commandes-cli-de-base">Gestion des modèles et commandes CLI de base
&lt;/h1>&lt;p>Le plus grand attrait d&amp;rsquo;Ollama est que la gestion des modèles est très intuitive. Vous pouvez essayer divers modèles de la même manière que vous manipulez des images Docker.&lt;/p>
&lt;h2 id="1-exécuter-un-modèle-run">1. Exécuter un modèle (&lt;code>run&lt;/code>)
&lt;/h2>&lt;p>C&amp;rsquo;est la commande que vous utiliserez le plus fréquemment. Si le modèle spécifié n&amp;rsquo;existe pas, il sera automatiquement téléchargé (&lt;code>pull&lt;/code>), puis une invite de commande interactive s&amp;rsquo;ouvrira.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama run llama3.1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>L&amp;rsquo;exécution de la commande ci-dessus démarre Llama 3.1 (version avec 8B de paramètres), le modèle le plus récent de Meta. Lorsque vous saisissez un message dans l&amp;rsquo;invite, la réponse du modèle s&amp;rsquo;affiche en streaming. Pour quitter, saisissez &lt;code>/bye&lt;/code> ou appuyez sur &lt;code>Ctrl+D&lt;/code>.&lt;/p>
&lt;h2 id="2-télécharger-un-modèle-pull">2. Télécharger un modèle (&lt;code>pull&lt;/code>)
&lt;/h2>&lt;p>Si vous souhaitez télécharger des modèles en arrière-plan, utilisez la commande &lt;code>pull&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama pull phi3:instruct
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ollama pull mistral:v0.3
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dans la bibliothèque de modèles d&amp;rsquo;Ollama, vous pouvez spécifier les versions et les niveaux de quantification sous la forme &lt;code>nom_du_modèle:tag&lt;/code>. Si la balise est omise, &lt;code>latest&lt;/code> (la plus récente) est appliquée, mais vous pouvez également spécifier explicitement un modèle quantifié particulier (par exemple : &lt;code>llama3:8b-instruct-q4_0&lt;/code>).&lt;/p>
&lt;h3 id="quest-ce-que-la-quantification-quantization-">Qu&amp;rsquo;est-ce que la quantification (Quantization) ?
&lt;/h3>&lt;p>Abordons brièvement la quantification. Les LLM normaux conservent un paramètre de poids sous forme de nombre à virgule flottante de 16 bits (FP16), par exemple. Pour un modèle de 8 milliards (8B) de paramètres, les poids seuls consommeront environ 16 Go de VRAM. La quantification est une technologie qui compresse cela dans un format entier de 4 bits (Q4) ou de 8 bits (Q8).&lt;/p>
&lt;p>La quantification peut réduire considérablement la quantité de mémoire et de bande passante mémoire requises tout en minimisant la dégradation de la précision du modèle. Les modèles distribués par Ollama sont par défaut au format GGUF avec une quantification optimale appliquée (souvent 4 bits).&lt;/p>
&lt;h2 id="3-lister-les-modèles-list">3. Lister les modèles (&lt;code>list&lt;/code>)
&lt;/h2>&lt;p>Affiche une liste des modèles téléchargés localement et leurs tailles.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama list
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Exemple de sortie :&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">NAME ID SIZE MODIFIED
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">llama3.1:latest 43f7a214e532 4.7 GB 2 hours ago
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">phi3:instruct a2c89ceaed85 2.3 GB 3 days ago
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="4-supprimer-un-modèle-rm">4. Supprimer un modèle (&lt;code>rm&lt;/code>)
&lt;/h2>&lt;p>Supprime les modèles devenus inutiles pour libérer de l&amp;rsquo;espace disque.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama rm phi3:instruct
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="personnalisation-de-modèle-avec-un-modelfile">Personnalisation de modèle avec un Modelfile
&lt;/h1>&lt;p>Dans Ollama, vous pouvez utiliser un mécanisme appelé &amp;ldquo;&lt;strong>Modelfile&lt;/strong>&amp;rdquo; pour injecter des invites système ou ajuster les hyperparamètres sur des modèles existants, vous permettant ainsi de créer vos propres modèles personnalisés. C&amp;rsquo;est exactement le même concept que le Dockerfile pour Docker.&lt;/p>
&lt;p>Le diagramme ci-dessous illustre comment un modèle personnalisé dérive d&amp;rsquo;un modèle de base.&lt;/p>
&lt;div class="mermaid">graph LR
A["Modèle de base (llama3.1)"] -->|"Ajout d'une invite système"| B["Configuration intermédiaire"]
B -->|"Paramétrage de Temperature &amp; Top_p"| C["Modèle personnalisé (kansai-coder)"]
C -->|"Exécution"| D["CLI interactive / API"]&lt;/div>
&lt;p>À titre d&amp;rsquo;exemple, créons un modèle d&amp;rsquo;assistant de programmation qui répond en dialecte du Kansai (Kansai-ben).&lt;/p>
&lt;p>Créez un fichier texte nommé &lt;code>Modelfile&lt;/code> dans votre répertoire de travail et écrivez ce qui suit :&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Spécifier le modèle de base
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">FROM llama3.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Configurer les hyperparamètres comme la créativité (temperature)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER top_p 0.9
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER repeat_penalty 1.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 4096
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Définir l&amp;#39;invite système
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Vous êtes un ingénieur logiciel senior de classe mondiale.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Veuillez toujours répondre aux questions techniques des utilisateurs de manière amicale en utilisant le « dialecte du Kansai ».
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Lorsque vous fournissez des exemples de code, proposez un code moderne qui suit les meilleures pratiques.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Construisez (créez) un nouveau modèle à partir de ce Modelfile.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama create kansai-coder -f Modelfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Une fois la compilation terminée, exécutez-le pour le tester.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama run kansai-coder
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt;&amp;gt;&amp;gt; Comment je peux trier une liste en Python ?
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Il fera alors preuve d&amp;rsquo;un comportement personnalisé, répondant par exemple : &amp;ldquo;Et bien, tu peux utiliser la fonction &lt;code>sorted()&lt;/code> ou la méthode &lt;code>sort()&lt;/code> de Python !&amp;rdquo;. De cette façon, il devient possible de créer et de gérer localement un nombre illimité d&amp;rsquo;agents spécialisés pour des cas d&amp;rsquo;utilisation spécifiques.&lt;/p>
&lt;hr>
&lt;h1 id="explication-détaillée-de-lapi-rest-dollama">Explication détaillée de l&amp;rsquo;API REST d&amp;rsquo;Ollama
&lt;/h1>&lt;p>Bien que l&amp;rsquo;interaction via le CLI soit pratique, c&amp;rsquo;est avec sa puissante API REST qu&amp;rsquo;Ollama révèle tout son potentiel dans le développement d&amp;rsquo;applications réelles. Vous pouvez obtenir des résultats d&amp;rsquo;inférence en envoyant des requêtes HTTP au processus serveur (par défaut &lt;code>http://localhost:11434&lt;/code>).&lt;/p>
&lt;p>Les 3 principaux points de terminaison (endpoints) sont :&lt;/p>
&lt;ol>
&lt;li>&lt;code>/api/generate&lt;/code> : Génération de texte à partir d&amp;rsquo;une simple invite&lt;/li>
&lt;li>&lt;code>/api/chat&lt;/code> : Génération de chat (dialogue) dans un format similaire à l&amp;rsquo;API OpenAI&lt;/li>
&lt;li>&lt;code>/api/embeddings&lt;/code> : Génération de plongements vectoriels (Embeddings)&lt;/li>
&lt;/ol>
&lt;h2 id="génération-de-texte-avec-apigenerate">Génération de texte avec /api/generate
&lt;/h2>&lt;p>C&amp;rsquo;est le point de terminaison de génération le plus basique. Envoyons une requête en utilisant cURL.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -X POST http://localhost:11434/api/generate -d &lt;span class="s1">&amp;#39;{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;model&amp;#34;: &amp;#34;llama3.1&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;prompt&amp;#34;: &amp;#34;Explain the concept of quantum entanglement in simple terms.&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;stream&amp;#34;: false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>En spécifiant &lt;code>&amp;quot;stream&amp;quot;: false&lt;/code>, un objet JSON est renvoyé en une seule fois après la fin de la génération complète. Par défaut (qui est &lt;code>true&lt;/code>), les jetons générés sont envoyés de manière séquentielle au format JSON Lines, ce qui est idéal pour implémenter une interface utilisateur en streaming.&lt;/p>
&lt;p>Exemple de réponse (partiellement omise) :&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;model&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;llama3.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;created_at&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2026-09-11T10:00:00.000Z&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;response&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Quantum entanglement is like having a pair of magical dice...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;done&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">128006&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">882&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">128007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">271&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10445&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;total_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4567890000&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;load_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1234000&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prompt_eval_count&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">14&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;eval_count&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">256&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;eval_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4321000000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Le tableau &lt;code>context&lt;/code> contient l&amp;rsquo;état de la conversation passée encodé, ce qui permet de maintenir le contexte en l&amp;rsquo;incluant dans la requête suivante. Cependant, pour gérer plus facilement l&amp;rsquo;historique des conversations, nous utiliserons l&amp;rsquo;endpoint suivant &lt;code>/api/chat&lt;/code>.&lt;/p>
&lt;h2 id="génération-de-dialogue-avec-apichat">Génération de dialogue avec /api/chat
&lt;/h2>&lt;p>Puisque les LLM récents sont affinés (fine-tunés) dans un format de chat, il est recommandé d&amp;rsquo;utiliser &lt;code>/api/chat&lt;/code> pour le développement d&amp;rsquo;applications.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -X POST http://localhost:11434/api/chat -d &lt;span class="s1">&amp;#39;{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;model&amp;#34;: &amp;#34;llama3.1&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;messages&amp;#34;: [
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;system&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;You are a helpful AI assistant.&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;What is the capital of France?&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;assistant&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;The capital of France is Paris.&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;What is its famous tower?&amp;#34; }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> ],
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;stream&amp;#34;: false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ainsi, en transmettant un tableau d&amp;rsquo;objets messages avec des rôles (&lt;code>role&lt;/code>: system, user, assistant), vous pouvez facilement gérer des contextes de dialogue complexes.&lt;/p>
&lt;hr>
&lt;h1 id="intégration-avec-des-applications-python">Intégration avec des applications Python
&lt;/h1>&lt;p>Python est le langage le plus standard dans le développement de l&amp;rsquo;IA. Bien qu&amp;rsquo;il existe plusieurs façons d&amp;rsquo;utiliser Ollama depuis Python, l&amp;rsquo;utilisation du package officiel &lt;code>ollama-python&lt;/code> est la méthode la plus simple et la plus fiable.&lt;/p>
&lt;h2 id="installation">Installation
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="utilisation-de-lapi-synchrone">Utilisation de l&amp;rsquo;API synchrone
&lt;/h2>&lt;p>Voici le code de base pour générer un chat.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Liste pour conserver l&amp;#39;historique du chat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">messages&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;system&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Vous êtes un excellent assistant.&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">chat_with_ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">user_input&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">user_input&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Appel de l&amp;#39;API Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ollama&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">messages&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">assistant_reply&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;message&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;assistant&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">assistant_reply&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">assistant_reply&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chat_with_ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Quelles sont les trois principales approches de l&amp;#39;apprentissage automatique ?&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="utilisation-du-streaming-asynchrone-async-streaming">Utilisation du streaming asynchrone (Async Streaming)
&lt;/h2>&lt;p>Lors du développement d&amp;rsquo;applications Web (FastAPI, Starlette) ou de bots pour Discord / Slack, il est important d&amp;rsquo;utiliser l&amp;rsquo;API asynchrone et le streaming pour éviter les blocages.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">asyncio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">ollama&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AsyncClient&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">generate_stream&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AsyncClient&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Spécifier stream=True renvoie un générateur asynchrone&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">async&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">chunk&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[{&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Explique en détail les décorateurs en Python.&amp;#39;&lt;/span>&lt;span class="p">}],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">stream&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Affichage séquentiel sur la sortie standard par morceau (chunk)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;message&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">end&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">flush&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="c1"># Saut de ligne final&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Exécuter la fonction asynchrone&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">asyncio&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">generate_stream&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>En écrivant de cette façon, vous pouvez facilement implémenter une expérience utilisateur (UX) où les caractères s&amp;rsquo;affichent un par un, tout comme dans l&amp;rsquo;interface de ChatGPT.&lt;/p>
&lt;h2 id="intégration-avec-langchain-et-llamaindex">Intégration avec LangChain et LlamaIndex
&lt;/h2>&lt;p>Ollama est également pris en charge de manière native par LangChain et LlamaIndex, qui sont souvent utilisés lors de la construction de systèmes RAG (Retrieval-Augmented Generation).&lt;/p>
&lt;p>Exemple avec LangChain :&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3.1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llm&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Explain dark matter.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Il est possible d&amp;rsquo;exécuter localement les puissantes fonctionnalités de chaînes et d&amp;rsquo;agents de LangChain sans configurer aucune clé d&amp;rsquo;API externe.&lt;/p>
&lt;hr>
&lt;h1 id="intégration-avec-des-applications-nodejs">Intégration avec des applications Node.js
&lt;/h1>&lt;p>Pour les ingénieurs front-end ou les développeurs full-stack, pouvoir appeler un LLM local à partir d&amp;rsquo;un environnement TypeScript/Node.js est un énorme avantage. Nous utiliserons le package NPM officiel &lt;code>ollama&lt;/code>.&lt;/p>
&lt;h2 id="installation-1">Installation
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="exemple-dimplémentation-dun-chatbot-utilisant-typescript">Exemple d&amp;rsquo;implémentation d&amp;rsquo;un chatbot utilisant TypeScript
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">Message&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s1">&amp;#39;ollama&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">async&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="nx">runChatbot() {&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">messages&lt;/span>: &lt;span class="kt">Message&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">role&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;system&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">content&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;You are a concise expert.&amp;#39;&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">role&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">content&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Explain RESTful APIs.&amp;#39;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">chat&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">messages&lt;/span>: &lt;span class="kt">messages&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">stream&lt;/span>: &lt;span class="kt">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Assistant:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">message&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">content&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">error&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Error communicating with Ollama:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">error&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">runChatbot&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="création-dun-serveur-express-prenant-en-charge-le-streaming">Création d&amp;rsquo;un serveur Express prenant en charge le streaming
&lt;/h2>&lt;p>Voici un exemple d&amp;rsquo;implémentation d&amp;rsquo;une API backend qui renvoie une réponse en streaming à un frontend Web. Des morceaux (chunks) sont envoyés à l&amp;rsquo;aide de SSE (Server-Sent Events) ou du streaming HTTP normal.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">express&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;express&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">Ollama&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;ollama&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">express&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">use&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">express&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">json&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">ollama&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Ollama&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">host&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;http://127.0.0.1:11434&amp;#39;&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">post&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/api/stream-chat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kr">async&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">req&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">prompt&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">req&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">body&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Configuration des en-têtes de réponse HTTP (transfert par blocs)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setHeader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Content-Type&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;text/plain; charset=utf-8&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setHeader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Transfer-Encoding&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;chunked&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">stream&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">generate&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">prompt&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">prompt&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">stream&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">chunk&lt;/span> &lt;span class="k">of&lt;/span> &lt;span class="nx">stream&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">chunk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">response&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">end&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Error generating response.&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">end&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">listen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Server is running on port 3000&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="métriques-de-performance-et-analyse-mathématique">Métriques de performance et analyse mathématique
&lt;/h1>&lt;p>Pour offrir un LLM local à un niveau viable pour une utilisation en production, l&amp;rsquo;analyse de la latence et du débit est indispensable. Les réponses de l&amp;rsquo;API d&amp;rsquo;Ollama incluent des métriques détaillées concernant les performances.&lt;/p>
&lt;h2 id="modèle-de-calcul-de-la-vitesse-de-génération-de-jetons">Modèle de calcul de la vitesse de génération de jetons
&lt;/h2>&lt;p>Le temps de réponse du LLM, directement lié à l&amp;rsquo;expérience utilisateur, peut être principalement décomposé en &amp;ldquo;&lt;strong>Time To First Token (TTFT)&lt;/strong>&amp;rdquo; et &amp;ldquo;&lt;strong>Time Per Output Token (TPOT)&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;p>Le temps de génération total $T_{total}$, avec $N$ comme nombre de jetons générés, est formulé comme suit :&lt;/p>
$$
T_{total} = t_{ttft} + \sum_{i=1}^{N-1} t_{tpot}^{(i)}
$$
&lt;p>Ici, si nous approximons le temps moyen mis pour générer chaque jeton à $\bar{t}_{tpot}$, l&amp;rsquo;équation est simplifiée :&lt;/p>
$$
T_{total} \approx t_{ttft} + (N - 1) \times \bar{t}_{tpot}
$$
&lt;p>La correspondance avec les champs de réponse de l&amp;rsquo;API d&amp;rsquo;Ollama est la suivante :&lt;/p>
&lt;ul>
&lt;li>&lt;code>prompt_eval_duration&lt;/code> : Cela correspond approximativement à $t_{ttft}$ (temps d&amp;rsquo;évaluation de l&amp;rsquo;invite). Il est renvoyé en nanosecondes.&lt;/li>
&lt;li>&lt;code>eval_duration&lt;/code> : Temps total pris pour le processus de génération.&lt;/li>
&lt;li>&lt;code>eval_count&lt;/code> : Nombre de jetons générés $N$.&lt;/li>
&lt;/ul>
&lt;p>Par conséquent, la vitesse de génération de jetons par seconde (Tokens Per Second : TPS) peut être calculée avec la formule suivante :&lt;/p>
$$
TPS = \frac{eval\_count}{(eval\_duration / 10^9)} \quad [\text{tokens/sec}]
$$
&lt;p>Par exemple, dans le cas de &lt;code>eval_count: 256&lt;/code> et &lt;code>eval_duration: 4321000000&lt;/code> (environ 4,32 secondes),
&lt;/p>
$$
TPS = \frac{256}{4.321} \approx 59.24 \text{ tokens/sec}
$$
&lt;p>
cela donne environ 59,24. Si elle dépasse 50 jetons par seconde dans un environnement local, elle surpasse de loin la vitesse de lecture humaine, ce qui signifie qu&amp;rsquo;elle offre une expérience de réponse extrêmement confortable.&lt;/p>
&lt;h2 id="formule-destimation-de-la-capacité-vram-requise">Formule d&amp;rsquo;estimation de la capacité VRAM requise
&lt;/h2>&lt;p>Lors de l&amp;rsquo;exécution d&amp;rsquo;un modèle en local, la capacité du modèle à tenir dans la VRAM du GPU est la clé de la performance. S&amp;rsquo;il ne tient pas dans la VRAM et qu&amp;rsquo;il se replie sur la mémoire principale (RAM) du système, la vitesse de génération chutera de manière significative.&lt;/p>
&lt;p>Une formule simplifiée pour estimer la capacité de mémoire requise $M$ (en gigaoctets) est la suivante :&lt;/p>
$$
M \approx \frac{P \times Q}{8 \times 1024} + C
$$
&lt;ul>
&lt;li>$P$ : Nombre de paramètres du modèle (Exemple : 8B = $8000 \times 10^6$)&lt;/li>
&lt;li>$Q$ : Nombre de bits de la quantification (Exemple : 4-bit, 8-bit, 16-bit)&lt;/li>
&lt;li>$C$ : Mémoire supplémentaire pour la fenêtre de contexte (cache KV, etc. Dépend du modèle et des paramètres, mais on estime généralement autour de 1 à 2 Go)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Exemple de calcul&lt;/strong> : Lors de l&amp;rsquo;exécution de Llama 3 (8B paramètres) avec une quantification de 4-bit
&lt;/p>
$$
M_{model} = \frac{8,000 \times 4}{8 \times 1024} = \frac{32,000}{8192} \approx 3.9 \text{ GB}
$$
&lt;p>
En y ajoutant la mémoire pour le contexte, nous pouvons constater qu&amp;rsquo;avec environ 5 Go à 6 Go de VRAM, le modèle peut être entièrement déployé (Full Offload) sur le GPU. Même avec un GPU de milieu de gamme récent équipé de 8 Go de VRAM (comme la RTX 4060), il est possible de faire fonctionner un LLM suffisamment puissant.&lt;/p>
&lt;hr>
&lt;h1 id="cas-dutilisation-avancés-et-conclusion">Cas d&amp;rsquo;utilisation avancés et conclusion
&lt;/h1>&lt;p>En exposant Ollama en tant qu&amp;rsquo;API au sein d&amp;rsquo;un réseau local, diverses applications au-delà d&amp;rsquo;un simple chatbot deviennent possibles.&lt;/p>
&lt;h3 id="1-construction-dun-rag-retrieval-augmented-generation-local">1. Construction d&amp;rsquo;un RAG (Retrieval-Augmented Generation) local
&lt;/h3>&lt;p>En combinant des bases de données vectorielles locales telles que ChromaDB ou Qdrant avec le point de terminaison &lt;code>/api/embeddings&lt;/code> d&amp;rsquo;Ollama (en utilisant des modèles de plongement comme &lt;code>nomic-embed-text&lt;/code>), vous pouvez construire un système RAG sécurisé et entièrement hors ligne qui lit des documents internes confidentiels pour répondre aux questions.&lt;/p>
&lt;h3 id="2-assistant-ia-pour-les-ide-et-éditeurs">2. Assistant IA pour les IDE et éditeurs
&lt;/h3>&lt;p>En spécifiant Ollama comme backend pour des extensions VS Code (comme Continue.dev) ou des plugins Neovim, vous pouvez bénéficier d&amp;rsquo;une complétion et d&amp;rsquo;une explication de code similaires à GitHub Copilot gratuitement, en utilisant des modèles locaux (par exemple &lt;code>codellama&lt;/code> ou &lt;code>deepseek-coder&lt;/code>).&lt;/p>
&lt;h3 id="3-intégration-dans-des-scripts-dautomatisation">3. Intégration dans des scripts d&amp;rsquo;automatisation
&lt;/h3>&lt;p>En intégrant des requêtes API Ollama dans vos scripts Python ou Shell, vous pouvez insuffler la puissance de l&amp;rsquo;IA partout dans votre flux de travail quotidien : résumés automatiques de journaux, génération automatique de messages de commit Git, tâches de classification de textes standardisés, etc.&lt;/p>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>Avec l&amp;rsquo;apparition d&amp;rsquo;Ollama, la barrière à l&amp;rsquo;entrée pour l&amp;rsquo;adoption de LLM locaux a considérablement diminué. Il n&amp;rsquo;est pas exagéré de dire que la combinaison de son système de commandes simple, similaire à la manipulation de conteneurs Docker, et de son API REST facilement utilisable par des applications externes, constitue l&amp;rsquo;actuel standard de facto dans le développement d&amp;rsquo;IA locale.&lt;/p>
&lt;p>Pour les développeurs confrontés aux coûts et aux contraintes de sécurité des LLM cloud, nous vous invitons à vous référer aux procédures présentées dans cet article pour configurer votre environnement LLM local avec Ollama et l&amp;rsquo;intégrer à vos propres applications. Vous pourrez ainsi ressentir le potentiel de l&amp;rsquo;IA de manière plus libre et plus accessible.&lt;/p></description></item></channel></rss>