- Publié le
Révolutionnez vos mises à jour de codebase avec o3-mini de ChatGPT : L’avenir du développement automatisé

Révolutionnez vos mises à jour de codebase avec o3-mini de ChatGPT : L’avenir du développement automatisé
Dans cet article, j'explore comment le LLM o3-mini de ChatGPT transforme la manière dont je mets à jour ma codebase. Cette approche innovante rationalise les corrections de bugs et implémente de nouvelles fonctionnalités dans les fichiers Python, JavaScript et de configuration JSON de manière unifiée et semi-automatisée.
Présentation de o3-mini
L'un des principaux atouts de o3-mini est sa grande taille de contexte, qui lui permet de traiter efficacement des codebases entières. o3-mini dispose d'une fenêtre de contexte de 200 000 tokens et d'une sortie maximale de 100 000 tokens (voir le lancement officiel de l'API o3-mini ici). Cela signifie que o3-mini peut prendre en charge plusieurs fichiers source dans une seule invite, permettant une analyse et des modifications complètes du code à travers des fichiers interdépendants. Cela le rend idéal pour les mises à jour à grande échelle de la codebase sans nécessiter d'entrées fragmentées.
Le modèle o3-mini est un modèle de langage léger mais puissant disponible via le navigateur ChatGPT. Il excelle dans l'interprétation des instructions en langage naturel, ce qui le rend parfait pour automatiser les modifications complexes de la codebase. Pour en savoir plus sur les capacités de ChatGPT et ses modèles, visitez ChatGPT.
Mon cas d'utilisation : Utiliser o3-mini pour automatiser les changements de codebase
Mes projets, principalement construits en Python et JavaScript avec quelques fichiers de configuration JSON, avaient besoin d'une méthode fiable pour gérer les modifications de code de manière efficace. Voici comment j'ai procédé :
- Corrections de bugs et ajouts de fonctionnalités : o3-mini analyse toute ma codebase, assurant la cohérence entre les fichiers lors de la résolution de bugs ou de l'ajout de nouvelles fonctionnalités.
- Mises à jour complètes : Au lieu de mettre à jour les fichiers un par un, j'utilise une analyse de l'ensemble de la codebase, permettant au modèle de proposer des changements interdépendants de manière cohérente et unifiée.
L'approche
Mon approche consiste à créer une invite qui inclut l'instruction et l'ensemble du code de la codebase dans un format structuré. Ensuite, j'instruis le modèle pour générer les fichiers modifiés au format JSON. Le modèle o3-mini traite cette invite, et sa réponse est capturée pour appliquer les changements à la codebase.
Cette approche est soutenue par deux scripts :
generate_codebase_prompt.py
: Automatise la création d'une invite structurée qui inclut l'ensemble de la codebase.apply_changes.py
: Analyse la sortie du modèle et met à jour les fichiers correspondants dans la codebase.
Ces scripts Python peuvent être trouvés à la fin de cet article.
Cette méthode offre une manière claire, organisée et évolutive d'appliquer les changements de code de manière cohérente dans l'ensemble du projet.
Le flux de travail
Le diagramme suivant illustre mon flux de travail pour instruire et implémenter les changements dans ma codebase en utilisant o3-mini :

