Gemini vs. ChatGPT: Qui écrit le meilleur code ?

Ari Mahpour
|  Créé: Mars 1, 2024  |  Mise à jour: Avril 2, 2024
Gemini vs. ChatGPT

Les jours où les ingénieurs électriques pouvaient se passer d'écrire ne serait-ce qu'une ligne de code sont révolus. Savoir coder est devenu une compétence requise, nécessaire pour tous les types d'ingénieurs. Bien que les ingénieurs n'aient pas besoin de comprendre comment écrire une application web complète, il est important qu'ils possèdent des compétences de base en script. L'analyse de grands ensembles de données, par exemple, nécessite certaines connaissances en programmation. Pour des tâches plus complexes, les ingénieurs peuvent se retrouver dans l'embarras, passant parfois des heures en ligne à rechercher une fonction ou une solution particulière. Avec la sortie de ChatGPT, le monde, sans aucun doute, a changé et le paysage de la génération de code automatisée également. Les ingénieurs sans un solide background peuvent désormais écrire du code de haute qualité avec l'aide de l'IA générative.

Dans des articles précédents tels que Utiliser ChatGPT pour le Scripting Altium et Utiliser ChatGPT pour les Tests Automatisés, nous avons examiné comment tirer parti de l'IA générative, spécifiquement ChatGPT, pour écrire du code pour nous. Jusqu'à présent, Google Bard (le concurrent de ChatGPT) était à la traîne, mais un nouveau modèle, Gemini, a annoncé qu'il surpassait son concurrent sur l'échelle de compréhension du langage multitâche massif (MMLU) :

Figure 1: Gemini’s MMLU  performance metric

Figure 1 : Indicateur de performance MMLU de Gemini. Source : https://deepmind.google/technologies/gemini/#capabilities

