Avanzato 10 minMulti-modello

LLM Council: far deliberare più modelli locaux

LLM Council è un piccolo progetto pubblicato da Andrej Karpathy alla fine del 2025: invece di inviare una domanda a un solo modello, la sottopone a diversi modelli, ciascuno dei quali classifica poi le risposte degli altri senza sapere chi le ha scritte, e un modello «presidente» redige la sintesi finale. Il repository punta a modelli cloud tramite OpenRouter, ma il modello operativo sta in un centinaio di righe e si trasferisce a modelli locali serviti da Ollama. Questa guida illustra i tre passaggi, mostra come riprodurli su un computer personale, descrive in dettaglio il costo in memoria e in tempo e spiega perché non bisogna presumere che il consiglio risponda meglio di un buon modello singolo.

Di Léa B.·Agg. 2026-10-12·Testato su Windows, macOS e Linux

#LLM Council: il modello in tre passaggi

Il repository descrive un flusso fisso in tre fasi. Ogni fase è una normale chiamata a un modello, senza strumenti né memoria: l’unico accorgimento è il modo in cui le uscite della prima fase alimentano le due successive.

  1. 01
    Prime opinioni
    La domanda dell'utente viene inviata così com'è a ogni membro del consiglio, separatamente. Ognuno risponde senza vedere gli altri. Nell'interfaccia originale, queste risposte vengono visualizzate in schede, una per modello.
  2. 02
    Rilettura e classificazione
    Ogni membro riceve poi le risposte degli altri, anonimizzate (etichettate «Risposta A», «Risposta B»...), e deve classificarle dalla migliore alla peggiore giudicandone correttezza e profondità. L'anonimizzazione mira a evitare che un modello favorisca o sfavorisca un concorrente noto.
  3. 03
    Sintesi del presidente
    Un modello designato come presidente riceve la domanda, tutte le risposte e tutte le classifiche, poi redige l'unica risposta finale presentata all'utente.

Nulla in questo schema richiede modelli diversi, ma è proprio questo il punto: si fa affidamento sulla diversità degli addestramenti affinché gli errori di un modello vengano individuati da un altro. Il presidente può essere uno dei membri o un modello separato, in genere quello più capace dell'elenco.

i
Un progetto esplorativo, non un prodotto
Nel suo messaggio di annuncio, Karpathy presenta LLM Council come un progetto del fine settimana scritto in gran parte da assistenti di programmazione, che non prevede di mantenere. Le impressioni che condivide sui modelli che si classificano bene o male tra loro sono qualitative e datate. Il repository non contiene alcuna valutazione quantitativa: questa guida non ne aggiunge.

#Cosa contiene il repository di Karpathy

Il kit Agenti Locali

Agenti che agiscono sulla tua macchina: Cline agentico, MCP, n8n + Ollama, automazioni locali.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita

Il deposito github.com/karpathy/llm-council è un'applicazione web locale che ricorda una classica interfaccia di chat. Secondo il suo README e i file di configurazione al momento della stesura, è composto da:

Un backend Python (FastAPI)
Nella cartella backend/: la logica dei tre passaggi, un client HTTP per l'API di OpenRouter e il salvataggio delle conversazioni in file JSON nella cartella data/. Le dipendenze sono gestite con uv.
Un frontend React (Vite)
Nella cartella frontend/: l’interfaccia che mostra le singole risposte, le classifiche e la sintesi.
Un file di configurazione
backend/config.py elenca i membri del consiglio (COUNCIL_MODELS) e il presidente (CHAIRMAN_MODEL) sotto forma di identificatori OpenRouter, oltre all'indirizzo dell'API chiamata.
Uno script di avvio
start.sh avvia insieme il backend e il frontend. In un file .env è richiesta una chiave OPENROUTER_API_KEY.

I modelli configurati per impostazione predefinita sono modelli cloud chiusi (le famiglie GPT, Gemini, Claude e Grok nella versione pubblicata). Questo è il punto da cambiare per una versione locale: al resto del codice non importa chi risponde, purché l'API utilizzi il formato «chat completions» reso popolare da OpenAI. Rileggi il README e config.py prima di seguire questa guida: il progetto potrebbe essere cambiato dal 12 ottobre 2026.

#Prerequisiti per una versione locale

