API de orçamento inteligente que entende comandos de voz e texto para registrar e consultar transações financeiras. O usuário fala/escreve algo como "Gastei 50 reais no mercado hoje" e a IA entende a intenção, executa uma função real da aplicação (Tool Calling) e responde de forma natural.
Projeto desenvolvido para o Desafio de Projeto com Spring AI da DIO.
Autor: Luis Eduardo Carvalho
Fluxo principal (voz → ação → resposta):
🎤 Áudio ──► 📝 Transcrição (Whisper) ──► 🤖 IA entende a intenção (ChatClient)
│
▼
🔧 Tool Calling executa função real
│
▼
💾 Cria/consulta transações (JPA + H2)
│
▼
💬 Resposta em texto ──► 🔊 (opcional) Voz (TTS)
Também é possível usar tudo por texto puro (sem áudio) e pelos endpoints REST tradicionais.
O projeto vem com um front-end (HTML + CSS + JS puro, em src/main/resources/static/)
servido pelo próprio Spring Boot. Basta abrir http://localhost:8081 depois de rodar:
- 💬 Chat para conversar com o assistente (com atalhos de exemplo);
- 🎤 Botão de microfone que grava sua voz no navegador e envia para transcrição;
- 📊 Painel financeiro com saldo, receitas, despesas e a lista de transações, que atualiza sozinho a cada comando;
- 🌗 Tema claro/escuro automático e layout responsivo (funciona no celular).
| Camada | Tecnologia |
|---|---|
| Linguagem | Java 21 |
| Framework | Spring Boot 3.4 |
| IA | Spring AI 1.0 (ChatClient, Tool Calling, Transcrição, TTS) |
| Provedor de IA | Groq (gratuito) via API compatível com a OpenAI |
| Modelos | llama-3.3-70b-versatile (chat), whisper-large-v3 (áudio→texto), playai-tts (texto→voz) |
| Persistência | Spring Data JPA + H2 (em memória) |
| Validação | Bean Validation (Jakarta) |
| Build | Maven |
| Testes | JUnit 5 + AssertJ (@DataJpaTest) |
com.dio.orcamentoai
├─ controller → TransactionController, AssistantController (endpoints REST)
├─ dto → records de request/response (nunca expõe a entidade)
├─ model → Transaction, TransactionType (entidade JPA + auditoria)
├─ repository → TransactionRepository (Spring Data JPA)
├─ service → TransactionService (regras), AssistantService (IA + áudio)
├─ tools → FinanceTools (funções @Tool que a IA pode chamar)
└─ exception → GlobalExceptionHandler (@RestControllerAdvice)
As ferramentas de IA (FinanceTools)
apenas delegam para o TransactionService. Assim, IA e REST compartilham exatamente as mesmas
regras de negócio e validações — nenhuma lógica é duplicada.
Ferramentas disponíveis para o modelo:
registrarTransacao(descricao, tipo, valor, categoria)consultarSaldo()consultarTotalPorCategoria(categoria)listarTransacoes(tipo?)
Além do fluxo base, evoluí o projeto com validação e novas consultas financeiras:
- Validações de negócio antes de salvar (centralizadas em
TransactionService.create):- valor deve ser maior que zero;
- valor não pode passar de um teto de segurança (evita erro de interpretação da voz, ex.: "mil" virar "1000000");
- data não pode ser futura;
- descrição, tipo e categoria obrigatórios.
- Como IA e REST passam pelo mesmo método, a proteção vale para os dois caminhos.
- Novos tipos de consulta: saldo consolidado (
/summary), total por categoria e total por tipo. - Auditoria: campo
createdAtpreenchido automaticamente com JPA Auditing (@CreatedDate). - Tratamento de erros padronizado com
ProblemDetail(RFC 7807). - Testes automatizados do fluxo principal (5 testes, sem depender de chave de API).
- Java 21+
- Uma chave do Groq (gratuita, sem cartão) — https://console.groq.com/keys
O projeto usa o Groq por padrão (gratuito). Como o Groq é compatível com a API da OpenAI, o mesmo código funciona; só muda a configuração.
Windows (PowerShell):
$env:GROQ_API_KEY = "gsk_sua-chave-aqui"Linux/macOS:
export GROQ_API_KEY="gsk_sua-chave-aqui"Quer usar a OpenAI oficial em vez do Groq?
Defina as variáveis abaixo (a chave sk-... exige crédito na conta OpenAI):
$env:AI_BASE_URL = "https://api.openai.com"
$env:GROQ_API_KEY = "sk-sua-chave-openai"
$env:AI_CHAT_MODEL = "gpt-4o-mini"
$env:AI_STT_MODEL = "whisper-1"
$env:AI_TTS_MODEL = "tts-1"
$env:AI_TTS_VOICE = "alloy"./mvnw spring-boot:runA API sobe em http://localhost:8081.
Console do banco H2: http://localhost:8081/h2-console (JDBC URL: jdbc:h2:mem:orcamento).
A aplicação já inicia com 5 transações de exemplo (
src/main/resources/data.sql) para você testar as consultas imediatamente.
curl -X POST http://localhost:8081/api/assistant/command \
-H "Content-Type: application/json" \
-d '{"message": "Gastei 50 reais no mercado hoje na categoria Alimentacao"}'A IA chama a ferramenta registrarTransacao e responde confirmando o registro.
Consultando por texto:
curl -X POST http://localhost:8081/api/assistant/command \
-H "Content-Type: application/json" \
-d '{"message": "Qual o meu saldo atual?"}'curl -X POST http://localhost:8081/api/assistant/voice \
-F "audio=@meu-comando.mp3"Retorna { "transcription": "...", "reply": "..." }.
Para receber a resposta em áudio (voz → voz):
curl -X POST http://localhost:8081/api/assistant/voice/speak \
-F "audio=@meu-comando.mp3" --output resposta.mp3# Criar transação
curl -X POST http://localhost:8081/api/transactions \
-H "Content-Type: application/json" \
-d '{"description":"Salario","type":"RECEITA","amount":5000,"category":"Salario"}'
# Listar (ou filtrar por ?type=DESPESA)
curl http://localhost:8081/api/transactions
# Resumo financeiro
curl http://localhost:8081/api/transactions/summary./mvnw test| Método | Rota | Descrição |
|---|---|---|
| POST | /api/assistant/command |
Comando em texto para a IA |
| POST | /api/assistant/voice |
Comando em áudio → transcrição + resposta em texto |
| POST | /api/assistant/voice/speak |
Comando em áudio → resposta em áudio (MP3) |
| POST | /api/transactions |
Cria transação (REST) |
| GET | /api/transactions |
Lista transações (?type=RECEITA|DESPESA) |
| GET | /api/transactions/summary |
Resumo: receitas, despesas e saldo |
- Como o Spring AI conecta um modelo de linguagem a uma aplicação real através do
ChatClient. - Tool Calling: a IA não executa código sozinha — ela decide qual função chamar, e o Spring AI
invoca o método
@Toolda aplicação, respeitando as camadas e as regras de negócio. - Que a responsabilidade do código precisa ser respeitada: a IA é só mais um "cliente" do Service — por isso concentrei as validações no Service, e não nas ferramentas.
- Integração de áudio: transcrição (Whisper) e síntese de voz (TTS) como etapas do mesmo fluxo.
- A importância de validar a entrada quando ela vem de voz, que é naturalmente ambígua.
- Filtro de transações por período (mês/ano).
- Autenticação por usuário (cada pessoa com seu próprio orçamento).
- Trocar H2 por PostgreSQL para persistência real.
- Ferramenta de "orçamento por categoria" com alerta de estouro.
Projeto construído por Luis Eduardo Carvalho como entrega do Desafio DIO Spring AI. Registro do que foi trabalhado/criado:
| Componente | O que foi feito |
|---|---|
| Modelagem | Entidade Transaction + enum TransactionType com auditoria (@CreatedDate) |
| Persistência | TransactionRepository (Spring Data JPA) com consultas de soma por tipo e por categoria |
| Regras de negócio | TransactionService centralizando criação e validações (valor > 0, teto, data não futura) |
| Integração com IA | AssistantService com ChatClient (Groq), transcrição (Whisper) e TTS |
| Tool Calling | FinanceTools — 4 ferramentas @Tool que a IA aciona (registrar, saldo, categoria, listar) |
| API REST | AssistantController (texto/voz) e TransactionController (CRUD + resumo) |
| Tratamento de erros | GlobalExceptionHandler com ProblemDetail (RFC 7807) |
| Interface web | Página única (static/index.html): chat, gravação de voz, painel com auto-refresh, tema claro/escuro, ícones SVG |
| Testes | TransactionServiceTest — 5 testes do fluxo principal (@DataJpaTest) |
| Configuração | Provedor de IA trocado para Groq (gratuito) via API compatível com a OpenAI |
Principal evolução sobre a base: validações de negócio antes de salvar, novas consultas financeiras (saldo/categoria), auditoria de criação e uma interface web própria.