Usar IA para Ahorrar Tiempo en Dev: Explicación Detallada con Ejemplos

Este artículo tiene un vídeo corto:TikTok

1. Resumen general

Este artículo aborda una pregunta muy práctica: cómo usar IA (específicamente LLM como GPT, Claude) para ahorrar tiempo en el trabajo diario de desarrollo sin convertirte en alguien que “copia y pega ciegamente”. Verás cómo integrar LLM en una aplicación Spring Boot usando Spring AI, cómo usar IA para generar tests, crear Javadoc, y qué trampas debes evitar.

Al terminar de leer, podrás escribir tu propio ChatClient para llamar LLM en Spring Boot, sabrás cómo escribir prompts para cada tarea (generar código, revisar, escribir tests), y entenderás cuándo IA realmente te ayuda y cuándo solo te ralentiza.

2. Dónde ahorra la IA tiempo en el trabajo dev

No es cierto que la IA sea más rápida que tú en todas partes. Hay tres tipos de tareas donde realmente vale la pena usarla:

  • Tareas repetitivas con patrón claro: generar DTOs desde entities, generar getters/setters (aunque el IDE ya lo hace), generar casos de test boilerplate.
  • Tareas que requieren síntesis rápida de información: leer stacktraces largos, resumir PRs, explicar fragmentos de código legacy sin comentarios.
  • Tareas que necesitan un borrador inicial: escribir Javadoc, escribir README, escribir consultas SQL complejas para que luego las revises y corrijas.

Por el contrario, la IA no ahorra tiempo cuando: todavía no entiendes bien el problema (prompt vago produce output vago), la lógica de negocio es compleja y específica de tu empresa, o el código necesita alta precisión en seguridad/finanzas y no lo revisas cuidadosamente.

Nota: Si la IA genera código rápido pero la revisión es lenta, el tiempo total no se reduce, a veces incluso aumenta porque tienes que debuggear código que “se ve correcto pero está mal en lógica”.

3. Integración de LLM en Spring Boot con Spring AI

En lugar de llamar manualmente la API REST con RestTemplate, usa Spring AI para tener un ChatClient conveniente.

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Declara la clave API en application.properties:

spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-4o-mini

Crea un servicio que envuelva ChatClient:

@Service
public class CodeAssistantService {

    private final ChatClient chatClient;

    public CodeAssistantService(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    public String explainStackTrace(String stackTrace) {
        String prompt = """
                Eres un ingeniero Java senior. Explica brevemente la causa
                del siguiente stacktrace y sugiere una solución:
                %s
                """.formatted(stackTrace);

        return chatClient.prompt()
                .user(prompt)
                .call()
                .content();
    }
}
  • ChatClient.Builder es auto-configurado por Spring Boot gracias al starter anterior, solo necesitas inyectarlo.
  • prompt().user(...).call().content() envía el prompt y obtiene la respuesta como texto, sin necesidad de parsear JSON manualmente.
  • El método explainStackTrace recibe un stacktrace largo y devuelve una explicación breve — esto ahorra 5–10 minutos leyendo logs cada vez que debuggeas un error extraño.

Pruébalo en un controller:

@RestController
@RequestMapping("/api/assist")
public class CodeAssistantController {

    private final CodeAssistantService assistantService;

    public CodeAssistantController(CodeAssistantService assistantService) {
        this.assistantService = assistantService;
    }

    @PostMapping("/explain")
    public String explain(@RequestBody String stackTrace) {
        return assistantService.explainStackTrace(stackTrace);
    }
}

Llamar POST /api/assist/explain con un body que contiene un stacktrace de NullPointerException devuelve una explicación como:

El NullPointerException ocurre porque la variable `customer` no fue inicializada
antes de llamar `customer.getEmail()`. Revisa OrderService — posiblemente
el repositorio devuelva null cuando no encuentra el registro. Deberías usar
Optional o verificar null antes de acceder a propiedades.

4. Usar IA para generar unit tests automáticamente — ejemplo concreto

Una de las tareas más tediosas es escribir casos de test para cada rama de lógica. Supongamos que tienes la clase DiscountCalculator:

public class DiscountCalculator {

    public BigDecimal calculate(BigDecimal orderAmount, CustomerTier tier) {
        if (orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("El monto debe ser positivo");
        }
        BigDecimal rate = switch (tier) {
            case GOLD -> new BigDecimal("0.15");
            case SILVER -> new BigDecimal("0.10");
            case BASIC -> new BigDecimal("0.05");
        };
        return orderAmount.multiply(rate).setScale(2, RoundingMode.HALF_UP);
    }
}

Prompt sugerido para pedirle a LLM que genere tests (copias la clase anterior en el prompt):

Escribe un unit test JUnit 5 + AssertJ para la clase DiscountCalculator.
Incluye casos: GOLD, SILVER, BASIC, y el caso donde orderAmount <= 0 debe lanzar
IllegalArgumentException. Usa @ParameterizedTest si es apropiado.

La IA normalmente devuelve un borrador casi correcto, que luego ajustas al estilo de tu equipo:

class DiscountCalculatorTest {

    private final DiscountCalculator calculator = new DiscountCalculator();

    @ParameterizedTest
    @CsvSource({
            "GOLD, 100, 15.00",
            "SILVER, 100, 10.00",
            "BASIC, 100, 5.00"
    })
    void shouldCalculateDiscountByTier(CustomerTier tier, String amount, String expected) {
        BigDecimal result = calculator.calculate(new BigDecimal(amount), tier);

        assertThat(result).isEqualByComparingTo(new BigDecimal(expected));
    }

