Vai al contenuto

Guida all'integrazione con agenti

Se sei un agente IA: usa MCP se il tuo framework lo supporta, altrimenti usa l'API REST. Per la configurazione, vedi Avvio rapido.

Panoramica

asiai espone l'infrastruttura di inferenza LLM del tuo Mac agli agenti IA attraverso due meccanismi:

  • Server MCP — Integrazione nativa degli strumenti tramite il Model Context Protocol. Ideale per agenti IA che supportano MCP (Claude Code, Cursor, Cline e altri client compatibili con MCP).
  • API REST — Endpoint HTTP/JSON standard. Ideale per framework di agenti, orchestratori di swarm e qualsiasi sistema con capacità HTTP (CrewAI, AutoGen, LangGraph, agenti personalizzati).

Entrambi danno accesso alle stesse funzionalità:

  • Monitorare lo stato del sistema (CPU, RAM, GPU, termica, swap)
  • Rilevare quali motori di inferenza sono in esecuzione e quali modelli sono caricati
  • Diagnosticare problemi di prestazioni usando l'osservabilità della GPU e i segnali di attività di inferenza
  • Valutare modelli in modo programmatico e tracciare le regressioni
  • Ottenere raccomandazioni per il miglior modello/motore basandosi sul tuo hardware

Nessuna autenticazione richiesta per l'accesso locale. Tutte le interfacce si collegano a 127.0.0.1 per impostazione predefinita.

Quale integrazione dovrei usare?

Criterio MCP API REST
Il tuo agente supporta MCP Usa MCP
Swarm / orchestratore multi-agente Usa API REST
Polling / monitoraggio programmato Usa API REST
Integrazione Prometheus / Grafana Usa API REST
Assistente IA interattivo (Claude Code, Cursor) Usa MCP
Agente in container Docker Usa API REST
Script personalizzati o automazione Usa API REST

Avvio rapido

Installa asiai

# Homebrew (raccomandato)
brew tap druide67/tap && brew install asiai

# pip (con supporto MCP)
pip install "asiai[mcp]"

# pip (solo API REST)
pip install asiai

Opzione A: Server MCP (per agenti compatibili con MCP)

# Avvia il server MCP (trasporto stdio — usato da Claude Code, Cursor, ecc.)
asiai mcp

Non è necessario avviare manualmente il server — il client MCP lancia asiai mcp automaticamente. Vedi la configurazione MCP qui sotto.

Opzione B: API REST (per agenti basati su HTTP)

# In primo piano (sviluppo)
asiai web --no-open

# Daemon in background (produzione)
asiai daemon start web

L'API è disponibile su http://127.0.0.1:8899. La porta è configurabile con --port:

asiai daemon start web --port 8642

Per l'accesso remoto (es. agente IA su un'altra macchina o da un container Docker):

asiai daemon start web --host 0.0.0.0

Nota: Se il tuo agente gira all'interno di Docker, 127.0.0.1 non è raggiungibile. Usa l'IP di rete dell'host (es. 192.168.0.16) o host.docker.internal su Docker Desktop per Mac.

Verifica

# API REST
curl http://127.0.0.1:8899/api/status

# MCP (elenco strumenti disponibili)
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | asiai mcp

MCP (Model Context Protocol)

asiai implementa un server MCP che espone il monitoraggio dell'inferenza come strumenti nativi. Qualsiasi client compatibile con MCP può connettersi e utilizzare questi strumenti direttamente — nessuna configurazione HTTP, nessuna gestione di URL.

Configurazione

Locale (stessa macchina)

Aggiungi alla configurazione del tuo client MCP (es. ~/.claude/settings.json per Claude Code):

{
  "mcpServers": {
    "asiai": {
      "command": "asiai",
      "args": ["mcp"]
    }
  }
}

Se asiai è installato in un virtualenv:

{
  "mcpServers": {
    "asiai": {
      "command": "/path/to/.venv/bin/asiai",
      "args": ["mcp"]
    }
  }
}

Remoto (macchina diversa via SSH)

