Corso
Anthropic ha recentemente introdotto Claude Skills, un modulo riutilizzabile e specifico per il compito che permette a Claude di caricare solo le competenze necessarie per un lavoro. Invece di prompt lunghi e ripetitivi, le Skills raggruppano istruzioni, script e asset così che Claude possa produrre risultati coerenti e in linea con il brand su app Claude, Claude Code e API.
In questo tutorial costruiremo un “Generatore di fatture automatico” che trasforma un timesheet Excel in una fattura pronta per il cliente (DOCX/PDF). Lungo il percorso imparerai a:
- Creare un
SKILL.mdminimale e caricare una Skill con gli asset di supporto. - Preprocessare dati come un timesheet con
pandasin un payload JSON prevedibile. - Invocare la Skill tramite API con un ciclo di uso sicuro degli strumenti (tag bash/text-editor).
- Catturare gli artifact generati da Claude (PDF/DOCX)
Alla fine, avrai una Skill portatile che puoi riutilizzare ovunque nell’ecosistema Claude.
Cosa sono le Claude Skills?
Le Claude Skills sono moduli di attività autonomi che includono un file SKILL.md (istruzioni), script opzionali e asset di supporto. Quando un’attività corrisponde allo scopo di una Skill, Claude carica le parti minime di quella Skill per eseguire il compito in modo efficiente. Una Skill può essere vista come un pacchetto di competenze che puoi versionare, condividere e governare in tutta la tua organizzazione.
Caratteristiche principali delle Claude Skills
Le funzionalità principali delle Claude Skills spiegano come restino veloci, riutilizzabili e affidabili nell’ecosistema Claude. Tra le caratteristiche chiave:
- Componibili: puoi combinare più Skills per eseguire workflow in più step, come pulizia dei dati, analisi e generazione di report.
- Portabili: le Skills seguono un formato comune, quindi la stessa Skill funziona in modo coerente in tutto l’ecosistema Claude.
- Efficienti: Claude carica solo i componenti minimi richiesti per il task, migliorando velocità e accuratezza.
- Eseguibili come codice: le Skills possono eseguire codice in una sandbox sicura, abilitando azioni deterministiche come creazione file, parsing e analytics.
Quando chiedi a Claude di “creare un budget Excel con roll-up mensili”, valuta la richiesta, scansiona le Skills disponibili e attiva solo le parti rilevanti. L’attivazione è visibile nella vista di ragionamento all’interno dell’app Claude. Poiché le Skills sono componenti versionati, i team possono distribuire aggiornamenti senza cambiare i prompt ovunque.
Uso delle Claude Skills nell’ecosistema Claude
Che tu stia chattando nelle app Claude, programmando in Claude Code o automatizzando workflow tramite la Developer API, la stessa Skill può essere versionata una sola volta, gestita centralmente e invocata automaticamente quando il compito corrisponde al suo scopo. Questo porta a qualità costante e tempi più rapidi. Insomma, una Skill da riutilizzare ovunque.
In questo tutorial applicheremo la Skill “Generatore di fatture automatico” nell’app Claude e nell’API per analizzare un file Excel e produrre una fattura pronta da inviare.
App Claude
Le Claude Skills vivono nella tua app Claude e si attivano automaticamente quando una richiesta corrisponde al loro scopo. Le abiliti una volta nelle Impostazioni e poi descrivi semplicemente il risultato che vuoi ottenere. Claude carica la Skill giusta e la mostra nella vista di ragionamento.

Fonte: Claude Blog
Per iniziare:
- Accedi o registrati con il tuo account Google e vai su Impostazioni.
- Sotto Capacità, cerca la scheda Skills e carica una Skill (di solito un file SKILL.md) che può essere usata in qualsiasi chat.

Fonte: Claude Blog
Nota: questa funzione è disponibile solo per utenti Pro, Max, Team ed Enterprise.
Puoi anche trovare un elenco di Skills come algorithmic-art, artifacts-builder, brand-guidelines, canvas-design, internal-comms, mcp-builder, slack-gif-creator, ecc., da aggiungere alle tue conversazioni con Claude.
Clicca su upload skill e carica un file zip contenente il file SKILL.md. Ecco i requisiti del file.
-
File ZIP che include esattamente un file SKILL.md al livello root
-
SKILL.mdcontiene un nome Skill e una descrizione formattati in YAML
Il file SKILL.md usato in questo tutorial è così:
name: "auto-invoice-generator-monthly-articles"
description: "Generate monthly invoices for written content from simple line items. Produces a branded PDF or editable DOCX/RTF invoice and, optionally, a one-page timesheet if article titles/links are provided."