    @Test
    void shouldThrowWhenOrderAmountIsNotPositive() {
        assertThatThrownBy(() -> calculator.calculate(BigDecimal.ZERO, CustomerTier.GOLD))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("El monto debe ser positivo");
    }
}
  • @ParameterizedTest + @CsvSource agrupa 3 casos de tier en un solo test, reduciendo duplicación de código.
  • assertThat(result).isEqualByComparingTo(...) compara BigDecimal correctamente (evita errores con equals que considera la escala).
  • El caso restante verifica la excepción con mensaje específico.

Donde la IA es rápida aquí es listando todos los casos límite (fácilmente olvidas el caso orderAmount <= 0), pero lo que tú debes hacer es verificar que los valores esperados sean correctos — la IA calculando números incorrectamente es algo común.

5. Usar IA para generar Javadoc y resumir código legacy

Con código antiguo sin comentarios, la IA resume más rápido que tú leyendo línea por línea. Por ejemplo, si tienes un fragmento de lógica compleja:

public List<Order> filterEligibleOrders(List<Order> orders) {
    return orders.stream()
            .filter(o -> o.getStatus() == OrderStatus.PAID)
            .filter(o -> o.getCreatedAt().isAfter(LocalDate.now().minusDays(30)))
            .filter(o -> o.getItems().stream().anyMatch(Item::isRefundable))
            .toList();
}

Prompt: “Escribe Javadoc para este método, explicando claramente las 3 condiciones de filtrado.” La IA devuelve:

/**
 * Filtra la lista de órdenes elegibles para procesar reembolso.
 * Condiciones: la orden debe estar en estado PAID, haber sido creada en los últimos 30 días,
 * y tener al menos un item que permita reembolso.
 *
 * @param orders lista de órdenes de entrada
 * @return lista de órdenes que cumplen las tres condiciones anteriores
 */

Esto ahorra tiempo onboarding de personas nuevas a una codebase legacy — copias muchos métodos al prompt, la IA devuelve borradores de Javadoc, y solo corriges términos específicos del negocio.

6. Automatizar revisión de código con IA en CI

Puedes integrar una llamada a IA para revisar diffs en tu pipeline CI para detectar errores temprano, antes de que un humano lo revise. Ejemplo simple en GitHub Actions llamando la API:

name: ai-review
on: [pull_request]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Obtener diff
        run: git diff origin/main...HEAD > diff.txt
      - name: Llamar revisión IA
        run: |
          curl -s https://api.openai.com/v1/chat/completions \
            -H "Authorization: Bearer ${{ secrets.OPENAI_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d "$(jq -n --rawfile diff diff.txt \
              '{model:"gpt-4o-mini", messages:[{role:"user", content: ("Revisa el siguiente diff Java, solo menciona problemas graves: " + $diff)}]}')" \
            > review.json
  • git diff origin/main...HEAD obtiene solo el código cambiado en el PR, evitando enviar todo el repo (consume tokens, es lento).
  • jq -n --rawfile construye el JSON body de forma segura, evitando errores de escape en caracteres especiales del código.
  • El resultado review.json puedes publicarlo nuevamente como comentario en el PR en otro step.

Nota: La revisión IA no reemplaza la revisión de un senior. Solo detecta errores obvios (null checks faltantes, catch Exception vacío, SQL injection básico). No hagas merge de un PR solo porque la IA lo “aprobó”.

7. Errores comunes y cuándo no usar IA

Algunas trampas reales al usar LLM en proyectos Java:

  • Alucinación de APIs inexistentes: la IA puede sugerir llamar Order.markAsRefundable() cuando la clase real no tiene ese método. Siempre compila primero antes de confiar.
  • Código sintácticamente correcto pero versión inconsistente: la IA suele mezclar estilo Java 8 (new ArrayList<>()) con Java 21 (List.of(...)) sin consistencia — necesitas estandarizar según la convención de tu equipo.
  • Fuga de información sensible: no pegues configuración con secrets, cadenas de conexión, o datos reales de clientes en un prompt que envías a un servicio IA de terceros.
  • Prompt vago → output vago: “escribe test para esta clase” produce resultados mucho más pobres que un prompt que especifique casos límite claros.
  • No usar IA cuando: el cálculo de intereses, cálculo de impuestos, o cualquier parte relacionada con cumplimiento normativo donde un error es una cuestión legal — la IA solo debe ayudar a escribir la estructura, la parte de cálculo core debe ser verificada cuidadosamente por alguien con experiencia en negocio usando casos de test reales, no casos de test inventados por la IA.

Una pequeña checklist que deberías aplicar cada vez que uses IA para generar código:

1. ¿El código compila?
2. ¿Los casos de test generados por IA cubren realmente los casos límite, o solo cubren lo que "suena razonable"?
3. ¿Alguna información sensible terminó en el prompt?
4. ¿El estilo de código coincide con la convención actual de tu equipo?

8. Conclusión

La IA te ahorra tiempo de forma evidente en tareas repetitivas y que necesitan borradores rápidos: generar casos de test, explicar stacktraces, escribir Javadoc, revisar diffs inicialmente. Spring AI hace que integrar LLM en aplicaciones Java sea simple, solo con algunas líneas de configuración y ChatClient.

El punto clave es que todavía necesitas revisar cuidadosamente todo lo que genera la IA — ahorra tiempo escribiendo, no ahorra tiempo entendiendo y verificando. Usada en los lugares correctos y con el nivel correcto de confianza, puedes reducir significativamente las horas repetitivas cada semana sin comprometer la calidad del código.

llmspring-aiaiproductivityjava