{
  "mcpServers": {
    "asiai": {
      "command": "ssh",
      "args": [
        "-o", "ServerAliveInterval=30",
        "-o", "ServerAliveCountMax=3",
        "your-mac-host",
        "cd /path/to/asiai && .venv/bin/asiai mcp"
      ]
    }
  }
}

Trasporto SSE (rete)

Per ambienti che preferiscono il trasporto MCP basato su HTTP:

asiai mcp --transport sse --host 127.0.0.1 --port 8900

Riferimento strumenti MCP

Tutti gli strumenti restituiscono JSON. Gli strumenti in sola lettura rispondono in < 2 secondi. run_benchmark è l'unica operazione attiva.

Strumento Descrizione Parametri
check_inference_health Controllo rapido — motori attivi/inattivi, pressione di memoria, termica, utilizzo GPU
get_inference_snapshot Snapshot completo dello stato del sistema (salvato in SQLite per lo storico)
list_models Tutti i modelli caricati su tutti i motori con VRAM, quantizzazione, lunghezza contesto
detect_engines Rilevamento a 3 livelli: config, scansione porte, rilevamento processi. Trova motori su porte non standard automaticamente.
run_benchmark Esegui benchmark su un modello o confronto tra modelli. Limitato: 1 per 60 secondi model (opzionale), runs (1–10, default 3), compare (lista stringhe, opzionale, mutuamente esclusivo con model, max 8)
get_recommendations Raccomandazioni modello/motore consapevoli dell'hardware per il tuo chip e RAM
diagnose Esegui controlli diagnostici (sistema, motori, stato daemon)
get_metrics_history Metriche di sistema storiche da SQLite hours (1–168, default 24)
get_benchmark_history Risultati benchmark storici hours (1–720, default 24), model (opzionale), engine (opzionale)
compare_engines Confronto motori classificato con verdetto per un modello; supporta confronto multi-modello dallo storico model (obbligatorio)
refresh_engines Ri-rileva i motori senza riavviare il server MCP

Risorse MCP

Endpoint di dati statici, disponibili senza chiamare uno strumento:

URI Descrizione
asiai://status Stato attuale (memoria, termica, GPU)
asiai://models Tutti i modelli caricati su tutti i motori
asiai://system Info hardware (chip, RAM, core, SO, uptime)

Sicurezza MCP

  • Nessun sudo: Le metriche di potenza sono disabilitate in modalità MCP (power=False forzato)
  • Limitazione di frequenza: I benchmark sono limitati a 1 per 60 secondi
  • Clamping degli input: hours limitato a 1–168, runs limitato a 1–10
  • Locale per default: il trasporto stdio non ha esposizione di rete; SSE si collega a 127.0.0.1

Limitazioni MCP

  • Nessuna riconnessione: Se la connessione SSH cade (problema di rete, sleep del Mac), il server MCP muore e il client deve riconnettersi manualmente. Per monitoraggio non presidiato, l'API REST con polling è più resiliente.
  • Client singolo: il trasporto stdio serve un client alla volta. Usa il trasporto SSE se più client necessitano accesso concorrente.

Riferimento API REST

L'API di asiai è in sola lettura — monitora e riporta, ma non controlla i motori. Per caricare/scaricare modelli, usa i comandi nativi del motore (ollama pull, lms load, ecc.).

Tutti gli endpoint restituiscono JSON con HTTP 200. Se un motore non è raggiungibile, la risposta restituisce comunque 200 con "running": false per quel motore — l'API stessa non fallisce.

Endpoint Tempo di risposta tipico Timeout consigliato
GET /api/status < 500ms (cache 10s) 2s
GET /api/snapshot 1–3s (raccolta live) 10s
GET /api/metrics < 500ms 2s
GET /api/history < 500ms 5s
GET /api/engine-history < 500ms 5s

GET /api/status

Controllo rapido dello stato. Cache di 10 secondi. Tempo di risposta < 500ms.

Risposta:

{
  "hostname": "mac-mini",
  "chip": "Apple M4 Pro",
  "ram_gb": 64.0,
  "cpu_percent": 12.3,
  "memory_pressure": "normal",
  "gpu_utilization_percent": 45.2,
  "engines": {
    "ollama": {
      "running": true,
      "models_loaded": 2,
      "port": 11434
    },
    "lmstudio": {
      "running": true,
      "models_loaded": 1,
      "port": 1234
    }
  },
  "asiai_version": "1.0.1",
  "uptime_seconds": 86400
}