Una volta caricata la Skill, Claude la riconosce automaticamente e apre una nuova chat dove è pronta all’uso.

Come influisce sull’uso in chat?
- Non devi “attivare” una Skill in ogni conversazione. Quando è rilevante, Claude invoca automaticamente le Skills abilitate e le mostra nella vista di ragionamento per trasparenza.
- Disabilitare una Skill impedisce che venga considerata in qualsiasi chat finché non la riabiliti.
- Se la tua organizzazione fissa un set canonico di Skills come template di brand, reportistica, ecc., mantenerle abilitate garantisce risultati coerenti ogni volta.


Successivamente, ho passato il mio timesheet e chiesto a Claude di creare una fattura modificabile.

Claude ha individuato la Skill da solo, ha letto il file Excel e ha restituito una fattura Word modificabile, che può anche essere esportata in PDF o Word. Il layout della fattura è pulito e subtotale e totale sono corretti. Ha rispettato il prompt e lo stile sia del file DOCX modificabile sia del PDF formattato corrispondeva alle impostazioni di brand della Skill.
Ora eseguiamo lo stesso esempio usando l’API.
Claude Developer Platform (API)
Le Claude Skills sono accessibili anche tramite la Claude API. In questa sezione vedremo come possiamo imitare l’interfaccia dell’app Claude via API.
Step 1: Prerequisiti
Inizia installando tutte le dipendenze runtime:
-
Anthropicper la Messages API di Claude -
pandaseopenpyxlper leggere i timesheet da Excel -
reportlabper generare localmente una fattura PDF di fallback
!pip -q install anthropic pandas openpyxl reportlab
Ora abbiamo tutte le dipendenze installate. Successivamente, possiamo configurare la nostra API key.
Step 2: Configura la tua API key
Prima di poter chiamare la Messages API, dobbiamo autenticarci. Questo step crea un unico anthropic.Client riutilizzabile con la chiave API.
import os, json, sys, re
import anthropic
from datetime import datetime, timedelta
API_KEY = "YOUR_ANTHROPIC_API_KEY"
client = anthropic.Client(api_key=API_KEY)
Accedi alla Anthropic Console e trova la scheda delle API keys sotto Impostazioni. Clicca su Create Key e copia la tua chiave API Anthropic.

