LLM Council : faire délibérer plusieurs modèles locaux
LLM Council est un petit projet publié par Andrej Karpathy fin 2025 : au lieu d'envoyer une question à un seul modèle, on la soumet à plusieurs, chacun classe ensuite les réponses des autres sans savoir qui les a écrites, et un modèle « président » rédige la synthèse finale. Le dépôt vise des modèles cloud via OpenRouter, mais le patron tient en une centaine de lignes et se transpose à des modèles locaux servis par Ollama. Ce guide explique les trois étapes, montre comment les reproduire sur une machine personnelle, détaille ce que cela coûte en mémoire et en temps, et pourquoi il ne faut pas supposer que le conseil répond mieux qu'un bon modèle seul.
#LLM Council : le patron en trois étapes
Le dépôt décrit un flux fixe en trois temps. Chaque temps est un appel de modèle ordinaire, sans outil ni mémoire : la seule astuce est la façon dont les sorties du premier temps nourrissent les deux suivants.
- 01Premières opinionsLa question de l'utilisateur est envoyée telle quelle à chaque membre du conseil, séparément. Chacun répond sans voir les autres. Dans l'interface d'origine, ces réponses s'affichent dans des onglets, une par modèle.
- 02Relecture et classementChaque membre reçoit ensuite les réponses des autres, anonymisées (étiquetées « Réponse A », « Réponse B »...), et doit les classer de la meilleure à la moins bonne en jugeant la justesse et la profondeur. L'anonymisation vise à éviter qu'un modèle favorise ou défavorise un concurrent connu.
- 03Synthèse du présidentUn modèle désigné comme président reçoit la question, toutes les réponses et tous les classements, puis rédige la réponse finale unique présentée à l'utilisateur.
Rien dans ce schéma n'exige des modèles différents, mais c'est tout l'intérêt : on compte sur la diversité des entraînements pour que les erreurs d'un modèle soient repérées par un autre. Le président peut être l'un des membres ou un modèle à part, en général le plus capable de la liste.
#Ce que contient le dépôt de Karpathy
Des agents qui agissent sur ta machine : Cline agentique, MCP, n8n + Ollama, automatisations locales.
- Espace en ligne à vie
- PDF + fichiers
- Mises à jour à vie
Le dépôt github.com/karpathy/llm-council est une application web locale qui ressemble à une interface de chat classique. D'après son README et ses fichiers de configuration au moment de la rédaction, il se compose de :
- Un backend Python (FastAPI)
- Dans le dossier backend/ : la logique des trois étapes, un client HTTP vers l'API d'OpenRouter, et le stockage des conversations en fichiers JSON dans un dossier data/. Les dépendances sont gérées avec uv.
- Un frontend React (Vite)
- Dans le dossier frontend/ : l'interface qui affiche les réponses individuelles, les classements et la synthèse.
- Un fichier de configuration
- backend/config.py liste les membres du conseil (COUNCIL_MODELS) et le président (CHAIRMAN_MODEL) sous forme d'identifiants OpenRouter, ainsi que l'adresse de l'API appelée.
- Un script de lancement
- start.sh démarre le backend et le frontend ensemble. Une clé OPENROUTER_API_KEY est attendue dans un fichier .env.
Les modèles configurés par défaut sont des modèles cloud fermés (familles GPT, Gemini, Claude et Grok dans la version publiée). C'est le point à changer pour une version locale : le reste du code ne se soucie pas de qui répond, tant que l'API parle le format « chat completions » popularisé par OpenAI. Relisez le README et config.py avant de suivre ce guide, le projet peut avoir évolué depuis le 12 octobre 2026.
#Prérequis pour une version locale
- Ollama installé et fonctionnel
- Le serveur écoute par défaut sur http://localhost:11434. Vérifiez avec la commande ollama list que vos modèles apparaissent.
- Trois à quatre modèles de familles différentes
- Un conseil de modèles issus de la même famille perd l'intérêt de la diversité. Visez par exemple un Qwen, un Llama, un Mistral et un Gemma, dans des tailles proches.
- Mémoire adaptée
- En Q4_K_M, comptez environ 5 Go par modèle 7B et 9 Go par modèle 14B. Les membres n'ont pas besoin de tenir tous en mémoire en même temps, mais le confort en dépend (voir la section sur les coûts).
- Python 3.10 ou plus
- Pour le script minimal de ce guide, avec le paquet requests. Pour le dépôt original, uv et Node.js en plus.
- Patience
- Un tour de conseil coûte au moins deux fois plus de générations que le nombre de membres, plus une. Ce n'est pas un outil de chat instantané.
#Étape 1 : choisir le conseil et le président
Le choix des membres est une affaire d'équilibre entre diversité et mémoire. Le président, lui, doit surtout bien lire de longs contextes : il reçoit la question, toutes les réponses et tous les classements, ce qui représente facilement plusieurs milliers de tokens. Prenez pour ce rôle le modèle le plus capable que votre machine supporte, même s'il est plus lent, car il n'est appelé qu'une fois par tour.
Les tailles 7B à 8B conviennent aux membres sur une carte de 12 Go : un seul tient en mémoire avec une marge pour le contexte, et Ollama alterne entre eux. Avec 24 Go ou un Mac à mémoire unifiée de 48 Go, vous pouvez monter les membres en 14B ou garder deux à trois modèles chargés en même temps, ce qui supprime les rechargements.
#Étape 2 : régler Ollama pour plusieurs modèles
Deux réglages d'Ollama comptent ici. Le premier est le nombre de modèles gardés en mémoire, fixé par la variable OLLAMA_MAX_LOADED_MODELS : si la mémoire le permet, garder tous les membres chargés évite un rechargement à chaque passage de l'un à l'autre. Le second est la fenêtre de contexte, num_ctx, qui par défaut est courte sur Ollama : l'étape de classement et la synthèse du président font lire plusieurs réponses complètes, et un contexte trop petit tronque silencieusement le début du prompt.
Sur macOS, les mêmes variables se posent avec launchctl setenv avant de relancer l'application. La valeur de OLLAMA_MAX_LOADED_MODELS doit rester cohérente avec votre mémoire : deux modèles 8B en Q4 occupent déjà une dizaine de Go avec leur contexte. Le contexte, lui, se règle par requête (champ options.num_ctx de l'API) ou dans un Modelfile dérivé ; la section suivante le passe à chaque appel.
#Étape 3 : un conseil minimal en Python
Le script ci-dessous reproduit les trois étapes du dépôt avec l'API native d'Ollama, sans interface. Il mélange l'ordre des réponses avant le classement pour que les étiquettes ne trahissent pas l'auteur, demande à chaque membre un classement court, puis confie le tout au président. Adaptez les noms de modèles à ceux de votre machine.
Le dépôt original va un peu plus loin : il extrait la ligne de classement de chaque juge pour calculer un rang moyen par réponse et l'afficher à côté des onglets. Vous pouvez l'ajouter en quelques lignes en lisant la ligne « CLASSEMENT : » de chaque sortie. Gardez en tête que les petits modèles ne respectent pas toujours ce format : prévoyez un repli quand la ligne manque.
#Étape 4 : adapter le dépôt original à Ollama
Si vous voulez l'interface web, le chemin le plus court consiste à utiliser le point d'accès compatible OpenAI d'Ollama, servi à l'adresse http://localhost:11434/v1/chat/completions. Le backend du dépôt envoie déjà des requêtes dans ce format vers OpenRouter : il suffit en principe de remplacer l'adresse de l'API et les identifiants de modèles dans backend/config.py, puis de renseigner une clé factice, Ollama ignorant l'en-tête d'autorisation.
Deux points restent à traiter à la main. D'abord le contexte : le point d'accès compatible OpenAI n'a pas de champ num_ctx, il faut donc soit créer des variantes de modèles avec un Modelfile fixant le contexte, soit basculer le client sur l'API native /api/chat qui accepte les options. Ensuite le parallélisme évoqué plus haut : la première étape lance les appels en même temps, ce qui vaut un passage en séquentiel si vos membres ne tiennent pas tous en mémoire.
Plusieurs forks communautaires ont fait ces modifications pour Ollama ou pour d'autres serveurs locaux. Avant d'en adopter un, regardez la date du dernier commit, le nombre de fichiers touchés par rapport au dépôt d'origine, et lisez le code qui appelle le modèle : c'est court, et c'est là que se logent les différences. Ce guide ne recommande aucun fork en particulier, leur état change trop vite.
#Coût en mémoire et en temps
Le compte est simple et vaut la peine d'être posé avant de s'engager. Pour un conseil de N membres, un tour complet demande N générations à l'étape 1, N générations à l'étape 2 et une pour le président, soit 2N + 1 appels. Les appels de l'étape 2 et celui du président sont plus longs à traiter que le premier, car le prompt contient toutes les réponses : le temps de lecture du prompt s'ajoute au temps de génération.
- Trois membres
- Sept générations par question. Si chaque réponse prend de l'ordre d'une demi-minute sur votre machine, un tour dépasse les trois minutes, sans compter les rechargements.
- Mémoire minimale
- Le plus gros modèle du conseil plus son contexte. Avec des membres 8B en Q4 et un contexte de 16 000 tokens, une carte de 12 Go tient, à condition de ne garder qu'un modèle chargé.
- Mémoire confortable
- Tous les membres chargés en même temps : la somme de leurs tailles, plus un cache de contexte par modèle. Trois modèles 8B en Q4 réclament un GPU de 24 Go ou un Mac de 32 Go unifiés au minimum.
- Rechargements
- Quand les membres ne tiennent pas ensemble, chaque changement de modèle coûte quelques secondes de chargement depuis le disque. Sur un tour, cela arrive jusqu'à 2N fois. Un SSD NVMe rend ce coût supportable ; un disque lent le rend pénible.
Ces ordres de grandeur dépendent de votre matériel, de la quantification et de la longueur des réponses : nous n'avons pas mesuré de temps de tour pour cet article et les chiffres ci-dessus sont des règles de calcul, pas des résultats. Pour évaluer votre cas, chronométrez une génération simple avec chacun de vos membres et appliquez la formule.
#Limites et biais du conseil
Le patron est séduisant parce qu'il ressemble à une relecture par les pairs. Il faut pourtant résister à l'idée qu'il est forcément plus juste qu'un bon modèle seul : le dépôt n'apporte aucune mesure dans ce sens, et plusieurs biais connus des modèles juges jouent contre lui.
- Anonymisation imparfaite
- Les étiquettes masquent le nom, pas le style. Un modèle peut reconnaître sa propre façon d'écrire, ou celle d'une famille qu'il connaît, et classer en conséquence. Karpathy note lui-même, de façon qualitative, que les modèles ont souvent préféré la réponse d'un autre à la leur : c'est une observation, pas une garantie.
- Biais de position et de longueur
- Les travaux sur les modèles juges, par exemple l'article MT-Bench de Zheng et al. (2023), documentent une préférence pour la première réponse lue et pour les réponses longues. Mélanger l'ordre atténue le premier biais ; le second se corrige mal.
- Erreurs corrélées
- Des modèles entraînés sur des corpus proches se trompent souvent de la même manière. Un conseil de petits modèles peut voter à l'unanimité pour une réponse fausse, et le président la retiendra.
- Le président reste seul
- La synthèse dépend entièrement du modèle président : s'il hallucine, le conseil n'y change rien. Lisez les réponses individuelles quand le sujet compte, c'est d'ailleurs l'intérêt des onglets de l'interface originale.
- Petits modèles, instructions longues
- Le prompt de classement est exigeant : lire trois ou quatre textes, juger, justifier, respecter un format. En dessous de 7B, les sorties deviennent irrégulières et le classement moyen perd son sens.
#Cas d'usage réels d'un LLM Council local
Le surcoût de 2N + 1 générations se justifie quand la question est rare et importante, pas pour du bavardage. Trois situations ressortent chez les personnes qui ont repris le patron en local.
- Relecture d'un texte ou d'un code sensible
- Un courrier contractuel, une procédure, une fonction critique : les membres relèvent des problèmes différents, le président les consolide en une liste. Le classement sert ici moins que la diversité des remarques.
- Décision technique argumentée
- « Faut-il migrer cette base », « quel format pour cet export » : les réponses divergentes sont une information en soi. Demandez au président de rendre les désaccords visibles plutôt que de les lisser.
- Contrôle qualité d'un seul modèle
- Utiliser le conseil comme jury pour comparer deux versions de prompt ou deux quantifications du même modèle, en lui demandant de classer des sorties que vous avez produites ailleurs. C'est une application directe de l'étape 2, sans l'étape 1.
Dans tous ces cas, la confidentialité est le vrai argument de la version locale : les documents relus ne quittent pas la machine, là où la version originale les envoie à quatre fournisseurs différents via OpenRouter. C'est ce qui rend le patron intéressant pour une équipe qui traite des données internes, à condition d'accepter les minutes d'attente.
#Dépannage
- Le classement ignore une réponse
- Le contexte est trop court et le début du prompt a été tronqué. Augmentez num_ctx (ou le Modelfile) et vérifiez dans les journaux d'Ollama qu'aucun avertissement de troncature n'apparaît.
- Les appels de l'étape 1 sont très lents
- Les membres sont appelés en parallèle et se bousculent en mémoire. Passez en séquentiel ou réduisez le conseil à ce qui tient en VRAM ensemble.
- Le président répond à côté
- Son contexte est le plus chargé du tour. Donnez-lui un modèle plus gros ou résumez les classements avant de les lui transmettre.
- Format de classement absent
- Les petits modèles oublient la ligne « CLASSEMENT : ». Rappelez le format en fin de prompt, baissez la température, ou acceptez une lecture manuelle des justifications.
- Réponses d'un membre vides ou en anglais
- Vérifiez que le modèle ne renvoie pas uniquement sa phase de réflexion, et précisez la langue attendue dans la question.
- Mémoire saturée après quelques tours
- OLLAMA_MAX_LOADED_MODELS trop haut pour la machine. Ramenez-le à 1 et laissez Ollama alterner.
#Pour aller plus loin
LLM Council est un patron de délibération, pas un cadre d'agents : il ne gère ni outils, ni rôles, ni mémoire. Si votre besoin dépasse la synthèse d'avis, ces guides du site couvrent les briques voisines.
- CrewAI avec Ollama
- Quand les modèles doivent se répartir des rôles et enchaîner des tâches plutôt que juger une même réponse. https://quelllm.fr/guide/crewai-ollama-multi-agents
- LiteLLM en passerelle locale
- Pour exposer plusieurs serveurs de modèles derrière une seule API compatible OpenAI, par exemple un conseil réparti sur deux machines. https://quelllm.fr/guide/litellm-proxy-gateway-local
- Architecture d'un agent IA local
- Les composants à assembler autour d'un modèle quand on veut lui donner des outils et une mémoire. https://quelllm.fr/guide/agent-ia-local-architecture
- Partager un serveur Ollama sur le réseau local
- Héberger les membres du conseil sur une machine plus grosse et les appeler depuis votre poste. https://quelllm.fr/guide/ollama-serveur-reseau-local-partage
Guide rédigé le 12 octobre 2026 à partir du dépôt GitHub de Karpathy et de la documentation d'Ollama. Aucune mesure de temps ni de qualité n'a été réalisée pour cet article ; les repères de mémoire sont des ordres de grandeur en Q4_K_M. Les noms de constantes, de ports et de modèles évoluent : relisez les sources ci-dessous avant de copier les commandes.
- Dépôt GitHub karpathy/llm-council (README, backend/config.py, start.sh)
- Documentation Ollama (API native /api/chat, compatibilité OpenAI, variables d'environnement)
- Zheng et al., 2023 : Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (biais des modèles juges)
Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.