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):
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.
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.
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.
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"> |
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 # URL del sito da raschiare # Invia una richiesta GET all'URL # Analizza il contenuto HTML della pagina usando BeautifulSoup # Trova tutti i titoli delle notizie # Dizionario per memorizzare i titoli dove la chiave è il rango e il valore è il testo del titolo # Cicla attraverso ogni titolo, estrailo e memorizzalo nel dizionario # Stampa il dizionario |
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 # Invia una richiesta HTTP GET al sito web di Hacker News # Analizza il contenuto HTML usando BeautifulSoup # Trova tutti gli elementi della classe 'athing', che contengono gli articoli di notizie # Crea un dizionario vuoto per memorizzare i titoli # Cicla attraverso ogni articolo ed estrai il titolo e l'URL # Trova l'elemento dell'URL # Aggiungi il titolo e l'URL al dizionario # Stampa il dizionario dei titoli |
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.
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 app = Flask(__name__) @app.route('/') fig = go.Figure() per ogni stock in stocks: graph_html = fig.to_html(full_html=False) return render_template_string(""" |
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 app = flask.Flask(__name__) # Simboli delle azioni # Recupera i dati delle azioni usando yfinance @app.route('/') charts = [] return render_template('index.html', charts=charts) if __name__ == '__main__': |
Richiedeva anche la creazione di un nuovo file, index.html, in una nuova cartella chiamata templates:
<!DOCTYPE html> |
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.
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.
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?
Figura 5: Gemini Avanzato confuso sulle elezioni imminenti?
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.