# Prompting di Claude Opus 5

> Sintesi della lezione basata sulla documentazione ufficiale *"Prompting Claude Opus 5"*.
> Fonte: https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5

> **Nota correlata:** [Context engineering per i modelli di generazione 5](./context-engineering.md).
> Le due note stanno a livelli diversi e condividono un principio: *non scrivere ciò che il modello già sa o già fa*.
> Là è "non scrivere quello che il codice racconta"; qui è "non scrivere quello che il comportamento nativo già copre".

---

## Il concetto in una frase

Il prompt engineering per Opus 5 non è "scrivere buone istruzioni da zero": è **tuning differenziale**. Le istruzioni non agiscono su un modello neutro, agiscono su una **baseline** già ricca — Opus 5 di suo verifica il proprio lavoro, narra i progressi, delega a subagent, corregge i propri errori.

Da cui il meccanismo centrale: ogni istruzione che **duplica** un comportamento nativo non lo rafforza, lo fa **sommare a se stesso**.

E la regola operativa che ne discende:

> **Il primo intervento su un prompt ereditato è una cancellazione, non un'aggiunta.**

## Perché esiste questa guida

Opus 5 è ottimizzato per lavoro agentico *long-horizon* — compiti lunghi, multi-file, molti tool call, poca supervisione umana. Per riuscirci ha alzato l'autonomia, e l'autonomia ha effetti collaterali misurabili: risposte più lunghe, più narrazione, scope che si allarga, delega più frequente.

Il prompt serve a **riportare quei default dentro i vincoli del tuo prodotto**, non ad aggiungere capacità.

## Tre termini da fissare subito

| Termine | Cos'è |
|---|---|
| **Effort** (`output_config.effort`, `low` → `max`) | Quanto il modello *pensa e agisce*: profondità di ragionamento e spesa complessiva di token. **Non** è un budget di output |
| **Thinking** | La fase di ragionamento interno prima della risposta. Su Opus 5 è **attiva per default** (su Opus 4.8 omettere il parametro significava "spento") e disattivabile solo a effort `high` o inferiore |
| **Subagent** | Un'istanza figlia lanciata per un sottocompito indipendente. Ricostruisce il proprio contesto da zero, quindi costa |

---

## Due leve ortogonali

Il modello mentale utile: due leve diverse controllano due grandezze diverse, e confonderle è l'errore più comune.

```
                     ┌──────────────────────────────┐
   effort ──────────▶│  quanto RAGIONA e AGISCE     │──▶ token di thinking,
   (low..max)        │  (profondità, n. tool call)  │    numero di passi, latenza
                     └──────────────────────────────┘
                     ┌──────────────────────────────┐
   prompt ──────────▶│  quanto SCRIVE e cosa fa     │──▶ lunghezza risposta,
   (istruzioni)      │  (verbosità, scope, delega)  │    narrazione, ampiezza task
                     └──────────────────────────────┘

   ✗ Errore tipico: abbassare effort per accorciare la risposta.
     Risultato: pensa meno (qualità giù), scrive uguale (verbosità invariata).
```

La verbosità visibile si controlla **solo via prompt**. Al contrario, `low` e `medium` su Opus 5 danno qualità forte a una frazione di token e latenza: sono la leva primaria per **costo e tempo di risposta**, non per lunghezza.

## Il flusso di adattamento di un prompt esistente

Un ciclo di **sottrazione prima di addizione**:

```mermaid
flowchart TD
    A[Prompt scritto per Opus 4.8] --> B{Contiene istruzioni di verifica?<br/>'double-check', 'verifica prima di rispondere',<br/>'usa un subagent per verificare'}
    B -->|Si'| C[RIMUOVI<br/>compongono col comportamento nativo]
    B -->|No| D
    C --> D{Contiene 'delega di piu' ai subagent'?<br/>guardrail scritto per Opus 4.8}
    D -->|Si'| E[RIMUOVI e sostituisci con un CAP numerico]
    D -->|No| F
    E --> F{Contiene 'segnala solo bug high-severity'<br/>o 'sii conservativo'?}
    F -->|Si'| G[SPOSTA il filtro a valle:<br/>chiedi tutto + confidence/severity]
    F -->|No| H
    G --> H[Ora AGGIUNGI: concisione, scope,<br/>cadenza narrazione, correzioni]
    H --> I[Effort sweep sulle proprie eval:<br/>low / medium / high / xhigh]
    I --> J[Prompt tarato]
```

Il ramo "rimuovi" viene **prima** del ramo "aggiungi" per un motivo preciso: se aggiungi vincoli di concisione sopra istruzioni di verifica non rimosse, il modello continua a spendere token in verifiche ridondanti e tu misuri un miglioramento parziale, concludendo che l'istruzione di concisione "non funziona".

---

## Il meccanismo della composizione

Un'istruzione come *"verifica sempre il tuo lavoro prima di rispondere"* su un modello che già verifica non produce "verifica una volta" ma **"verifica due volte, e narralo"**. Lo stesso vale per `"double-check your answer"`.

La documentazione è esplicita: rimuoverle **riduce i token senza perdita di qualità**.

