Le Prompting de Zéro à Héro : Guide Complet pour Développeurs avec GitHub Copilot
AI
GitHub Copilot
Productivity
Prompting
Development Tools

Le Prompting de Zéro à Héro : Guide Complet pour Développeurs avec GitHub Copilot

FS
Fernand SOUALO
|
16 min read

Le Prompting de Zéro à Héro : Guide Complet pour Développeurs

Table of Contents

  1. Pourquoi le prompting est une compétence technique
  2. Les fondamentaux du prompting
  3. Techniques intermédiaires
  4. Techniques avancées
  5. Application à GitHub Copilot
  6. Templates réutilisables
  7. Erreurs courantes et corrections
  8. Workflow complet d'un projet
  9. Conclusion

Pourquoi le prompting est une compétence technique

Le prompting n'est pas un art mystique. C'est une compétence d'ingénierie : structurée, reproductible, et mesurable.

Un bon prompt, c'est comme une bonne spécification technique. Il définit :

  • Quoi construire (l'objectif)
  • Comment le construire (les contraintes)
  • Pourquoi le construire ainsi (le contexte)
  • Quand c'est terminé (les critères de validation)

La différence entre un prompt qui produit du code poubelle et un prompt qui produit du code production-ready tient souvent en 30 secondes de réflexion supplémentaire.

Les fondamentaux du prompting

Le modèle CRAC

Tout prompt technique efficace suit la structure CRAC :

C — Contexte : Où se situe la tâche dans le projet ?

"Dans mon application Next.js 15 avec App Router, j'utilise Prisma
avec PostgreSQL et Tailwind CSS pour le styling."

R — Rôle : Quel type d'expertise est nécessaire ?

"Tu es un expert en performance web et en optimisation React."

A — Action : Que faut-il faire précisément ?

"Optimise le composant ProductList qui re-render à chaque
changement de filtre, même quand les données ne changent pas."

C — Contraintes : Quelles sont les limites ?

"Ne change pas l'API publique du composant. Garde la
compatibilité avec les tests existants. Utilise React.memo
et useMemo uniquement là où c'est mesurablement bénéfique."

Le principe de parcimonie

Plus un prompt est précis, meilleur est le résultat.

Markdown
## ❌ Prompt vague

"Crée un composant de pagination"

## ✅ Prompt précis

"Crée un composant Pagination dans components/ui/pagination.tsx :

- Props : currentPage, totalPages, onPageChange
- Affiche max 7 boutons avec ellipsis (...) au milieu
- Boutons Précédent/Suivant désactivés aux extrêmes
- Style : shadcn/ui Button variant outline
- Accessible : aria-label sur chaque bouton, aria-current sur la page active
- Ne re-render pas si les props n'ont pas changé"

Le pouvoir des exemples : Few-Shot Prompting

Montrer ce qu'on veut est souvent plus efficace que de le décrire :

Markdown
"Génère des tests pour la fonction calculateShipping().
Voici le pattern à suivre :

describe('calculateShipping', () => {
it('should return free shipping for orders over 50€', () => {
expect(calculateShipping({ total: 75, weight: 2 })).toEqual({
cost: 0,
method: 'standard',
label: 'Livraison gratuite'
});
});

// Génère des tests pour :
// - Commande < 50€ avec poids < 5kg
// - Commande < 50€ avec poids > 5kg (surcharge poids)
// - Livraison express
// - Adresse internationale vs domestique
// - Panier vide (edge case)
});"

L'IA voit le pattern (structure du test, convention de nommage, format du résultat) et le reproduit.

La hiérarchie d'information

L'ordre des informations dans un prompt compte. L'IA accorde plus d'attention :

  1. Aux instructions système (rôle, contexte global)
  2. Au début du prompt (objectif principal)
  3. À la fin du prompt (dernières instructions — effet de récence)
  4. Au milieu du prompt (détails — zone la moins attentive)

Conséquence pratique : Mettez l'objectif en premier, les contraintes critiques en dernier, et les détails au milieu.

Techniques intermédiaires

Chain-of-Thought (CoT)

Demander à l'IA de raisonner étape par étape avant de coder produit systématiquement de meilleur résultat :

Markdown
"Avant d'écrire le code, analyse étape par étape :

1. Identifie les types de données en entrée et en sortie
2. Liste les edge cases possibles
3. Propose l'algorithme en pseudo-code
4. Implémente en TypeScript
5. Ajoute la gestion d'erreurs"

Prompting par contraintes négatives

Dire ce qu'on ne veut PAS est souvent aussi utile que dire ce qu'on veut :

Markdown
"Implémente un système de cache.

NE PAS :

- Utiliser de bibliothèque externe
- Stocker en mémoire globale (pas de variable module-level)
- Ignorer la gestion de la mémoire (max size)
- Oublier la thread-safety
- Utiliser any ou unknown sans assertion"

Le pattern "Avant/Après"

Pour le refactoring, montrer l'état actuel et décrire l'état souhaité :

TypeScript
// AVANT (actuel) :
function getUser(id: string) {
  const response = fetch(/api/users/);
  return response.json();
}

// APRÈS (souhaité) :
// - Typage strict avec interface User
// - Gestion d'erreurs (404, 500, network)
// - Retry automatique avec backoff exponentiel
// - Cache en mémoire avec TTL de 5 minutes
// - Logging des temps de réponse

Décomposition structurée

Pour les tâches complexes, décomposez explicitement :

Markdown
"Implémente un système de notifications en 4 phases :

Phase 1 — Le modèle de données :

- Table Notification (id, userId, type, title, body, read, createdAt)
- Migration Prisma

Phase 2 — Le service :

- NotificationService avec create(), markAsRead(), getUnread()
- Support des types : info, warning, error, success

Phase 3 — La route API :

- GET /api/notifications — liste avec pagination
- PATCH /api/notifications/:id/read — marquer comme lu
- Authentification requise

Phase 4 — Le composant UI :

- NotificationBell avec badge de count
- Dropdown avec liste des notifications
- Mark-all-as-read
- Temps relatif (il y a 5 min)"

Techniques avancées

Meta-prompting

Demandez à l'IA de vous aider à mieux prompter :

"Je veux implémenter un système de permissions RBAC.
Avant de coder, pose-moi les 10 questions les plus
importantes pour bien comprendre mes besoins."

L'IA va vous demander des précisions sur la hiérarchie des rôles, l'héritage de permissions, la granularité, le multi-tenant... Des questions que vous n'auriez peut-être pas anticipées.

Self-Consistency

Demandé à l'IA de produire plusieurs solutions et de choisir la meilleure :

Markdown
"Propose 3 approches différentes pour implémenter la pagination
côté serveur avec Prisma :

1. Offset-based (LIMIT/OFFSET)
2. Cursor-based
3. Keyset pagination

Pour chacune, donne :

- Le code Prisma
- Les performances sur 1M de lignes
- Les limites connues
- Quand l'utiliser

Puis recommande la meilleure approche pour mon cas d'usage :
une API publique avec tri dynamique et 100k+ résultats possibles."

Prompt Chaining

Enchaîner des prompts où chaque résultat nourrit le suivant :

Prompt 1: "Analyse ce schéma Prisma et identifie les problèmes
           de performance potentiels"
→ Résultat : liste de 5 problèmes identifiés

Prompt 2: "Pour le problème #3 (N+1 queries sur la relation
           User→Posts), propose un fix avec les index appropriés
           et le code Prisma optimisé"
