Automatizando procesos de desarrollo: cómo usar la API de OpenAI para la generación de código

0
2261

En un anterior artículo ya planteamos cómo, usando una IA, podíamos crear una API con un CRUD muy sencillo simplemente indicando una serie de pasos más o menos precisos. Aunque aún queda mucho camino que recorrer, vemos atisbos de cómo usar esta tecnología en nuestro beneficio, y podemos intentar automatizar pequeños procesos en nuestro día a día.

En este artículo proponemos una aplicación más práctica, y vamos a crear de manera automatizada una API REST completa para Spring Boot. Para ello vamos a crear un script en Python, el cual consuma de la API de OpenAI, y genere los archivos deseados paso a paso de manera autónoma, partiendo de un prompt inicial.

Índice de contenidos

  1. ¿Qué necesitamos?
  2. OpenIA API
    2.1 CURL
    2.2 Librería NodeJS
    2.3 Librería Python
  3. Vamos a ello
  4. Poniendolo en funcionamiento
  5. Conclusiones

¿Qué necesitamos?

  • Una cuenta en OpenAI para poder consumir su API
  • Generar una API key
  • Tener Python instalado
  • Un nuevo proyecto en Spring Boot para ejecutar el código generado
  • Librería de OpenAI (si aplica)

OpenAI API

OpenAI ofrece una API de pago para sus usuarios (en nuestro caso al registrarnos obtuvimos un tiempo de prueba gratis). Esta será el eje central del tutorial, por lo que vamos a explayarnos un poco en su funcionamiento.

Actualmente hay diversos modos de consumirla, así que vamos a hacer un pequeño repaso de las tres formas oficiales.

CURL

curl https://api.openai.com/v1/chat/completions 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer $OPENAI_API_KEY" 
  -d '{
     "model": "gpt-3.5-turbo",
     "messages": [{"role": "user", "content": "Say this is a test!"}],
     "temperature": 0.7
   }'

El comando es muy sencillo, sólo necesitamos indicarle:

  • OPENAI_API_KEY: API key previamente generada en tu cuenta.
  • Model: modelo que queramos usar para nuestra consulta.
  • Messages: el contenido del prompt o prompts que va a interpretar el modelo.
  • Role: rol que ha de tomar el modelo.
  • Content: prompt que va a interpretar el modelo.

Librería NodeJS

Para instalar la librería debemos usar:

npm install openai

Después de eso, ya podemos hacer uso de la misma. En este ejemplo hacemos uso de la librería para obtener los modelos disponibles:

const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion({
  model: "text-davinci-003",
  prompt: "Say this is a test",
  temperature: 0,
  max_tokens: 7,
});
  • ApiKey: API key previamente generada en tu cuenta.
  • Model: modelo que queramos usar para nuestra consulta.
  • Prompt: prompt que va a interpretar el modelo.

Libreria de Python

Al igual que con node, hemos de instalar la librería, en este caso para Python:

pip install openai

El ejemplo de obtención de los modelos existentes sería el siguiente:

import os
import openai

# Load your API key from an environment variable or secret management service
openai.api_key = os.getenv("OPENAI_API_KEY")

response = openai.Completion.create(model="text-davinci-003", prompt="Say this is a test", temperature=0, max_tokens=7)
  • ApiKey: como con el paso de Node, debemos indicarle el API key.
  • Model: le indicamos el modelo a usar.
  • Prompt: la consulta al modelo.

Además de estas herramientas que OpenAI nos proporciona, existen multitud de librerías para distintos lenguajes de programación creadas y mantenidas por comunidades. En la documentación oficial podéis encontrar dichas librerías, además de los ejemplos aquí expuestos.

Vamos a ello

Ahora que hemos visto cómo se utiliza la librería de la API, podemos comenzar con nuestro script de Python. 

Lo primero que debemos hacer es inicializar la API key indicándosela al contexto. Depués definimos los prompts que van a ejecutarse consecutivamente de manera automática. Para ello guardamos cada sentencia en un diccionario y como clave utilizamos el nombre del archivo donde posteriormente se guardará. Con esto tenemos una estructura de datos con  un clave valor fichero/sentencia:

openai.api_key = "OPENAI_API_KEY"
promptsDict = {
    ".sql": "Create a SQL {} table with {} and create a primary key sequence.",
    "Entity.java": "Create a JPA class entity {} using the previous table and use Lombok API.",
    "Repository.java": "Using the previous {} entity, create a JPA crud repository.",
    "Service.java": "Using the previous {} repository, create a CRUD service that injects the repository by the constructor.",
    "Controller.java" : "Using the previous {} service, create a Springboot REST API controller that injects the service by the constructor."
}

