Vai al contenuto

Guida pratica

CrewAI con Ollama: agenti AI che girano sul tuo server

Eseguire un crew su modelli locali: la configurazione corretta della classe LLM, l'errore della chiave OpenAI che colpisce quasi tutti, e i limiti veri di qualità e hardware.

Aggiornato il 17 agosto 2026

Perché far girare gli agenti in locale

Tre motivi concreti spingono verso l'esecuzione locale, e in Italia il primo pesa più degli altri due messi insieme.

  • I dati restano nel perimetro. Prompt, documenti e output non transitano dai server di un fornitore di modelli. Per chi lavora su contratti, cartelle cliniche o dati di clienti, è la differenza fra una valutazione privacy complessa e una molto più corta.
  • Il costo per token è zero. Un crew che gira cento volte al giorno su un'API commerciale produce una fattura che cresce con l'uso. In locale paghi l'hardware una volta e la corrente sempre, ma il costo marginale della singola esecuzione sparisce.
  • La latenza è prevedibile. Niente limiti di richieste, niente errori 429, niente code nelle ore di punta. Il modello risponde alla velocità del tuo hardware, sempre la stessa.

I due prezzi da pagare vanno detti subito, perché sono reali. Primo: la qualità è inferiore. Un modello da 8 miliardi di parametri quantizzato non ragiona come i modelli di punta serviti via API, e negli agenti la differenza si vede soprattutto nelle chiamate agli strumenti. Secondo: serve hardware. Senza una GPU con abbastanza memoria video, l'inferenza scende su CPU e diventa lenta al punto da cambiare il modo in cui usi il sistema. Se questi due vincoli non sono accettabili per il tuo caso, l'esecuzione locale non fa per te, e saperlo prima costa meno che scoprirlo dopo.

Installare Ollama e scaricare un modello

Ollama è il runtime che scarica i modelli e li espone con un'API HTTP locale sulla porta 11434. Si installa dal sito ufficiale su Linux, macOS e Windows. Servono due modelli, non uno: quello di chat che farà ragionare gli agenti e un modello di embedding, che servirà più avanti per memoria e knowledge.

terminale
# Scarica i due modelli: chat ed embedding
ollama pull llama3.1
ollama pull mxbai-embed-large
ollama ls                  # elenca i modelli scaricati

# Avvia il server, se non gira già come servizio
ollama serve

# Verifica che risponda sulla porta 11434
curl http://localhost:11434/api/chat -d '{
  "model": "llama3.1",
  "messages": [{"role": "user", "content": "Rispondi solo: ok"}]
}'
Comandi verificati sulla documentazione ufficiale Ollama il 17 agosto 2026.

Se il curl restituisce una risposta del modello, il server funziona e puoi passare a CrewAI. Se Ollama è stato installato come applicazione desktop, il servizio parte da solo e ollama serve non serve: un errore di porta già occupata in quel caso è normale.

La classe LLM: il punto dove quasi tutti sbagliano

CrewAI non parla direttamente con Ollama: instrada ogni chiamata attraverso LiteLLM, che smista verso decine di fornitori in base al prefisso del nome del modello. La configurazione corretta ha tre pezzi, e mancarne uno produce errori poco leggibili.

  • La classe LLM, importata da crewai.
  • Il prefisso ollama/ davanti al nome del modello: è l'istruzione di instradamento per LiteLLM. Senza prefisso, il nome viene interpretato come un modello OpenAI.
  • Il base_url del server, che in locale è http://localhost:11434.
llm_locale.py
from crewai import Agent, LLM

llm_locale = LLM(
    model="ollama/llama3.1",          # il prefisso instrada verso Ollama
    base_url="http://localhost:11434",
)

analista = Agent(
    role="Analista documentale",
    goal="Estrarre i punti chiave da {documento}",
    backstory="Sintetizza senza inventare.",
    llm=llm_locale,                     # senza questa riga cerca OpenAI
)
Verificato con crewai 1.15.16 il 17 agosto 2026, sintassi dalla documentazione ufficiale.

Un dettaglio utile che sta nella documentazione LiteLLM e non in quella CrewAI: il prefisso ollama/ chiama l'endpoint /api/generate, mentre ollama_chat/ chiama /api/chat, e LiteLLM consiglia il secondo per la qualità delle risposte. Gli esempi nella documentazione CrewAI usano ollama/: parti da quello, e prova l'altro solo se le risposte deludono.

Il problema numero uno: chiede ancora la chiave OpenAI

errore

Hai configurato Ollama e l'errore parla di OPENAI_API_KEY

È l'errore più segnalato in assoluto da chi usa CrewAI con modelli locali. La causa non è mai una: c'è un componente, da qualche parte, che sta ancora usando il modello predefinito. E il modello predefinito di CrewAI è di OpenAI.