→ Résultat : code corrigé

Prompt 3: "Écris un test de performance qui vérifie que le fix
           réduit le nombre de queries de N+1 à 2"
→ Résultat : test complet

Le pattern "Persona Expert"

Activer un domaine d'expertise spécifique :

Markdown
"En tant qu'expert en sécurité applicative (OWASP Top 10),
analyse cette route API et identifie toutes les vulnérabilités :

export async function POST(req: Request) {
const { email, password } = await req.json();
const user = await db.user.findFirst({
where: { email, password }
});
if (user) {
const token = jwt.sign({ id: user.id }, 'secret123');
return Response.json({ token });
}
return Response.json({ error: 'Invalid' }, { status: 401 });
}"

L'IA va identifier : mot de passe en clair, secret JWT hardcodé, pas de rate limiting, pas de validation d'input, timing attack possible, message d'erreur trop vague ou trop précis, pas de HTTPS enforcement...

Application à GitHub Copilot

Configurer son environnement

1. Instructions personnalisées

Créez .github/copilot-instructions.md à la racine de votre projet :

Markdown
# Instructions pour GitHub Copilot

## Stack technique

- Next.js 15.2+ avec App Router
- TypeScript strict mode
- Prisma avec PostgreSQL
- Tailwind CSS v4 + shadcn/ui
- Zod pour la validation

