Gemini vs. ChatGPT: Chi Scrive Codice Migliore?

Ari Mahpour
|  Creato: marzo 1, 2024  |  Aggiornato: aprile 2, 2024
Gemini vs. ChatGPT

I tempi in cui gli ingegneri elettrici potevano cavarsela senza scrivere nemmeno una riga di codice sono finiti. Saper programmare è diventata una competenza necessaria, indispensabile per ingegneri di tutti i tipi. Sebbene gli ingegneri non debbano necessariamente sapere come scrivere un'applicazione web completa, è importante che abbiano competenze di base nella scrittura di script. Eseguire analisi su grandi set di dati, ad esempio, richiede una certa conoscenza nella programmazione. Per compiti più complessi, gli ingegneri possono trovarsi in difficoltà, a volte trascorrendo ore in ricerca online di una funzione particolare o di una soluzione. Con il rilascio di ChatGPT, il mondo, senza dubbio, è cambiato così come il panorama della generazione automatica di codice. Gli ingegneri senza una solida formazione possono ora scrivere codice di alta qualità con l'aiuto dell'Intelligenza Artificiale Generativa.

In articoli precedenti come Utilizzo di ChatGPT per la Scripting di Altium e Utilizzo di ChatGPT per il Testing Automatico, abbiamo esaminato come sfruttare l'Intelligenza Artificiale Generativa, specificamente ChatGPT, per scrivere codice per noi. Fino ad ora, Google Bard (il concorrente di ChatGPT) era rimasto indietro ma un nuovo modello, Gemini, ha pubblicizzato di superare il suo concorrente sulla scala di Massive Multitask Language Understanding (MMLU):

Figure 1: Gemini’s MMLU  performance metric

Figura 1: Metrica di prestazione MMLU di Gemini. Fonte: https://deepmind.google/technologies/gemini/#capabilities

In questo articolo metteremo a confronto il motore più sofisticato di ChatGPT, GPT4, contro Gemini Advanced (precedentemente noto come Ultra), il motore AI più avanzato di Google, per vedere chi è migliore nella generazione di codice.

Codice Standard

Effettuare un confronto completamente esaustivo tra i due motori sarebbe estremamente impegnativo. In questo articolo esamineremo come questi due motori generano codice standard scritto in Python (poiché è una delle lingue più supportate per la scrittura di codice LLMs). Questo non è una scienza esatta poiché buono contro cattivo può essere molto soggettivo. Invece, valuteremo ogni motore basandoci semplicemente sul fatto che il codice funzioni e su quanto bene ha compreso le nostre istruzioni.

Compito 1: Stampa Ricorsiva delle Proprietà dei File

Per iniziare, diamo un'occhiata a un compito di scripting molto semplice:

Sviluppare uno script di automazione Python che, dato un percorso assoluto a una cartella, recuperi ricorsivamente i metadati di ogni file come oggetto dizionario. Stampare ogni oggetto dizionario riga per riga e includere il percorso assoluto.

Analizziamo prima il codice che proviene da 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__)))

È conciso, funziona e fa il suo lavoro. Lo considererei adeguato. È anche un compito eccezionalmente banale, ma va bene così.