Les sections suivantes décrivent chaque étape du flux de travail en détail.
1. Création d'un instantané de la codebase
J'ai créé un fichier codebase.txt
à la racine du projet qui liste tous les noms de fichiers (avec des chemins relatifs) sur des lignes séparées. Cet instantané est essentiel pour identifier les fichiers à traiter.
2. Génération d'une invite unifiée
J'utilise un script Python appelé generate_codebase_prompt.py
pour automatiser cette étape.
generate_codebase_prompt.py
fonctionne comme suit :
- Lit
codebase.txt
, en ignorant les lignes commençant par#
, pour collecter les chemins de fichiers. - Lit le contenu complet de chaque fichier et gère les erreurs avec élégance si un fichier ne peut pas être lu.
- Construit un tableau JSON où chaque entrée contient le nom du fichier (avec le chemin) et le contenu du fichier, puis l'ajoute à un texte d'invite fixe.
Cette invite demande à o3-mini de ne produire que les fichiers modifiés, en conservant le même nom de fichier (avec le chemin) et le contenu mis à jour. Elle demande au modèle de produire les résultats au format JSON avec une structure donnée. Voici la structure générique de l'invite :
Vous êtes un assistant IA chargé de modifier une codebase en fonction de l'instruction fournie ci-dessus. L'ensemble de la codebase est fourni ci-dessous sous forme de
tableau JSON, où chaque objet représente un fichier avec son chemin relatif et son contenu complet. Votre travail consiste à appliquer l'instruction et à retourner un
objet JSON pur qui inclut uniquement les fichiers modifiés ainsi qu'une brève explication des changements.
L'objet JSON doit avoir exactement deux clés :
- "files" : un tableau d'objets, chacun avec :
- "path" : le chemin relatif du fichier
- "content" : le contenu complet du fichier modifié
- "explanation" : une explication concise des modifications apportées
N'incluez aucun texte, formatage markdown ou commentaire supplémentaire en dehors de cet objet JSON.
Codebase :
...
Pour copier rapidement l'invite générée dans ChatGPT, j'utilise la commande suivante :
python3 generate_codebase_prompt.py ./codebase.txt | xclip -selection clipboard
L'utilisation de xclip
garantit que la sortie est directement placée dans le presse-papiers, me permettant de la coller dans ChatGPT sans étapes supplémentaires. Pour installer xclip
sur Ubuntu, exécutez la commande suivante :
sudo apt update && sudo apt install xclip
3. Interaction avec ChatGPT
En utilisant l'invite générée, j'interagis avec ChatGPT en fournissant une instruction claire.
"Implémentez la nouvelle fonctionnalité..."
ou
"Corrigez cette erreur..."
Après avoir tapé mon instruction, je colle l'invite générée à l'étape précédente avec la codebase, qui est déjà dans mon presse-papiers. La capture d'écran ci-dessous montre l'interaction avec ChatGPT.

4. Exécution de o3-mini et capture de la sortie
J'exécute o3-mini avec l'invite et capture sa sortie dans un fichier texte. Cette sortie contient les changements formatés en JSON, détaillant uniquement les fichiers modifiés. Je copie facilement les résultats à partir du bouton Copier
de ChatGPT et les colle dans un fichier texte que j'utiliserai à l'étape suivante. La capture d'écran ci-dessous montre la sortie de o3-mini et le bouton Copier.