La diagnosi è una lista di controllo, da percorrere tutta anche quando il primo punto sembra risolvere.

  • Un agente senza llm. Il caso più frequente: in un crew di quattro agenti, tre hanno il modello locale e uno è rimasto senza parametro. Basta quello per far partire la richiesta di chiave. Controlla ogni singolo Agent, non solo il primo.
  • Il processo gerarchico senza manager_llm. Con process=Process.hierarchical CrewAI crea un agente manager in più, che non è nella tua lista e quindi non eredita niente: il suo modello va dichiarato a parte nel parametro manager_llm del crew.
  • Memoria e knowledge usano un altro modello. Quando attivi memory=True o passi delle knowledge_sources, entra in gioco un modello di embedding, separato da quello di chat, che per impostazione predefinita è di OpenAI anche se tutti gli agenti girano su Ollama. Si configura con il parametro embedder, come nel codice della prossima sezione.

Il modo più rapido per stanare il colpevole: leggi il traceback fino in fondo, perché la riga che nomina embedding o memory distingue subito il terzo caso dai primi due. Se il traceback non basta, togli memoria e knowledge, verifica che il crew giri pulito, e riaggiungili con l'embedder configurato. Altri errori tipici di questo passaggio sono raccolti nella pagina sugli errori comuni.

Un crew interamente locale, completo

Questo è il codice di riferimento: due agenti, memoria attiva, nessuna chiamata esterna. Ogni punto in cui un modello può intrufolarsi è coperto in modo esplicito.

crew_locale.py
from crewai import Agent, Task, Crew, Process, LLM

llm_locale = LLM(
    model="ollama/llama3.1",
    base_url="http://localhost:11434",
)

analista = Agent(
    role="Analista",
    goal="Isolare i 3 punti critici in {testo}",
    backstory="Separa i fatti dalle opinioni.",
    llm=llm_locale,
)

redattore = Agent(
    role="Redattore",
    goal="Scrivere una sintesi ordinata dei punti critici",
    backstory="Scrive frasi brevi, senza aggettivi inutili.",
    llm=llm_locale,               # su OGNI agente, nessuno escluso
)

analisi = Task(
    description="Analizza {testo} e isola 3 punti critici.",
    expected_output="3 punti: problema, evidenza, gravità.",
    agent=analista,
)

sintesi = Task(
    description="Trasforma l'analisi in una sintesi di 150 parole.",
    expected_output="Un paragrafo, massimo 150 parole.",
    agent=redattore,
)

crew = Crew(
    agents=[analista, redattore],
    tasks=[analisi, sintesi],
    process=Process.sequential,
    memory=True,
    embedder={                     # anche gli embedding restano in locale
        "provider": "ollama",
        "config": {
            "model": "mxbai-embed-large",
            "url": "http://localhost:11434/api/embeddings",
        },
    },
)

esito = crew.kickoff(inputs={"testo": "..."})
print(esito.raw)
Verificato con crewai 1.15.16 il 17 agosto 2026. Richiede ollama pull llama3.1 e ollama pull mxbai-embed-large.

attenzione

La documentazione non è uniforme sulla chiave del modello

Nelle pagine ufficiali la configurazione dell'embedder Ollama compare con la chiave model nella sezione knowledge e con model_name in quella sulla memoria. È uno dei punti in cui la documentazione CrewAI risulta disallineata fra le sue stesse pagine: se una forma produce errori di validazione, prova l'altra prima di cercare cause più esotiche.

Quali modelli reggono un agente

Un agente non è una chat. A ogni passo il modello deve decidere se rispondere o usare uno strumento, e in quel secondo caso deve produrre la chiamata nel formato esatto che il framework si aspetta. È qui che i modelli piccoli cadono: la prosa la reggono, la sintassi delle chiamate agli strumenti no. Una parentesi fuori posto o un nome di parametro inventato, e l'agente entra in un ciclo di tentativi che brucia iterazioni fino al limite di max_iter. Le chiamate a strumenti sbagliate con modelli non OpenAI sono fra gli errori più segnalati dagli utenti del framework, e in locale il fenomeno si amplifica.

Non pubblichiamo classifiche di modelli locali: cambiano troppo in fretta e i risultati dipendono da quantizzazione, hardware e tipo di compito. Il metodo conta più della classifica, e il metodo è questo:

  • Parti senza strumenti. Un crew di sola lettura, analisi e scrittura mette alla prova il modello sul ragionamento senza esporlo al suo punto debole.
  • Aggiungi uno strumento alla volta, e guarda i log: se le chiamate falliscono o vengono ripetute con argomenti a caso, il modello non regge quel formato e serve una taglia superiore.
  • Tieni i compiti stretti. Descrizioni corte e un expected_output rigido compensano in parte la minore capacità del modello. Su un modello piccolo, un compito vago non produce un risultato mediocre: non produce proprio.