Ora vediamo il codice che proviene da 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  # Dimensione in byte

        metadata['modified_time'] = stat.st_mtime  # Timestamp dell'ultima modifica

        metadata['accessed_time'] = stat.st_atime  # Timestamp dell'ultimo accesso

    except OSError:

        print(f"Errore nell'accesso al file: {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"Percorso assoluto: {file_path}")  # Stampa il percorso assoluto

                print(metadata)

 

if __name__ == '__main__':

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

Gemini è un po' più verboso, anche se ha aggiunto del gestione degli errori che, suppongo, sia una cosa positiva. È piuttosto lungo ma funziona quindi gli daremo un passaggio.

Compito 2: Web Scraper

Per il prossimo compito volevo vedere quanto bene entrambi i motori possono comprendere una data lingua e creare un parser basato su quella lingua. In questo caso costruiremo uno scraper web utilizzando il seguente prompt:
Scrivi uno script Python utilizzando BeautifulSoup o Scrapy che estrae i principali titoli delle notizie da 'https://news.ycombinator.com' e li esporta in un oggetto dizionario.

Ecco un frammento della fonte della pagina da 'https://news.ycombinator.com'. Usa questo per determinare come analizzare i tag.

Scrivi uno script Python utilizzando BeautifulSoup o Scrapy che estrae i principali titoli delle notizie da 'https://news.ycombinator.com' e li esporta in un oggetto dizionario.

Ecco un frammento della fonte della pagina da 'https://news.ycombinator.com'. Usa questo per determinare come analizzare i tag.

<html lang="it" 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>

Come noterai, ho incluso dell'HTML nel mio prompt. Il mio prompt effettivo consiste in più HTML ma l'ho troncato per questo articolo. Ecco cosa ha generato GPT4:

import requests
from bs4 import BeautifulSoup

# URL del sito da raschiare
url = 'https://news.ycombinator.com'

# Invia una richiesta GET all'URL
response = requests.get(url)

# Analizza il contenuto HTML della pagina usando BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')

# Trova tutti i titoli delle notizie
headlines = soup.find_all('tr', class_='athing')

# Dizionario per memorizzare i titoli dove la chiave è il rango e il valore è il testo del titolo
news_headlines = {}

# Cicla attraverso ogni titolo, estrailo e memorizzalo nel dizionario
for headline in headlines:
    rank = headline.find('span', class_='rank').text.strip('.')
    title = headline.find('span', class_='titleline').text
    news_headlines[rank] = title

# Stampa il dizionario
print(news_headlines)

Questo codice funziona bene e fa quello che deve fare. Speravo intuitivamente che sapesse che volevo il link agli articoli ma non sono stato esplicito quindi non posso usarlo come un punto contro il voto di GPT4.

Ecco cosa ha generato Gemini:

import requests
from bs4 import BeautifulSoup

# Invia una richiesta HTTP GET al sito web di Hacker News
response = requests.get("https://news.ycombinator.com/")

# Analizza il contenuto HTML usando BeautifulSoup
soup = BeautifulSoup(response.content, "html.parser")

# Trova tutti gli elementi della classe 'athing', che contengono gli articoli di notizie
articles = soup.find_all("tr", class_="athing")

# Crea un dizionario vuoto per memorizzare i titoli
headlines = {}

# Cicla attraverso ogni articolo ed estrai il titolo e l'URL
for article in articles:
    # Trova l'elemento del titolo
    headline_element = article.find("span", class_="titleline")
    headline = headline_element.find("a").text.strip()

    # Trova l'elemento dell'URL
    url_element = headline_element.find("a")
    url = url_element["href"]

    # Aggiungi il titolo e l'URL al dizionario
    headlines[headline] = url

# Stampa il dizionario dei titoli
print(headlines)

Questo funziona ed è abbastanza simile all'output di GPT4, ma questo codice estrae effettivamente l'URL. Questo è interessante ma, di nuovo, non è un'aspettativa. In questa sfida direi che sono, più o meno, la stessa cosa. Forse Gemini guadagna un punto extra per essere un lettore di menti.

Compito 3: Applicazione Web per Azioni

Per questo compito voglio creare un'applicazione web che disegni i grafici delle azioni di alcuni ticker diversi:

Crea un'applicazione web in Python che mostri i grafici delle seguenti azioni: RIVN, TSLA, NKLA, FSR

Questo compito è stato decisamente più complicato. Richiede una componente frontend (cioè grafici/immagini) e una componente backend (cioè il recupero dei dati da un database di azioni). Ho generato innumerevoli applicazioni con GPT4 e volevo vedere come si comportava Gemini al confronto. Ecco cosa ha generato GPT4 per me:

from flask import Flask, render_template_string
import yfinance come yf
import plotly.graph_objects come 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()

    per ogni 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

Figura 2: Screenshot dell'applicazione web generata da GPT4

È semplice, pulita e diretta. Senza fronzoli ma fa il suo lavoro. Ecco cosa ha generato Gemini per me:

import flask
da flask import render_template
import yfinance come yf
import plotly.graph_objects come go

app = flask.Flask(__name__)

# Simboli delle azioni
tickers = ['RIVN', 'TSLA', 'NKLA', 'FSR']

# Recupera i dati delle azioni usando yfinance
def get_stock_data(ticker):
    start_date = '2023-02-10'  # Regola la data di inizio come necessario
    end_date = '2024-02-10'  # Data odierna
    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)