GET /api/snapshot

Stato completo del sistema. Include tutto da /api/status più informazioni dettagliate sui modelli, metriche GPU e dati termici.

Risposta:

{
  "system": {
    "hostname": "mac-mini",
    "chip": "Apple M4 Pro",
    "cores_p": 12,
    "cores_e": 4,
    "gpu_cores": 20,
    "ram_total_gb": 64.0,
    "ram_used_gb": 41.2,
    "ram_percent": 64.4,
    "swap_used_gb": 0.0,
    "memory_pressure": "normal",
    "cpu_percent": 12.3,
    "thermal_state": "nominal",
    "gpu_utilization_percent": 45.2,
    "gpu_renderer_percent": 38.1,
    "gpu_tiler_percent": 12.4,
    "gpu_memory_allocated_bytes": 8589934592
  },
  "engines": [
    {
      "name": "ollama",
      "running": true,
      "port": 11434,
      "models": [
        {
          "name": "qwen3.5:latest",
          "size_params": "35B",
          "size_vram_bytes": 21474836480,
          "quantization": "Q4_K_M",
          "context_length": 32768
        }
      ]
    }
  ],
  "timestamp": "2026-03-09T14:30:00Z"
}

GET /api/metrics

Metriche in formato Prometheus. Raccogli con Prometheus, Datadog o qualsiasi strumento compatibile.

Risposta (text/plain):

# HELP asiai_cpu_percent CPU usage percentage
# TYPE asiai_cpu_percent gauge
asiai_cpu_percent 12.3

# HELP asiai_ram_used_gb RAM used in GB
# TYPE asiai_ram_used_gb gauge
asiai_ram_used_gb 41.2

# HELP asiai_gpu_utilization_percent GPU utilization percentage
# TYPE asiai_gpu_utilization_percent gauge
asiai_gpu_utilization_percent 45.2

# HELP asiai_engine_up Engine availability (1=up, 0=down)
# TYPE asiai_engine_up gauge
asiai_engine_up{engine="ollama"} 1
asiai_engine_up{engine="lmstudio"} 1

# HELP asiai_models_loaded Number of models loaded per engine
# TYPE asiai_models_loaded gauge
asiai_models_loaded{engine="ollama"} 2

GET /api/history?hours=N

Metriche di sistema storiche da SQLite. Default: hours=24. Max: hours=2160 (90 giorni).

Risposta:

{
  "points": [
    {
      "timestamp": "2026-03-09T14:00:00Z",
      "cpu_percent": 15.2,
      "ram_used_gb": 40.1,
      "ram_percent": 62.7,
      "swap_used_gb": 0.0,
      "memory_pressure": "normal",
      "thermal_state": "nominal",
      "gpu_utilization_percent": 42.0,
      "gpu_renderer_percent": 35.0,
      "gpu_tiler_percent": 10.0,
      "gpu_memory_allocated_bytes": 8589934592
    }
  ],
  "count": 144,
  "hours": 24
}

GET /api/engine-history?engine=X&hours=N

Storico dello stato dei motori. Utile per rilevare pattern di inferenza.

Parametri:

Parametro Obbligatorio Default Descrizione
engine Nome del motore (ollama, lmstudio, ecc.)
hours No 24 Intervallo di tempo

Risposta:

{
  "engine": "ollama",
  "points": [
    {
      "timestamp": "2026-03-09T14:00:00Z",
      "running": true,
      "tcp_connections": 3,
      "requests_processing": 1,
      "kv_cache_usage_percent": 45.2
    }
  ],
  "count": 144,
  "hours": 24
}

Interpretare le metriche

Soglie di stato del sistema

Metrica Normale Attenzione Critico
memory_pressure normal warn critical
ram_percent < 75% 75–90% > 90%
swap_used_gb 0 0.1–2.0 > 2.0
thermal_state nominal fair serious / critical
cpu_percent < 80% 80–95% > 95%

Soglie GPU