Questo è il caso in cui una best practice generale — "chiedi al modello un self-check" — va **sospesa** per questo modello specifico. Se hai una libreria di prompt che la applica in modo uniforme, serve un'eccezione, non una regola globale.

## Il letteralismo è un'arma a doppio taglio

Opus 5 segue i vincoli **alla lettera**. Nel code review questo produce un effetto controintuitivo:

un prompt che dice *"segnala solo problemi high-severity"* fa **calare la recall misurata** anche se la capacità di trovare bug è migliorata.

Il modello trova gli stessi bug, poi ne scarta quelli che giudica sotto la soglia che gli hai dato. La precisione sale, il numero di finding scende, e la tua dashboard registra un **peggioramento del modello** che in realtà è un artefatto del tuo prompt.

La soluzione è strutturale, non testuale: **separare `trovare` da `filtrare`**. Chiedi tutto con confidence e severity per ciascun finding, e filtra in un passo successivo nella tua pipeline.

## Edge case: thinking disabilitato

È il punto più insidioso perché i due fallimenti sono **silenziosi**.

1. **Tool call come testo.** Con thinking spento, il modello a volte scrive la chiamata al tool nel testo visibile invece di emettere un blocco `tool_use` strutturato. Il turno si chiude con successo, nessun errore, **e la chiamata non viene mai eseguita**. In un loop agentico quel testo resta nella cronologia e inquina i turni successivi. Frequente sui carichi tool-heavy come la ricerca.
2. **Tag XML interni nell'output.** Possono comparire tag di sistema nella risposta visibile.

Due regole controintuitive:

- **Cancella** ogni istruzione tipo "non ragionare" / "non pensare": **aumenta** il leak dei tag invece di sopprimerlo.
- **Non nominare i tag di thinking** nell'istruzione. La formulazione generica ("nessun tag XML interno o di sistema") è più efficace di quella specifica.

Ma la mitigazione principale **non è un prompt**: è **riaccendere il thinking e abbassare l'effort**. Per la maggior parte dei task, thinking attivo a `low` batte thinking disattivato a costo comparabile. Disabilitare il thinking è la leva più cara in tutti i sensi.

## Delega: inversione di direzione rispetto a Opus 4.8

Questo è il caso in cui un guardrail ereditato diventa **dannoso**.

Opus 4.8 *sotto*-delegava e richiedeva prompt che lo spingessero a usare i subagent. Opus 5 delega prontamente. Se migri un prompt e porti dietro il "delega di più", moltiplichi costo e latenza: ogni subagent ricostruisce il contesto, esplora, riporta, e il coordinatore rilegge il report.

Il rimedio affidabile è un **cap deterministico** sul numero di agenti, più il divieto esplicito di usare subagent **per verificare**.

## Il pattern da sfruttare, non solo contenere

Sulla **vision**, dare al modello dei tool per ritagliare, analizzare e verificare visivamente il proprio lavoro è più cost-effective che alzare il thinking. È l'unico caso in cui la risposta non è "prompt" ma **"amplia il tool set"**.

## Da non confondere

| Coppia | Differenza |
|---|---|
| **Effort vs `max_tokens`** | `max_tokens` è un tetto **imposto** che il modello non vede; effort è profondità di ragionamento. Con thinking attivo `max_tokens` limita thinking **più** testo insieme: se avevi dimensionato `max_tokens` strettamente sulla risposta con thinking spento, ora la risposta **si tronca a metà** |
| **Verbosità conversazionale vs lunghezza dei deliverable** | Due comportamenti separati con due istruzioni separate. I file scritti su disco (report, Markdown) si allungano indipendentemente dalla concisione in chat |
| **Narrazione vs auto-correzione** | La prima è "annuncio cosa faccio"; la seconda è "spiego l'errore che avevo fatto prima". Istruzioni distinte, e la seconda è quella che in un prodotto user-facing legge come **indecisione** |

---

## Esempio pratico

### Scenario

Un team di 4 persone gestisce un agente di code review che gira in CI su ogni pull request. È stato scritto per Opus 4.8, il thinking è disattivato per tenere bassa la latenza (il commento deve arrivare entro 90 secondi), e gira a `effort: "xhigh"`.

Dopo lo switch a Opus 5 osservano tre cose:

- i commenti sono **raddoppiati** in lunghezza;
- il conto token è salito del **60%**;
- un paio di run al giorno terminano **senza aver eseguito nessuna ricerca** nel codebase, pur dichiarando di averla fatta.

Il prompt attuale:

```text
Sei un revisore senior. Per ogni PR non banale, includi un passo finale di
verifica: rileggi le tue conclusioni e ricontrolla la tua risposta prima di
rispondere. Usa un subagent per verificare i finding.
Delega liberamente ai subagent quando puoi parallelizzare.
Segnala solo problemi di severità alta: non fare nitpicking.
Non ragionare passo a passo, rispondi direttamente.
```

### Passo 1 — Sistemare l'errore bloccante di configurazione, prima di toccare il prompt