Como podemos ver, dejamos parametrizado (utilzando {}) el nombre de la entidad, así como las propiedades en el caso del sql, ya que eso es algo que introducirá el usuario por teclado.

Vamos a definir también una función para realizar la llamada a la API y que retorne el contenido de la respuesta en formato de texto:

def generate_response(prompt):
    response = openai.Completion.create(
        engine="text-davinci-003",
        prompt=prompt,
        max_tokens=1000,
        n=1,
        stop=None,
        temperature=0.5,
    )
    return response.choices[0].text.strip()

Para finalizar este apartado de definición, creamos una función que se encargue de escribir en ficheros los resultados que devuelve la API. Definimos como parámetros el nombre, la extensión y el contenido:

def write_file(property_name, file_extension, text):
    file = name + file_extension
    with open(file, "w") as file:
        file.write(text)

Ahora vamos con el flujo principal. Lo primero que tenemos que hacer es pedirle al usuario el nombre de la entidad que quiera definir, así como el nombre de las propiedades y sus respectivos tipos. Para ello podemos usar el siguiente código:

name = input("Please enter the API name, type 'end' when you want to stop defining: ")
property_name = input("Please enter property name: ")
property_dict = {}

while property_name != "end":
    property_type = input("Please enter property type: ")
    property_dict[property_name] = property_type
    property_name = input("Please enter property name: ")

Como se puede apreciar tenemos un bucle en el que el usuario define el nombre de la entidad y posteriormente va indicando las propiedades de la misma. 

Ahora transformamos el diccionario donde hemos guardado la información en una sola sentencia para introducirla en el prompt de creación de SQL:

sql_prompt_parameter = ''

for key in property_dict:
    sql_prompt_parameter += 'a ' + property_dict[key] + ' ' + key + ' field, '

promptsDict['.sql'] = promptsDict['.sql'].format('{}', sql_prompt_parameter)

Ahora sólo queda definir el algoritmo final, el cual tiene un funcionamiento muy simple. Lo primero que debemos tener en cuenta es que Chat GPT necesita el contexto de las entradas anteriores para generar correctamente las clases. Esto desde la clásica interfaz de texto que todos usamos es transparente para nosotros, puesto que vas escribiendo debajo de lo que la IA responde. Por lo tanto, para el correcto funcionamiento tenemos que ir anidando una respuesta con el siguiente prompt, consiguiendo así el mismo efecto:

accumulativePrompt = ""

for key in promptsDict:
    accumulativePrompt += ' ' + promptsDict[key].format(name)
    response = generate_response(accumulativePrompt)
    accumulativePrompt += ' ' + response
    write_file(name, key, response)
    print(response)

Si observamos el código, lo que hacemos es que a cada llamada a la API invocamos a nuestra función de escribir en fichero. Utilizamos la key del diccionario junto con el nombre de la entidad para generar correctamente el nombre del archivo, dejándonos unos .class y un .sql listos para copiar y pegar en nuestro proyecto Java.

Poniéndolo en funcionamiento

Ahora que ya tenemos todo no queda más que probar el script. En nuestro caso, voy a definir una entidad Student con dos atributos: nombre y edad.

Una vez terminada la primera fase de introducir datos, comienzan las llamadas a la API. Como tenemos un printf con las respuestas podemos ir monitoreando lo que ocurre:

Cuando termina, observamos cómo, en efecto, se han creado cuatro ficheros en la raíz de nuestro proyecto:

Por último, si visualizamos cualquiera de ellos, comprobaremos que está el código perfectamente formateado y listo para su uso:

Conclusiones

En definitiva, utilizar una API de una IA es bastante más sencillo de lo que uno puede pensar en un inicio, tal y como hemos visto a lo largo del artículo. En nuestro caso hemos hecho un simple CRUD a modo de ejemplo, pero hay miles de diferentes aplicaciones posibles. Al final, el límite es lo que queramos complicarnos, pero sin duda las IAs se plantean como una herramienta muy potente implementadas de esta manera.

Como detalle, cabe decir que no entramos en la calidad del código generado por Chat GPT, ya que lo que nos interesa en este artículo es cómo podemos automatizar mediante una API los procesos de prompt con un fin concreto. De hecho, ese sería uno de los mayores peros, la inconsistencia en las respuestas. A cada intento que hemos hecho, utilizando prompts idénticos, devuelve código ligeramente distinto, cambiando pequeñas cosas aquí y allá.

En mi opinión, queda camino por recorrer y de afinación, pero creo que es muy interesante lo que pueden ofrecernos las IAs si sabemos sacarle provecho.

Este artículo ha sido realizado por David Plaza y Óscar Sánchez.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad