L'ingegneria dei prompt è diventata una delle competenze a più alto impatto nello sviluppo software moderno. Il prompt che si fornisce a un agente ne modella la pianificazione, il modo in cui utilizza gli strumenti e se costruisce o rompe la propria pipeline. Piccoli cambiamenti — una riga extra di contesto, un vincolo chiarito, un'istruzione riordinata — spesso producono guadagni sproporzionati in accuratezza e affidabilità.

Questo post distilla tattiche collaudate sul campo che utilizziamo in Augment Code per costruire agenti autonomi che si comportano come compagni di squadra disciplinati anziché come strumenti di codifica che allucinano e mancano di precisione. Gli esempi nel post si concentrano sugli agenti di codifica, ma le tecniche sono generalmente applicabili.

Che cos'è l'ingegneria dei prompt?

Il prompt di un agente include tutto ciò che viene fornito al modello come input. Questo comprende vari componenti:

  • Prompt di sistema
  • Definizioni degli strumenti
  • Output degli strumenti
  • Istruzioni dell'utente
  • Gli output del modello stesso da turni precedenti

L'ingegneria dei prompt è l'arte di migliorare le prestazioni di un modello su un compito fornendogli un prompt migliore. Tutte le parti del prompt possono essere potenzialmente migliorate con l'ingegneria dei prompt. Ad esempio:

  • Il prompt di sistema può includere istruzioni generali per spingere il modello verso diversi stili di risposta o livelli di autonomia.
  • Le definizioni degli strumenti possono spiegare al modello in quali circostanze uno strumento dovrebbe o non dovrebbe essere utilizzato.
  • Gli output degli strumenti possono informare il modello sulle condizioni di errore.
  • Le istruzioni dell'utente possono essere riscritte prima di essere mostrate al modello (miglioramento del prompt).
  • Gli output precedenti del modello possono essere compressi o troncati per risparmiare token, in modo che storie di dialogo più lunghe possano rientrare nella finestra di contesto. Il modo in cui vengono troncati è importante per la qualità.

Come pensare al modello

Il modello è (artificialmente) intelligente. Fare prompting a un modello è più simile a parlare con una persona che a programmare un computer. Il modello costruisce una visione del mondo che si basa esclusivamente su ciò che è presente nel prompt. Più questa visione è completa e coerente, migliori saranno i risultati del modello.

Il modello ci presenta un'interfaccia in linguaggio naturale, che è separata da quella del linguaggio di programmazione in cui si lavora. È utile pensare all'interfaccia del modello di linguaggio (LM) come a un livello di astrazione separato ma reale. Questa interfaccia può essere utilizzata per presentare risultati "happy-path", ma anche per segnalare errori, notificare cambiamenti, ecc. — per comunicare in generale con il modello.

Esempio:
Se il modello chiama uno strumento in modo errato, non generare un'eccezione nel codice del tuo agente. Invece, restituisci un risultato dello strumento che spieghi qual è stato l'errore:

Lo strumento è stato chiamato senza il parametro richiesto xyz

Il modello recupererà e riproverà.

Come valutare i prompt

Di solito è difficile valutare automaticamente i prompt, a meno che l'obiettivo non sia che il modello esegua un compito molto specifico. Si dovrebbero ideare scenari che testino il prompt in vari modi, e anche cercare esempi in cui la modifica del prompt potrebbe causare regressioni. Per un esempio concreto di questi principi di valutazione in azione, si veda come le stesse tecniche di ingegneria dei prompt hanno spinto Augment Code al punteggio open-source numero 1 su SWE-bench.

Consigli per l'ingegneria dei prompt

Segui questi consigli e sbloccherai l'AGI.

Concentrati prima sul contesto

Il fattore più importante nell'ingegneria dei prompt è fornire al modello il miglior contesto possibile: le informazioni fornite dall'utente (in contrapposizione al testo del prompt fornito da noi). Questo è il segnale principale che il modello utilizza per eseguire il suo compito.

I modelli attuali sono bravi a trovare pezzi pertinenti di contesto utile all'interno di prompt di grandi dimensioni, quindi in caso di dubbio, propendi per fornire più informazioni se ciò aumenta la probabilità che il contesto includa informazioni utili e rilevanti. La prima domanda da porsi riguardo a un prompt è: contiene tutte le informazioni rilevanti, e con quale probabilità? Rispondere a questa domanda non è sempre banale.

