🔧 Cos'è una Skill?
Nel contesto degli agenti AI, una skill (chiamato anche tool or function) è una capacità impacchettata e riutilizzabile che un LLM può invocare per interagire con il mondo al di fuori della sua finestra di contesto. Le skills colmano il divario tra comprensione linguistica e azione nel mondo reale.
Ogni skill ha quattro componenti:
- Name — un identificatore unico che il modello usa per fare riferimento alla skill (es.,
web_search) - Description — testo in linguaggio naturale che spiega cosa fa la skill e quando usarla; l'LLM legge questo per decidere quando chiamare la skill
- Schema di input — una definizione strutturata degli argomenti (JSON Schema); il modello li compila in base al compito
- Implementation — il codice effettivo che viene eseguito: una chiamata API, una query al database, un comando shell o qualsiasi altra operazione
Esempio: A get_weather la skill ha la descrizione "Recupera le condizioni meteo correnti per una città", accetta { "city": "string" } come input e chiama un'API meteo. L'LLM non vede mai la chiave API o la chiamata HTTP — riceve solo il risultato come testo.
⚙️ Come Funziona la Chiamata degli Strumenti
Quando un agente ha accesso alle skills, l'LLM non le chiama direttamente — requests una chiamata generando un output strutturato. Il runtime (il codice della tua applicazione) esegue la chiamata reale e restituisce il risultato. Ecco l'intero ciclo:
- Registrazione dello strumento — Il tuo codice invia al modello una lista di skills disponibili con le loro descrizioni e schemi
- Ragionamento del modello — L'LLM legge il compito e gli strumenti disponibili, decide quale strumento chiamare e con quali argomenti
- Richiesta di chiamata dello strumento — Il modello emette un messaggio strutturato di "tool call" (es.,
{ "tool": "web_search", "args": { "query": "current Gemini models" } }) - Execution — Il tuo codice runtime chiama la funzione, l'API o il servizio effettivo
- Iniezione di risultati — Il risultato viene aggiunto di nuovo al contesto della conversazione
- Ragionamento continuato — Il modello legge il risultato e o chiama un altro strumento, pone una domanda di follow-up o genera la risposta finale
Questo ciclo può ripetersi molte volte in un singolo turno. Un compito agentico complesso potrebbe chiamare 10–20 tool in sequenza prima di produrre una risposta finale.
📊 Skills vs Plugins vs MCP Servers
La terminologia si è evoluta rapidamente. Ecco come i concetti si relazionano storicamente:
| Era | Name | Come funzionava | Status |
|---|---|---|---|
| 2023 | ChatGPT Plugins | Estensioni installabili dall'utente con uno spec OpenAPI; ChatGPT le chiamava via HTTP | Deprecato (sostituito da GPTs + tools) |
| 2023 | OpenAI Function Calling | Definizioni JSON Schema a livello API; il modello genera una chiamata di funzione strutturata, il tuo codice la esegue | Attivo — rinominato "tool use" |
| 2023– | Tool Use / Skills | Identico a function calling; Anthropic ha coniato "tool use", altri usano "skills" o "functions" | Attivo — standard corrente |
| 2024– | MCP Servers | Protocollo standardizzato (Anthropic, Dec 2024) per impacchettare e distribuire server di tool; qualsiasi client MCP può connettersi a qualsiasi MCP server | Attivo — ecosistema in crescita |
Distinzione chiave: L'uso tradizionale degli strumenti è definito inline nel codice della tua applicazione. Gli MCP servers sono processi standalone che espongono strumenti tramite un protocollo standardizzato — rendendoli riutilizzabili tra diversi client AI (Claude Desktop, Cursor, VS Code, agenti custom). Leggi di più: Cos'è MCP.
🗂️ Categorie di Strumenti e Livelli di Rischio
Non tutti gli strumenti comportano lo stesso rischio. Raggruppare per livelli di rischio aiuta a definire il spazio delle azioni e dove aggiungere checkpoint human-in-the-loop:
| Category | Examples | Risk | Recommendation |
|---|---|---|---|
| Read-only | web_search, read_file, get_weather, list_dir | Low | Permetti autonomamente; registra tutte le chiamate |
| Scrittura (locale) | write_file, create_dir, edit_code | Medium | Limitare a una directory di lavoro sandboxata |
| Rete / Esterno | send_email, post_to_slack, call_api | Medio–Alto | Approvazione HITL per invii irreversibili |
| OS / Shell | run_command, execute_script, install_package | High | Limitare a ambiente containerizzato; HITL richiesto |
| Destructive | delete_file, drop_table, revoke_access | Critical | Richiedere sempre conferma esplicita umana |
🏗️ Anatomia di una Buona Skill
La decisione progettuale più importante per una skill è il suo description. L'LLM legge le descrizioni per decidere quale tool chiamare — una descrizione scritta male porta a selezioni errate, chiamate mancate o argomenti ambigui.
Cosa rende una descrizione efficace
- Sii esplicito su quando usarla — "Usa questo strumento quando l'utente chiede dati in tempo reale o eventi correnti" è meglio di "Cerca sul web"
- Dichiara cosa NON fa — "Non restituisce dati storici più vecchi di 30 giorni"
- Descrivi il formato di output — "Restituisce un array JSON di risultati di ricerca con i campi title, url e snippet"
- Mantienilo sotto le 200 parole — descrizioni più lunghe di ~200 token possono sovraccaricare l'attenzione del modello quando molti strumenti sono registrati
Principi di progettazione degli schemi
- Obbligatorio vs opzionale — Contrassegna i campi come required solo se veramente necessari; i campi opzionali con valori predefiniti riducono gli errori del modello
- Usa enum per valori vincolati —
"format": {"enum": ["json", "markdown", "text"]}previene valori inventati - Preferisci strumenti idempotenti — Gli strumenti che possono essere ripetuti in sicurezza (letture, lookup) sono più sicuri rispetto ad azioni one-shot (invii, cancellazioni)
- Restituisci dati strutturati — Le risposte JSON sono più semplici da elaborare per il modello rispetto a blob di testo non strutturati
💡 Esempi nel mondo reale
| Nome della skill | Cosa fa | Argomenti chiave | Risk |
|---|---|---|---|
web_search | Interroga un motore di ricerca e restituisce i risultati principali | query: string, num_results?: number | Low |
read_file | Leggi un file dalla directory di lavoro | path: string, offset?: number, limit?: number | Low |
write_file | Crea o sovrascrivi un file | path: string, content: string | Medium |
run_tests | Esegui la suite di test del progetto e restituisci i risultati | filter?: string | Medium |
browser_screenshot | Naviga verso un URL e restituisci uno screenshot | url: string | Medium |
send_email | Invia un'email a uno o più destinatari | to: string[], subject: string, body: string | Alto — sempre HITL |
run_shell | Esegui un comando shell arbitrario | command: string, cwd?: string | Alto — sandbox richiesta |
✅ Best Practices
Permessi minimi
Concedi a ogni agente solo gli strumenti necessari per il suo compito specifico. Un agente che risponde a FAQ non ha bisogno di write_file or send_email. Più piccolo è lo spazio delle azioni, più piccolo è il raggio d'azione se l'agente viene manipolato. Vedi: Agenzia Eccessiva.
Audita tutte le chiamate agli strumenti
Registra ogni chiamata allo strumento con i suoi argomenti e il risultato. Questo permette il debug, l'attribuzione dei costi e il rilevamento di comportamenti anomali (es., un agente che legge ~/.ssh/ quando dovrebbe solo accedere alla directory del progetto). Piattaforme AgentOps come LangSmith rendono questo semplice.
Human-in-the-loop per azioni irreversibili
Qualsiasi azione difficile o impossibile da annullare — inviare messaggi, cancellare dati, effettuare acquisti — dovrebbe richiedere conferma esplicita umana prima dell'esecuzione. Integra checkpoint HITL nel runtime del tuo agente, non solo nel prompt. I prompt possono essere sovrascritti; il codice no.
Attenzione al tool poisoning
Se permetti agli agenti di installare o scoprire MCP servers dinamicamente, un server maligno può registrare uno strumento con una descrizione che contiene istruzioni nascoste. Revisiona sempre le descrizioni degli strumenti prima di aggiungerli al registro del tuo agente. Vedi: Tool Poisoning.
Scrivi ritorni di errore chiari
Quando uno strumento fallisce, restituisci un errore strutturato con abbastanza contesto perché il modello possa recuperare o escalare — non una raw exception stack trace. Esempio: { "error": "rate_limited", "retry_after": 5 }. Un errore ben descritto permette all'agente di ritentare, usare uno strumento di fallback o informare l'utente con grazia.