## Conventions de code

- Fichiers en kebab-case, composants en PascalCase
- Server Components par défaut
- 'use client' uniquement quand nécessaire
- Pas de 'any' — utilise 'unknown' avec type guards
- Erreurs typées avec des classes Error custom
- Imports absolus avec @/ prefix

## Patterns obligatoires

- Server Actions pour les mutations
- Zod schemas dans lib/validators/
- Error boundaries par route segment
- Loading.tsx et error.tsx pour chaque route
- Suspense pour les données asynchrones

## Interdictions

- Pas de CSS-in-JS ni de styles inline
- Pas d'appels DB directs dans les composants
- Pas de useEffect pour le fetch de données
- Pas de console.log en code committé

2. Fichiers de contexte spécialisés

Pour les features complexes, ajoutez des fichiers .md dans le dossier concerné :

Markdown
# features/payments/ARCHITECTURE.md

## Flow de paiement

1. User clique "Payer" → Client Component
2. Appel Server Action createCheckoutSession()
3. Stripe.checkout.sessions.create()
4. Redirect vers Stripe Checkout
5. Webhook POST /api/webhooks/stripe
6. Mise à jour status commande en DB
7. Email de confirmation via Resend

Patterns Copilot efficaces

Commentaires directifs

Les commentaires au-dessus du code guident Copilot pour l'autocomplétion :

TypeScript
// Validate email format, check for disposable domains,
// normalize to lowercase, trim whitespace
function validateEmail(email: string): ValidationResult {
  // Copilot comprend exactement quoi implémenter
}

Signature-first

Écrire la signature complète avant le corps donne le meilleur résultat en autocomplétion :

TypeScript
/**
 * Calculate the optimal shipping cost based on weight,
 * destination zone, and current promotions.
 *
 * @throws {InvalidWeightError} if weight <= 0
 * @throws {UnknownZoneError} if zone is not in the supported list
 */
function calculateShipping(
  weight: number,
  zone: ShippingZone,
  promotions: Promotion[],
): ShippingResult {
  // Copilot a maintenant assez de contexte pour générer
  // une implémentation de qualité
}

Test-driven completion

Écrivez le describe et le premier test, Copilot génère les suivants :

TypeScript
describe("parseMarkdown", () => {
  it("should convert **bold** to <strong>", () => {
    expect(parseMarkdown("**hello**")).toBe("<strong>hello</strong>");
  });

  // Positionnez le curseur ici
  // Copilot va proposer les tests pour italic, links, headers...
});

Copilot Chat : techniques avancées

Commandes slash

Les commandes slash accèdent à des fonctionnalités spécialisées :

  • /explain — Explique le code sélectionné en profondeur
  • /fix — Propose un fix pour les erreurs de compilation
  • /tests — Génère des tests pour le code sélectionné
  • /doc — Génère la documentation JSDoc

Références de contexte

Utilisez # pour référencer des éléments du workspace :

#file:src/services/auth.ts Explique le flow d'authentification

@workspace Trouve tous les endroits où on gère les erreurs
de paiement

#selection Refactor ce code pour utiliser le pattern Strategy

Le mode Agent

Le mode Agent de Copilot transforme l'assistant en agent autonome :

"Ajoute un système de favoris pour les articles du blog.
- Modèle Prisma : table Favorite (userId, articleSlug, createdAt)
- Server Action : toggleFavorite(slug)
- Composant : FavoriteButton avec état optimistic
- API : GET /api/favorites pour la liste des favoris de l'utilisateur
- Intégration dans la page article existante"

L'agent va :

  1. Modifier le schéma Prisma
  2. Générer la migration
  3. Créer le Server Action
  4. Créer le composant client
  5. Créer la route API
  6. Modifier la page article
  7. Vérifier que le build passe

