Objetivo da Aula
Diferenciar prompting ad hoc de engenharia de contexto sistêmico como disciplina de arquitetura
Descrever as camadas de contexto que um harness monta antes de cada chamada ao motor de inferência
Explicar o modelo spec-driven (regras declarativas em Markdown versionado) e por que ele substitui prompts hardcoded
Justificar a ordem de precedência entre camadas de contexto quando elas entram em conflito
Reconhecer os limites físicos (janela de contexto) que tornam a montagem de contexto uma decisão de engenharia, não um detalhe cosmético
Por que isso importa
Todo profissional que já usou um LLM sabe escrever um prompt. Poucos sabem projetar um sistema que monta o prompt certo, na hora certa, para o agente certo, sem exceder a janela de contexto e sem que uma regra de segurança se perca no meio de um histórico de conversa longo. Essa é a diferença entre "prompting" — uma habilidade de usuário final — e "engenharia de contexto sistêmico" — uma responsabilidade de arquiteto.
Quando você trabalha sozinho num chat, prompting manual é suficiente: você digita a instrução, o modelo responde, você ajusta. Mas um harness de produção atende múltiplos usuários, múltiplos agentes, múltiplas sessões simultâneas — e precisa reconstruir o contexto correto a cada chamada, de forma determinística, sem depender de alguém copiar e colar o prompt "bom" manualmente. Se as regras do sistema vivem na cabeça de quem escreveu o primeiro prompt, elas não escalam, não são auditáveis, e não sobrevivem à saída dessa pessoa da empresa.
Impacto direto no seu trabalho: a pergunta que separa uma arquitetura madura de contexto de uma amadora é "onde vive a regra que este agente precisa seguir?". Se a resposta é "num arquivo de texto que alguém copia manualmente para dentro do prompt", você tem uma dívida técnica silenciosa. Se a resposta é "num arquivo declarativo, versionado, injetado automaticamente pelo harness conforme a operação em curso", você tem um sistema que pode ser auditado, testado e evoluído como qualquer outro artefato de engenharia.
Conceitos Fundamentais
O contexto não é um prompt — é uma montagem em camadas
Um erro conceitual comum é tratar "o prompt" como um bloco de texto único, escrito à mão. Num harness de produção, o que chega ao motor de inferência a cada chamada é o resultado de uma montagem de várias camadas, cada uma com uma origem e uma responsabilidade distintas:
| Camada | Conteúdo | Peso / Estabilidade |
|---|---|---|
| Camada 5: Mensagem do turno atual | O que o usuário/sistema pediu agora | Mais recente, maior peso |
| Camada 4: Histórico da sessão | Turnos anteriores, resumidos se necessário | |
| Camada 3: Estado operacional dinâmico | Arquivos abertos, resultado da última ferramenta, variáveis de ambiente da tarefa | |
| Camada 2: Regras e specs do domínio | Arquivos .md versionados: convenções, políticas, definições de "pronto" | |
| Camada 1: Identidade e restrições do sistema | Quem é o agente, o que nunca pode fazer | Mais estável, menor variação |
Cada chamada ao motor reconstrói essas cinco camadas — o harness decide o que entra em cada uma, em que ordem, e o que é cortado quando o total excede a janela de contexto disponível. Prompting manual mistura tudo isso numa string só, escrita uma vez; engenharia de contexto sistêmico trata cada camada como uma fonte de dados independente, montada em tempo de execução.
Fundamento: Janela de Contexto como Recurso Físico Escasso
Todo LLM tem um limite de tokens que consegue processar numa única chamada — a janela de contexto (por exemplo, 200 mil tokens). Isso não é um detalhe de implementação, é uma restrição física do sistema, análoga à memória RAM de um servidor. Cada camada de contexto que o harness injeta consome parte desse orçamento. Um harness ingênuo que injeta tudo que existe (histórico completo, todas as specs, todos os arquivos) esgota a janela rapidamente e força o modelo a "esquecer" instruções antigas por simples corte físico — não por decisão do modelo, mas por estouro do buffer. Orçar tokens por camada é, portanto, uma decisão arquitetural tão concreta quanto dimensionar memória de um servidor.
De prompt hardcoded a spec declarativa
A evolução natural de um sistema de IA corporativo passa por três estágios de maturidade na forma como as regras de comportamento são expressas:
Estágio 1 — Prompt hardcoded (frágil)
system_prompt = "Você é um assistente. Sempre responda em
português. Nunca delete arquivos. Use tom formal."
→ Regra e código de aplicação estão no mesmo lugar.
→ Mudar uma regra exige deploy de código.
→ Nenhum versionamento independente, nenhum dono claro.
Estágio 2 — Prompt em arquivo externo (melhor, ainda manual)
system_prompt = ler_arquivo("prompts/sistema.txt")
→ Regra sai do código, mas ainda é texto solto,
sem estrutura, sem validação.
Estágio 3 — Spec declarativa versionada (spec-driven)
regras = carregar_specs("specs/*.md")
contexto = montar_por_precedencia(regras, estado_atual)
→ Regras vivem em Markdown estruturado, versionado em
git, revisado por PR como qualquer outro artefato.
→ O harness resolve DINAMICAMENTE quais specs se aplicam
à operação em curso (ver capítulo 1.5).O estágio 3 é o que a ementa chama de spec-driven: em vez de um prompt monolítico escrito por uma pessoa, você tem um conjunto de documentos declarativos — tipicamente Markdown — que descrevem regras, convenções e restrições do domínio. O harness lê esses documentos e os injeta no contexto de forma programática, igual a como uma aplicação lê um arquivo de configuração em vez de ter valores fixos no código.
Exemplo concreto de spec declarativa
# specs/politica-de-escrita.md
## Regra: Arquivos protegidos
Nunca escrever diretamente em:
- `/prod/config/*`
- `/.env`
- Qualquer arquivo sob `/secrets/`
## Regra: Convenção de commit
Toda alteração de código deve incluir mensagem de commit
no padrão Conventional Commits (feat:, fix:, chore:).
## Regra: Definição de "tarefa concluída"
Uma tarefa só é considerada concluída se:
1. Os testes existentes passam
2. Não há novo warning de lint
3. A mudança foi documentada no CHANGELOGEsse arquivo não é um prompt — é uma fonte de verdade que o harness carrega, parseia (mesmo que de forma simples, por seção) e injeta na Camada 2 da montagem de contexto descrita acima. A diferença crucial: esse arquivo pode ser testado, versionado com histórico de mudanças, revisado por outra pessoa antes de entrar em vigor, e reutilizado por múltiplos agentes diferentes sem duplicação de texto.
Aprofundamento Técnico
Precedência entre camadas: o que vence quando há conflito
Contexto sistêmico bem projetado precisa de uma regra explícita de precedência — o que acontece quando a Camada 5 (pedido do usuário no turno atual) contradiz a Camada 1 (restrição do sistema)? Um harness maduro resolve isso com uma hierarquia fixa, não deixando a decisão para o "bom senso" do modelo:
Ordem de precedência, da mais forte para a mais fraca:
| Camada | Regra de precedência | Exemplo |
|---|---|---|
| 1. Identidade e restrições do sistema | NUNCA cede a um pedido de camada inferior. | "Nunca revelar chaves de API" vence mesmo se o usuário pedir explicitamente. |
| 2. Regras e specs do domínio | Cede apenas à Camada 1. Vence pedidos de usuário. | Convenção de commit vence "só faça rápido, sem seguir o padrão" pedido pelo usuário. |
| 3. Estado operacional dinâmico | Fornece fatos, não ordens. Não "vence" nada — só informa o que está acontecendo agora. | — |
| 4. Histórico da sessão | Contexto de continuidade. Pode ser resumido/descartado sob pressão de espaço sem perda crítica. | — |
| 5. Mensagem do turno atual | Mais específica, mais recente, mas SUBORDINADA às camadas 1 e 2. | — |
Essa hierarquia é o que impede um dos ataques mais comuns contra sistemas de IA: a tentativa de um usuário (ou de conteúdo malicioso injetado via ferramenta) de sobrescrever, via linguagem natural no turno atual, uma restrição definida em camada superior. O harness que trata todas as camadas como texto simples concatenado, sem hierarquia explícita de precedência, está delegando ao modelo a tarefa de "adivinhar" qual instrução deveria prevalecer — e isso é exatamente o tipo de decisão que, pelo princípio do capítulo 1.1, não deveria depender do comportamento probabilístico do motor.
Orçamento de tokens por camada
Na prática, um harness de produção define um orçamento (budget) de tokens por camada, não apenas um limite global. Isso evita que uma camada "guerreie" com as outras por espaço de forma imprevisível:
Janela de contexto total considerada no exemplo: 200.000 tokens.
| Camada | Orçamento | Observação |
|---|---|---|
| Camada 1 (identidade/restrições) | Reservado: 2.000 tokens | Fixo |
| Camada 2 (specs do domínio) | Até 15.000 tokens | Dinâmico, resolvido por relevância — ver capítulo 1.5 |
| Camada 3 (estado operacional) | Até 20.000 tokens | Truncado por recência/relevância |
| Camada 4 (histórico da sessão) | Até 100.000 tokens | Resumido progressivamente quando excede o teto |
| Camada 5 (turno atual) | O que sobrar | Mínimo garantido de 10.000 tokens |
| Margem de segurança (resposta do modelo) | ~53.000 tokens | Reservada, não disponível para as camadas acima |
Note que a Camada 1 recebe orçamento fixo e prioritário — restrições de sistema nunca são as primeiras a serem cortadas. Já a Camada 4 (histórico) é a mais elástica, porque é a que mais se beneficia de técnicas de resumo (sumarização progressiva de turnos antigos) sem perda crítica de informação. Esse tipo de orçamento por camada é o que separa um harness dimensionado de um que simplesmente concatena tudo e espera não estourar.
Markdown como formato de spec: por que funciona
A escolha de Markdown (em vez de JSON, YAML ou XML) para specs declarativas não é acidental. Markdown tem uma propriedade rara: é ao mesmo tempo legível por humanos sem ferramenta (qualquer revisor de PR lê direto) e suficientemente estruturado (headings, listas) para que o harness faça parsing programático por seção sem exigir um schema rígido. Formatos mais estruturados como JSON exigem mais cerimônia para editar (aspas, vírgulas, escaping) e são mais hostis a revisão humana em PR — o que aumenta a fricção exatamente na etapa (revisão de regra de governança) onde você menos quer fricção. O trade-off: Markdown como spec sacrifica validação de schema automática forte em troca de legibilidade e velocidade de revisão — aceitável quando a spec descreve política e convenção, menos aceitável quando descreve dados estruturados que precisam de validação rígida (nesse caso, um schema formal continua sendo a escolha certa).
Injeção declarativa não elimina a necessidade de revisão de prompt
Vale nomear o limite dessa abordagem: mover regras para specs declarativas resolve o problema de onde a regra vive e como ela é versionada, mas não resolve, sozinho, o problema de se o modelo vai obedecer a regra. Uma spec bem escrita, mal montada no contexto (por exemplo, cortada pela metade por estouro de orçamento de tokens, ou colocada numa camada de baixa precedência por engano) tem o mesmo efeito prático de uma spec que nunca existiu. Por isso a disciplina de engenharia de contexto sistêmico não termina em "escrever a spec" — ela inclui testar, de forma sistemática, se a montagem de contexto realmente entrega a regra ao modelo nas condições reais de carga da sessão (histórico longo, múltiplas specs concorrentes, estado operacional volumoso). Esse tipo de teste de integração de contexto é tão parte da arquitetura quanto testes de integração de API em qualquer outro sistema.
Padrões e Armadilhas
Padrões recomendados
Padrão 1: trate cada spec como uma unidade testável isoladamente. Antes de compor várias specs no contexto final, valide cada uma sozinha: ela é compreensível fora do documento inteiro? Ela contradiz alguma outra spec já existente no repositório? Specs que só fazem sentido lidas em conjunto com outras, numa ordem específica não documentada, viram dívida de manutenção assim que uma pessoa nova começa a editá-las.
Padrão 2: versione mudanças de spec com o mesmo rigor de mudança de código. Uma alteração em specs/politica-de-escrita.md que afrouxa uma restrição (por exemplo, remover um diretório da lista de protegidos) merece revisão de PR tão criteriosa quanto uma mudança de permissão em código — porque, do ponto de vista do harness, é exatamente isso que ela é.
Padrão 3: meça o consumo de tokens por camada em produção, não apenas em teste. O orçamento por camada definido em desenho raramente sobrevive intacto ao primeiro mês de uso real — sessões de usuários reais tendem a gerar históricos mais longos e mais specs concorrentes do que os cenários de teste previram. Instrumentar quanto cada camada realmente consome, por sessão, é o que permite recalibrar o orçamento com dado, não com suposição.
Armadilhas comuns
⚠️ Armadilha 1: specs redundantes escritas por pessoas diferentes. O que acontece: dois times, sem saber um do outro, escrevem specs que cobrem parcialmente a mesma regra com redações levemente diferentes — uma diz "nunca escrever em /prod", outra diz "toda escrita em produção exige aprovação". O harness injeta as duas, o modelo recebe sinal parcialmente conflitante sobre o que é proibido e o que é apenas condicionado. Versão correta: um único dono por área de política, com processo de revisão que detecta sobreposição antes do merge.
⚠️ Armadilha 2: confundir Camada 3 (estado operacional) com Camada 2 (regras). O que acontece: alguém injeta um fato operacional ("o último deploy falhou") misturado no mesmo bloco de texto que uma regra de política, sem separação clara. O modelo, e principalmente qualquer ferramenta de auditoria automatizada que tente extrair "quais regras este agente segue", não consegue distinguir fato de norma. Versão correta: manter fronteiras textuais e, se possível, estruturais (seções ou até campos separados) entre fato e regra.
⚠️ Armadilha 3: aumentar o limite de tokens em vez de resolver a causa do estouro. O que acontece: a janela de contexto estoura, e a solução aplicada é simplesmente trocar para um modelo com janela maior, sem investigar se o estouro vem de histórico não resumido ou de specs irrelevantes sendo injetadas sem filtro. Isso adia o problema e aumenta custo (aprofundado na Parte 5 desta série), sem corrigir a causa raiz. Versão correta: instrumentar a composição do contexto por camada antes de assumir que o problema é falta de espaço.