Amazon CodeWhisperer el asistente de programación de Amazon

0
179
Foto de Joshua J. Cotten en Unsplash

Estamos viviendo una explosión de la IA y la programación. Están entrando en juego numerosos actores y, entre ellos, no podía faltar Amazon para meter dentro de los servicios que provee un asistente para la programación que han llamado CodeWhisperer. En este artículo vamos a ver como podemos usarlo y que nos ofrece. Cabe destacar que está en período de vista previa y se espera que evolucione. Dentro de todo el ecosistema de productos, seguramente su rival más directo seria Github Copilot, que ya hemos visto en otros artículos.

0. Índice de contenidos.

  1. Introducción.
  2. Entorno.
  3. Creación del modelo.
  4. Creación del repositorio.
  5. Creación del servicio.
  6. Creación del controlador.
  7. Conclusiones.
  8. Referencias.

1. Introducción.

Amazon CodeWhisperer es una herramienta que nos ayuda a hacer pair programming basado en IA que genera sugerencias de código en tiempo real en nuestro IDE para ayudarnos a crear software.

CodeWhisperer Individual es de uso gratuito y solo necesitamos un inicio de sesión con AWS Builder.

La arquitectura de CodeWhisperer se basa en LLM (Large Language Model) entrenado con grandes cantidades de código.

2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Lenovo t480 (1.80 GHz intel i7-8550U, 32GB DDR4).
  • Sistema Operativo: Linux fedora 6.2.15-300.fc38.x86_64
  • IntelliJ IDEA 2023.1.2 (Ultimate Edition)

3. Creación del modelo.

Antes de comenzar, para usar CodeWhisperer se necesita:

El plug-in sería el siguiente:
aws toolkit plugin intellij

Una vez tenemos todo instalado siguiendo los pasos anteriores, veremos un panel donde podemos pausar o iniciar las sugerencias.

panel aws toolkit intellij

Al igual que pasaba con Github Copilot, CodeWhisperer no nos genera el fichero del proyecto. Vamos a seguir los mismos pasos que vimos en el tutorial de Github Copilot que es un proyecto generado con spring initializr.

Vamos a contar con las siguientes dependencias:

  • lombok
  • spring-boot-starter-data-jpa
  • h2
  • spring-boot-starter-web

Siendo todo parte de la última versión hasta la fecha de Spring Boot 3 (3.1.0)

El pom.xml queda asi:

Al ser la primera entidad vamos a pedirle a CodeWhisperer que nos genere el código de la entidad.

Con // create a jpa entity class called Student with lombok annotations

Como podemos ver funciona como Github Copilot:

sugerencia code whisperer

Esa sugerencia es bastante comedida, nos pone mas sugerencias en comentarios que hace pensar que no sabe bien que es lombok. Tiene más sugerencias que nos da en una ventana como esta:

diferentes sugerencias code whisperer

Otro ejemplo de sugerencia sería este:

Aquí vemos que adolece del mismo problema que Github Copilot, que usa el API de persistencia de javax y no la de jakarta. Vamos a pedirle que nos genere el código con la API de Jakarta. Otro problema que tiene es que no deja que ningún campo sea nulo. Por último está usando palabras cortas como dob en lugar de dateOfBirth que sería más legible. Vamos a intentar que use jakarta

// jpa entity class called Student with lombok annotations using jakarta

Ahora vemos que la respuesta no es consistente con la anterior, no ha generado los mismos campos, porque seguramente no tenga claro que es un estudiante y no itera sobre lo anterior como si fuera una conversación. De hecho es un poco raro poner a una columna emailId el nombre de email_address. Otra cosa rara es la clase Guardian que no existe. Tampoco ha usado las anotaciones de jakarta.

Si intentamos darle más pistas para indicar que estamos usando spring boot 3 con el siguiente prompt:

// create a jpa entity class called Student with lombok annotations an id and a name for springboot 3

Nos genera lo siguiente:

Nos damos cuenta que ha omitido toda la parte de lombok y no ha puesto nada de spring. Parece que le hemos confundido mas que ayudado. En algunas ocasiones puede parecer que mas que ayudarnos a nosotros, somos nosotros los que tenemos que ayudarle a él.

El mejor resultado para esta entidad lo hemos conseguido con el siguiente prompt:

// create a jpa entity class called Student with lombok annotations

Es la clase más comedida en cuanto a campos y anotaciones. Con unos pocos retoques quedaría como nosotros queremos.

Da la sensación que a medida que hemos ido avanzando nos ha ido conociendo algo más y va afinando resultados.

También, a medida que vamos usando este tipo de herramientas nos vamos dando cuenta que estos asistentes están para asistir y que puede que intentar que nos genere entidades desde cero, sea mucho.

Si queremos que nos vaya ayudando en lugar de ponerle un comentario, se empeña en crearnos un User y no un Student.

Sugerencia user

Lo dejamos así.

4. Creación del repositorio.