`effort: "xhigh"` con thinking disabilitato restituisce un **400** su Opus 5: la disabilitazione è ammessa solo a `high` o inferiore. Ed è anche la causa dei run che "non cercano" — è il fallimento silenzioso dei tool call scritti come testo.

La correzione giusta non è scendere a `high` mantenendo il thinking spento, ma **riaccenderlo abbassando l'effort**:

```python
response = client.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    thinking={"type": "adaptive"},        # riaccendere: era disabled
    output_config={"effort": "low"},      # era "xhigh"
    system=SYSTEM_PROMPT,
    messages=[{"role": "user", "content": diff}],
)
```

> **Nota su `max_tokens`:** con il thinking attivo il tetto copre thinking **più** testo. Se era dimensionato sul solo commento, alzalo — altrimenti il commento si tronca.

### Passo 2 — Sottrarre

Escono quattro righe, ognuna per un motivo diverso:

| Riga rimossa | Perché |
|---|---|
| *"includi un passo finale di verifica"* + *"ricontrolla la tua risposta"* | Il modello verifica già; sommate producono over-verification pura |
| *"usa un subagent per verificare i finding"* | Doppio danno: verifica ridondante **e** delega inutile |
| *"delega liberamente ai subagent"* | Guardrail scritto per un modello che sotto-delegava; su Opus 5 va nella direzione **opposta** a quella che serve |
| *"non ragionare passo a passo"* | È esattamente l'istruzione che **aumenta** il leak dei tag di thinking |

### Passo 3 — Spostare il filtro di severity a valle

*"segnala solo problemi di severità alta"* non va cancellato, va **trasformato**: la soglia si applica dopo, non durante. Il modello riporta tutto con confidence e severity; il codice della CI filtra.

### Passo 4 — Aggiungere i tre vincoli che ora servono davvero

Concisione, scope, e narrazione delle correzioni. Il prompt risultante:

```text
Sei un revisore senior.

Riporta ogni problema che trovi, inclusi quelli su cui hai dubbi o che
consideri di bassa severità. Non filtrare per importanza o confidenza in
questa fase: un passo separato lo farà. Per ogni finding indica il tuo
livello di confidenza e una stima di severità.

Keep responses focused, brief, and concise. Keep disclaimers and caveats
short, and spend most of the response on the main answer.

Deliver what was asked, at the scope intended. Make routine judgment calls
yourself, and check in only when different readings of the request would
lead to materially different work. If the request seems mistaken or a better
approach exists, say so in a sentence and continue with the task as asked
rather than quietly narrowing, widening, or transforming it. Finish the whole
task, and stop short of actions that are clearly beyond what was asked.

Only correct an earlier statement when the error would change the user's
code, conclusions, or decisions. State corrections plainly and briefly, then
continue the task. For slips that change nothing for the user, make the fix
and move on without noting it.
```

Se il team decidesse comunque di tenere il thinking spento (vincolo di latenza non negoziabile), va aggiunta **una** riga combinata — nella forma **generica**, senza nominare i tag:

```text
When you use a tool, you may say a brief sentence first. If no tool can
express what the user asked for, say so instead of guessing. Do not include
internal or system XML tags in your response.
```

### Passo 5 — Effort sweep

Il default ereditato non si trasferisce mai. Si gira lo stesso set di 30 PR storiche a `low`, `medium` e `high`, misurando bug reali trovati, falsi positivi, token e latenza. Su Opus 5 `low` e `medium` reggono su gran parte dei carichi; `xhigh` si riserva al **lavoro di coding difficile**, non alla review.

### Risultato atteso

Il conto token scende su tre fronti sommati: verifiche ridondanti eliminate, subagent non più lanciati per compiti da pochi tool call, commenti più corti.

I run silenziosamente vuoti smettono di comparire, perché con il thinking attivo le chiamate ai tool tornano a essere blocchi `tool_use` strutturati anziché testo.

La recall misurata **sale** invece di scendere — non perché il modello sia migliorato in quel passo, ma perché il filtro di severity non gli sta più tagliando i finding prima che tu li veda: la severity ora la decide la tua pipeline, non lui.

E lo scope dei commenti resta sul diff, senza refactor non richiesti.

> **La regola generalizzabile:** su Opus 5 ogni istruzione che descrive un comportamento che il modello ha già nativamente **non è neutra** — è un costo che si somma.

---

## Riferimenti

- **"Prompting Claude Opus 5"** — https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5
  Fonte di questa nota; da cui provengono verbatim gli snippet in inglese (concisione, scope, correzioni, thinking disabilitato).
- **Effort** — https://platform.claude.com/docs/en/build-with-claude/effort — livelli raccomandati per Opus 5.
- **Migration guide, da Opus 4.8 a Opus 5** — https://platform.claude.com/docs/en/about-claude/models/migration-guide — i due breaking change API: thinking attivo per default, e disabilitazione ammessa solo fino a effort `high`.
- **What's new in Claude Opus 5** — https://platform.claude.com/docs/en/about-claude/models/whats-new-opus-5
- Note correlate: [Context engineering](./context-engineering.md) · [Scegliere il modello Claude giusto](./using-claude-models.md)
