Veröffentlicht am

Revolutionieren Sie Ihre Codebase-Updates mit o3-mini von ChatGPT: Die Zukunft der automatisierten Entwicklung

16 min read
Autoren
  • Profile picture of aithemes.net
    Name
    aithemes.net
    Twitter
Post Image

Revolutionieren Sie Ihre Codebase-Updates mit o3-mini von ChatGPT: Die Zukunft der automatisierten Entwicklung

In diesem Beitrag erkunde ich, wie das o3-mini LLM von ChatGPT die Art und Weise verändert, wie ich meine Codebase aktualisiere. Dieser innovative Ansatz rationalisiert Fehlerbehebungen und implementiert neue Funktionen in Python-, JavaScript- und JSON-Konfigurationsdateien auf einheitliche und halbautomatisierte Weise.

Einführung in o3-mini

Eine der Hauptstärken von o3-mini ist seine große Kontextgröße, die es ermöglicht, gesamte Codebases effektiv zu verarbeiten. o3-mini hat ein Kontextfenster von 200.000 Token und eine maximale Ausgabe von 100.000 Token (siehe den offiziellen o3-mini API-Start hier). Dies bedeutet, dass o3-mini mehrere Quelldateien in einer einzigen Eingabeaufforderung aufnehmen kann, wodurch umfassende Codeanalysen und -änderungen über voneinander abhängige Dateien hinweg ermöglicht werden. Dies macht es ideal für groß angelegte Codebase-Updates, ohne dass fragmentierte Eingaben erforderlich sind.

Das o3-mini-Modell ist ein leichtgewichtiges, aber leistungsstarkes Sprachmodell, das über den ChatGPT-Browser verfügbar ist. Es zeichnet sich durch die Interpretation natürlichsprachlicher Anweisungen aus, was es perfekt für die Automatisierung komplexer Codebase-Änderungen macht. Um mehr über die Fähigkeiten von ChatGPT und seinen Modellen zu erfahren, besuchen Sie ChatGPT.

Mein Anwendungsfall: Verwendung von o3-mini zur Automatisierung von Codebase-Änderungen

Meine Projekte, die hauptsächlich in Python und JavaScript mit einigen JSON-Konfigurationsdateien erstellt wurden, benötigten eine zuverlässige Methode, um Codeänderungen effizient zu handhaben. Hier ist, wie ich das erreicht habe:

  • Fehlerbehebungen und Funktionserweiterungen: o3-mini analysiert meine gesamte Codebase, um Konsistenz über Dateien hinweg sicherzustellen, wenn Fehler behoben oder neue Funktionen hinzugefügt werden.
  • Umfassende Updates: Anstatt Dateien einzeln zu aktualisieren, verwende ich eine vollständige Codebase-Analyse, die es dem Modell ermöglicht, voneinander abhängige Änderungen auf konsistente und einheitliche Weise vorzuschlagen.

Der Ansatz

Mein Ansatz besteht darin, eine Eingabeaufforderung zu erstellen, die die Anweisung und die vollständige Projekt-Codebase in einem strukturierten Format enthält. Dann weise ich das Modell an, die modifizierten Dateien im JSON-Format zu generieren. Das o3-mini-Modell verarbeitet diese Eingabeaufforderung, und seine Antwort wird erfasst, um die Änderungen auf die Codebase anzuwenden.

Dieser Ansatz wird durch zwei Skripte unterstützt:

  • generate_codebase_prompt.py: Automatisiert die Erstellung einer strukturierten Eingabeaufforderung, die die gesamte Codebase enthält.
  • apply_changes.py: Analysiert die Ausgabe des Modells und aktualisiert die entsprechenden Dateien in der Codebase.

Diese Python-Skripte finden Sie am Ende dieses Beitrags.

Diese Methode bietet eine klare, organisierte und skalierbare Möglichkeit, Codeänderungen konsistent über das gesamte Projekt hinweg anzuwenden.

Der Workflow

Das folgende Diagramm veranschaulicht meinen Workflow zur Anweisung und Implementierung von Änderungen an meiner Codebase mit o3-mini:

Image 03

Die folgenden Abschnitte beschreiben jeden Schritt des Workflows im Detail.

1. Erstellen eines Codebase-Snapshots