Fonte: Anthropic API
Nota: se stai usando un notebook privato per uso personale, allora aggiungi la tua API Key. Altrimenti, usa una variabile d’ambiente sicura così la chiave non è esposta nel notebook o nei log.
Il codice sopra inizializza il client SDK di Anthropic e configura l’ambiente. L’oggetto client viene poi riutilizzato per tutte le successive chiamate alla Messages API.
Step 3: Preprocessamento dei dati
In questo step trasformeremo il nostro foglio timesheet.xlsx in un oggetto JSON pulito e prevedibile che la Skill può consumare. Questo mantiene semplice la logica a valle ed evita parsing fragili del prompt.
def load_invoice_from_timesheet(excel_path):
import pandas as pd
df = pd.read_excel(excel_path)
df.columns = df.columns.str.strip()
invoice_period = "2025-10"
if 'Date' in df.columns:
first_date = str(df['Date'].iloc[0])
date_match = re.search(r'(\d{2})\s+(\w+)\s+(\d{4})', first_date)
if date_match:
month_name = date_match.group(2)
year = date_match.group(3)
month_num = datetime.strptime(month_name[:3], '%b').month
invoice_period = f"{year}-{month_num:02d}"
article_col = next((col for col in df.columns if 'article' in col.lower() and 'name' in col.lower()), None)
amount_col = next((col for col in df.columns if 'amount' in col.lower()), None)
topic_col = next((col for col in df.columns if 'topic' in col.lower()), None)
line_items = []
timesheet_articles = []
for idx, row in df.iterrows():
if pd.isna(row.get(article_col)) or row.get(article_col) == '':
continue
article_name = str(row[article_col]).strip()
amount = row.get(amount_col, 0)
if isinstance(amount, str):
amount = float(amount.replace('$', '').replace(',', '').strip())
line_items.append({
"title": article_name,
"rate_type": "flat",
"qty": 1,
"rate": float(amount)
})
timesheet_articles.append({
"title": article_name,
"topic": str(row.get(topic_col, 'N/A')) if topic_col else 'N/A'
})
return {
"client_name": "Client",
"billing_contact": "billing@example.com",
"invoice_period": invoice_period,
"currency": "USD",
"payment_terms": "Net-30",
"line_items": line_items,
"discount_pct": 0.0,
"tax_pct": 0.0,
"timesheet": timesheet_articles
}
La funzione load_invoice_from_timesheet converte un file Excel caricato in un payload JSON di fattura normalizzato.
-
Legge l’Excel con pandas e normalizza le intestazioni delle colonne.
-
Il codice poi deduce
invoice_perioddalla prima rigaDate(se presente) usando una regex e il parsing del mese. -
Infine rileva i nomi delle colonne per titolo dell’articolo, importo e argomento in modo case-insensitive.
-
Genera due strutture:
-
line_items: usata per il calcolo della fatturazione (tariffa fissa per articolo in questo caso). -
timesheet: un elenco piatto di voci{title, topic}per un’appendice opzionale. -
La regex
(\d{2})\s+(\w+)\s+(\d{4})si aspetta formati come01 Oct 2025; adattala se il tuo foglio usa un altro formato. -
Le colonne/valori mancanti sono gestiti saltando le righe vuote, oppure puoi estendere il codice per fallire rapidamente se necessario.
Il nostro input è pronto. Ora chiameremo la Skill di Claude via API per trasformare il timesheet elaborato in una fattura modificabile.
Step 4: Funzioni di supporto
In questa sezione definiamo due funzioni helper che simulano l’esecuzione degli strumenti che Claude richiede durante l’esecuzione di una Skill.
def execute_bash_tool(command):
try:
dangerous = ['rm -rf /', 'sudo', 'chmod', 'mkfs', '> /dev/']
if any(d in command for d in dangerous):
return f"Error: Command blocked for safety: {command}"
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30,
cwd=tempfile.gettempdir()
)
output = result.stdout if result.stdout else result.stderr
return output if output else "Command executed successfully"
except subprocess.TimeoutExpired:
return "Error: Command timed out"
except Exception as e:
return f"Error executing command: {str(e)}"
def execute_text_editor_tool(params):
try:
command = params.get('command')
path = params.get('path')
if command == 'create':
file_text = params.get('file_text', '')
os.makedirs(os.path.dirname(path) if os.path.dirname(path) else '.', exist_ok=True)
with open(path, 'w') as f:
f.write(file_text)
return f"File created: {path}"
elif command == 'view':
if os.path.exists(path):
with open(path, 'r') as f:
content = f.read()
return content[:1000]
return f"Error: File not found: {path}"
elif command == 'str_replace':
if os.path.exists(path):
with open(path, 'r') as f:
content = f.read()
old_str = params.get('old_str', '')
new_str = params.get('new_str', '')
content = content.replace(old_str, new_str)
with open(path, 'w') as f:
f.write(content)
return f"File updated: {path}"
return f"Error: File not found: {path}"
return f"Unknown command: {command}"
except Exception as e:
return f"Error: {str(e)}"
La funzione execute_bash_tool simula uno strumento bash sicuro per azioni guidate dalla Skill. Prima blocca pattern pericolosi come rm -rf /, sudo, chmod, mkfs, ecc., come barriera di sicurezza, e poi esegue il comando con subprocess.run() nella directory temporanea del sistema operativo con un timeout di 30 secondi.
La funzione execute_text_editor_tool fornisce un’interfaccia minima di editing testuale usata dalle Skills. Supporta tre comandi: create (per scrivere un nuovo file con file_text), view (per restituire fino a 1.000 caratteri di un file) e str_replace (sostituzione in-place con new_str). Crea automaticamente le cartelle padre per create, verifica l’esistenza del file per view e str_replace, e salva gli aggiornamenti su disco.
Questi helper ti permettono di completare localmente un ciclo di uso degli strumenti con dei binari di sicurezza. Ora la Skill può richiedere modifiche ai file o azioni shell durante la generazione della fattura senza rischiare il tuo sistema.
Step 5: Invoca la Skill via API
Questo step guida la generazione end-to-end della fattura tramite la Claude Messages API. Invia una richiesta strutturata, abilita l’uso degli strumenti, itera tra eventuali chiamate a tool richieste da Claude e infine raccoglie eventuali file PDF generati dalla working directory e dalla directory temporanea.
def generate_invoice_with_claude(invoice):
user_text = f"""Generate a professional PDF invoice with the following data:
Client: {invoice['client_name']}
Period: {invoice['invoice_period']}
Currency: {invoice['currency']}
Payment Terms: {invoice['payment_terms']}
Line Items:
{json.dumps(invoice['line_items'], indent=2)}
Timesheet Articles:
{json.dumps(invoice['timesheet'], indent=2)}
Please create a professional PDF invoice with:
1. Invoice header with invoice number (INV-{invoice['invoice_period'].replace('-', '')}-001)
2. Client billing information
3. Line items table with amounts
4. Subtotal and total calculations
5. Timesheet section showing all articles and topics
Save the PDF as: invoice_{invoice['client_name'].lower()}_{invoice['invoice_period']}.pdf
"""
tools = [
{"type": "bash_20250124", "name": "bash"},
{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}
]
messages = [{"role": "user", "content": user_text}]
iteration = 0
max_iterations = 15
while iteration < max_iterations:
iteration += 1
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8192,
tools=tools,
messages=messages
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason == "end_turn":
break
if response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
if tool_name == "bash":
result = execute_bash_tool(tool_input.get('command', ''))
elif tool_name == "str_replace_based_edit_tool":
result = execute_text_editor_tool(tool_input)
else:
result = f"Unknown tool: {tool_name}"
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
messages.append({"role": "user", "content": tool_results})
else:
break
pdf_files = []
for file in os.listdir('.'):
if file.endswith('.pdf') and 'invoice' in file.lower():
pdf_files.append(file)
for file in os.listdir(tempfile.gettempdir()):
if file.endswith('.pdf') and 'invoice' in file.lower():
temp_path = os.path.join(tempfile.gettempdir(), file)
import shutil
dest_path = os.path.join('.', file)
shutil.copy2(temp_path, dest_path)
pdf_files.append(file)
return pdf_files
def main():
if len(sys.argv) < 2:
print("Usage: python app.py <timesheet.xlsx>")
sys.exit(1)
excel_file = sys.argv[1]
if not os.path.exists(excel_file):
print(f"Error: File not found: {excel_file}")
sys.exit(1)
try:
invoice = load_invoice_from_timesheet(excel_file)
pdf_files = generate_invoice_with_claude(invoice)
if pdf_files:
for pdf in pdf_files:
print(f"Invoice generated: {os.path.abspath(pdf)}")
else:
print("Error: No PDF file was generated.")
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()
La funzione generate_invoice_with_claude invia la fattura normalizzata alla Claude API e guida l’esecuzione della Skill end-to-end. Ecco cosa fa il codice:
-
Crea un
user_textchiaro che include cliente, periodo, valuta, termini, righe e voci del timesheet, oltre a requisiti espliciti di output come intestazione, tabelle, totali e nome file. -
Abilita quindi l’esecuzione degli strumenti dichiarando un
bash_numbere untext_editor_numbercon un loop di messaggi “tool-aware” che invia la richiesta, ispezionastop_reasone, quando viene richiestotool_use, delega agli helper locali e restituisce blocchitool_resultper proseguire lo scambio. -
Infine si ferma su
end_turno al raggiungimento del limite del loop, quindi scandisce la working directory e la directory temporanea del sistema per file che corrispondono ainvoice*.pdf. Copia eventuali artifact temporanei nella cartella del progetto e restituisce l’elenco dei PDF trovati. -
La funzione
mainoffre un semplice comando CLI:python app.py <timesheet.xlsx>, che valida il percorso di input, quindi esegue la pipeline:load_invoice_from_timesheet(...)per creare il payload egenerate_invoice_with_claude(...)per invocare la Skill e raccogliere i PDF.
Con questo in place, la chiamata API dovrebbe produrre un PDF pronto per il cliente. Se non compare alcun file, rivedi i log tool_result e la configurazione della Skill, quindi riprova con un foglio di test piccolo.

Conclusione
Ora hai un Generatore di fatture automatico funzionante basato su Claude Skills e l’API è in grado di trasformare fogli di calcolo grezzi in fatture pronte per il cliente. Questa demo mostra ciò che le Skills fanno meglio, cioè setup portabile, auto-attivazione, esecuzione di codice deterministica e risultati coerenti tra app e API senza ricreare i prompt in ogni thread. Le Claude Skills restituiscono output coerenti nei vari contesti, cioè conoscenza di dominio riutilizzabile con supporto di codice. Anche se le Skills possono eseguire codice, devi comunque applicare misure di sicurezza abilitando solo Skills fidate, usando controlli a livello di organizzazione e rivedendo gli aggiornamenti prima del rollout.
Per approfondire, esplora la documentazione delle Skills di Anthropic e la Console per versioning e upgrade, quindi inizia a comporre più Skills per costruire workflow end-to-end.
Sono una Google Developers Expert in ML (Gen AI), una Kaggle 3x Expert e una Women Techmakers Ambassador con oltre 3 anni di esperienza nel tech. Ho co-fondato una startup health-tech nel 2020 e sto conseguendo un master in informatica al Georgia Tech, con specializzazione in machine learning.