5. Mise à jour de la codebase
J'utilise le script Python apply_changes.py
pour appliquer les changements générés par ChatGPT. Ce script traite un fichier JSON contenant les fichiers modifiés et leur nouveau contenu, puis met à jour ou crée les fichiers en conséquence. Il garantit que les répertoires nécessaires existent, écrit le nouveau contenu et enregistre les changements.
Pour exécuter le script, j'utilise la commande suivante, où inputs.txt
est le fichier dans lequel j'ai capturé la sortie de ChatGPT à l'étape précédente.
python3 apply_changes.py ./inputs.txt
Exemple de sortie du script de mise à jour :
Mis à jour : ./app/[locale]/top/page.tsx
Mis à jour : ./components/navigation/Header.tsx
Nombre total de fichiers mis à jour : 2
6. Vérification des changements et tests
Après avoir appliqué les changements, j'exécute git diff
pour examiner toutes les modifications, m'assurant qu'elles correspondent aux mises à jour prévues. Enfin, j'exécute quelques tests pour confirmer que tout fonctionne.
Cas pratiques : Projet de blog Next.js
Le projet que j'évalue pour les mises à jour de la codebase dans cet article est un projet de blog Next.js. Voici quelques métriques clés concernant le projet :
Métrique | Valeur |
---|---|
Fichiers | ~130 |
LOC | ~13,000 |
Langages | TS, JS, JSON |
Frameworks | Next.js, React, Tailwind CSS |
Voici plusieurs cas pratiques où j'applique ces mises à jour automatisées à ce projet de blog Next.js.
Instruction 1
Pour améliorer l'expérience utilisateur, j'ai décidé d'ajouter une nouvelle entrée de menu appelée Top à gauche de "Blog" dans l'en-tête de la page d'accueil.
Dans l'en-tête de la page d'accueil, ajoutez une nouvelle entrée de menu à gauche de "Blog", appelée Top (avec un T majuscule). Considérez qu'il s'agit d'un blog multilingue, et que toutes les étiquettes du menu supérieur ont des traductions par langue. Implémentez quelque chose d'équivalent pour Top de sorte que dans toutes les langues l'étiquette reste Top. Lorsque vous appuyez sur Top, les entrées de post en vedette seront affichées.
Ce changement a introduit une erreur, que j'ai abordée à l'étape suivante.
Instruction 2
Après avoir implémenté la nouvelle entrée de menu, j'ai rencontré une erreur liée à la gestion des routes dynamiques dans Next.js. J'ai instruit le modèle pour corriger l'erreur.
Lorsque j'appuie sur Top, j'obtiens cette erreur. Corrigez-la. Erreur : La route "/[locale]/top" a utilisé params.locale. params doit être attendu avant d'utiliser ses propriétés. En savoir plus : https://nextjs.org/docs/messages/sync-dynamic-apis à locale (app/[locale]/top/page.tsx:13:10) 11 | 12 | export default async function TopPage({ params }: PageProps) { 13 | const { locale } = params | ^ 14 | const sortedPosts = sortPosts(allBlogs) 15 | const posts = allCoreContent(sortedPosts) 16 | const featuredPosts = posts.filter((p) => p.language === locale && p.featured === true)
À ce stade, la nouvelle fonction a fonctionné comme prévu.
Instruction 3
Pour améliorer l'expérience utilisateur, j'ai décidé de supprimer la limitation d'affichage de seulement deux posts en vedette lors de la sélection de Top.
Lors de la sélection de Top, tous les posts en vedette seront affichés. Actuellement, il y a une limitation de deux. Cependant, sur la page principale, vous ne garderez qu'un maximum de deux posts en vedette comme implémenté actuellement.
Le changement a fonctionné comme prévu.
Instruction 4
Lors du processus de construction, j'ai rencontré une erreur de formatage liée à Prettier. J'ai instruit le modèle pour corriger l'erreur.
Corrigez cette erreur Linting et vérification de la validité des types .. ⚠ Les références de projet TypeScript ne sont pas entièrement prises en charge. Tentative de construction en mode incrémental. Échec de la compilation. ./app/[locale]/top/page.tsx 18:38 Erreur : Remplacez p par (p) prettier/prettier ./components/navigation/Header.tsx 59:53 Erreur : Remplacez {link.title·===·'Top'·?·'Top'·:·t(link.title.toLowerCase())} par ⏎······················{link.title·===·'Top'·?·'Top'·:·t(link.title.toLowerCase())}⏎···················· prettier/prettier info - Besoin de désactiver certaines règles ESLint ? En savoir plus ici : https://nextjs.org/docs/app/api-reference/config/eslint#disabling-rules
L'erreur de formatage a été corrigée.
Conclusion
L'utilisation de o3-mini pour analyser et mettre à jour une codebase entière offre plusieurs avantages :
- Vue d'ensemble : Le LLM prend en compte le tableau général, proposant des changements qui tiennent compte des dépendances entre plusieurs fichiers.
- Cohérence : Les mises à jour automatisées garantissent que les modifications interdépendantes sont appliquées de manière uniforme.
- Efficacité : Bien que le temps de traitement dépende de la taille de la codebase, le flux de travail global est rapide et efficace.
- Flux de travail de développement amélioré : Cette méthode minimise l'intervention manuelle, réduit les erreurs et accélère à la fois les corrections de bugs et les implémentations de fonctionnalités.
En donnant au modèle accès à une codebase complète, j'ai rationalisé mon processus de développement et démontré que les mises à jour automatisées et unifiées peuvent être plus intelligentes et plus cohérentes que la gestion des fichiers individuellement.
Les modèles avec des fenêtres de contexte étendues et des limites de sortie accrues, comme o3-mini, permettent cette approche.
Prochaines étapes
Je n'ai pas utilisé o3-mini-high pour ces exemples, mais l'approche reste valide. À l'avenir, je prévois d'évaluer également ce modèle pour comparer son efficacité et ses performances dans l'automatisation des mises à jour de la codebase.
L'étape naturelle suivante sera de construire un outil qui automatise ce flux de travail en utilisant l'API o3-mini. Cet outil suivrait l'approche structurée décrite dans cet article, permettant des modifications de codebase transparentes tout en s'intégrant directement à un dépôt Git pour valider les mises à jour de manière efficace. En utilisant o3-mini via l'API, le processus peut être entièrement automatisé, réduisant l'intervention manuelle et garantissant des améliorations structurées et contrôlées en version à travers les projets.
Scripts Python
Voici les scripts Python utilisés dans ce flux de travail. Ces scripts automatisent le processus de génération d'invites et d'application des changements à la codebase, rendant le flux de travail efficace et évolutif.
generate_codebase_prompt.py
Ce script lit une liste de chemins de fichiers, extrait leur contenu et les formate dans une invite structurée qui peut être utilisée avec un LLM pour analyser et modifier la codebase.
"""
generate_codebase_prompt.py
================
Description:
Ce script lit un fichier contenant des chemins de fichiers (un par ligne), en ignorant toute ligne
qui commence par le caractère '#'. Pour chaque chemin de fichier valide, il lit le contenu complet du fichier
et construit un tableau JSON où chaque élément est un objet contenant le "path" et le "content" du fichier. Ce tableau JSON est ajouté à un texte d'invite fixe destiné
à être utilisé avec un modèle de langage (LLM) pour modifier la codebase en fonction d'une instruction ajoutée manuellement.
Usage:
python generate_codebase_prompt.py <file_with_paths>
Où :
<file_with_paths> est un fichier texte contenant une liste de chemins de fichiers (un par ligne).
Example:
Étant donné un fichier d'entrée 'paths.txt' avec le contenu suivant :
/path/to/file1.txt
# /path/to/file2.txt
Exécution :
python generate_codebase_prompt.py paths.txt
Produit une sortie (sur la sortie standard) similaire à :
=== PROMPT ===
Vous êtes un assistant IA chargé de modifier une codebase en fonction de l'instruction fournie ci-dessus.
L'ensemble de la codebase est fourni ci-dessous sous forme de tableau JSON, où chaque objet représente un fichier avec son
chemin relatif et son contenu complet. Votre travail consiste à appliquer l'instruction et à retourner un objet JSON pur qui inclut uniquement les fichiers modifiés ainsi qu'une brève explication des changements.
L'objet JSON doit avoir exactement deux clés :
- "files" : un tableau d'objets, chacun avec :
- "path" : le chemin relatif du fichier
- "content" : le contenu complet du fichier modifié
- "explanation" : une explication concise des modifications apportées
N'incluez aucun texte, formatage markdown ou commentaire supplémentaire en dehors de cet objet JSON.
Codebase :
[
{
"path": "/path/to/file1.txt",
"content": "contenu complet de file1..."
},
...
]
"""
import sys
import json
def generate_codebase_json(file_with_paths):
"""
Lit un fichier d'entrée contenant des chemins de fichiers et génère une liste de dictionnaires,
chacun représentant un fichier avec son "path" et son "content" complet.
La fonction ignore les lignes vides et les lignes commençant par '#' (traitées comme des commentaires).
Si une erreur survient lors de la lecture d'un fichier, le message d'erreur est stocké dans le champ "content"
du dictionnaire correspondant.
Args:
file_with_paths (str): Chemin vers le fichier texte contenant les chemins de fichiers.
Returns:
list: Une liste de dictionnaires avec les clés "path" et "content".
Exits:
Met fin au script avec un code de statut 1 si le fichier d'entrée ne peut pas être lu.
"""
codebase = []
try:
with open(file_with_paths, 'r') as f:
for line in f:
filepath = line.strip()
# Ignorer les lignes vides et les lignes commentées
if not filepath or filepath.startswith("#"):
continue
try:
with open(filepath, 'r', encoding="utf-8") as file_content:
content = file_content.read()
codebase.append({"path": filepath, "content": content})
except Exception as e:
# Si une erreur survient lors de la lecture du fichier, enregistrez le message d'erreur comme contenu
codebase.append({"path": filepath, "content": f"Error reading file: {e}"})
return codebase
except Exception as e:
print(f"Error reading input file {file_with_paths}: {e}")
sys.exit(1)
def print_prompt_with_codebase(codebase):
"""
Construit et imprime une invite complète destinée à un LLM. L'invite se compose de
un texte d'instruction fixe suivi d'un tableau JSON de la codebase.
Le texte d'invite fixe instruit le LLM de modifier la codebase en fonction d'une instruction ajoutée
manuellement et de produire un objet JSON avec deux clés : "files" et "explanation".
Args:
codebase (list): Une liste de dictionnaires où chaque dictionnaire contient le "path" et
"content" d'un fichier.
"""
# Texte d'invite fixe (l'instruction manuelle est censée être ajoutée avant ce texte)
prompt_text = (
"Vous êtes un assistant IA chargé de modifier une codebase en fonction de l'instruction fournie ci-dessus. "
"L'ensemble de la codebase est fourni ci-dessous sous forme de tableau JSON, où chaque objet représente un fichier avec son chemin relatif "
"et son contenu complet. Votre travail consiste à appliquer l'instruction et à retourner un objet JSON pur qui inclut uniquement les "
"fichiers modifiés ainsi qu'une brève explication des changements.\n\n"
"L'objet JSON doit avoir exactement deux clés :\n"
" - \"files\" : un tableau d'objets, chacun avec :\n"
" - \"path\" : le chemin relatif du fichier\n"
" - \"content\" : le contenu complet du fichier modifié\n"
" - \"explanation\" : une explication concise des modifications apportées\n\n"
"N'incluez aucun texte, formatage markdown ou commentaire supplémentaire en dehors de cet objet JSON.\n\n"
"Codebase :"
)
# Convertir la liste de codebase en une chaîne JSON avec indentation pour une meilleure lisibilité
codebase_json = json.dumps(codebase, indent=2)
# Produire l'invite complète
print(prompt_text)
print("\n" + codebase_json)
def main():
"""
Fonction principale qui gère les arguments de la ligne de commande et exécute la fonctionnalité du script.
"""
if len(sys.argv) != 2:
print("Usage: python process_files.py <file_with_paths>")
sys.exit(1)
file_with_paths = sys.argv[1]
codebase = generate_codebase_json(file_with_paths)
print_prompt_with_codebase(codebase)
if __name__ == "__main__":
main()
apply_changes.py
Ce script traite la sortie JSON du LLM, met à jour les fichiers correspondants dans la codebase et garantit que les changements sont appliqués de manière cohérente tout en préservant les structures de répertoires.
"""
apply_changes.py
===============
Description:
Ce script lit un fichier JSON fourni en argument de ligne de commande. Le fichier JSON doit contenir
un objet avec une clé "files", qui est un tableau d'objets. Chaque objet du tableau doit
avoir les clés suivantes :
- "path" : le chemin relatif ou absolu du fichier à mettre à jour
- "content" : le contenu complet à écrire dans ce fichier
Le script met à jour ou crée chaque fichier tel que spécifié dans le fichier JSON. Les répertoires nécessaires
sont créés s'ils n'existent pas.
Usage:
python apply_changes.py /path/to/input.json
Example JSON file structure:
{
"files": [
{
"path": "example/file1.txt",
"content": "Ceci est le contenu mis à jour pour file1."
},
{
"path": "example/file2.txt",
"content": "Ceci est le contenu mis à jour pour file2."
}
]
}
"""
import os
import sys
import json
def update_files_from_json(json_file_path):
"""
Lit un fichier JSON et met à jour ou crée des fichiers tels que spécifiés dans l'objet JSON.
Le fichier JSON doit contenir un objet avec une clé "files", qui est un tableau d'objets.
Chaque objet doit avoir :
- "path" : le chemin relatif ou absolu du fichier à mettre à jour
- "content" : le contenu complet à écrire dans ce fichier
La fonction crée les répertoires nécessaires pour les chemins de fichiers s'ils n'existent pas.
Elle imprime un message pour chaque fichier qui est mis à jour et un résumé final du nombre total de fichiers mis à jour.
Args:
json_file_path (str): Le chemin vers le fichier JSON contenant les informations de mise à jour des fichiers.
Exits:
Le script se termine avec le code de statut 1 si le fichier JSON ne peut pas être lu ou s'il ne
contient pas la clé "files" requise.
"""
try:
with open(json_file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
except Exception as e:
print("Error reading JSON file '{}': {}".format(json_file_path, e))
sys.exit(1)
if 'files' not in data:
print("Invalid JSON format: missing 'files' key.")
sys.exit(1)
files_updated = 0
for file_obj in data['files']:
try:
file_path = file_obj['path']
content = file_obj['content']
# Créez les répertoires nécessaires s'ils n'existent pas.
directory = os.path.dirname(file_path)
if directory and not os.path.exists(directory):
os.makedirs(directory, exist_ok=True)
# Écrivez le contenu dans le fichier.
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print("Mis à jour : {}".format(file_path))
files_updated += 1
except Exception as e:
print("Échec de la mise à jour de '{}' : {}".format(file_obj.get('path', 'unknown'), e))
print("Nombre total de fichiers mis à jour : {}".format(files_updated))
def main():
"""
Fonction principale qui gère les arguments de la ligne de commande et déclenche le processus de mise à jour des fichiers.
"""
if len(sys.argv) != 2:
print("Usage: python update_files.py /path/to/input.json")
sys.exit(1)
json_file_path = sys.argv[1]
update_files_from_json(json_file_path)
if __name__ == '__main__':
main()
Avez-vous apprécié cet article ? L'avez-vous trouvé utile ? N'hésitez pas à laisser un commentaire ci-dessous pour partager vos réflexions ou poser des questions. Un compte GitHub est requis pour participer à la discussion.