Copilot en pratique : exemples réels

Exemple 1 : Créer un hook custom

TypeScript
// Prompt dans Copilot Chat :
// "Crée un hook useDebounce<T>(value: T, delayMs: number): T
//  qui retourne la valeur debouncée. Inclus le cleanup
//  du timeout, le support de la generic, et un test."

// Copilot génère :
import { useState, useEffect } from "react";

export function useDebounce<T>(value: T, delayMs: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delayMs);

    return () => clearTimeout(timer);
  }, [value, delayMs]);

  return debouncedValue;
}

Exemple 2 : Server Action avec validation

TypeScript
// "Crée une Server Action updateProfile avec :
//  - Validation Zod (name: 2-50 chars, bio: max 500 chars)
//  - Vérification que l'utilisateur est authentifié
//  - Mise à jour via Prisma
//  - Revalidation du cache
//  - Gestion d'erreurs typée"

"use server";

import { z } from "zod";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/db";
import { revalidatePath } from "next/cache";

const updateProfileSchema = z.object({
  name: z.string().min(2).max(50),
  bio: z.string().max(500).optional(),
});

export async function updateProfile(formData: FormData) {
  const session = await auth();
  if (!session?.user) {
    throw new Error("Non authentifié");
  }

  const validated = updateProfileSchema.parse({
    name: formData.get("name"),
    bio: formData.get("bio"),
  });

  await prisma.user.update({
    where: { id: session.user.id },
    data: validated,
  });

  revalidatePath("/profile");
  return { success: true };
}

Exemple 3 : Composant complexe

// "Crée un composant DataTable réutilisable avec :
//  - Tri par colonnes (asc/desc/none)
//  - Pagination (10/25/50 par page)
//  - Recherche globale avec debounce 300ms
//  - Sélection de lignes avec checkbox
//  - Actions en batch sur la sélection
//  - Skeleton loading state
//  - Empty state avec illustration
//  - Responsive : cards sur mobile, table sur desktop
//  - TypeScript generics pour les colonnes typées"

Templates réutilisables

Template : Nouvelle feature

Markdown
## Feature : [Nom]

### Contexte

[Pourquoi cette feature ? Quel problème résout-elle ?]

### Spécification

[Description précise du comportement attendu]

### Modèle de données

[Schéma Prisma ou interfaces TypeScript]

### Routes/Actions

[Endpoints API ou Server Actions nécessaires]

### Composants UI

[Liste des composants avec leurs props]

### Validation

[Schémas Zod requis]

### Tests

[Cas de test critiques]

### Critères de complétion

- [ ] Critère 1
- [ ] Critère 2
- [ ] Tests passent
- [ ] Build réussi

Template : Bug fix

Markdown
## Bug : [Description courte]

### Reproduction

1. Aller sur [page]
2. Cliquer sur [élément]
3. Observer [comportement actuel]

### Comportement attendu

[Ce qui devrait se passer]

### Stack trace / Erreur