Ich habe eine codebase.txt-Datei im Projektstammverzeichnis erstellt, die alle Dateinamen (mit relativen Pfaden) in separaten Zeilen auflistet. Dieser Snapshot ist entscheidend, um die zu verarbeitenden Dateien zu identifizieren.

2. Generieren einer einheitlichen Eingabeaufforderung

Ich verwende ein Python-Skript namens generate_codebase_prompt.py, um diesen Schritt zu automatisieren.

generate_codebase_prompt.py funktioniert wie folgt:

  • Liest codebase.txt, ignoriert Zeilen, die mit # beginnen, um Dateipfade zu sammeln.
  • Liest den vollständigen Inhalt jeder Datei und behandelt Fehler elegant, wenn eine Datei nicht gelesen werden kann.
  • Erstellt ein JSON-Array, in dem jeder Eintrag den Dateinamen (mit Pfad) und den Dateiinhalt enthält, und fügt es dann einem festen Eingabeaufforderungstext hinzu.

Diese Eingabeaufforderung weist o3-mini an, nur die modifizierten Dateien auszugeben, wobei derselbe Dateiname (mit Pfad) und der aktualisierte Inhalt beibehalten werden. Es weist das Modell an, die Ergebnisse im JSON-Format mit einer gegebenen Struktur auszugeben. Hier ist die generische Struktur der Eingabeaufforderung:

You are an AI assistant tasked with modifying a codebase based on the instruction provided above. The full codebase is provided below as a
JSON array, where each object represents a file with its relative path and complete contents. Your job is to apply the instruction and retu
rn a pure JSON object that includes only the modified files along with a brief explanation of the changes.

The JSON object must have exactly two keys:
  - "files": an array of objects, each with:
       - "path": the relative file path
       - "content": the full content of the modified file
  - "explanation": a concise explanation of the modifications made

Do not include any additional text, markdown formatting, or commentary outside this JSON object.

Codebase:
...

Um die generierte Eingabeaufforderung schnell in ChatGPT zu kopieren, verwende ich den folgenden Befehl:

python3 generate_codebase_prompt.py ./codebase.txt | xclip -selection clipboard

Die Verwendung von xclip stellt sicher, dass die Ausgabe direkt in die Zwischenablage eingefügt wird, sodass ich sie ohne zusätzliche Schritte in ChatGPT einfügen kann. Um xclip auf Ubuntu zu installieren, führen Sie den folgenden Befehl aus:

sudo apt update && sudo apt install xclip

3. Interaktion mit ChatGPT

Mit der generierten Eingabeaufforderung interagiere ich mit ChatGPT, indem ich eine klare Anweisung gebe.

"Implementieren Sie das neue Feature ..."

oder

"Beheben Sie diesen Fehler ..."

Nachdem ich meine Anweisung eingegeben habe, füge ich die Eingabeaufforderung ein, die im vorherigen Schritt mit der Codebase generiert wurde und sich bereits in meiner Zwischenablage befindet. Der folgende Screenshot zeigt die Interaktion mit ChatGPT.

Image 01

4. Ausführen von o3-mini und Erfassen der Ausgabe

Ich führe o3-mini mit der Eingabeaufforderung aus und erfasse seine Ausgabe in einer Textdatei. Diese Ausgabe enthält die JSON-formatierten Änderungen, die nur die modifizierten Dateien detailliert beschreiben. Ich kopiere die Ergebnisse einfach aus der Schaltfläche Copy von ChatGPT und füge sie in eine Textdatei ein, die ich im nächsten Schritt verwenden werde. Der folgende Screenshot zeigt die Ausgabe von o3-mini und die Schaltfläche Copy.

Image 02

5. Aktualisieren der Codebase

Ich verwende das Python-Skript apply_changes.py, um die von ChatGPT generierten Änderungen anzuwenden. Dieses Skript verarbeitet eine JSON-Datei, die die modifizierten Dateien und deren neuen Inhalt enthält, und aktualisiert oder erstellt die Dateien entsprechend. Es stellt sicher, dass die erforderlichen Verzeichnisse vorhanden sind, schreibt den neuen Inhalt und protokolliert die Änderungen.

Um das Skript auszuführen, verwende ich den folgenden Befehl, wobei inputs.txt die Datei ist, in der ich die Ausgabe von ChatGPT im vorherigen Schritt erfasst habe.