Richiedeva anche la creazione di un nuovo file, index.html, in una nuova cartella chiamata templates:

<!DOCTYPE html>
<html>
<head>
    <title>Grafici Azionari</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

Figura 3: Screenshot dell'applicazione web generata da Gemini Advanced

Questa era decisamente più sofisticata, poiché includeva un istogramma e astratteva il contenuto HTML in un nuovo file. Ancora una volta, entrambi erano funzionali, quindi, entrambi ricevono un voto di approvazione.

Insuccessi e Allucinazioni

Quando GPT4 è stato lanciato per la prima volta, ci è voluto tempo per capire come "sollecitarlo" correttamente. Quando si utilizza l'Intelligenza Generativa per scrivere codice, i dettagli sono importanti. Di conseguenza, molti di noi sono diventati "Ingegneri dei Prompt" più competenti nel corso dell'ultimo anno. Sfortunatamente, ciò può introdurre alcuni bias nel confronto tra GPT4 e altri motori, e lo ammetto volontariamente. Conosco il modo in cui GPT4 "funziona" più di quanto conosca Gemini. Il modo in cui creo i prompt per GPT4 potrebbe essere diverso da ciò che Gemini si aspetta. Nonostante ciò, ho comunque riscontrato alcuni problemi molto fondamentali con Gemini.

Un problema comune che ho riscontrato con Gemini nell'interpretare le istruzioni riguardava la generazione di test unitari. Il mio obiettivo iniziale era coprire i test unitari nell'articolo ma, per frustrazione, ho rinunciato completamente a Gemini perché non seguiva mai le istruzioni. Ad esempio, chiedevo a Gemini di scrivere un test unitario utilizzando Pytest e di incapsularlo in una classe. Generava il test utilizzando UnitTest invece, ignorando palesemente la mia richiesta, ma incapsulava il codice all'interno di una classe. Lo correggevo e riconosceva di aver usato accidentalmente UnitTest invece di Pytest. Poi riscriveva il codice usando Pytest ma dimenticava di metterlo in una classe. Quando chiedevo di utilizzare una costruzione Mock, di default usava il mock di UnitTest invece del Mock di Pytest. Queste sono sfumature ma importanti quando si interagisce con l'IA Generativa.

Figure 4: Gemini Advanced not following directions

Figura 4: Gemini Avanzato non segue le istruzioni

La risoluzione dei problemi era un altro punto dolente. Il motore di ragionamento di GPT4 si è dimostrato piuttosto potente nel debuggare errori in Python. Gemini... non tanto. Quando chiedevo di correggere determinati problemi, semplicemente tentava di riscrivere il codice aggiungendo indentazioni o scambiando variabili... una risposta completamente inutile.

A volte Gemini semplicemente non funzionava. Diceva che non poteva elaborare la mia richiesta. In altri casi iniziava a commentare riguardo... le elezioni imminenti?

Gemini Advanced confused about the upcoming elections?

Figura 5: Gemini Avanzato confuso sulle elezioni imminenti?

Conclusione

Nel complesso, la qualità del codice boilerplate generato da Gemini era piuttosto competitiva rispetto a GPT4. L'esperienza e il suo motore di ragionamento, tuttavia, lasciavano molto a desiderare. Fortunatamente per Google, questi elementi fanno parte dell'implementazione dell'LLM e non dell'LLM stesso. In altre parole, l'LLM di Gemini sembra essere, fondamentalmente, abbastanza buono e alla pari con GPT4 ma il codice scritto intorno ad esso che viene utilizzato nell'esperienza di chat ha bisogno di aiuto. Col tempo, probabilmente vedremo Google iterare sul loro codice e migliorare quell'esperienza e motore di ragionamento.

Sull'Autore

Sull'Autore

Ari è un ingegnere con una solida esperienza nei campi di progettazione, produzione, collaudo e integrazione di sistemi elettrici, meccanici e software. Ama riunire gli ingegneri addetti alla progettazione, alla verifica e al collaudo e farli lavorare insieme come un'unità affiatata.

Risorse correlate

Documentazione Tecnica Correlata

Tornare alla Pagina Iniziale
Thank you, you are now subscribed to updates.