Quanta memoria serve: ordini di grandezza

I numeri che seguono sono stime indicative per i modelli quantizzati a 4 bit, il formato in cui Ollama distribuisce di solito le sue varianti predefinite. Non sono specifiche: il consumo reale dipende dalla quantizzazione scelta, dalla finestra di contesto usata (il contesto occupa memoria oltre ai pesi) e dal runtime.

Parametri del modelloMemoria video indicativaDove gira
7-8 miliardi5-6 GBGPU consumer di fascia media
13-14 miliardi9-11 GBGPU consumer di fascia alta
circa 30 miliardi18-22 GBGPU da 24 GB
70 miliardi40-48 GBDue GPU, o hardware da data center

Senza GPU l'inferenza gira su CPU e RAM: funziona, ed è un modo legittimo di provare il sistema, ma i tempi si allungano di un ordine di grandezza. Per un crew, dove ogni compito genera più chiamate al modello in sequenza, la differenza fra 20 secondi e 4 minuti a chiamata decide se il sistema è usabile. I Mac con memoria unificata sono un caso a parte favorevole: la memoria di sistema fa anche da memoria per il modello. Prima di comprare hardware, misura: fai girare il crew di prova su quello che hai e leggi i tempi reali.

GDPR e dati in casa: cosa cambia davvero

Il motivo per cui molte aziende italiane guardano a questa architettura è la riservatezza, e su questo serve precisione, non slogan. Quello che l'esecuzione locale cambia davvero: i dati trattati dagli agenti non vengono comunicati a un fornitore di modelli, quindi sparisce quel responsabile del trattamento, sparisce la valutazione del trasferimento extra UE per quel flusso, e i log delle conversazioni restano su macchine tue. Per dati sanitari, legali o finanziari è una riduzione concreta della superficie di rischio.

Quello che non cambia: tutto il resto. Il trattamento resta un trattamento, con la sua base giuridica, le informative, la minimizzazione, i tempi di conservazione. Anzi, un pezzo di responsabilità torna indietro: la sicurezza che prima era coperta dal contratto con il fornitore ora è tua, e un server mal protetto con dentro i log di tutte le conversazioni aziendali è un problema peggiore di un'API ben contrattualizzata. Eseguire in locale riduce il trasferimento di dati a terzi, ma non rende un sistema conforme da solo, e chi lo promette sta vendendo qualcosa.

C'è poi un livello ulteriore: gli obblighi normativi sugli agenti non finiscono con il GDPR, e l'AI Act introduce requisiti che non dipendono da dove gira il modello. La pagina su AI Act e agenti tratta quel pezzo del quadro.

Domande

Domande frequenti

Le domande che tornano più spesso su CrewAI con i modelli locali.

  • CrewAI funziona davvero senza nessuna chiave API?

    Sì, se ogni componente che tocca un modello è configurato per Ollama: il parametro llm di ogni agente, il manager_llm nel processo gerarchico e l'embedder di memoria e knowledge. Se una chiave viene ancora richiesta, qualche componente sta usando il modello predefinito, che è di OpenAI.

  • Posso puntare CrewAI a un server Ollama remoto?

    Sì. Il parametro base_url accetta qualsiasi indirizzo raggiungibile, quindi il modello può girare su una macchina con GPU mentre il crew gira altrove. La porta 11434 non va mai esposta su internet: va raggiunta attraverso una VPN o un reverse proxy con autenticazione.

  • Che differenza c'è fra i prefissi ollama/ e ollama_chat/?

    Sono due instradamenti di LiteLLM verso lo stesso server: ollama/ usa l'endpoint /api/generate, ollama_chat/ usa /api/chat. La documentazione LiteLLM consiglia ollama_chat per risposte migliori, ma gli esempi ufficiali CrewAI usano ollama/ ed è il punto di partenza più sicuro.

  • Perché la memoria del crew chiede una chiave OpenAI anche con il modello locale?

    Perché memoria e knowledge non usano il modello di chat ma un modello di embedding separato, che per impostazione predefinita è di OpenAI. Va configurato il parametro embedder del crew con provider ollama e un modello come mxbai-embed-large, scaricato a parte con ollama pull.

  • Un modello da 8 miliardi di parametri basta per un crew?

    Per compiti di lettura, sintesi e scrittura su testi brevi sì, con qualità inferiore ai modelli grandi via API. Il punto debole sono le chiamate agli strumenti: conviene far girare il crew senza tool e aggiungerli solo dopo aver verificato che il modello regge il formato delle chiamate.

  • Eseguire tutto in locale mi rende conforme al GDPR?

    No. Riduce il trasferimento di dati verso fornitori terzi, che è un vantaggio concreto, ma la conformità dipende da base giuridica, informative, misure di sicurezza e governo dell'intero trattamento. L'esecuzione locale è un tassello, non una certificazione.