E aí, dev que já pediu pro ChatGPT "gerar um relatório financeiro" e recebeu um texto bonito, mas completamente fora do padrão da empresa?
Pois é. Prompt genérico gera resultado genérico. E quando o assunto é relatório financeiro, "genérico" é sinônimo de retrabalho, inconsistência e aquele e-mail do diretor perguntando por que o balanço veio diferente do mês passado.
A boa notícia? Dá pra resolver com engenharia de prompt bem feita — transformando um prompt numa função reutilizável, com input e output bem definidos, baixa variabilidade e zero alucinação.
E melhor ainda: com o Spring AI Prompt Template, você tira esse prompt do "copiar e colar" e coloca ele dentro da sua aplicação Java, parametrizado e versionado.
Neste post, vou mostrar como estruturar um prompt para geração de relatórios financeiros que funciona como um contrato, e como implementar isso na prática com Spring AI. Bora? 🚀
🏢 O cenário: o time financeiro que perde 3 dias por mês
Imagine uma empresa cujo time financeiro gasta dias montando relatórios mensais manualmente. Cada analista formata de um jeito, esquece uma seção, ou pior: inventa uma análise que não bate com os números.
O objetivo é criar um prompt estruturado que funcione como uma função reutilizável — capaz de gerar relatórios consistentes a partir de dados estruturados.
O relatório precisa ter 5 seções fixas:
- Sumário Executivo
- Demonstração de Resultados
- Balanço Patrimonial
- Análise de Fluxo de Caixa
- Notas Explicativas
E os inputs vêm em formatos variados: tabelas CSV de receitas e despesas, planilhas de balanço, registros de fluxo de caixa e notas explicativas em texto livre.
❌ O prompt genérico (e por que ele falha)
A primeira tentativa de qualquer pessoa é algo assim:
Gere um relatório financeiro com base nos dados fornecidos. Inclua análises e seja claro. O que acontece na prática:
"Com base nos dados fornecidos, a empresa apresentou receita de R$ 150.000 e despesas de R$ 95.000, resultando em lucro de R$ 55.000. O balanço patrimonial mostra uma situação estável. O fluxo de caixa está positivo. Recomenda-se continuar monitorando as despesas."
Bonito? Até é. Mas:
- ❌ Não tem seções definidas
- ❌ Não tem tabelas
- ❌ Análise superficial
- ❌ Formato muda a cada execução
- ❌ Pode inventar dados se faltar input
- ❌ Não dá pra integrar com sistema nenhum
Esse é o clássico "prompt de torcida": você torce para o modelo acertar, mas não tem controle nenhum sobre o resultado.
✅ O prompt estruturado (quatro partes + papel)
A solução é estruturar o prompt como um contrato, dividido em blocos explícitos:
🎭 Papel (Role)
Você é um assistente contábil virtual especializado em relatórios financeiros padronizados. Atua com precisão técnica, linguagem clara e foco em consistência. 🌍 Contexto
Uma empresa do setor [SETOR] precisa gerar relatórios financeiros mensais padronizados para acompanhamento interno e prestação de contas. Os dados disponíveis são referentes ao período [PERÍODO] e devem ser transformados em um relatório executivo. 📋 Instruções (as regras do jogo)
1. Utilize exclusivamente os dados fornecidos no campo [DADOS]. 2. Estruture o relatório nas seguintes seções obrigatórias, nesta ordem: - Sumário Executivo - Demonstração de Resultados - Balanço Patrimonial - Análise de Fluxo de Caixa - Notas Explicativas 3. Mantenha linguagem clara, concisa e objetiva. 4. Utilize formato tabular sempre que aplicável. 5. Não invente dados; caso alguma informação esteja ausente, indique "Dado não fornecido". 6. Destaque variações relevantes (crescimento, quedas, margens) de forma quantitativa. 7. As notas explicativas devem ser sintetizadas a partir do texto livre fornecido. 📊 Dados (os placeholders)
- Receitas e Despesas: {{receitas_despesas}} - Balanço Patrimonial: {{balanco_patrimonial}} - Fluxo de Caixa: {{fluxo_caixa}} - Notas Explicativas: {{notas_explicativas}} 📐 Formato de Saída (o contrato final)
O relatório deve conter exatamente as 5 seções listadas, com títulos em negrito. Cada seção deve iniciar com um parágrafo resumitivo seguido de tabelas (quando aplicável) e análises textuais. O tamanho total deve ser conciso (máximo 2 páginas). Não inclua seções adicionais. Pronto. Agora o modelo não tem escolha: ele sabe exatamente quem é, o que fazer, com quais dados e em qual formato entregar.
🧪 O antes e depois (com dados reais)
Input utilizado: receita de R$ 150.000, despesas de R$ 95.000, balanço patrimonial do trimestre, fluxo de caixa e notas explicativas.
❌ Saída com prompt genérico
Com base nos dados fornecidos, a empresa apresentou receita de R$ 150.000 e despesas de R$ 95.000, resultando em lucro de R$ 55.000. O balanço patrimonial mostra uma situação estável. O fluxo de caixa está positivo. Recomenda-se continuar monitorando as despesas. ✅ Saída com prompt estruturado
**Sumário Executivo** A empresa encerrou o período com receita de R$ 150.000 e despesas de R$ 95.000, gerando lucro líquido de R$ 55.000 (margem de 36,7%). O fluxo de caixa operacional permaneceu positivo em R$ 42.000. **Demonstração de Resultados** | Item | Valor (R$) | |----------------|------------| | Receita | 150.000 | | Despesas | (95.000) | | Lucro Líquido | 55.000 | | Margem Líquida | 36,7% | **Balanço Patrimonial** | Ativo | Valor (R$) | Passivo | Valor (R$) | |------------------|------------|------------------|------------| | Circulante | 200.000 | Circulante | 80.000 | | Não Circulante | 150.000 | Não Circulante | 120.000 | | **Total** | **350.000**| **Total** | **200.000**| **Análise de Fluxo de Caixa** O fluxo de caixa operacional foi positivo em R$ 42.000, impulsionado pelo recebimento de receitas. O fluxo de investimento apresentou saída de R$ 15.000 (aquisição de ativo imobilizado). **Notas Explicativas** - A receita apresentou crescimento de 12% em relação ao mês anterior. - As despesas mantiveram-se estáveis, com leve aumento de 3%. - O patrimônio líquido totalizou R$ 150.000. A diferença: formato idêntico ao padrão, tabelas, análises quantitativas, consistência.
📉 Variabilidade: o número que prova o ponto
O estudo mediu a consistência entre execuções com inputs similares:
| Cenário de Input | Prompt Genérico | Prompt Estruturado |
|---|---|---|
| Input completo | Formato varia a cada execução | Formato idêntico |
| Input faltando fluxo de caixa | Pode inventar dados ou ignorar a ausência | Indica "Dado não fornecido" |
| Período diferente (trimestral) | Mistura períodos | Adapta o contexto automaticamente |
| Notas explicativas longas | Resume de forma inconsistente | Sintetiza em tópicos padronizados |
| Valores extremos (prejuízo) | Pode não destacar | Destaca quantitativamente |
Conclusão do estudo: o prompt estruturado reduz a variabilidade de saída de ~70% para menos de 10% entre execuções com inputs similares.
E mais: ele é robusto a variações nos inputs — dados faltantes, períodos distintos, notas extensas. As instruções e o formato de saída atuam como contratos que delimitam o comportamento do modelo.
🚀 Do prompt ao código: Spring AI Prompt Templates
Agora que você já tem o prompt perfeito, como colocá-lo dentro da aplicação sem depender de copiar e colar manual?
É aí que entra o Spring AI. A API ChatClient permite definir templates de prompt com variáveis que são substituídas em tempo de execução. Em vez de concatenar strings na mão — o que é propenso a erro e difícil de manter — você declara o template uma vez e passa apenas os parâmetros dinâmicos.
🧩 O template como recurso da aplicação
Você pode externalizar o prompt num arquivo dentro de src/main/resources/prompts/relatorio-financeiro.st:
Você é um assistente contábil virtual especializado em relatórios financeiros padronizados. Uma empresa do setor {setor} precisa gerar relatórios financeiros mensais referentes ao período {periodo}. INSTRUÇÕES: 1. Utilize exclusivamente os dados fornecidos abaixo. 2. Estruture o relatório nas 5 seções obrigatórias: Sumário Executivo, Demonstração de Resultados, Balanço Patrimonial, Análise de Fluxo de Caixa, Notas Explicativas. 3. Não invente dados; se algo estiver ausente, indique "Dado não fornecido". 4. Destaque variações quantitativas (crescimento, quedas, margens). 5. Formato tabular sempre que aplicável. Máximo 2 páginas. DADOS: - Receitas e Despesas: {receitas} - Balanço Patrimonial: {balanco} - Fluxo de Caixa: {fluxoCaixa} - Notas Explicativas: {notas} Aqui usamos a sintaxe {variavel}, que é o padrão do StTemplateRenderer do Spring AI (baseado no mecanismo StringTemplate).
☕ Integrando com o ChatClient
Agora, no seu serviço Java, você injeta o template e passa os valores dinâmicos:
@Service public class RelatorioFinanceiroService { private final ChatClient chatClient; @Value("classpath:prompts/relatorio-financeiro.st") private Resource promptTemplate; public RelatorioFinanceiroService(ChatClient.Builder builder) { this.chatClient = builder.build(); } public String gerarRelatorio(DadosFinanceiros dados) { return chatClient.prompt() .user(u -> u .text(promptTemplate) .param("setor", dados.getSetor()) .param("periodo", dados.getPeriodo()) .param("receitas", dados.getReceitas()) .param("balanco", dados.getBalanco()) .param("fluxoCaixa", dados.getFluxoCaixa()) .param("notas", dados.getNotasExplicativas()) ) .call() .content(); } } O método .text(Resource) carrega o template do classpath, e os .param(...) substituem as variáveis {setor}, {periodo}, etc.. O resultado é exatamente o prompt estruturado que definimos, mas parametrizado e reutilizável.
🔧 E se o prompt tiver JSON?
Um detalhe importante: se o seu prompt incluir JSON, as chaves {} do template podem conflitar com a sintaxe do JSON. O Spring AI permite customizar os delimitadores. Por exemplo, para usar < >:
String resposta = chatClient.prompt() .user(u -> u .text("Liste 5 filmes cuja trilha foi composta por <compositor>") .param("compositor", "John Williams") ) .templateRenderer( StTemplateRenderer.builder() .startDelimiterToken('<') .endDelimiterToken('>') .build() ) .call() .content(); Essa flexibilidade evita dores de cabeça quando o prompt é mais complexo.
🎯 Por que isso muda o jogo?
Com o Prompt Template do Spring AI, você:
- Elimina a concatenação de strings — o template é declarativo e legível.
- Centraliza o prompt num único lugar — mudou a regra? Altera o arquivo
.st, não o código Java. - Facilita testes — você pode testar o template com diferentes inputs sem tocar na lógica de negócio.
- Integra com o ecossistema Spring — injeção de dependência, configuração externalizada, observabilidade.
- Mantém a consistência — o mesmo template é usado por todas as instâncias da aplicação, garantindo o formato padronizado.
💡 Dicas quentes (que ninguém conta)
1. 🎭 Papel é ancoragem
Definir "assistente contábil virtual especializado" reduz alucinações porque delimita o domínio de conhecimento e orienta o tom técnico.
2. 📋 Instruções numeradas são contratos
Sete regras explícitas e numeradas reduzem ambiguidade e garantem consistência. Sem numeração, o modelo "esquece" regras no meio do caminho.
3. 🔌 Placeholders isolam dados
Usar {...} separa os dados do prompt, facilitando integração com sistemas e testes automatizados — e é exatamente a sintaxe que o Spring AI espera.
4. 📐 Formato de saída é a trava final
Definir as 5 seções fixas com limite de páginas garante baixa variabilidade. Sem isso, o modelo inventa seções extras ou omite partes.
5. 🚫 "Dado não fornecido" é obrigatório
Sem essa instrução, o modelo inventa dados quando o input está incompleto. Com ela, ele admite a ausência e mantém a estrutura.
6. ⚙️ Externalize o template
Colocar o prompt num arquivo .st (ou .txt) dentro de resources facilita versionamento, revisão e até internacionalização.
📦 O prompt final (pronto para copiar)
[PAPEL] Você é um assistente contábil virtual especializado em relatórios financeiros padronizados. Atua com precisão técnica, linguagem clara e foco em consistência. [CONTEXTO] Uma empresa do setor {setor} precisa gerar relatórios financeiros mensais padronizados referentes ao período {periodo}. [INSTRUÇÕES] 1. Utilize exclusivamente os dados fornecidos no campo [DADOS]. 2. Estruture o relatório nas seguintes seções obrigatórias, nesta ordem: - Sumário Executivo - Demonstração de Resultados - Balanço Patrimonial - Análise de Fluxo de Caixa - Notas Explicativas 3. Mantenha linguagem clara, concisa e objetiva. 4. Utilize formato tabular sempre que aplicável. 5. Não invente dados; caso alguma informação esteja ausente, indique "Dado não fornecido". 6. Destaque variações relevantes (crescimento, quedas, margens) de forma quantitativa. 7. As notas explicativas devem ser sintetizadas a partir do texto livre fornecido. [DADOS] - Receitas e Despesas: {receitas} - Balanço Patrimonial: {balanco} - Fluxo de Caixa: {fluxoCaixa} - Notas Explicativas: {notas} [FORMATO DE SAÍDA] O relatório deve conter exatamente as 5 seções listadas, com títulos em negrito. Cada seção deve iniciar com um parágrafo resumitivo seguido de tabelas (quando aplicável) e análises textuais. O tamanho total deve ser conciso (máximo 2 páginas). Não inclua seções adicionais. Sugestão de nome para publicar: financial-report-generator-prompt-v1.0.
🎯 Conclusão
Engenharia de prompt não é sobre escrever perguntas bonitas. É sobre projetar mecanismos de controle do comportamento do modelo.
Para um ambiente corporativo, confiabilidade é mais importante que criatividade. E o experimento provou: a estrutura do prompt é um componente crítico de governança de IA, transformando um modelo generalista em um assistente alinhado às regras e ao tom da empresa.
Com o Spring AI Prompt Template, você leva esse contrato um passo adiante: tira o prompt do papel e coloca ele dentro da aplicação, parametrizado, versionado e integrado ao ecossistema Spring.
A receita é simples:
- 🎭 Defina o papel
- 🌍 Dê contexto
- 📋 Numere as instruções
- 📊 Isole os dados com placeholders
- 📐 Trave o formato de saída
- ⚙️ Externalize o template com Spring AI
Faça isso, e seu LLM vai parar de "inventar" e começar a entregar exatamente o que você pediu.
Já usou prompt estruturado em produção? Ou ainda está na fase do "gera aí que eu confio"? Conta nos comentários! 👇