Esempio:
Quando si troncano output di comando lunghi per fornirli al modello, il metodo di troncamento è importante. Tipicamente, il troncamento di testi lunghi comporta il troncamento del suffisso. Tuttavia, per gli output di comando, le informazioni utili hanno maggiori probabilità di apparire nel prefisso e nel suffisso che nel mezzo. Ad esempio, gli stack trace da crash generalmente appaiono nel suffisso. Pertanto, per massimizzare la probabilità che il modello ottenga il contesto più rilevante, è meglio troncare il centro degli output di comando piuttosto che il suffisso.

Presenta un quadro completo del mondo

Aiuta il modello a entrare nella giusta mentalità spiegando l'ambiente in cui opera e fornendo dettagli che potrebbero essergli utili per funzionare bene. Ad esempio, se vuoi che il modello agisca come uno sviluppatore software, diglielo nel prompt di sistema. Spiegagli a quali risorse ha accesso e come dovrebbe usarle.

Ad esempio, queste due righe sono state introdotte nel prompt di sistema all'inizio dello sviluppo dell'agente Augment e ne hanno migliorato drasticamente le prestazioni:

Sei un assistente AI, con accesso alla base di codice dello sviluppatore.
Puoi leggere e scrivere nella base di codice utilizzando gli strumenti forniti.

Sii coerente tra i componenti del prompt

Assicurati che tutti i componenti del prompt (prompt di sistema, definizioni degli strumenti, ecc.), così come le definizioni degli strumenti sottostanti, siano coerenti.

Esempio:
Il prompt di sistema include la riga
La directory corrente è $CWD
Lo strumento execute_command, che consente all'agente di eseguire comandi shell, include un parametro opzionale cwd. La coerenza implica che il valore predefinito di questo parametro dovrebbe essere $CWD. Questo può essere specificato nella definizione dello strumento. Se non lo è, il modello probabilmente lo assumerà.

Lo strumento read_file accetta un parametro di percorso del file da leggere. Se fornito con un percorso relativo, dovrebbe essere interpretato come relativo a $CWD.

💡 Nota: Evita di sorprendere il modello.

I modelli si confondono facilmente. Se il modello si aspetta probabilmente un certo risultato da una chiamata a uno strumento, assicurati di fornire quel risultato, o di spiegare la deviazione nel risultato dello strumento. Ad esempio, se la definizione dello strumento promette di restituire un output di una certa lunghezza, restituisci un output di quella lunghezza, o premetti alla risposta una dichiarazione come:

È stato richiesto un output di lunghezza N, ma si sta restituendo un output di lunghezza K invece perché...

Esempio:
Se il prompt contiene uno stato che può cambiare durante una sessione (ad esempio, l'ora corrente), non includerlo nel prompt di sistema o nelle definizioni degli strumenti. Invece, informa il modello del cambiamento nel messaggio utente successivo. Questo mantiene il prompt internamente coerente: il modello può vedere qual era lo stato a ogni turno.

Allinea il modello con la prospettiva dell'utente

Considera la prospettiva dell'utente e cerca di allineare il modello con quella prospettiva.

Esempio: Quando l'utente lavora nell'IDE, al modello può essere presentata una vista dettagliata dello stato dell'IDE, concentrandosi sugli elementi di cui l'utente è più propenso a preoccuparsi o a cui fare riferimento nelle sue istruzioni.

Esempi di cose che possono potenzialmente aiutare ad allineare il modello:

  • L'ora e il fuso orario corrente dell'utente
  • La posizione corrente dell'utente
  • La cronologia delle attività dell'utente

Esempio di un prompt di sistema di base che include lo stato dell'IDE:

L'utente lavora in un IDE. Lo stato corrente dell'IDE:
Il file foo.py è aperto.
L'IDE è di tipo VSCode.

Esempio di un prompt di sistema più dettagliato che descrive lo stato dell'IDE:

L'utente lavora in un IDE. Lo stato corrente dell'IDE:
L'IDE è di tipo VSCode.
Il file attualmente aperto è foo.py.
Le righe dalla 134 alla 179 sono visibili sullo schermo.
Ecco il testo attualmente visibile, con la posizione del cursore indicata da <CURSOR>:
```python
134 def bar():
135 print("hell<CURSOR>o")
...
179 # TODO implement this
```
Non c'è testo selezionato.
Ci sono 14 schede aperte. Ecco le schede dalla più recente alla meno recente visitata:
foo.py
bar.py ...
xyz.py

💡 Nota:
Questo non suggerisce che uno di questi prompt sia necessariamente migliore dell'altro. Il potenziale svantaggio del prompt dettagliato è che il modello potrebbe iniziare a prestare troppa attenzione allo stato dell'IDE, che non è sempre il segnale migliore per ciò che l'utente sta cercando di fare.

Sii accurato

I modelli traggono beneficio da prompt accurati. Non preoccuparti