Programmare con chatGPT e modelli simili

Programmare con chatGPT e modelli simili

Condividi con i tuoi amici...

Facciamo subito una premessa importante:

ChatGPT non è un programmatore, ma può diventare un buon assistente alla programmazione.

Allo stato attuale delle cose, il miglior approccio per programmare con chatGPT o modelli affini è quello collaborativo e conversazionale accompagnato dall’impiego di qualche prompt e system messages predefiniti.

Non si raggiungono quasi mai obiettivi che richiedono una programmazione complessa in un colpo solo, con un solo prompt. Il chatbot commette molti errori, ma non sappiamo se ne commette di più o di meno rispetto ad un assistente umano ipoteticamente seduto al nostro fianco. Sicuramente un tale assistente in carne ed ossa ci costerebbe molto di più, quindi è probabile che con il giusto approccio il nostro assistente virtuale possa costituire la soluzione maggiormente sostenibile.

Personalmente, tendo a mantenere sotto il mio totale controllo la pianificazione generale del programma e gli obiettivi principali, però resta una scelta personale. È sempre possibile chiedere al chatbot di fornire delle idee su come impostare il lavoro e di stabilire degli obiettivi generali, ma spesso capita che questi siano già fissati e che il chatbot risulta molto più utile per indicarci come raggiungere passo dopo passo tali obiettivi.

“Passo dopo passo” è l’espressione che meglio descrive l’approccio da adottare per interagire con il chatbot. La lunghezza di questi passi è discrezionale e va stabilita caso per caso in base agli errori che il chatbot commette.

Autocorrezione

Se chiediamo al chatbot di creare una funzione che svolga un certo compito, il chatbot ci fornirà il codice per testarla subito. Se funziona non ci resta che adottarlo, dopo esserci impegnati almeno un po’ per comprenderlo. Se non funziona possiamo sottoporre il problema al chatbot che, dopo le solite scuse, ci fornirà una spiegazione del fallimento e una soluzione alternativa. Questo ciclo di tentativi ed errori o di autocorrezione potrebbe ripetersi per un po’, ma se i tempi che richiede non sono molto lunghi può valer la pena eseguirlo in quanto entro un certo numero di iterazioni il modello potrebbe trovare da solo la soluzione. Per esempio, il modulo Code Interpreter di GPT4 compie autonomamente questo ciclo e cerca di giungere alla soluzione in un certo numero di passi. Se giunge alla soluzione non ci resta che capire il codice ed inserirlo nel nostro programma.

Con il crescere della complessità del programma sarà sempre più difficile dare tutte le informazioni complete al chatbot affinché risolva problemi particolari che richiedono in tutto o in parte la comprensione del contesto del programma. D’altra parte è possibile dare in pasto al chatbot delle parti di codice più ampie affinché comprenda tale contesto. Evitiamo di incollare sovrascrivendo senza controllo sul nostro editor il codice che ci fornisce, soprattutto quello che coinvolge parti già funzionanti in modo soddisfacente. Verifichiamo sempre i cambiamenti apportati. Il modello potrebbe modificare codice da lui stesso creato in passato, migliorandolo o addirittura peggiorandolo. Non pensiamo di avere a che fare con un modello che ricorda ciò che ha fatto. Non è in grado di riconoscere il proprio operato se non all’interno della stessa conversazione.

A volte può essere utile continuare ad interagire nell’ambito della stessa conversazione. Altre volte è meglio un “cambio di passo” e avviarne una nuova sottoponendo una richiesta formulata in modo diverso rispetto alla precedente. Il contesto può essere utile quando siamo sulla strada giusta, ma se ci stiamo allontanando dalla soluzione potrebbe condizionarlo negativamente imprigionandoci in un loop infinito di tentativi ed errori che probabilmente non porterà a nessuna soluzione.

Se il chatbot non riesce a fornirci un codice soddisfacente dopo diversi cicli di tentativi ed errori, diventa fondamentale comprendere bene il procedimento che segue. Si può chiedere al modello stesso di fare una descrizione step by step dell’algoritmo con spiegazione accurata. Nell’ambito di una nuova conversazione si può sottoporre una richiesta di nuovo codice per ogni step separatamente. Può essere utile chiedere di offrire soluzioni alternative che non si avvalgono di certe istruzioni che generano errore.

Se sappiamo già che la programmazione necessaria sarà complessa possiamo procedere sin da subito step by step aggiungendo una funzione alla volta e solo dopo che le funzioni precedenti siano state implementate e testate.

Se, per esempio, si desidera creare una pulsantiera i cui bottoni attivano funzioni che agiscono su uno stesso oggetto, testo o immagine modificandoli anche in funzione dello stato precedente dell’oggetto, è chiaro che la logica che si cela sotto questo apparentemente semplice task può essere un po’ intricata e, ad oggi (agosto 2023), il modello non riesce in un colpo solo ad offrire una soluzione. Procedere step by step, in questo caso, significa proprio richiedere l’implementazione di un bottone/funzione alla volta seguendo il modello da lui stesso fornito per creare la/e funzione/i precedente/i. Il tutto va fatto nell’ambito della stessa conversazione.

Spesso capita, proprio come avviene tra collaboratori umani, che dopo aver più volte testato senza successo il codice proposto dal chatbot, venga in mente a noi la soluzione migliore. Indicandola al modello, se è davvero una soluzione interessante, otterremo un codice pronto all’uso e ulteriori indicazioni utili.

Ecco alcuni tra i prompt più utilizzati durante il ciclo o nella programmazione step by step:

Il codice: ^codice^ non svolge il compito: ^compito^. Spiega il motivo e riscrivi il codice in modo che svolga correttamente il compito indicato.

Il codice: ^codice^ genera l’errore: ^errore^. Spiega il motivo e trova una soluzione.

(Spesso nella conversazione è sufficiente incollare l’errore)

Genera un codice che esegua il compito: ^compito^

Risolvi i problemi di questo codice: ^codice^

Spiega riga per riga il codice: ^codice^

Spiega l’istruzione ^istruzione^

Riscrivi il seguente codice ^codice^ in modo che svolga anche il compito: ^compito^

A partire da questa funzione ^codice funzione^ integra in essa il compito: ^compito^

Attivando la funzione: ^codice funzione^ ottengo l’output: ^output1^ invece vorrei ottenere: ^output2^. Indica quali modifiche devo fare.