Prompt é Software: Versionamento, Estrutura e Testes

Prompt é Software: Versionamento, Estrutura e Testes

Se você está integrando IA no seu software, já deve ter percebido que tratar o Prompt de qualquer jeito é um convite para o desastre. Então a ideia desse artigo é trazer uma ideia de como melhorar esse processo.

Podemos classificar os prompts em duas categorias:

  1. Prompts de Produtividade (usados no dia a dia para gerar resumos, especificar, criar documentações, etc...)
  2. Prompts de Aplicações Específicas (usados em aplicações que precisam de inteligência para interagir com usuários/sistemas, agentes especializados, etc...)

O nosso foco aqui é no segundo tipo. Estamos falando de prompts complexos que interagem com usuários/sistemas, possuem múltiplas etapas e vivem dentro do código do projeto.

A dor surge quando esses prompts críticos ficam espalhados pelo repositório sem um padrão estruturado. Se um prompt de produtividade falha, você o corrige na hora, mas se um prompt de aplicações falha, o comportamento do sistema inteiro muda para o usuário/sistema final.

Com isso em mente podemos pensar em como classificar, estruturar, testar e por fim versionar, permitindo que os resultados sejam reproduzíveis e consistentes. O objetivo inicial não é avaliar a inteligência do modelo (Evaluation), mas sim garantir consistência e segurança a esse artefato tão importante.

Para resolver esse problema, vamos tratar o prompt como software (e software tem controle de versão e testes). Essa abordagem foca em criar uma arquitetura utilizando o próprio GitHub como ferramenta de versionamento, estruturada nos seguintes pilares:

  • Estruturação em YAML: Adotar o formato .yaml para estruturação permite organizar as instruções de maneira hierárquica, separando metadados importantes, chaves bem definidas e as variáveis de entrada (input_variables) do texto bruto do prompt (template). Essa rigidez facilita imensamente a leitura e a integração com o código, veja abaixo:
  • Registry de Prompts (O Catálogo Central): Criamos um repositório específico no GitHub que funciona como um catálogo centralizado. Utilizando um arquivo registry.yml, mapeamos, categorizamos e documentamos todos os prompts disponíveis. Esse registro permite o rastreio a evolução dos prompts ao longo do tempo, encontre versões anteriores rapidamente e colabore nas melhorias através de Pull Requests.
    • A categorização desses prompts é feita através de estruturas de pastas como: ProjetosAgentesVersão (Semantic Versioning);
    • A documentação desses prompts é feita através de um README.md para cada prompt, mantendo um mínimo de informações como:
      • Descrição;
      • Uso;
      • Variáveis de Entrada;
      • Onde é utilizado;
      • Formato de saída;
      • Changelog.
      • Etc...
  • Integração via Links Simbólicos: Para reutilizar esses prompts centralizados em diferentes projetos, podemos usar links simbólicos, sub-modulos do github ou até mesmo manter junto ao projeto principal.

(Hoje existem ferramentas de terceiros bem completas que cobrem todo esse ciclo de gestão, como o LangSmith, o que tira a necessidade de manter um repositório próprio. Porém, focar no Git nos permite controle absoluto e gratuito).

Existem algumas barreiras técnicas importantes nessa abordagem:

  • Ambiguidade: Ao criar um repositório centralizado, cometemos o erro de deixar os Modelos dos nossos editores de código (como Copilot e Cursor) lerem a pasta inteira. Isso cruza contextos de diferentes projetos e gera uma grande confusão nas respostas.
    • A Solução: Usar o Links Simbólicos como citamos acima.
  • Fragilidade da Renderização: Erros bobos de digitação (typos) no nome de variáveis de entrada quebram a renderização final do prompt, enviando instruções incompletas para a LLM.
    • A Solução: Implementar Testes Automatizados Estruturais (prompt.tests.yml). Eles não avaliam o modelo ou as repostas, mas rodam scripts na nossa esteira de CI/CD para validar injeção de inputs, verificar a existência de variáveis órfãs e testar asserções (expectContains). Se a estrutura quebrar, a pipeline falha antes de ir para produção.
      • Temos uma suíte (tests/prompts.test.ts - Vitest) valida prompts de forma puramente estática, sem chamar nenhum LLM: um tokenizador/renderizador de templates embutido no próprio arquivo interpreta placeholders {{name}} (chave dupla, escolhida para não conflitar com JSON literal embutido nos prompts) e, a partir do registry.yaml, gera dinamicamente uma suíte por agente que checa quatro coisas:
        • Campos Obrigatórios do prompt.yaml presentes (id, version, input_variables, template);
        • Sintaxe Válida das tags do template ({{name}});
        • Paridade Exata entre as input_variables declaradas e as efetivamente usadas no template (erro tanto se falta declaração quanto se sobra variável não usada);
        • Cada Caso em prompt.tests.yaml renderiza corretamente contendo as substrings esperadas em expect_contains;
        • Além disso, testes globais garantem que o registry aponta para arquivos que existem, que cada agente tem README e que todo YAML em prompts/ tem sintaxe válida. Ou seja, é uma validação de integridade estrutural do prompt como artefato, não uma avaliação de qualidade de resposta do modelo.

Se você está construindo sistemas que dependem de LLMs e quer evitar dores de cabeça futuras, recomendo começar por estes 3 pontos:

  • Adote YAML e crie um Registry: Abandone textos soltos no código. Estruture seus prompts com chaves rígidas e mantenha um catálogo central para que a equipe encontre e rastreie o comportamento das instruções facilmente.
  • Use Links Simbólicos para Contexto: Se for centralizar prompts no Git, utilize Symlinks nos projetos para que os modelos auxiliares leiam apenas o escopo necessário, evitando alucinações por excesso de contexto misturado.
  • Automatize Testes Estruturais: Aproveite o formato YAML para injetar dados fictícios via CI/CD, garantindo que variáveis não fiquem órfãs e que o artefato será renderizado corretamente antes de chamar a API do modelo de linguagem.

Por fim, muitos se sentem mais confortáveis usando prompts em Markdown, e não há nenhum problema nisso, e isso é simples de resolver, basta exportar eles e manter todo o fluxo mais estruturado:

Repositório de exemplo:
https://github.com/alcir-junior-caju/study-prompt-structures-testing-and-versioning-article

A fonte desse artigo foi baseado em um módulo da disciplina Engenharia de Prompt da Pós que estou fazendo em Arquitetura de Software com IA:
https://github.com/alcir-junior-caju/study-mba-em-engenharia-de-software-com-ia