Use AI para Economizar Tempo como Dev: Explicação Detalhada
1. Visão geral
Este artigo resolve uma pergunta muito prática: como usar AI (especificamente LLMs como GPT, Claude) para economizar tempo no trabalho de código diário, sem se tornar alguém que faz “copy-paste cego”. Você verá como integrar LLM em uma aplicação Spring Boot usando Spring AI, como usar AI para gerar testes, gerar Javadoc, e armadilhas a evitar.
Depois de ler, você será capaz de escrever seu próprio ChatClient chamando LLM em Spring Boot, saber como escrever prompts para cada tarefa (gerar código, review, escrever testes), e saber quando AI realmente ajuda e quando apenas o desacelera.
2. AI economiza tempo em quais tarefas no trabalho dev
Nem todo lugar AI é mais rápido do que você fazer sozinho. Três grupos de trabalho onde AI realmente vale a pena usar:
- Trabalho repetitivo com padrão claro: gerar DTO de entity, gerar getter/setter (mesmo que IDE já faça), gerar boilerplate test cases.
- Trabalho que precisa sintetizar informações rápido: ler stacktrace longo, resumir PR, explicar código legacy sem comentários.
- Trabalho que precisa de um rascunho inicial: escrever Javadoc, escrever README, escrever query SQL complexa para você corrigir depois.
Por outro lado, AI não economiza tempo quando: você ainda não entendeu bem o problema (prompt vago = resultado vago), a lógica de negócio é complexa e específica da empresa, ou o código precisa de alta precisão em segurança/finanças e você não revisa bem.
Nota: AI gera código rápido mas revisar é lento, então o tempo total às vezes não diminui, e pode até aumentar porque você precisa debugar código que “parece certo mas está errado”.
3. Integrar LLM em Spring Boot com Spring AI
Em vez de chamar REST API manualmente com RestTemplate, você usa Spring AI para ter um ChatClient conveniente.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
Declare a chave API em application.properties:
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-4o-mini
Crie um serviço que encapsule o 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 = """
Você é um senior Java engineer. Explique brevemente a causa
do seguinte stacktrace e proponha como corrigir em português:
%s
""".formatted(stackTrace);
return chatClient.prompt()
.user(prompt)
.call()
.content();
}
}
ChatClient.Builderé auto-configurado pelo Spring Boot graças ao starter acima, você só precisa injetar.prompt().user(...).call().content()envia o prompt e retorna a resposta como string, sem precisar fazer parse JSON manual.- O método
explainStackTracerecebe um stacktrace longo e retorna uma explicação breve — isso economiza 5–10 minutos lendo log cada vez que debuga um erro estranho.
Tente em um 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);
}
}
O resultado de chamar POST /api/assist/explain com um stacktrace de NullPointerException no body retornará algo como:
O erro NullPointerException acontece porque a variável `customer` não foi inicializada
antes de chamar `customer.getEmail()`. Verifique novamente o OrderService — é possível
que o repository retorne null quando não encontrar o registro. Você deveria usar Optional
ou verificar null antes de acessar propriedades.
4. Usar AI para gerar testes unitários automaticamente — exemplo prático
Uma das tarefas mais demoradas é escrever test cases para cada branch de lógica. Suponha que você tenha a classe DiscountCalculator:
public class DiscountCalculator {
public BigDecimal calculate(BigDecimal orderAmount, CustomerTier tier) {
if (orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Order amount must be positive");
}
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);
}
}
Sugestão de prompt para pedir ao LLM que gere testes (você copia a classe acima no prompt):
Escreva testes JUnit 5 + AssertJ para a classe DiscountCalculator.
Inclua os casos: GOLD, SILVER, BASIC, e o caso onde orderAmount <= 0 deve lançar
IllegalArgumentException. Use @ParameterizedTest se apropriado.
AI geralmente retorna um rascunho quase correto, você só ajusta para combinar com o style do seu time:
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("Order amount must be positive");
}
}
@ParameterizedTest+@CsvSourcecombinam 3 casos de tier em um teste, reduzindo código duplicado.- A linha
assertThat(result).isEqualByComparingTo(...)comparaBigDecimalcorretamente (evita o problema deequalsser sensível a escala). - O caso restante verifica a exception com mensagem específica.
O que AI faz rápido aqui é listar todos os casos edge (você facilmente esqueceria do caso orderAmount <= 0), mas o que você precisa fazer é verificar se os valores expected estão corretos — AI calculando errado é algo que acontece frequentemente.
5. Usar AI para gerar Javadoc e resumir código legacy
Com código antigo sem comentários, AI resume mais rápido do que você ler linha por linha. Por exemplo, você tem este trecho complexo:
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: “Escreva Javadoc em português para este método, explicando as 3 condições de filtro.” AI retorna:
/**
* Filtra a lista de pedidos elegíveis para processamento de reembolso.
* Condições: pedido deve estar no status PAID, ter sido criado nos últimos 30 dias,
* e ter pelo menos um item que permite reembolso.
*
* @param orders lista de pedidos de entrada
* @return lista de pedidos que atendem todas as três condições acima
*/
Isso economiza tempo ao integrar alguém novo à base de código antiga — você joga um monte de métodos para AI, ela retorna Javadoc em rascunho, você só corrige onde errou terminologia de negócio.
6. Automatizar review de código com AI no CI
Você pode integrar uma chamada para AI revisar diff no pipeline para pegar erros cedo, antes da revisão humana. Por exemplo, um passo simples em GitHub Actions usando um script que chama a API:
name: ai-review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get diff
run: git diff origin/main...HEAD > diff.txt
- name: Call AI review
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: ("Revise o seguinte diff Java, indique apenas problemas graves: " + $diff)}]}')" \
> review.json
git diff origin/main...HEADpega apenas a parte do código que mudou na PR, evitando enviar o repositório inteiro (gasta token, fica lento).jq -n --rawfileconstrói o JSON body com segurança, evitando erros de escape em caracteres especiais do código.- O resultado
review.jsonvocê pode postar de volta como comentário na PR usando outro step.
Nota: Review por AI não substitui review senior. Ele só pega erros óbvios (null check faltando, catch Exception vazio, SQL injection básico). Não faça merge em PR só porque AI “aprovou”.
7. Erros comuns e quando não usar AI
Algumas armadilhas reais quando se usa LLM em projetos Java:
- Alucinação de API que não existe: AI pode sugerir chamar
Order.markAsRefundable()quando a classe real não tem esse método. Sempre compile antes de confiar. - Código correto sintaticamente mas errado na versão: AI costuma misturar Java 8 style (
new ArrayList<>()) com Java 21 (List.of(...)) sem consistência — você precisa padronizar de acordo com a convention do time. - Vazamento de informação sensível: não cole config inteira contendo secrets, connection strings, ou dados reais de clientes no prompt enviado para serviço AI de terceiros.
- Prompt vago → saída vaga: “escreva testes para esta classe” resulta em algo bem mais superficial do que um prompt que liste especificamente quais casos edge cobrir.
- Não use AI quando: lógica de cálculo de juros, cálculo de impostos, ou qualquer parte ligada a compliance onde um erro mínimo é problema legal — AI deveria só ajudar a escrever o framework, a parte core de cálculo deve ser verificada por alguém com expertise em negócio usando casos de teste reais, não casos que AI inventou.
Um pequeno checklist que você deveria aplicar toda vez que usa AI para gerar código:
1. O código compila?
2. Os test cases que AI gerou cobrem os casos edge reais, ou só cobrem o que "parece razoável"?
3. Nenhuma informação sensível vazou para o prompt?
4. O estilo de código combina com a convention atual do time?
8. Conclusão
AI ajuda você economizar tempo mais claramente em trabalho repetitivo e que precisa de rascunho rápido: gerar test cases, explicar stacktrace, escrever Javadoc, revisar diff inicial. Spring AI torna a integração de LLM em aplicações Java simples com apenas alguns lines de configuração e ChatClient.
O ponto crítico é que você ainda precisa revisar bem todo output — AI economiza tempo escrevendo, não economiza tempo entendendo e verificando. Se usar no lugar certo, com o nível certo de confiança, você pode reduzir muitas horas de trabalho repetitivo toda semana sem comprometer a qualidade do código.