Metrica Inattivo Inferenza attiva Sovraccarico
gpu_utilization_percent 0–5% 20–80% > 90% sostenuto
gpu_renderer_percent 0–5% 15–70% > 85% sostenuto
gpu_memory_allocated_bytes < 1 GB 2–48 GB > 90% della RAM

Importante: gpu_utilization_percent = 0 significa che la GPU è inattiva, non guasta. Un valore di -1.0 significa che la metrica non è disponibile (es. hardware non supportato o errore nella raccolta) — non trattarlo come "GPU morta".

Prestazioni di inferenza

Metrica Eccellente Buono Degradato
tok/s (modello 7B) > 80 40–80 < 40
tok/s (modello 35B) > 40 20–40 < 20
tok/s (modello 70B) > 15 8–15 < 8
TTFT < 100ms 100–500ms > 500ms

Alberi decisionali diagnostici

Generazione lenta (tok/s basso)

graph TD
    A["tok/s below expected?"] --> B["Check memory_pressure"]
    A --> C["Check thermal_state"]
    A --> D["Check gpu_utilization_percent"]
    A --> E["Check swap_used_gb"]

    B -->|critical| B1["Models swapping to disk.<br/>Unload models or add RAM."]
    B -->|normal| B2["Continue"]

    C -->|"serious / critical"| C1["Thermal throttling.<br/>Cool down, check airflow."]
    C -->|nominal| C2["Continue"]

    D -->|"< 10%"| D1["GPU not being used.<br/>Check engine config (num_gpu layers)."]
    D -->|"> 90%"| D2["GPU saturated.<br/>Reduce concurrent requests."]
    D -->|"20-80%"| D3["Normal. Check model<br/>quantization and context size."]

    E -->|"> 0"| E1["Model too large for RAM.<br/>Use smaller quantization."]
    E -->|"0"| E2["Check engine version,<br/>try different engine."]

Motore non risponde

graph TD
    A["engine.running == false?"] --> B["Check process: lsof -i :port"]
    A --> C["Check memory_pressure"]
    A --> D["Try: asiai doctor"]

    B -->|No process| B1["Engine crashed. Restart it."]
    B -->|Process exists| B2["Engine hung."]

    C -->|critical| C1["OOM killed.<br/>Unload other models first."]
    C -->|normal| C2["Check engine logs."]

    D --> D1["Comprehensive diagnostics"]

Pressione di memoria elevata / Overflow VRAM

graph TD
    A["memory_pressure == warn/critical?"] --> B["Check swap_used_gb"]
    A --> C["Check models loaded"]
    A --> D["Check gpu_memory_allocated_bytes"]

    B -->|"> 2 GB"| B1["VRAM overflow.<br/>Latency 5-50x worse (disk swap).<br/>Unload models or use Q3_K_S."]
    B -->|"< 2 GB"| B2["Manageable.<br/>Monitor closely."]

    C -->|"Multiple large models"| C1["Unload unused models.<br/>ollama rm / lms unload"]
    C -->|"Single model > 80% RAM"| C2["Use smaller quantization."]

    D --> D1["If > 80% of RAM,<br/>next model load triggers swap."]

Segnali di attività di inferenza

asiai rileva l'inferenza attiva attraverso più segnali:

Utilizzo GPU

GET /api/snapshot → system.gpu_utilization_percent
  • < 5%: Nessuna inferenza in corso
  • 20–80%: Inferenza attiva (range normale per memoria unificata Apple Silicon)
  • > 90%: Inferenza pesante o richieste concorrenti multiple

Connessioni TCP

GET /api/engine-history?engine=ollama&hours=1

Ogni richiesta di inferenza attiva mantiene una connessione TCP. Un picco in tcp_connections indica generazione attiva.

Metriche specifiche del motore

Per i motori che espongono /metrics (llama.cpp, vllm-mlx):

  • requests_processing > 0: Inferenza attiva
  • kv_cache_usage_percent > 0: Il modello ha un contesto attivo

Pattern di correlazione

Il rilevamento dell'inferenza più affidabile combina più segnali:

snapshot = get_snapshot()
gpu_active = snapshot["system"]["gpu_utilization_percent"] > 15
engine_busy = any(
    e.get("tcp_connections", 0) > 0
    for e in snapshot.get("engine_status", [])
)
inference_running = gpu_active and engine_busy