Ollama installato e funzionante
Il server è in ascolto per impostazione predefinita su http://localhost:11434. Verifica con il comando ollama list che i tuoi modelli compaiano.
Da tre a quattro modelli di famiglie diverse
Un consiglio di modelli appartenenti alla stessa famiglia perde il vantaggio della diversità. Punta, per esempio, su un Qwen, un Llama, un Mistral e un Gemma, di dimensioni simili.
Memoria adeguata
In Q4_K_M, considera circa 5 GB per modello 7B e 9 GB per modello 14B. Non è necessario che i membri siano tutti in memoria contemporaneamente, ma da questo dipende la comodità d'uso (vedi la sezione sui costi).
Python 3.10 o versione successiva
Per lo script minimale di questa guida, con il pacchetto requests. Per il deposito originale, anche uv e Node.js.
Patience
Un turno del consiglio costa almeno il doppio delle generazioni rispetto al numero di membri, più una. Non è uno strumento di chat istantanea.

#Passaggio 1: scegliere il consiglio e il presidente

La scelta dei membri è una questione di equilibrio tra diversità e memoria. Il presidente, invece, deve soprattutto saper leggere contesti lunghi: riceve la domanda, tutte le risposte e tutte le classifiche, per un totale che può facilmente raggiungere diverse migliaia di token. Per questo ruolo scegli il modello più capace supportato dalla tua macchina, anche se è più lento, perché viene chiamato una sola volta per turno.

Terminale
# Exemple de conseil pour une carte 12 Go (noms à vérifier avec `ollama search` ou sur ollama.com/library)
ollama pull qwen3:8b
ollama pull llama3.1:8b
ollama pull mistral:7b
ollama pull gemma3:12b   # président : plus gros, appelé une seule fois par tour
ollama list

Le dimensioni da 7B a 8B sono adatte ai membri su una scheda da 12 GB: un solo modello entra in memoria lasciando margine per il contesto e Ollama alterna tra loro. Con 24 GB o un Mac con 48 GB di memoria unificata, puoi portare i membri a 14B oppure mantenere caricati contemporaneamente da due a tre modelli, eliminando così i ricaricamenti.

→
Aggiungi un modello di ragionamento, se puoi
Un membro capace di «riflettere» prima di rispondere offre spesso un punto di vista diverso rispetto ai modelli diretti. Ricordati però di disattivare o limitare la fase di riflessione durante la valutazione, altrimenti questa fase diventa la più lunga del turno.

#Passaggio 2: impostare Ollama per più modelli

Qui contano due impostazioni di Ollama. La prima è il numero di modelli mantenuti in memoria, definito dalla variabile OLLAMA_MAX_LOADED_MODELS: se la memoria lo consente, mantenere caricati tutti i membri evita di ricaricarli a ogni passaggio dall'uno all'altro. La seconda è la finestra di contesto, num_ctx, che per impostazione predefinita è breve su Ollama: il passaggio di classificazione e la sintesi del presidente fanno leggere diverse risposte complete e un contesto troppo piccolo tronca silenziosamente l'inizio del prompt.

Terminale (Linux, servizio systemd)
sudo systemctl edit ollama
# puis dans le bloc [Service] :
# Environment="OLLAMA_MAX_LOADED_MODELS=2"
# Environment="OLLAMA_KEEP_ALIVE=30m"
sudo systemctl restart ollama

Su macOS, le stesse variabili si impostano con launchctl setenv prima di riavviare l'applicazione. Il valore di OLLAMA_MAX_LOADED_MODELS deve rimanere coerente con la memoria disponibile: due modelli 8B in Q4 occupano già una decina di GB con il relativo contesto. Il contesto, invece, si imposta per richiesta (campo options.num_ctx dell'API) o in un Modelfile derivato; la sezione successiva lo passa a ogni chiamata.

!
Parallelismo: sequenziale per impostazione predefinita
Il codice originale avvia i membri in parallelo, il che è logico con le API cloud. In locale, inviare quattro richieste simultanee a quattro modelli diversi costringe Ollama a caricarli e scaricarli a turno, o persino a spostarne una parte sul processore. A meno che tutti i membri entrino in memoria, chiamali uno dopo l'altro.

#Passaggio 3: un consiglio minimale in Python

Lo script qui sotto riproduce le tre fasi del deposito con l'API nativa di Ollama, senza interfaccia. Mescola l'ordine delle risposte prima della valutazione, così che le etichette non tradiscano l'autore, chiede a ciascun membro una valutazione breve e poi affida il tutto al presidente. Adatta i nomi dei modelli a quelli della tua macchina.

council.py
import random
import requests

OLLAMA = "http://localhost:11434/api/chat"
COUNCIL = ["qwen3:8b", "llama3.1:8b", "mistral:7b"]
CHAIRMAN = "gemma3:12b"
NUM_CTX = 16384