python3 apply_changes.py ./inputs.txt

Beispielausgabe des Aktualisierungsskripts:

Updated: ./app/[locale]/top/page.tsx
Updated: ./components/navigation/Header.tsx
Total files updated: 2

6. Überprüfen von Änderungen und Testen

Nach dem Anwenden der Änderungen führe ich git diff aus, um alle Änderungen zu überprüfen und sicherzustellen, dass sie mit den beabsichtigten Updates übereinstimmen. Schließlich führe ich einige Tests durch, um zu bestätigen, dass alles funktioniert.

Praktische Fälle: Next.js Blog-Projekt

Das Projekt, das ich in diesem Beitrag auf Codebase-Updates überprüfe, ist ein Next.js Blog-Projekt. Hier sind einige wichtige Metriken zu dem Projekt:

MetrikWert
Dateien~130
LOC~13.000
SprachenTS, JS, JSON
FrameworksNext.js, React, Tailwind CSS

Im Folgenden finden Sie einige praktische Fälle, in denen ich diese automatisierten Updates auf dieses Next.js Blog-Projekt anwende.

Anweisung 1

Um die Benutzererfahrung zu verbessern, habe ich beschlossen, einen neuen Menüeintrag namens Top links von "Blog" im Kopf der Startseite hinzuzufügen.

Im Kopf der Startseite links von "Blog" einen neuen Menüeintrag namens Top (mit großem T) hinzufügen. Berücksichtigen Sie, dass dies ein mehrsprachiger Blog ist und alle Beschriftungen im oberen Menü Übersetzungen pro Sprache haben. Implementieren Sie etwas Äquivalentes für Top, sodass die Beschriftung in allen Sprachen Top bleibt. Wenn Top gedrückt wird, werden die Einträge der vorgestellten Beiträge angezeigt.

Diese Änderung führte zu einem Fehler, den ich im nächsten Schritt behebe.

Anweisung 2

Nach der Implementierung des neuen Menüeintrags stieß ich auf einen Fehler in Bezug auf die dynamische Routenverarbeitung in Next.js. Ich wies das Modell an, den Fehler zu beheben.

Beim Drücken von Top erhalte ich diesen Fehler. Beheben Sie ihn.

Error: Route "/[locale]/top" used params.locale. params should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
   at 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)

An diesem Punkt funktionierte die neue Funktion wie beabsichtigt.

Anweisung 3

Um die Benutzererfahrung zu verbessern, habe ich beschlossen, die Beschränkung aufzuheben, dass nur zwei vorgestellte Beiträge angezeigt werden, wenn Top ausgewählt wird.

Wenn Top ausgewählt wird, werden alle vorgestellten Beiträge angezeigt. Derzeit gibt es eine Beschränkung auf zwei. Auf der Hauptseite behalten Sie jedoch weiterhin maximal zwei vorgestellte Beiträge bei, wie derzeit implementiert.

Die Änderung funktionierte wie beabsichtigt.

Anweisung 4

Während des Build-Prozesses stieß ich auf einen Formatierungsfehler in Bezug auf Prettier. Ich wies das Modell an, den Fehler zu beheben.

Beheben Sie diesen Fehler

  Linting and checking validity of types  ..  TypeScript project references are not fully supported. Attempting to build in incremental mode.

Failed to compile.

./app/[locale]/top/page.tsx
18:38  Error: Replace p with (p)  prettier/prettier

./components/navigation/Header.tsx
59:53  Error: Replace {link.title·===·'Top'·?·'Top'·:·t(link.title.toLowerCase())} with ⏎······················{link.title·===·'Top'·?·'Top'·:·t(link.title.toLowerCase())}⏎····················  prettier/prettier

info  - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/app/api-reference/config/eslint#disabling-rules

Der Formatierungsfehler wurde behoben.

Schlussfolgerung

Die Verwendung von o3-mini zur Analyse und Aktualisierung einer gesamten Codebase bietet mehrere Vorteile:

  • Umfassende Einblicke: Das LLM berücksichtigt das große Ganze und schlägt Änderungen vor, die Abhängigkeiten über mehrere Dateien hinweg berücksichtigen.
  • Konsistenz: Automatisierte Updates stellen sicher, dass voneinander abhängige Änderungen einheitlich angewendet werden.
  • Effizienz: Obwohl die Verarbeitungszeit von der Größe der Codebase abhängt, ist der gesamte Workflow schnell und effektiv.
  • Verbesserter Entwicklungsworkflow: Diese Methode minimiert manuelle Eingriffe, reduziert Fehler und beschleunigt sowohl Fehlerbehebungen als auch Funktionsimplementierungen.