Codice di esempio

Controllo stato (Python, solo stdlib)

import json
import urllib.request

ASIAI_URL = "http://127.0.0.1:8899"  # Docker: usa IP host o host.docker.internal

def check_health():
    """Controllo rapido dello stato. Restituisce dict con lo stato."""
    req = urllib.request.Request(f"{ASIAI_URL}/api/status")
    with urllib.request.urlopen(req, timeout=5) as resp:
        return json.loads(resp.read())

def is_healthy(status):
    """Interpreta lo stato."""
    issues = []
    if status.get("memory_pressure") != "normal":
        issues.append(f"memory_pressure: {status['memory_pressure']}")
    gpu = status.get("gpu_utilization_percent", 0)
    if gpu > 90:
        issues.append(f"gpu_utilization: {gpu}%")
    engines = status.get("engines", {})
    for name, info in engines.items():
        if not info.get("running"):
            issues.append(f"engine_down: {name}")
    return {"healthy": len(issues) == 0, "issues": issues}

# Utilizzo
status = check_health()
health = is_healthy(status)
if not health["healthy"]:
    print(f"Issues detected: {health['issues']}")

Stato completo del sistema

def get_full_state():
    """Ottieni lo snapshot completo del sistema."""
    req = urllib.request.Request(f"{ASIAI_URL}/api/snapshot")
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())

def get_history(hours=24):
    """Ottieni le metriche storiche."""
    req = urllib.request.Request(f"{ASIAI_URL}/api/history?hours={hours}")
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())

# Rileva tendenza nelle prestazioni
history = get_history(hours=6)
points = history["points"]
if len(points) >= 2:
    recent_gpu = points[-1].get("gpu_utilization_percent", 0)
    earlier_gpu = points[0].get("gpu_utilization_percent", 0)
    if recent_gpu > earlier_gpu * 1.5:
        print("GPU utilization trending up significantly")

Schede benchmark (immagini condivisibili)

Genera un'immagine di scheda benchmark condivisibile con CLI:

asiai bench --card                    # SVG salvato localmente (zero dipendenze)
asiai bench --card --share            # SVG + PNG via API comunitaria
asiai bench --quick --card --share    # Bench rapido + scheda + condivisione (~15s)

Una scheda 1200x630 a tema scuro con modello, chip, grafico a barre del confronto tra motori, evidenziazione del vincitore e chip di metriche. Ottimizzata per Reddit, X, Discord e README di GitHub.

Le schede sono salvate in ~/.local/share/asiai/cards/ come SVG. Aggiungi --share per ottenere un download PNG e un URL condivisibile — il PNG è necessario per postare su Reddit, X e Discord.

Via MCP

Lo strumento MCP run_benchmark supporta la generazione di schede con il parametro card:

{"tool": "run_benchmark", "arguments": {"model": "qwen3.5", "card": true}}

La risposta include card_path — il percorso assoluto del file SVG sul filesystem del server MCP.

Avvisi webhook (notifiche push)

Invece di fare polling, configura asiai per inviare notifiche quando si verificano cambiamenti di stato:

# Aggiungi un webhook (Slack, Discord o qualsiasi URL)
asiai alert add https://hooks.slack.com/services/YOUR/WEBHOOK/URL

# Gli avvisi si attivano su:
# - Motore va giù / torna su
# - Transizioni di pressione di memoria (normal → warn → critical)
# - Throttling termico rilevato

Gli avvisi scattano solo sulle transizioni (non ad ogni controllo) con un raffreddamento di 5 minuti per prevenire lo spam. Ideale per orchestratori di swarm che devono reagire ai cambiamenti dell'infrastruttura senza polling continuo.

Per elencare o rimuovere avvisi: asiai alert list, asiai alert remove <id>.

Identifica il tuo agente

Raccomandiamo di includere un header User-Agent che identifichi il tuo agente nelle richieste API REST:

User-Agent: asiai-agent/<framework>/<version>