def ask(model, prompt):
    r = requests.post(OLLAMA, json={
        "model": model,
        "messages": [{"role": "user", "content": prompt}],
        "stream": False,
        "options": {"num_ctx": NUM_CTX, "temperature": 0.3},
    }, timeout=1800)
    r.raise_for_status()
    return r.json()["message"]["content"].strip()


def council(question):
    # Étape 1 : premières opinions, une par membre, sans se voir
    answers = {m: ask(m, question) for m in COUNCIL}

    # Anonymisation : ordre mélangé, étiquettes A, B, C...
    order = list(COUNCIL)
    random.shuffle(order)
    labels = {m: chr(65 + i) for i, m in enumerate(order)}
    packed = "\n\n".join(
        f"### Réponse {labels[m]}\n{answers[m]}" for m in order
    )

    # Étape 2 : chaque membre classe les réponses (les siennes incluses)
    rankings = {}
    for m in COUNCIL:
        rankings[m] = ask(m,
            f"Question : {question}\n\n{packed}\n\n"
            "Classe ces réponses de la meilleure à la moins bonne selon leur "
            "justesse et leur profondeur. Pour chacune, une ligne de justification. "
            "Termine par la ligne 'CLASSEMENT :' suivie des lettres dans l'ordre.")

    # Étape 3 : le président rédige la synthèse finale
    votes = "\n\n".join(
        f"### Avis du juge {labels[m]}\n{rankings[m]}" for m in COUNCIL
    )
    final = ask(CHAIRMAN,
        f"Question : {question}\n\n{packed}\n\n{votes}\n\n"
        "Tu présides ce conseil. En t'appuyant sur les réponses et les classements, "
        "rédige une réponse finale unique, précise et sans redite. Signale les points "
        "sur lesquels les réponses se contredisent.")
    return answers, labels, rankings, final


if __name__ == "__main__":
    import sys
    q = " ".join(sys.argv[1:]) or "Quelle quantification choisir pour un modèle 14B sur 12 Go de VRAM ?"
    answers, labels, rankings, final = council(q)
    for m in COUNCIL:
        print(f"\n===== {m} (Réponse {labels[m]}) =====\n{answers[m]}")
    for m in COUNCIL:
        print(f"\n===== Classement par {m} =====\n{rankings[m]}")
    print(f"\n===== Synthèse ({CHAIRMAN}) =====\n{final}")
Terminale
python3 -m venv .venv && source .venv/bin/activate
pip install requests
python council.py "Faut-il un reranker dans un pipeline RAG local ?"

Il repository originale si spinge un po' oltre: estrae la riga della classificazione di ogni giudice per calcolare una posizione media per risposta e visualizzarla accanto alle schede. Puoi aggiungerla in poche righe leggendo la riga «CLASSIFICAZIONE:» di ogni output. Tieni presente che i modelli più piccoli non rispettano sempre questo formato: prevedi un fallback quando la riga manca.

→
Il membro giudica se stesso
In questo script, come nel repository, ogni giudice vede la propria risposta insieme alle altre, sotto un'etichetta anonima. È voluto: consente di verificare se un modello riconosce il proprio stile e si favorisce. Se preferisci escluderla, rimuovi la sua risposta dal blocco inviato a ogni giudice, ma le classifiche non riguarderanno più lo stesso insieme e la media sarà meno leggibile.

#Passaggio 4: adattare il repository originale a Ollama

Se vuoi l’interfaccia web, il percorso più breve consiste nell’usare l’endpoint compatibile con OpenAI di Ollama, disponibile all’indirizzo http://localhost:11434/v1/chat/completions. Il backend del repository invia già richieste in questo formato a OpenRouter: in linea di principio basta sostituire l’indirizzo dell’API e gli identificativi dei modelli in backend/config.py, quindi inserire una chiave fittizia, Ollama ignorando l’intestazione di autorizzazione.

Terminale
git clone https://github.com/karpathy/llm-council
cd llm-council
uv sync
cd frontend && npm install && cd ..
echo 'OPENROUTER_API_KEY=ollama' > .env
backend/config.py (estratto da adattare, verifica i nomi delle costanti nella tua versione)
COUNCIL_MODELS = [
    "qwen3:8b",
    "llama3.1:8b",
    "mistral:7b",
]
CHAIRMAN_MODEL = "gemma3:12b"

# Ollama expose une API compatible OpenAI sur /v1
OPENROUTER_API_URL = "http://localhost:11434/v1/chat/completions"
Terminale
./start.sh
# backend sur le port 8001, interface Vite sur http://localhost:5173 (valeurs du README à vérifier)

