Los días en los que los ingenieros eléctricos podían pasar sin escribir ni una sola línea de código han quedado atrás. Saber programar se ha convertido en una habilidad requerida, necesaria para ingenieros de todo tipo. Aunque los ingenieros no necesitan entender cómo escribir una aplicación web completa, es importante que tengan habilidades básicas de scripting. Realizar análisis en grandes conjuntos de datos, por ejemplo, requiere cierto conocimiento en programación. Para tareas más complejas, los ingenieros pueden encontrarse en apuros, a veces pasando horas buscando en línea una función o solución particular. Con el lanzamiento de ChatGPT, el mundo, sin duda, ha cambiado y también lo ha hecho el panorama para la generación de código automatizado. Ahora, los ingenieros sin un fuerte background pueden escribir código de alta calidad con la ayuda de la IA Generativa.
En artículos anteriores como Usando ChatGPT para Scripting en Altium y Usando ChatGPT para Pruebas Automatizadas, vimos cómo aprovechar la IA Generativa, específicamente ChatGPT, para escribir código por nosotros. Hasta ahora, Google Bard (el competidor de ChatGPT) ha quedado atrás, pero un nuevo modelo, Gemini, ha anunciado que supera a su competidor en la escala de Entendimiento del Lenguaje Multitarea Masivo (MMLU):
Figura 1: Métrica de rendimiento de MMLU de Gemini. Fuente: https://deepmind.google/technologies/gemini/#capabilities
En este artículo vamos a comparar el motor más sofisticado de ChatGPT, GPT4, contra Gemini Advanced (anteriormente conocido como Ultra), el motor de IA más avanzado de Google, para ver cuál es mejor generando código.
Realizar una comparación totalmente exhaustiva entre los dos motores sería extremadamente desafiante. En este artículo vamos a observar cómo estos dos motores generan código predeterminado escrito en Python (ya que es uno de los lenguajes más soportados para la escritura de código por LLMs). Esto no es una ciencia exacta ya que lo bueno versus lo malo puede ser muy subjetivo. En su lugar, calificaremos a cada motor basándonos simplemente en si el código funciona y cuán bien entendió nuestras instrucciones.
Para comenzar, veamos una tarea de scripting muy simple:
Desarrollar un script de automatización en Python que, dado un camino absoluto a una carpeta, recupere los metadatos de cada archivo de manera recursiva como un objeto de diccionario. Imprimir cada objeto de diccionario línea por línea e incluir el camino absoluto.
Analicemos primero el código que proviene de 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__))) |
Es conciso, funciona y cumple su función. Yo le daría un aprobado. También es una tarea excepcionalmente trivial, pero está bien.
Ahora veamos el código que proviene de 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 # Tamaño en bytes metadata['modified_time'] = stat.st_mtime # Última marca de tiempo de modificación metadata['accessed_time'] = stat.st_atime # Última marca de tiempo de acceso except OSError: print(f"Error al acceder al archivo: {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"Ruta absoluta: {file_path}") # Imprime la ruta absoluta print(metadata) if __name__ == '__main__': retrieve_metadata_recursively(os.path.dirname(os.path.abspath(__file__))) |
Gemini es un poco más verboso, aunque, añadió algo de manejo de errores lo cual, supongo, es bueno. Es algo largo pero funciona así que le daremos un pase.
Para la siguiente tarea quería ver qué tan bien ambos motores pueden entender un lenguaje dado y crear un analizador basado en ese lenguaje. En este caso vamos a construir un raspador web usando la siguiente indicación:
Escribe un script de Python usando BeautifulSoup o Scrapy que raspe los titulares principales de noticias de 'https://news.ycombinator.com' y los exporte a un objeto de diccionario.
Aquí hay un fragmento de la fuente de la página de 'https://news.ycombinator.com'. Usa esto para determinar cómo analizar las etiquetas.
Escribe un script de Python usando BeautifulSoup o Scrapy que raspe los titulares principales de noticias de 'https://news.ycombinator.com' y los exporte a un objeto de diccionario. Aquí hay un fragmento de la fuente de la página de 'https://news.ycombinator.com'. Usa esto para determinar cómo analizar las etiquetas. <html lang="es" 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"> |
Como notarás, incluí algo de HTML en mi indicación. Mi indicación real consiste en más HTML pero lo truncé para este artículo. Aquí está lo que generó GPT4:
import requests # URL del sitio a raspar # Envía una solicitud GET a la URL # Analiza el contenido HTML de la página usando BeautifulSoup # Encuentra todos los titulares de noticias # Diccionario para almacenar los titulares donde la clave es el rango y el valor es el texto del titular # Itera a través de cada titular, extráelo y almacénalo en el diccionario # Muestra el diccionario |
Este código funciona bien y hace lo que se supone que debe hacer. Esperaba que supiera, intuitivamente, que quería el enlace a los artículos pero no fui explícito, así que no puedo usar eso como una marca en contra de la calificación de GPT4.
Aquí está lo que Gemini generó:
import requests # Envía una solicitud HTTP GET al sitio web de Hacker News # Analizar el contenido HTML usando BeautifulSoup # Encontrar todos los elementos de clase 'athing', que contienen los artículos de noticias # Crear un diccionario vacío para almacenar los titulares # Recorrer cada artículo y extraer el titular y la URL # Encontrar el elemento de la URL # Añadir el titular y la URL al diccionario # Imprimir el diccionario de titulares |
Esto también funciona y es bastante similar a la salida de GPT4, pero este código realmente extrae la URL. Eso está bien, pero, de nuevo, no es una expectativa. En este desafío diría que son, prácticamente, lo mismo. Quizás Gemini gana un punto extra por ser un lector de mentes.
Para esta tarea quiero crear una aplicación web que muestre gráficos de acciones de algunos tickers diferentes:
Crea una aplicación web en Python que muestre gráficos de las siguientes acciones: RIVN, TSLA, NKLA, FSR |
Esta definitivamente fue más complicada. Requiere un componente de frontend (es decir, gráficos/imagenes) y un componente de backend (es decir, recuperar los datos de una base de datos de acciones). He generado innumerables aplicaciones con GPT4 y quería ver cómo se comparaba Gemini con él. Esto es lo que GPT4 generó para mí:
from flask import Flask, render_template_string app = Flask(__name__) @app.route('/') fig = go.Figure() for stock in stocks: graph_html = fig.to_html(full_html=False) return render_template_string(""" |
Figura 2: Captura de pantalla de la aplicación web generada por GPT4
Es simple, limpia y al grano. Sin adornos pero cumple su función. Esto es lo que Gemini generó para mí:
import flask app = flask.Flask(__name__) # Símbolos de acciones # Obtener datos de acciones usando yfinance @app.route('/') charts = [] return render_template('index.html', charts=charts) if __name__ == '__main__': |
También me requirió crear un nuevo archivo, index.html, en un nuevo directorio llamado templates:
<!DOCTYPE html> |
Figura 3: Captura de pantalla de la aplicación web generada por Gemini Advanced
Definitivamente era más sofisticado, ya que incluía un histograma y abstraía el contenido HTML en un nuevo archivo. De nuevo, ambos eran funcionales, por lo tanto, ambos reciben una calificación aprobatoria.
Cuando GPT4 se lanzó por primera vez, tomó tiempo entender cómo "solicitarlo" adecuadamente. Al usar IA Generativa para escribir código, los detalles importan. Como resultado, muchos de nosotros nos hemos vuelto más competentes como "Ingenieros de Solicitudes" durante este último año. Desafortunadamente, esto puede introducir cierto sesgo al comparar GPT4 con otros motores y estoy dispuesto a admitirlo. Sé cómo "funciona" GPT4 más que cómo funciona Gemini. La manera en que formulo solicitudes para GPT4 podría ser diferente a lo que Gemini espera. Sin embargo, aún me encontré con algunos problemas muy fundamentales con Gemini.
Un problema común que encontré con Gemini al interpretar instrucciones fue al generar pruebas unitarias. Mi objetivo inicial era cubrir las pruebas unitarias en el artículo pero, por frustración, renuncié por completo a Gemini porque nunca seguía las instrucciones. Por ejemplo, le pediría a Gemini que escribiera una prueba unitaria usando Pytest y la encapsulara en una clase. Generaría la prueba usando UnitTest en su lugar, ignorando descaradamente mi solicitud, pero encapsularía el código dentro de una clase. Lo corregiría y reconocería que accidentalmente usó UnitTest en lugar de Pytest. Luego reescribiría el código usando Pytest pero se olvidaría de ponerlo en una clase. Cuando solicito que use una construcción Mock, recurre por defecto al mock de UnitTest versus el Mock de Pytest. Estos son matices pero importantes al interactuar con la IA Generativa.
Figura 4: Gemini Avanzado no siguiendo instrucciones
La solución de fallos fue otro punto doloroso. El motor de razonamiento de GPT4 ha demostrado ser bastante poderoso al depurar errores en Python. Gemini… no tanto. Cuando le pedía que solucionara ciertos problemas, simplemente intentaba reescribir el código con sangrías adicionales o intercambiando variables… una respuesta completamente inútil.
A veces, Gemini simplemente no funcionaba. Decía que no podía procesar mi solicitud. En otros casos, comenzó a comentar sobre las... ¿próximas elecciones?
Figura 5: Gemini Advanced confundido acerca de las próximas elecciones?
En general, la calidad del código base generado por Gemini fue bastante competitiva en comparación con GPT4. Sin embargo, la experiencia y su motor de razonamiento dejaban mucho que desear. Afortunadamente para Google, esos elementos son parte de la implementación del LLM y no del LLM en sí. En otras palabras, el LLM de Gemini parece ser, fundamentalmente, bastante bueno y a la par con GPT4, pero el código escrito alrededor de él que se utiliza en la experiencia de chat necesita ayuda. Con el tiempo, probablemente veremos a Google iterar en su código y mejorar esa experiencia y motor de razonamiento.