Durch die Bereitstellung eines Zugangs zur gesamten Codebase für das Modell habe ich meinen Entwicklungsprozess rationalisiert und gezeigt, dass automatisierte, einheitliche Updates intelligenter und kohärenter sein können als die Bearbeitung einzelner Dateien.

Modelle mit erweiterten Kontextfenstern und erhöhten Ausgabelimits, wie o3-mini, ermöglichen diesen Ansatz.

Nächste Schritte

Ich habe o3-mini-high nicht für diese Beispiele verwendet, aber der Ansatz bleibt gültig. In Zukunft plane ich, dieses Modell ebenfalls zu bewerten, um seine Effektivität und Leistung bei der Automatisierung von Codebase-Updates zu vergleichen.

Der nächste natürliche Schritt wird der Aufbau eines Tools sein, das diesen Workflow mit der o3-mini API automatisiert. Dieses Tool würde dem strukturierten Ansatz folgen, der in diesem Beitrag beschrieben wird, und gleichzeitig nahtlose Codebase-Änderungen ermöglichen, während es direkt mit einem Git-Repository integriert wird, um Updates effizient zu committen. Durch die Verwendung von o3-mini über die API kann der Prozess vollständig automatisiert werden, wodurch manuelle Eingriffe reduziert und versionskontrollierte, strukturierte Verbesserungen über Projekte hinweg sichergestellt werden.

Python-Skripte

Im Folgenden finden Sie die in diesem Workflow verwendeten Python-Skripte. Diese Skripte automatisieren den Prozess der Erstellung von Eingabeaufforderungen und der Anwendung von Änderungen an der Codebase, wodurch der Workflow effizient und skalierbar wird.

generate_codebase_prompt.py

Dieses Skript liest eine Liste von Dateipfaden, extrahiert deren Inhalt und formatiert sie in eine strukturierte Eingabeaufforderung, die mit einem LLM verwendet werden kann, um die Codebase zu analysieren und zu modifizieren.

"""
generate_codebase_prompt.py
================

Description:
    This script reads a file containing file paths (one per line), ignoring any lines
    that start with the '#' character. For each valid file path, it reads the full file
    contents and constructs a JSON array where each element is an object containing the file's
    "path" and "content". This JSON array is appended to a fixed prompt text which is intended
    for use with a Language Model (LLM) to modify the codebase based on a manually added instruction.

Usage:
    python generate_codebase_prompt.py <file_with_paths>

    Where:
        <file_with_paths> is a text file containing a list of file paths (one per line).

Example:
    Given an input file 'paths.txt' with the following content:
        /path/to/file1.txt
        # /path/to/file2.txt

    Running:
        python generate_codebase_prompt.py paths.txt

    Produces output (on standard output) similar to:
        === PROMPT ===
        You are an AI assistant tasked with modifying a codebase based on the instruction provided above.
        The full codebase is provided below as a JSON array, where each object represents a file with its
        relative path and complete contents. Your job is to apply the instruction and return a pure JSON
        object that includes only the modified files along with a brief explanation of the changes.

        The JSON object must have exactly two keys:
          - "files": an array of objects, each with:
               - "path": the relative file path
               - "content": the full content of the modified file
          - "explanation": a concise explanation of the modifications made

        Do not include any additional text, markdown formatting, or commentary outside this JSON object.

        Codebase:
        [
          {
            "path": "/path/to/file1.txt",
            "content": "full contents of file1..."
          },
          ...
        ]
"""

import sys
import json