\\\
[Coller l'erreur ici]
\\\

### Fichiers probablement impliqués

- [fichier1.ts] — parce que [raison]
- [fichier2.ts] — parce que [raison]

### Fix demandé

[Description du fix souhaité + contraintes]

Template : Refactoring

Markdown
## Refactoring : [Composant/Module]

### État actuel

[Problèmes identifiés : dette technique, performance, lisibilité]

### État souhaité

[Architecture cible avec justification]

### Contraintes

- Ne pas casser les tests existants
- Garder la compatibilité API
- [Autres contraintes]

### Plan de migration

1. [Étape 1]
2. [Étape 2]
3. [Étape 3]

### Métriques de succès

- Avant : [métrique]
- Après : [métrique attendue]

Erreurs courantes et corrections

Erreur 1 : Trop de contexte tue le contexte

❌ Trop✅ Juste assez
Copier-coller 10 fichiersRéférencer les 2-3 fichiers clés
Longs historiques de conversationRésumer le contexte pertinent
Copier toute la documentationExtraire les sections pertinentes

Erreur 2 : Prompts ambigus

❌ Ambigu✅ Précis
"Améliore ce code""Réduis la complexité cyclomatique de cette fonction de 12 à moins de 5"
"Ajoute de la sécurité""Ajoute une validation Zod sur les inputs et un rate limit de 100 req/min"
"Rends-le plus rapide""Le rendu initial prend 3s, optimise pour moins de 500ms avec un Suspense boundary"

Erreur 3 : Ignorer le format de sortie

Spécifiez toujours le format attendu :

Markdown
"Analyse ce code et retourne :

1. Un résumé en 2 phrases
2. La liste des problèmes (un par ligne, format: PROBLÈME → SOLUTION)
3. Le code corrigé dans un seul bloc TypeScript
4. Un test qui vérifie la correction"

Erreur 4 : Ne pas itérer

Le premier prompt donne rarement le résultat parfait. Itérez :

Prompt 1: "Implémente la pagination"
→ Code basique OK mais sans gestion d'erreur

Prompt 2: "Ajoute la gestion d'erreur pour les cas :
           page < 1, page > totalPages, pageSize > 100"
→ Code amélioré mais sans tests

Prompt 3: "Ajoute des tests unitaires qui couvrent tous
           les edge cases qu'on vient de gérer"
→ Résultat complet

Workflow complet d'un projet

Voici comment un développeur senior utilise le prompting IA pour une feature complète :

Phase 1 : Planification (10 min)

Markdown
"Je dois implémenter un système de commentaires pour les articles
de blog. Propose une architecture complète incluant :

- Modèle de données (avec replies imbriquées)
- Endpoints nécessaires
- Composants UI
- Considérations de sécurité
- Estimation du temps de développement"

Phase 2 : Modèle de données (5 min)

Markdown
"Crée le schéma Prisma pour Comment avec :

- Relation avec User et Article
- Support des replies (self-referencing)
- Soft delete
- Timestamps"

Vérifier manuellement, ajuster, lancer la migration.

Phase 3 : Backend (15 min)

Markdown
"Crée les Server Actions dans app/blog/[slug]/actions.ts :

- addComment(articleSlug, content, parentId?)
- deleteComment(commentId) — soft delete, auteur uniquement
- reportComment(commentId, reason)
  Validation Zod, auth requise, rate limit 10 comments/heure."

Review le code, tester manuellement.

Phase 4 : Frontend (15 min)

Markdown
"Crée le composant CommentSection :

- Affiche les commentaires avec replies imbriquées (max 3 niveaux)
- Formulaire d'ajout avec textarea auto-resize
- Bouton reply sur chaque commentaire
- Optimistic update à l'ajout
- Confirmation avant suppression
- Temps relatif (il y a 5 min)
- Avatar utilisateur
- Skeleton loading
  Utilise shadcn/ui pour les composants de base."

Phase 5 : Tests (10 min)

Markdown
"Génère les tests pour le système de commentaires :

- Actions : ajout, suppression, report, validation
- Composant : affichage, soumission, reply, loading state
- Edge cases : commentaire vide, HTML injection, user non authentifié"

Total : ~55 min pour une feature complète et testée

Sans IA : 4-6 heures. Gain : 5x sur l'implémentation, avec plus de couverture de tests.

Conclusion

Le prompting technique est une compétence qui se développe avec la pratique. Voici les règles d'or :

  1. Soyez spécifique — Chaque mot compte. "Composant accessible avec aria-labels" >> "Composant"
  2. Donnez du contexte — Stack, conventions, patterns existants
  3. Montrez des exemples — Un exemple vaut mille mots
  4. Décomposez — Plusieurs petits prompts > un prompt géant
  5. Itérez — Le premier résultat est un brouillon, pas un produit fini
  6. Vérifiez — L'IA est un junior très rapide encore inconstant, pas un senior infaillible

Le développeur qui maîtrise le prompting ne code pas plus vite. Il résout des problèmes plus vite, avec plus de rigueur, et avec une couverture de cas plus exhaustive.

Commencez chaque prompt par la question : "Qu'est-ce que je sais que l'IA ne sait pas sur mon projet ?" — et écrivez-le en premier.

Cet article vous a été utile ?

16 min read
0 vues
0 j'aime
0 partages