Cheshire Cat AI 2: un agente con tool in locale con Ollama

Tutorial passo per passo con Cheshire Cat AI 2.0.23, uscito oggi: installazione con uv, collegamento a un modello open weight su Ollama, un plugin con due tool e la chiamata via API. Con gli errori da evitare al primo avvio e due accortezze di sicurezza.

AIOpen SourceAIAgenti AICheshire CatOllamaOpen SourceTutorialPython

Articolo

Quattro dati sul tutorial di Cheshire Cat AI con Ollama
Cheshire Cat AI 2.0.23, rilasciato l’8 luglio 2026. Fonti in fondo.

Cheshire Cat AI è un framework open source italiano per costruire agenti AI, creato da Piero Savastano e distribuito con licenza GPL-3.0. Il README lo presenta come il framework per imparare come funzionano gli agenti, con istruzione e ricerca come uso principale. La versione 2 cambia molto rispetto alla prima: si installa come pacchetto Python e gli agenti si scrivono come classi con i propri tool.

Il README avverte che la versione 2 è un’alpha instabile (con possibili modifiche incompatibili) e non la consiglia ancora per la produzione. Il tutorial che segue serve per capire e sperimentare.

In noze lo usiamo da tempo nei nostri progetti. Gli esempi che seguono si riferiscono alla 2.0.23, rilasciata l’8 luglio 2026, con un modello open weight servito da Ollama (qui qwen3.6:35b-a3b). Serve un modello che supporti il tool calling.

1. Installazione

Serve solo uv, il gestore di pacchetti Python. In una cartella vuota:

uv init --bare
uv add cheshire-cat-ai
uv run ccat

Al primo avvio il Cat crea le cartelle plugins/ e data/ e installa i plugin di base, fra cui l’interfaccia web. Non create plugins/ prima del primo avvio: se la cartella esiste già, i plugin di base non vengono copiati e l’interfaccia non c’è.

  • Interfaccia web: http://localhost:1865
  • Playground delle API REST: http://localhost:1865/docs

2. Collegare Ollama

Un’installazione nuova usa un modello segnaposto. Per usare Ollama basta un file config.py nella cartella del progetto:

DEFAULT_LLM = "ollama:qwen3.6:35b-a3b"

Il formato è provider:modello. Il provider Ollama si collega a http://localhost:11434/v1; per un altro indirizzo si usa la variabile d’ambiente OLLAMA_URL. In alternativa il modello si sceglie dalle impostazioni dell’interfaccia.

Riavviate il Cat e provate l’agente predefinito:

curl -X POST http://localhost:1865/agents/default/message \
  -H "Authorization: meow" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":[{"type":"text","text":"Ciao, chi sei?"}]}],"stream":false}'

meow è la chiave predefinita per lo sviluppo locale.

3. Un agente con due tool

Creiamo un assistente di help desk che consulta lo stato dei ticket. La struttura:

plugins/
└── help_desk/
    ├── plugin.json
    └── help_desk.py

plugin.json:

{
  "name": "Help Desk",
  "description": "Assistente che controlla lo stato dei ticket con due tool."
}

help_desk.py:

from cat import Agent, tool

TICKETS = {
    "T-101": {"stato": "aperto", "priorita": "alta", "oggetto": "VPN non si connette"},
    "T-102": {"stato": "chiuso", "priorita": "bassa", "oggetto": "Cambio password"},
}


class HelpDesk(Agent):
    slug = "help_desk"
    name = "Help Desk"
    description = "Risponde sullo stato dei ticket."
    system_prompt = (
        "Sei l'assistente dell'help desk interno. Rispondi in italiano, in modo breve. "
        "Per lo stato di un ticket usa sempre i tool, non inventare."
    )

    @tool
    def stato_ticket(self, codice: str) -> str:
        """Stato e priorità di un ticket. Input: codice del ticket, per esempio T-101."""
        t = TICKETS.get(codice.upper())
        if not t:
            return f"Nessun ticket {codice}"
        return f"{codice}: {t['oggetto']}, stato {t['stato']}, priorità {t['priorita']}"

    @tool
    def ticket_aperti(self) -> str:
        """Elenco dei ticket ancora aperti."""
        aperti = [c for c, t in TICKETS.items() if t["stato"] == "aperto"]
        return ", ".join(aperti) or "Nessun ticket aperto"

La docstring di ogni tool è la descrizione che il modello legge per decidere quando usarlo: conviene scriverla con cura. In un caso reale le due funzioni interrogherebbero il sistema di ticketing.

4. Attivare il plugin

Un plugin nuovo parte disattivato. Si attiva dalla scheda Plugins dell’interfaccia oppure via API:

curl -X PUT http://localhost:1865/plugins/help_desk/toggle -H "Authorization: meow"

L’endpoint inverte lo stato: chiamato su un plugin già attivo, lo disattiva. Lo stato si controlla con GET /plugins/help_desk. Una volta attivo, l’agente compare in GET /agents.

5. Provarlo

curl -X POST http://localhost:1865/agents/help_desk/message \
  -H "Authorization: meow" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":[{"type":"text","text":"Com è messo il ticket T-101? E quali ticket sono ancora aperti?"}]}],"stream":false}'

Il modello chiama da solo stato_ticket con T-101 e ticket_aperti, poi risponde, per esempio: “Il ticket T-101 ha lo stato aperto con priorità alta (problema di connessione VPN). Attualmente è l’unico ticket elencato come aperto.” La risposta JSON contiene l’intera sequenza: chiamate ai tool, argomenti, risultati e testo finale. È il modo più diretto per vedere che cosa fa un agente.

Due accortezze di sicurezza

  • Il Cat ascolta su tutte le interfacce di rete (0.0.0.0:1865): nella vostra rete locale altri dispositivi possono raggiungerlo.
  • La chiave meow è quella predefinita: la documentazione chiede di cambiarla prima di qualunque uso fuori dallo sviluppo locale. Le istruzioni sono nella sezione Deploy della documentazione.

Cosa ne pensiamo

Il modello a classi della versione 2 rende un agente leggibile in poche righe: un prompt, alcune funzioni Python con la loro descrizione e un endpoint per interrogarlo. Con un modello open weight su Ollama tutto resta sulla propria macchina. La risposta mostra ogni chiamata ai tool con argomenti e risultati, un buon punto di partenza per capire come lavorano gli agenti prima di scegliere un framework per la produzione.

Fonti

Vuoi supporto?Sei sotto attacco?Stato dei servizi
Vuoi supporto?Sei sotto attacco?Stato dei servizi