Restano da gestire manualmente due punti. Primo, il contesto: l'endpoint compatibile con OpenAI non dispone di un campo num_ctx, quindi bisogna creare varianti dei modelli con un Modelfile che fissi il contesto oppure passare il client all'API nativa /api/chat che accetta le opzioni. Secondo, il parallelismo menzionato sopra: la prima fase avvia le chiamate contemporaneamente, il che richiede di passare all'esecuzione sequenziale se i tuoi membri non entrano tutti in memoria.

Terminale (variante con contesto fissato)
cat > Modelfile.qwen-council <<'EOF'
FROM qwen3:8b
PARAMETER num_ctx 16384
EOF
ollama create qwen3-council -f Modelfile.qwen-council

Diversi fork della comunità hanno apportato queste modifiche per Ollama o per altri server locali. Prima di adottarne uno, controlla la data dell’ultimo commit, il numero di file modificati rispetto al repository originale e leggi il codice che chiama il modello: è breve, ed è lì che si trovano le differenze. Questa guida non raccomanda alcun fork in particolare: il loro stato cambia troppo rapidamente.


#Costo in memoria e in tempo

Il calcolo è semplice e vale la pena farlo prima di impegnarsi. Per un consiglio di N membri, un turno completo richiede N generazioni nella fase 1, N generazioni nella fase 2 e una per il presidente, per un totale di 2N + 1 chiamate. Le chiamate della fase 2 e quella del presidente richiedono più tempo per essere elaborate rispetto alla prima, perché il prompt contiene tutte le risposte: al tempo di generazione si aggiunge il tempo di lettura del prompt.

Tre membri
Sette generazioni per domanda. Se ogni risposta richiede circa mezzo minuto sulla tua macchina, un turno supera i tre minuti, senza contare i ricaricamenti.
Memoria minima
Il modello più grande del consiglio, più il suo contesto. Con membri 8B in Q4 e un contesto di 16 000 token, una scheda da 12 GB è sufficiente, a condizione di mantenere caricato un solo modello.
Memoria per un utilizzo agevole
Tutti i membri vengono caricati contemporaneamente: la somma delle loro dimensioni, più una cache di contesto per modello. Tre modelli 8B in Q4 richiedono almeno una GPU da 24 GB o un Mac con 32 GB di memoria unificata.
Rechargements
Quando i membri non entrano tutti insieme, ogni cambio di modello costa alcuni secondi di caricamento dal disco. In un turno può accadere fino a 2N volte. Un SSD NVMe rende questo costo sopportabile; un disco lento lo rende fastidioso.

Questi ordini di grandezza dipendono dal tuo hardware, dalla quantizzazione e dalla lunghezza delle risposte: non abbiamo misurato la durata di un turno per questo articolo e le cifre sopra riportate sono regole di calcolo, non risultati. Per valutare il tuo caso, cronometra una generazione semplice con ciascuno dei tuoi membri e applica la formula.

#Limiti e distorsioni del consiglio

Lo schema è accattivante perché ricorda una revisione tra pari. Tuttavia, bisogna resistere all’idea che sia necessariamente più corretto di un buon modello singolo: il repository non fornisce alcuna misurazione in tal senso e diversi bias noti dei modelli giudici giocano a suo sfavore.

Anonimizzazione imperfetta
Le etichette nascondono il nome, non lo stile. Un modello può riconoscere il proprio modo di scrivere, o quello di una famiglia che conosce, e classificare di conseguenza. Karpathy osserva lui stesso, in modo qualitativo, che i modelli hanno spesso preferito la risposta di un altro alla propria: è un’osservazione, non una garanzia.
Bias di posizione e di lunghezza
Gli studi sui modelli giudici, come l'articolo MT-Bench di Zheng et al. (2023), documentano una preferenza per la prima risposta letta e per le risposte lunghe. Mescolare l'ordine attenua il primo bias; il secondo si corregge difficilmente.
Errori correlati
I modelli addestrati su corpus simili spesso commettono gli stessi errori. Un consiglio di modelli piccoli può votare all'unanimità per una risposta falsa, e il presidente la manterrà.
Il presidente resta solo
La sintesi dipende interamente dal modello presidente: se allucina, il consiglio non può farci nulla. Leggi le singole risposte quando l'argomento è importante: è proprio questo, d'altra parte, il vantaggio delle schede dell'interfaccia originale.
Modelli piccoli, istruzioni lunghe
Il prompt di valutazione è impegnativo: leggere tre o quattro testi, giudicare, motivare e rispettare un formato. Al di sotto di 7B, gli output diventano irregolari e la valutazione media perde significato.
!
Nessuna misurazione, nessuna promessa
Se vuoi sapere se il consiglio migliora i tuoi risultati, costruisci un piccolo insieme di domande di cui conosci le risposte, esegui prima il modello migliore da solo e poi il consiglio, quindi confrontali alla cieca. Senza questo test sui tuoi casi reali, l'intuizione «più opinioni valgono più di una» è soltanto un'ipotesi.

