Il prompt engineering per GitHub Copilot è la disciplina di formulare input — espliciti o impliciti — in modo che il modello generi codice pertinente, corretto e allineato al contesto del progetto. A differenza di un chatbot generico, Copilot opera dentro l’IDE: il suo comportamento dipende tanto da ciò che scrivi nel prompt quanto dal codice già presente attorno al cursore.
I due canali di prompting
Copilot riceve istruzioni attraverso due canali che l’esame distingue con attenzione.
- Prompt espliciti (chat): le richieste in linguaggio naturale che invii a Copilot Chat, inline chat o alla CLI. Qui controlli direttamente istruzione, contesto e vincoli.
- Prompt impliciti (completions): durante le code completions, non digiti un prompt in senso stretto. Il “prompt” è costruito automaticamente da Copilot a partire dal contesto del file — codice sopra e sotto il cursore, nome e tipo del file, import e file aperti nelle tab vicine (neighboring tabs) — e da segnali che tu inserisci deliberatamente: nomi di funzioni e variabili significativi, firme tipizzate e commenti descrittivi.
Capire questa dualità è centrale: un commento come // calcola l'IVA al 22% arrotondando a 2 decimali è a tutti gli effetti un prompt che guida la completion successiva.
I principi fondamentali
Essere specifici
Un prompt vago produce output generico. “Scrivi una funzione di validazione” lascia al modello troppe scelte; “Scrivi una funzione TypeScript validateEmail(email: string): boolean che usi una regex RFC 5322 semplificata e restituisca false su input vuoto” vincola il risultato in modo verificabile. La specificità include linguaggio, firma, tipo di ritorno e comportamento sui casi limite.
Fornire contesto
Il modello lavora meglio quando “vede” il codice rilevante. Strategie pratiche:
- Tenere aperti i file correlati (models, interfacce, helper) perché entrano nel contesto via neighboring tabs.
- In Copilot Chat, usare le references come
#file,#selectiono@workspaceper agganciare esplicitamente il contesto invece di descriverlo a parole. - Includere esempi di input/output attesi quando il comportamento non è ovvio.
Fornire vincoli
Esplicita librerie da usare o evitare, stile, gestione degli errori, performance. “Usa solo la standard library, niente dipendenze esterne” o “gestisci le eccezioni con un Result type” orientano l’output verso le convenzioni del progetto.
Scomporre i task complessi
Copilot rende meglio su unità piccole e coese. Una richiesta monolitica (“costruisci l’intero layer di autenticazione”) va spezzata: prima il modello dati, poi l’hashing della password, poi l’endpoint di login. Questo pattern — task decomposition — riduce le allucinazioni e rende ogni output ispezionabile.
Iterare
Il prompting è un ciclo. Se la prima risposta è imperfetta, si raffina aggiungendo vincoli, correggendo assunzioni o incollando l’errore ottenuto, anziché ripartire da zero. In chat la conversazione mantiene lo stato, quindi i follow-up (“ora aggiungi i test”, “rendi la funzione async”) sfruttano il contesto già stabilito.
Il contesto del file conta quanto il testo
Il punto architetturale più insidioso: puoi scrivere un prompt eccellente e ottenere comunque codice mediocre se il file circostante è disordinato, gli import sono assenti o i nomi sono ambigui. Al contrario, un file ben strutturato con firme tipizzate e commenti mirati produce completions di qualità anche con input minimi. Curare il contesto — non solo il testo del prompt — è parte integrante del prompt engineering.
Trappole tipiche d’esame
- Scenario: lo sviluppatore lamenta completions generiche e fuori tema → Risposta giusta: il prompt è troppo vago e/o manca contesto; aggiungere specificità (firma, vincoli) e aprire i file rilevanti, non “cambiare modello”.
- Scenario: si vuole guidare una completion (non la chat) verso un comportamento preciso → Risposta giusta: inserire un commento descrittivo e nomi/firme significativi sopra il cursore, poiché il commento agisce da prompt implicito.
- Scenario: una richiesta grande e articolata dà risultati incoerenti → Risposta giusta: applicare la task decomposition, scomponendo in sotto-task iterativi, non insistere con un unico prompt.
- Scenario: in Copilot Chat serve far ragionare il modello su file specifici del repo → Risposta giusta: usare le references (
#file,#selection,@workspace), non descrivere il codice a parole. - Scenario: la prima risposta è quasi corretta ma con un bug → Risposta giusta: iterare nel thread fornendo l’errore o un vincolo aggiuntivo, sfruttando il contesto conversazionale, invece di riscrivere il prompt da capo.