Para el repositorio, hemos intentado que nos asista, pero las sugerencias que nos da no son muy buenas. En el StudentRepository nos sugiere que usemos la entidad User.

sugerencia 1 repositorio
sugerencia 2 repositorio

Ayudándole se puede conseguir que genere el repositorio. Si cambiamos la entidad de dominio por la nuestra mejora, pero por ejemplo no le pone los tipos al JpaRepository que sería algo así como JpaRepository<Student, Long>. Es como si no tuviera contexto y por eso nos sugiere primero poner un User y luego no nos da la sugerencia de usar Student y Long en el JpaRepository.

Con la interfaz vacía, nos sugiere métodos que no tienen mucho sentido, ya que por ejemplo nuestra entidad no tiene un campo email. Lo mismo pasa con otros campos, el único campo que tiene la entidad es el id.

Lo dejamos así.

5. Creación del servicio.

Para el servicio, pasa lo mismo que con el repositorio, empieza a sugerirnos el uso de List y Optional, que son muy comunes. Pero la tercera sugerencia es que usemos la entidad User que no existe.

Al igual que con el repositorio, si le ayudamos un poco, vamos a conseguir que nos genere el servicio. Le ponemos el modelo correcto y nos genera el servicio, pero como antes, nos empieza a sugerir métodos que no pueden darse, ya que no existen en la entidad.

Lo dejamos así.

Vamos con la implementación.

Dándole otro pequeño empujón, le indicamos que es lo que queremos (que nos implemente el StudentService) y ya si nos va ofreciendo más ayuda. Aun así, necesitamos dejarle casi todo hecho.

Como vemos a continuación, muchas de las sugerencias tienen código de más o nos da tests un poco dudosos. Hay que ir jugando y tener paciencia con las recomendaciones.

sugerencia 1 servicio
sugerencia 1 servicio
sugerencia 2 servicio
sugerencia 2 servicio

Queda así

6. Creación del controlador.

En el caso del controlador, nos ayuda más. El path que nos sugiere esta bastante bien y a medida que vamos implementando la clase, nos va sugiriendo métodos. Da la impresión que los controladores los genera mejor, tal vez porque son más sencillos y sus implementaciones suelen ser siempre más o menos iguales. En cambio en servicios y repositorios se puede meter lógica de negocio.

Pero tenemos que ir corrigiendo los tipos que devuelve. También vemos que se lía con el nombre de los métodos. Lo dejamos solo con el get

A medida que hemos ido implementando cosas, ha ido metiendo endpoints que apuntan a tests. Parece que está mezclando la implementación con los tests, pero no ha sugerido importar nada relacionado con los tests.

7. Conclusiones.

Todos los ejemplos que hemos visto, al igual que anteriores artículos, no son deterministas, por lo que siguiendo los mismos pasos, se pueden llegar a situaciones distintas.

Basándonos en lo que hemos probado de Amazon CodeWhisperer, creemos que tiene potencial, pero mucho camino por recorrer. Parece que está un paso por detrás de Github Copilot, pero estando Amazon detrás, seguro que consigue ponerse a la altura.

Tras las pruebas que se han hecho con CodeWhisperer y Copilot, da la sensación que no son muy buenos de momento a la hora de crear cosas desde cero, o que cuando hay muchas posibilidades, no dan muy buenos resultados. Por ejemplo, un controlador siempre suele ser una llamada al servicio. En cambio, con los servicios, donde seguramente ha visto código con más lógica, no ha sido muy útil.

Los ejemplos que siempre nos ponen, son ejemplos de algoritmos, donde ellos tienen ventaja, ya que si es un problema matemático conocido, es más fácil que ellos sepan la solución óptima, mientras que nosotros podemos no ser conscientes de que hay varias alternativas o incluso no saber que ese problema tiene una solución conocida y hacer nosotros una solución que no sea la más óptima o legible.

Si vemos la solución de geeksforgeeks:

La respuesta de codewhisperer es más rebuscada. Si optamos por la versión estática con clase, acabamos en un callejón sin salida

Quicksort estático
Quicksort estático
Implementación quicksort estático
Implementación quicksort estático

Si optamos por la versión estática de la función sin clase (la primera sugerencia que nos da), este es el código

Hemos tenido que crear la clase y la función desde el IDE porque no nos da una respuesta entera.

Puede que cuando esto avance, en vez de pasarnos tiempo pensando en soluciones, pasemos tiempo pensando en mejores soluciones y haciendo software de mayor calidad o más óptimo.

Esto no ha hecho más que empezar, hay muchas empresas con muchos intereses que están apostando fuerte en estas tecnologías, así que veremos un avance exponencial y, donde ahora vemos que le tenemos que ayudar más, nos ayudara más él a nosotros.

También hay que tener cuidado con la privacidad de estas herramientas en general.

8. Referencias.

Dejar respuesta

Please enter your comment!
Please enter your name here