#Casi d'uso reali di un LLM Council locale

Il costo aggiuntivo di 2N + 1 generazioni è giustificato quando la domanda è rara e importante, non per le chiacchiere. Tre situazioni emergono tra le persone che hanno ripreso il modello in locale.

Rilettura di un testo o di codice sensibile
Una lettera contrattuale, una procedura, una funzione critica: i membri individuano problemi diversi, il presidente li consolida in un elenco. Qui la classificazione conta meno della varietà delle osservazioni.
Decisione tecnica motivata
«Conviene migrare questo database», «quale formato usare per questa esportazione»: le risposte divergenti sono un'informazione di per sé. Chiedi al presidente di rendere visibili i disaccordi invece di appianarli.
Controllo qualità di un singolo modello
Usa il consiglio come giuria per confrontare due versioni di un prompt o due quantizzazioni dello stesso modello, chiedendogli di classificare gli output che hai prodotto altrove. È un'applicazione diretta del passaggio 2, senza il passaggio 1.

In tutti questi casi, la riservatezza è il vero argomento a favore della versione locale: i documenti esaminati non lasciano la macchina, mentre la versione originale li invia a quattro fornitori diversi tramite OpenRouter. È questo che rende il modello interessante per un team che gestisce dati interni, a condizione di accettare i minuti di attesa.

#Risoluzione dei problemi

La classificazione ignora una risposta
Il contesto è troppo breve e l'inizio del prompt è stato troncato. Aumenta num_ctx (o il Modelfile) e verifica nei log di Ollama che non compaia alcun avviso di troncamento.
Le chiamate del passaggio 1 sono molto lente
I membri vengono chiamati in parallelo e si contendono la memoria. Passa all'esecuzione sequenziale oppure riduci il consiglio a ciò che entra contemporaneamente nella VRAM.
Il presidente risponde fuori tema
Il suo contesto è quello più carico del turno. Dagli un modello più grande oppure riassumi le classifiche prima di trasmettergliele.
Formato della valutazione assente
I modelli più piccoli dimenticano la riga «CLASSEMENT:». Ricorda il formato alla fine del prompt, abbassa la temperatura oppure accetta di leggere manualmente le motivazioni.
Risposte di un membro vuote o in inglese
Verifica che il modello non restituisca soltanto la propria fase di ragionamento e specifica nella domanda la lingua attesa.
Memoria esaurita dopo pochi turni
OLLAMA_MAX_LOADED_MODELS è troppo alto per la macchina. Portalo a 1 e lascia che Ollama si alternino.

#Per approfondire

LLM Council è un modello di deliberazione, non un framework per agenti: non gestisce strumenti, ruoli o memoria. Se le tue esigenze vanno oltre la sintesi di opinioni, queste guide del sito illustrano i componenti correlati.

CrewAI con Ollama
Quando i modelli devono dividersi i ruoli e concatenare le attività invece di giudicare la stessa risposta. https://quelllm.fr/guide/crewai-ollama-multi-agents
LiteLLM come gateway locale
Per esporre più server di modelli dietro un'unica API compatibile con OpenAI, ad esempio un consiglio distribuito su due macchine. https://quelllm.fr/guide/litellm-proxy-gateway-local
Architettura di un agente IA locale
I componenti da assemblare intorno a un modello quando vuoi fornirgli strumenti e memoria. https://quelllm.fr/guide/agent-ia-local-architecture
Condividere un server Ollama sulla rete locale
Ospitare i membri del consiglio su una macchina più potente e chiamarli dalla tua postazione. https://quelllm.fr/guide/ollama-serveur-reseau-local-partage

Guida redatta il 12 ottobre 2026 a partire dal repository GitHub di Karpathy e dalla documentazione di Ollama. Per questo articolo non è stata effettuata alcuna misurazione dei tempi o della qualità; i riferimenti alla memoria sono ordini di grandezza in Q4_K_M. I nomi delle costanti, delle porte e dei modelli cambiano: rileggi le fonti qui sotto prima di copiare i comandi.

Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.