Dans cet article, nous allons comparer le moteur le plus sophistiqué de ChatGPT, GPT4, à Gemini Advanced (anciennement connu sous le nom d'Ultra), le moteur d'IA le plus avancé de Google, pour voir lequel est le meilleur pour générer du code.

Code standard

Effectuer une comparaison totalement exhaustive entre les deux moteurs serait extrêmement difficile. Dans cet article, nous allons examiner comment ces deux moteurs génèrent du code standard écrit en Python (car c'est l'un des langages les plus pris en charge pour la rédaction de code par les LLMs). Ce n'est pas une science exacte car bien versus mal peut être très subjectif. Au lieu de cela, nous évaluerons chaque moteur simplement sur la base de si le code fonctionne et à quel point il a bien compris nos instructions.

Tâche 1 : Impression récursive des propriétés de fichier

Pour commencer, examinons une tâche de script très simple :

Développer un script d'automatisation Python qui, étant donné un chemin absolu vers un dossier, récupère les métadonnées de chaque fichier de manière récursive sous forme d'objet dictionnaire. Imprimer chaque objet dictionnaire ligne par ligne et inclure le chemin absolu.

Analysons d'abord le code renvoyé par GPT4 :

import os

def get_file_metadata(directory):

    for foldername, subfolders, filenames in os.walk(directory):

        for filename in filenames:

            filepath = os.path.join(foldername, filename)

            metadata = {

                'filename': filename,

                'path': filepath,

                'size': os.path.getsize(filepath),

                'last_modified': os.path.getmtime(filepath)

            }

            print(metadata)

 

get_file_metadata(os.path.dirname(os.path.abspath(__file__)))

C'est concis, ça fonctionne et ça fait le travail. Je donnerais mon approbation. C'est aussi une tâche exceptionnellement triviale, mais c'est acceptable.

Maintenant, regardons le code renvoyé par Gemini Advanced :

import os

 

def get_file_metadata(file_path):

    metadata = {}

    try:

        stat = os.stat(file_path)

        metadata['name'] = os.path.basename(file_path)

        metadata['size'] = stat.st_size  # Taille en octets

        metadata['modified_time'] = stat.st_mtime  # Horodatage de la dernière modification

        metadata['accessed_time'] = stat.st_atime  # Horodatage du dernier accès

    except OSError:

        print(f"Erreur d'accès au fichier : {file_path}")

    return metadata

 

def retrieve_metadata_recursively(folder_path):

    for root, _, files in os.walk(folder_path):

        for file in files:

            file_path = os.path.join(root, file)

            metadata = get_file_metadata(file_path)

            if metadata:

                print(f"Chemin absolu : {file_path}")  # Imprime le chemin absolu

                print(metadata)

 

if __name__ == '__main__':

    retrieve_metadata_recursively(os.path.dirname(os.path.abspath(__file__)))

Gemini est un peu plus verbeux, certes, mais il a ajouté des gestions d'erreur ce qui, je suppose, est appréciable. C'est quelque peu long mais ça fonctionne donc on va lui accorder le bénéfice du doute.

Tâche 2 : Aspirateur Web

Pour la prochaine tâche, je voulais voir comment les deux moteurs comprennent une langue donnée et créent un analyseur basé sur cette langue. Dans ce cas, nous allons construire un aspirateur web en utilisant l'invite suivante :
Écrivez un script Python utilisant BeautifulSoup ou Scrapy qui récupère les principaux titres des nouvelles de 'https://news.ycombinator.com' et les sort dans un objet dictionnaire.

Voici un extrait de la source de la page de 'https://news.ycombinator.com'. Utilisez ceci pour déterminer comment analyser les balises.

Écrivez un script Python utilisant BeautifulSoup ou Scrapy qui récupère les principaux titres des nouvelles de 'https://news.ycombinator.com' et les sort dans un objet dictionnaire.

Voici un extrait de la source de la page de 'https://news.ycombinator.com'. Utilisez ceci pour déterminer comment analyser les balises.

<html lang="fr" op="news"><head><meta name="referrer" content="origin"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" type="text/css" href="news.css?J16btoAd8hqdkSoIdLSk">
        <link rel="icon" href="y18.svg">

</html>

Comme vous le remarquerez, j'ai inclus du HTML dans ma demande. Ma demande réelle comprend plus de HTML mais je l'ai tronquée pour cet article. Voici ce que GPT4 a généré :

import requests
from bs4 import BeautifulSoup

# URL du site à scraper
url = 'https://news.ycombinator.com'

# Envoyer une requête GET à l'URL
response = requests.get(url)

# Analyser le contenu HTML de la page en utilisant BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')

# Trouvez tous les titres des actualités
headlines = soup.find_all('tr', class_='athing')

# Dictionnaire pour stocker les titres où la clé est le rang et la valeur est le texte du titre
news_headlines = {}

# Bouclez à travers chaque titre, extrayez-le et stockez-le dans le dictionnaire
for headline in headlines:
    rank = headline.find('span', class_='rank').text.strip('.')
    title = headline.find('span', class_='titleline').text
    news_headlines[rank] = title

# Affichez le dictionnaire
print(news_headlines)

Ce code fonctionne bien et fait ce qu’il est censé faire. J’espérais qu’il saurait, intuitivement, que je voulais le lien vers les articles mais je n’ai pas été explicite donc je ne peux pas utiliser cela comme un point contre la note de GPT4.

Voici ce que Gemini a généré :

import requests
from bs4 import BeautifulSoup

# Envoyez une requête HTTP GET au site web de Hacker News
response = requests.get("https://news.ycombinator.com/")

# Analyser le contenu HTML en utilisant BeautifulSoup
soup = BeautifulSoup(response.content, "html.parser")

# Trouver tous les éléments de classe 'athing', qui contiennent les articles de nouvelles
articles = soup.find_all("tr", class_="athing")

# Créer un dictionnaire vide pour stocker les titres
headlines = {}

# Parcourir chaque article et extraire le titre et l'URL
for article in articles:
    # Trouver l'élément du titre
    headline_element = article.find("span", class_="titleline")
    headline = headline_element.find("a").text.strip()

    # Trouver l'élément URL
    url_element = headline_element.find("a")
    url = url_element["href"]

    # Ajouter le titre et l'URL au dictionnaire
    headlines[headline] = url

# Imprimer le dictionnaire des titres
print(headlines)

Cela fonctionne également et c'est assez similaire à la sortie de GPT4, mais ce code extrait réellement l'URL. C'est bien, mais encore une fois, ce n'est pas une attente. Dans ce défi, je dirais qu'ils sont, à peu près, identiques. Peut-être que Gemini marque un point supplémentaire pour avoir été devin.

Tâche 3 : Application Web de Suivi des Actions

Pour cette tâche, je souhaite créer une application web qui trace les graphiques boursiers de quelques tickers différents :

Créez une application web en Python qui montre les graphiques des actions suivantes : RIVN, TSLA, NKLA, FSR

Celle-ci était définitivement plus compliquée. Elle nécessite un composant frontal (c.-à-d. des graphiques/images) et un composant backend (c.-à-d. la récupération des données d'une base de données boursière). J'ai généré d'innombrables applications avec GPT4 et je voulais voir comment Gemini se mesurait à cela. Voici ce que GPT4 a généré pour moi :

from flask import Flask, render_template_string
import yfinance as yf
import plotly.graph_objects as go
from datetime import datetime

app = Flask(__name__)

@app.route('/')
def home():
    stocks = ['RIVN', 'TSLA', 'NKLA', 'FSR']
    start = datetime(2021, 1, 1)
    end = datetime.now()

    fig = go.Figure()

    for stock in stocks:
        df = yf.download(stock, start=start, end=end)
        fig.add_trace(go.Scatter(x=df.index, y=df.Close, mode='lines', name=stock))

    graph_html = fig.to_html(full_html=False)

    return render_template_string("""
        <html>
            <body>
                {{ graph_html | safe }}
            </body>
        </html>

Figure 2: Screenshot of GPT4 generated web application

Figure 2 : Capture d'écran de l'application web générée par GPT4

C'est simple, épuré et direct. Sans fioritures mais efficace. Voici ce que Gemini a généré pour moi :

import flask
from flask import render_template
import yfinance as yf
import plotly.graph_objects as go

app = flask.Flask(__name__)

# Symboles boursiers
tickers = ['RIVN', 'TSLA', 'NKLA', 'FSR']

# Récupérer les données boursières en utilisant yfinance
def get_stock_data(ticker):
    start_date = '2023-02-10'  # Ajuster la date de début selon le besoin
    end_date = '2024-02-10'  # Date d'aujourd'hui
    return yf.download(ticker, start=start_date, end=end_date)

@app.route('/')
def index():
    stock_data = {}
    for ticker in tickers:
        stock_data[ticker] = get_stock_data(ticker)

    charts = []
    for ticker, data in stock_data.items():
        fig = go.Figure(data=[go.Candlestick(x=data.index,
                                             open=data['Open'],
                                             high=data['High'],
                                             low=data['Low'],
                                             close=data['Close'])])
        fig.update_layout(title=ticker)
        charts.append(fig.to_html(full_html=False, include_plotlyjs='cdn'))

    return render_template('index.html', charts=charts)

if __name__ == '__main__':
    app.run(debug=True)

Il m'a également été nécessaire de créer un nouveau fichier, index.html, dans un nouveau répertoire appelé templates:

<!DOCTYPE html>
<html>
<head>
    <title>Graphiques Boursiers</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
    {% for chart in charts %}
        <div id="{{ loop.index0 }}"></div> 
        <script>
            Plotly.newPlot('{{ loop.index0 }}', {{ chart | safe }});
        </script>
    {% endfor %}
</body>
</html>

Figure 3: Screenshot of Gemini Advanced generated web application

Figure 3: Capture d'écran de l'application web générée par Gemini Advanced

C'était définitivement plus sophistiqué, car cela incluait un histogramme et abstrayait le contenu HTML dans un nouveau fichier. Encore une fois, les deux étaient fonctionnels, donc, les deux reçoivent une note de passage.

Échecs et Hallucinations

Lorsque GPT4 a été lancé pour la première fois, il a fallu du temps pour comprendre comment le "solliciter" correctement. Lors de l'utilisation de l'IA générative pour écrire du code, les détails sont importants. En conséquence, beaucoup d'entre nous sont devenus des "Ingénieurs de Sollicitation" plus compétents au cours de cette dernière année. Malheureusement, cela peut introduire certains biais lors de la comparaison de GPT4 avec d'autres moteurs et je l'admets volontiers. Je sais comment GPT4 "fonctionne" plus que comment Gemini fonctionne. La manière dont je formule les sollicitations pour GPT4 pourrait être différente de ce que Gemini attend. Néanmoins, j'ai encore rencontré quelques problèmes très fondamentaux avec Gemini.

Un problème courant que j'ai rencontré avec Gemini lorsqu'il s'agissait d'interpréter des instructions concernait la génération de tests unitaires. Mon objectif initial était de couvrir les tests unitaires dans l'article mais, par frustration, j'ai complètement abandonné Gemini car il ne suivait jamais les instructions. Par exemple, je demandais à Gemini d'écrire un test unitaire en utilisant Pytest et de l'encapsuler dans une classe. Il générait le test en utilisant UnitTest à la place, ignorant totalement ma demande, mais encapsulait le code dans une classe. Je le corrigeais et il reconnaissait qu'il avait accidentellement utilisé UnitTest au lieu de Pytest. Il réécrivait ensuite le code en utilisant Pytest mais oubliait de le mettre dans une classe. Lorsque je lui demandais d'utiliser une construction Mock, il se rabattait par défaut sur le mock de UnitTest plutôt que sur le Mock de Pytest. Ce sont des nuances mais importantes lorsqu'on interagit avec l'IA générative.

Figure 4: Gemini Advanced not following directions

Figure 4: Gemini Advanced ne suit pas les instructions

Le dépannage des échecs était un autre point douloureux. Le moteur de raisonnement de GPT4 s'est avéré assez puissant pour déboguer des erreurs en Python. Gemini... pas tant que ça. Quand je lui demandais de corriger certains problèmes, il se contentait de réécrire le code en ajoutant des indentations ou en échangeant des variables... une réponse totalement inutile.

Parfois, Gemini ne fonctionnait tout simplement pas. Il indiquait qu'il ne pouvait pas traiter ma demande. Dans d'autres cas, il se mettait à commenter sur... l'élection à venir ?

Gemini Advanced confused about the upcoming elections?

Figure 5: Gemini Advanced confus au sujet des élections à venir ?

Conclusion

Dans l'ensemble, la qualité du code générique produit par Gemini était assez compétitive face à GPT4. Cependant, l'expérience et son moteur de raisonnement laissaient beaucoup à désirer. Heureusement pour Google, ces éléments font partie de la mise en œuvre du LLM et non du LLM lui-même. Autrement dit, le LLM Gemini semble être, fondamentalement, assez bon et au niveau de GPT4, mais le code écrit autour de lui qui est utilisé dans l'expérience de chat a besoin d'aide. Avec le temps, nous verrons probablement Google itérer sur leur code et améliorer cette expérience et ce moteur de raisonnement.

A propos de l'auteur

A propos de l'auteur

Ari est un ingénieur doté d'une solide expérience dans la conception, la fabrication, les tests et l'intégration de systèmes électriques, mécaniques et logiciels. Il aime collaborer avec des ingénieurs chargés de la conception, la vérification et les tests afin de favoriser les synergies.

Ressources associées

Documentation technique liée

Retournez à la Page d'Accueil
Thank you, you are now subscribed to updates.