def generate_codebase_json(file_with_paths):
    """
    Reads an input file containing file paths and generates a list of dictionaries,
    each representing a file with its "path" and full "content".

    The function ignores empty lines and lines starting with '#' (treated as comments).
    If an error occurs while reading any file, the error message is stored in the "content" field
    of the corresponding dictionary.

    Args:
        file_with_paths (str): Path to the text file containing file paths.

    Returns:
        list: A list of dictionaries with keys "path" and "content".

    Exits:
        Exits the script with a status code 1 if the input file cannot be read.
    """
    codebase = []
    try:
        with open(file_with_paths, 'r') as f:
            for line in f:
                filepath = line.strip()
                # Skip empty lines and commented lines
                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:
                    # If there is an error reading the file, record the error message as content
                    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):
    """
    Constructs and prints a complete prompt intended for an LLM. The prompt consists of
    a fixed text instruction followed by a JSON array of the codebase.

    The fixed prompt instructs the LLM to modify the codebase based on a manually added
    instruction and to output a JSON object with two keys: "files" and "explanation".

    Args:
        codebase (list): A list of dictionaries where each dictionary contains the "path" and
                         "content" of a file.
    """
    # Fixed prompt text (the manual instruction is expected to be added before this text)
    prompt_text = (
        "You are an AI assistant tasked with modifying a codebase based on the instruction provided above. "
        "The full codebase is provided below as a JSON array, where each object represents a file with its relative path "
        "and complete contents. Your job is to apply the instruction and return a pure JSON object that includes only the "
        "modified files along with a brief explanation of the changes.\n\n"
        "The JSON object must have exactly two keys:\n"
        "  - \"files\": an array of objects, each with:\n"
        "       - \"path\": the relative file path\n"
        "       - \"content\": the full content of the modified file\n"
        "  - \"explanation\": a concise explanation of the modifications made\n\n"
        "Do not include any additional text, markdown formatting, or commentary outside this JSON object.\n\n"
        "Codebase:"
    )

    # Convert the codebase list to a JSON string with indentation for better readability
    codebase_json = json.dumps(codebase, indent=2)

    # Output the complete prompt
    print(prompt_text)
    print("\n" + codebase_json)


def main():
    """
    Main function that handles command-line arguments and executes the script functionality.
    """
    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

Dieses Skript verarbeitet die JSON-Ausgabe des LLM, aktualisiert die entsprechenden Dateien in der Codebase und stellt sicher, dass Änderungen konsistent angewendet werden, während Verzeichnisstrukturen erhalten bleiben.

"""
apply_changes.py
===============

Description:
    This script reads a JSON file provided as a command-line argument. The JSON file must contain
    an object with a key "files", which is an array of objects. Each object in the array should
    have the following keys:
      - "path": the relative or absolute path of the file to update
      - "content": the full content to write into that file

    The script updates or creates each file as specified in the JSON file. Necessary directories
    are created if they do not exist.

Usage:
    python apply_changes.py /path/to/input.json

Example JSON file structure:
    {
      "files": [
        {
          "path": "example/file1.txt",
          "content": "This is the updated content for file1."
        },
        {
          "path": "example/file2.txt",
          "content": "This is the updated content for file2."
        }
      ]
    }
"""

import os
import sys
import json


def update_files_from_json(json_file_path):
    """
    Reads a JSON file and updates or creates files as specified in the JSON object.

    The JSON file must contain an object with a key "files", which is an array of objects.
    Each object must have:
      - "path": the relative or absolute path of the file to update
      - "content": the full content to write into that file

    The function creates any necessary directories for the file paths if they do not exist.
    It prints a message for each file that is updated and a final summary of the total files updated.

    Args:
        json_file_path (str): The path to the JSON file containing file update information.

    Exits:
        The script exits with status code 1 if the JSON file cannot be read or if it does not
        contain the required "files" key.
    """
    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']
            # Create necessary directories if they do not exist.
            directory = os.path.dirname(file_path)
            if directory and not os.path.exists(directory):
                os.makedirs(directory, exist_ok=True)
            # Write the content to the file.
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            print("Updated: {}".format(file_path))
            files_updated += 1
        except Exception as e:
            print("Failed to update '{}': {}".format(file_obj.get('path', 'unknown'), e))
    print("Total files updated: {}".format(files_updated))


def main():
    """
    Main function that handles command-line arguments and triggers the file update process.
    """
    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()

Hat Ihnen dieser Beitrag gefallen? Fanden Sie ihn hilfreich? Hinterlassen Sie gerne einen Kommentar, um Ihre Gedanken zu teilen oder Fragen zu stellen. Ein GitHub-Konto ist erforderlich, um an der Diskussion teilzunehmen.