O que é Extrair Template Versionado?
Extrair Template Versionado (Extract Versioned Template) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Juntar pedaços de prompt espalhados em um template com nome, versão e variáveis.
Extract Versioned Template
Extrair Template Versionado (Extract Versioned Template) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Juntar pedaços de prompt espalhados em um template com nome, versão e variáveis.
O prompt está espalhado em pedaços pelo código, sem versão, ou ajustado a um modelo de um jeito que ninguém consegue mudar com segurança. São os smells Prompt Espalhado, Prompt Sem Versão e Prompt Preso ao Modelo.
Imagine o SDR da Empresa. A primeira mensagem para um lead nasce em quatro arquivos: a persona em persona.py, o tom em tone.py, a campanha do trimestre em campaigns/q3.py e um if no writer.py que esconde o preço se o lead for enterprise. Ninguém no time consegue colar o prompt inteiro num chat e dizer “é isto que o modelo vê”.
Uma segunda-feira a taxa de resposta cai. Você abre o trace e vê só a chamada ao modelo. Sem nome, sem versão, sem o texto renderizado. Qual dos quatro arquivos mudou? A campanha de Q3 ainda está no ar em outubro? O if de preço disparou para o lead errado? Sem um artefato, você está adivinhando.
O padrão de destino desta refatoração é o Registro de Templates.
Junte os pedaços num template único, com nome, versão imutável e variáveis declaradas. O código carrega o template por nome e versão, preenche as variáveis e registra a versão em cada execução.
-# persona.py, tone.py, campaigns/q3.py, writer.py
-prompt = BASE + tone(lead.segment) + CAMPAIGN + f"Lead: {lead.name}. " \
- + ("Não mencione preço. " if lead.is_enterprise else "")
+# prompts/sdr_first_message/v14.yaml
+# name: sdr_first_message
+# version: 14
+# model: claude-sonnet-4-5
+# variables: [lead_name, company, tone, pricing_policy, campaign]
+# template: |
+# Você é Júlia, consultora da Empresa.
+# Tom: {{ tone }}.
+# Campanha ativa: {{ campaign }}.
+# Política de preço para este lead: {{ pricing_policy }}.
+# Lead: {{ lead_name }}, {{ company }}.
+
+tpl = prompts.get("sdr_first_message", version=14)
+prompt = tpl.render(
+ lead_name=lead.name, company=lead.company, tone=tone_for(lead.segment),
+ pricing_policy=pricing_policy_for(lead), campaign=active_campaign())
+trace.set("prompt.name", tpl.name)
+trace.set("prompt.version", tpl.version)
Antes: o prompt existe só em tempo de execução.
flowchart LR
A["persona.py"]:::tool --> J["1. Concatenação"]:::tool
B["tone.py"]:::tool --> J
C["campaign.py"]:::tool --> J
J --> M(["2. Prompt sem nome nem versão"]):::llm
Depois: um template versionado, preenchido por variáveis declaradas.
flowchart LR
R[("1. Registro: sdr_first_message v14")]:::store --> T["2. Renderizar com variáveis"]:::tool
V(["Dados do lead"]):::io --> T
T --> M(["3. Modelo"]):::llm
M --> L[("4. Trace com nome e versão")]:::store
Pegue um lead realista: Marina, da Indústria Norte, segmento indústria, contrato enterprise. No antes, o writer.py concatena quatro strings e o if lead.is_enterprise acrescenta “Não mencione preço”. O texto final só existe naquele instante.
No depois, tone_for("industria") devolve "formal", pricing_policy_for(lead) devolve "Não mencione preço nem faixa." e active_campaign() devolve o texto da campanha vigente. O template v14 recebe cinco valores e produz um prompt reproduzível. O span fica assim:
prompt.name=sdr_first_message prompt.version=14
lead_name=Marina company=Indústria Norte tone=formal
Uma semana depois a taxa de resposta cai de novo. Você filtra o trace por prompt.version=14, pega o prompt renderizado e compara com um caso que funcionava. Se o texto for idêntico, o problema não é o prompt: é o lead, o modelo ou o canal. Se diferir, você sabe exatamente o que mudou.
Um template versionado transforma o prompt num artefato: dá para ler inteiro, revisar num pull request, comparar duas versões e voltar atrás. As variáveis declaradas deixam explícito o que muda de um pedido para outro; o resto é fixo e testável.
A versão no trace fecha o ciclo. Uma resposta ruim aponta para o texto exato que a gerou, e o eval pode comparar a versão nova com a anterior antes da troca. Migrar de modelo vira criar uma versão nova do template para o modelo novo e comparar as duas, em vez de reescrever if model == ... espalhados.
Há um ganho de cache também. Provedores como Anthropic e OpenAI cacheiam o prefixo estável do prompt. Se a persona, o tom-base e as regras ficam no começo do template, e só lead_name, campaign e a data mudam no fim, o cache acerta. Concatenação espalhada mistura o que muda com o que não muda, e o cache perde o prefixo.
Um erro comum: levar o if do Python para o YAML. {{ "formal" if segment == "industria" else "próximo" }} recria o Prompt Espalhado, agora escondido no template. Calcule tone em código e passe o resultado.
pricing_policy, tone), não lógica no template.Versão imutável quer dizer: o arquivo v14.yaml nunca é editado depois de publicado. Um ajuste de uma palavra vira v15.yaml. Produção aponta para um número, não para latest.
Quando o modelo muda, você não reaproveita a v14 “na esperança”. Cria v15 com o texto ajustado ao modelo novo, roda o eval nas duas e só então promove. Isso é o tratamento do Prompt Preso ao Modelo: o texto e o modelo andam juntos, mas de forma explícita.
campaign puder receber um PDF inteiro, o template vira um saco sem fundo. Declare tipo e tamanho máximo no registro, e recuse valores fora.Quais partes destes trechos viram variáveis do template, e quais ficam fixas?
prompt = "Você responde dúvidas de RH da Empresa. "
prompt += f"O funcionário se chama {emp.name} e trabalha em {emp.state}. "
if emp.state == "SP":
prompt += "Considere o feriado municipal de 25 de janeiro. "
prompt += "Seja breve. Hoje é " + date.today().isoformat() + "."
Fixo: a função, “seja breve”. Variáveis: employee_name, local_holidays (uma lista calculada em código a partir do estado) e today. A data deve ir no fim do prompt, ou na mensagem do usuário, para não quebrar o cache de prompt.
O if emp.state == "SP" não vai para o YAML. Em código, algo como holidays_for(emp.state) devolve "25 de janeiro (São Paulo)" ou uma lista vazia. O template só interpola.
name: hr_assistant
version: 3
variables: [employee_name, local_holidays, today]
template: |
Você responde dúvidas de RH da Empresa. Seja breve.
Funcionário: {{ employee_name }}.
Feriados locais a considerar: {{ local_holidays }}.
Data de hoje: {{ today }}.Extrair Template Versionado (Extract Versioned Template) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Juntar pedaços de prompt espalhados em um template com nome, versão e variáveis.
Trata Prompt Preso ao Modelo, Prompt Espalhado e Prompt Sem Versão.
Ao padrão de projeto Registro de Templates.