Esempi:

  • User-Agent: asiai-agent/openclaw/1.2.0
  • User-Agent: asiai-agent/crewai/0.5
  • User-Agent: asiai-agent/custom-orchestrator/1.0

Questo non è obbligatorio — le richieste senza header User-Agent funzionano normalmente. Ma aiuta con:

  • Debug — distinguere le richieste degli agenti dall'accesso browser umano nei log
  • Analytics per agente — vedere quali agenti accedono all'API, con quale frequenza e quali endpoint
  • Ambienti multi-agente — quando più agenti condividono la stessa istanza asiai, identificare chi è chi

Per i client MCP, l'identificazione è automatica (il protocollo MCP include i metadati del client).


Registra il tuo agente (opzionale)

La registrazione è completamente opzionale — asiai funziona pienamente senza di essa. Nessun "phone home", nessuna telemetria per impostazione predefinita.

Se scegli di registrarti, entri nella rete di agenti asiai: una chiamata API, nessuna email, nessun dato personale — solo le info del tuo hardware.

curl -X POST https://api.asiai.dev/api/v1/agent-register \
  -H "Content-Type: application/json" \
  -d '{
    "chip": "Apple M4 Pro",
    "ram_gb": 64,
    "engines": ["ollama", "lmstudio"],
    "framework": "my-agent",
    "asiai_version": "1.0.1"
  }'

Risposta:

{
  "status": "registered",
  "agent_id": "a1b2c3d4e5f6",
  "agent_token": "secret_...",
  "total_agents": 42
}

Salva agent_id e agent_token in modo sicuro in ~/.local/share/asiai/agent.json. Ti serviranno entrambi per le chiamate API comunitarie e l'invio di benchmark.

Cosa sblocca la registrazione

Funzionalità Senza agent_id Con agent_id
Bench/monitor/web locale
/api/status, /api/snapshot
--share benchmark No
asiai compare (community) No
asiai recommend --community No
Statistiche percentile No
Directory agenti (trova peer sullo stesso chip) No
Avvisi prestazioni (nuovo motore batte il tuo) No In arrivo

Heartbeat

Mantieni attiva la registrazione con heartbeat periodici:

curl -X POST https://api.asiai.dev/api/v1/agent-heartbeat \
  -H "Content-Type: application/json" \
  -H "X-Agent-Id: a1b2c3d4e5f6" \
  -H "X-Agent-Token: secret_..." \
  -d '{
    "engines": ["ollama", "lmstudio"],
    "version": "1.0.1",
    "models_loaded": 3,
    "uptime_hours": 72
  }'

Privacy

  • Nessun indirizzo IP salvato — il tuo IP è usato solo per il rate limiting e non viene mai persistito nel registro agenti
  • Nessun dato personale — solo info hardware (chip, RAM), nomi dei motori e nome del framework
  • Solo su adesione — asiai non comunica mai con l'esterno se non registri esplicitamente
  • Sicurezza token — il tuo agent_token viene hashato (SHA-256) prima del salvataggio; il testo in chiaro viene restituito solo una volta alla registrazione
  • Dati rate limit — gli hash IP (SHA-256 con salt giornaliero) nella tabella rate limit vengono eliminati automaticamente dopo 30 giorni

FAQ

D: asiai richiede root/sudo? R: No. L'osservabilità GPU usa ioreg (nessun privilegio). Le metriche di potenza (flag --power nei benchmark) richiedono sudo powermetrics, ma è opzionale.

D: Qual è il tempo di risposta dell'API? R: /api/status risponde in < 500ms (cache 10s). /api/snapshot richiede 1–3s (raccoglie dati in tempo reale da tutti i motori).

D: Posso eseguire asiai su Linux? R: No. asiai è solo per macOS Apple Silicon. Usa sysctl, vm_stat, ioreg e launchd — tutte API specifiche di macOS.

D: Come monitoro più Mac? R: Esegui asiai daemon start web --host 0.0.0.0 su ogni Mac. Raccogli /api/metrics con Prometheus. Visualizza in Grafana.

D: Cosa succede se un motore si blocca? R: asiai rileva automaticamente i guasti dei motori. Usa asiai doctor per la diagnostica. Configura le notifiche webhook con asiai alert add per le notifiche automatiche.