O que eu queria descobrir
Um briefing pode parecer claro e ainda deixar de fora informações importantes.
Imagine receber esta mensagem:
“Preciso de um site moderno para minha empresa.”
Ela comunica uma intenção, mas ainda deixa várias perguntas em aberto.
- Qual é o objetivo do site?
- Quem é o público?
- Quais páginas serão necessárias?
- Existem integrações?
- Quem fornecerá o conteúdo?
- Existe uma data de lançamento?
Uma pessoa que conhece o processo da empresa tende a fazer essas perguntas porque já conhece os requisitos envolvidos.
Um modelo de IA não possui esse contexto automaticamente.
Foi isso que decidi investigar.
Testei fornecer a um modelo de IA informações claras sobre os serviços, as regras e o contexto da empresa para verificar se isso melhora a revisão de briefings em comparação com usar apenas um prompt bem escrito.
O objetivo não era construir um produto pronto para produção. Eu queria comparar duas formas de resolver o mesmo problema e observar o que mudava quando informações da empresa deixavam de estar implícitas e passavam a fazer parte do contexto fornecido ao modelo.
Primeiro: uma versão baseada apenas em prompt
Comecei criando uma baseline.
Nela, o modelo recebia o briefing e um conjunto de instruções explicando o que deveria procurar.
Uma parte do prompt utilizado era:
You review first-contact client briefings.
Use only the briefing and the criteria below. Do not assume
company-specific services, policies, prices, processes,
documentation, or historical client data.
Review criteria:
- Detect the service requested.
- Identify ambiguity.
- Identify missing information.
- Identify conflicts.
- Identify unverifiable requirements.
Do not invent facts to fill missing information.
A restrição mais importante estava logo no início:
Do not assume company-specific services, policies,
prices, processes, documentation, or historical client data.
Eu estava deliberadamente impedindo que o modelo completasse as lacunas usando suposições sobre como uma empresa poderia funcionar.
A arquitetura era simples:
briefing ↓ prompt ↓ LLM ↓ structured review
Isso se tornou meu ponto de comparação.
Depois, tirei conhecimento empresarial do prompt
Na segunda abordagem, comecei a separar duas coisas que frequentemente aparecem misturadas em sistemas com LLMs: instrução e contexto.
O prompt continuava dizendo ao modelo o que fazer.
Mas informações sobre a empresa passaram a dizer com base em quê fazer.
Para o serviço de desenvolvimento de websites, por exemplo, o experimento possuía um pequeno documento como este:
{
"service": "website development",
"required_information": [
"website type and primary business goal",
"target audience",
"required pages or sections",
"required features and integrations",
"content responsibility and availability",
"visual references or brand guidelines",
"desired launch date"
]
}
Esse arquivo não era um prompt.
Era contexto operacional.
Ele dizia quais informações aquela empresa fictícia considerava necessárias para trabalhar com aquele serviço.
Isso permitia fazer uma distinção importante: se o briefing não informasse o público-alvo, o modelo não precisava decidir por conta própria que “público-alvo parece algo importante”. Havia uma fonte dizendo explicitamente que aquela informação era necessária.
O prompt mudou de responsabilidade
Na revisão com contexto, as instruções passaram a enfatizar a relação entre resposta e documentação:
You review first-contact client briefings using
explicit company documentation.
Use the briefing and only the supplied operational context.
For findings grounded in company documentation,
include the exact document path and the exact
requirement text that supports the finding.
Do not invent company requirements that are not
in the supplied context.
A diferença parece pequena, mas arquiteturalmente é importante.
Baseline prompt → contém os critérios da revisão Com contexto prompt → explica como revisar contexto → informa os requisitos da empresa
Essa foi uma das principais ideias investigadas no projeto.
O resultado também precisava ter estrutura
Eu não queria receber apenas um texto dizendo que o briefing “parecia incompleto”. Os problemas encontrados eram representados por tipos explícitos.
class FindingType(StrEnum):
AMBIGUITY = "ambiguity"
MISSING_INFORMATION = "missing_information"
CONFLICT = "conflict"
UNVERIFIABLE_REQUIREMENT = "unverifiable_requirement"
E um finding contextual podia carregar sua evidência:
class ContextEvidence(BaseModel):
document_path: str
requirement: str
class ContextAwareFinding(Finding):
context_evidence: list[ContextEvidence]
Assim, uma conclusão poderia conceitualmente assumir esta forma:
{
"type": "missing_information",
"description": "The target audience is not specified.",
"context_evidence": [
{
"document_path": "company/website-development.json",
"requirement": "target audience"
}
]
}
Agora havia algo que eu podia inspecionar:
problema encontrado
↓
documento utilizado
↓
requisito que sustenta o problema
Esse mecanismo foi mais importante para mim do que simplesmente aumentar a quantidade de problemas detectados. Ele criava rastreabilidade.
Mas citar um documento não significa estar correto
Surgiu então outro problema.
O que impediria o modelo de devolver uma referência para um arquivo verdadeiro, mas citando um requisito que não existia dentro dele?
{
"document_path": "company/website-development.json",
"requirement": "preferred programming language"
}
O arquivo existe. O requisito não.
Não seria suficiente confiar que o modelo citou uma fonte.
Por isso, depois da resposta da LLM, o software validava a evidência contra o contexto realmente fornecido.
for evidence in finding.context_evidence:
key = (
evidence.document_path,
normalize(evidence.requirement),
)
if key not in allowed_evidence:
raise ValueError(
"Finding references evidence not present "
"in selected context."
)
Essa parte do experimento mudou minha percepção sobre grounding.
Não basta pedir ao modelo: “use apenas as informações fornecidas”.
Quando uma afirmação precisa ser auditável, é útil criar mecanismos no software capazes de verificar essa relação.
LLM → interpreta software → verifica
Nem todo contexto precisava ser enviado
O experimento tinha inicialmente apenas dois serviços documentados.
SERVICE_DOCUMENTS = {
"website development":
Path("company/website-development.json"),
"chatbot development":
Path("company/chatbot-development.json"),
}
Isso permitiu testar outra pergunta: se o briefing trata apenas de website, preciso mandar também as regras de chatbot?
Implementei dois modos.
all_context → envia todos os documentos selected_context → envia apenas documentos dos serviços identificados
A seleção não usava outra LLM, embeddings ou busca vetorial. Era propositalmente simples e determinística.
if mode is ContextMode.ALL_CONTEXT:
return list(SERVICE_DOCUMENTS.items())
return [
(service, path)
for service, path in SERVICE_DOCUMENTS.items()
if service in detected_services
]
Para um briefing relacionado apenas a website, observei:
| Estratégia | Documentos | Caracteres | Palavras |
|---|---|---|---|
| selected_context | 1 | 335 | 36 |
| all_context | 2 | 662 | 71 |
Nesse cenário, selecionar o documento pertinente reduziu aproximadamente 49% do volume textual de contexto.
Isso não significa economia de 49% em tokens ou custo. O que foi medido aqui foram caracteres e palavras.
Também não significa que menos contexto seja sempre melhor. Quando os dois serviços eram relevantes, selected_context carregava os dois documentos e chegava ao mesmo volume de all_context.
A lógica era selecionar por relevância, não simplesmente minimizar texto.
Como fiz a comparação
Para evitar comparar exemplos diferentes, reutilizei três briefings:
website-ambiguouslanding-page-conflictchatbot-unverifiable
Cada um foi executado com três estratégias:
- baseline
selected_contextall_context
Fiz três rodadas completas. Isso produziu nove execuções por estratégia.
Durante essas rodadas, mantive constantes as principais variáveis do experimento. Também optei por não adicionar retry automático quando uma execução falhava.
O resultado foi:
| Estratégia | Execuções válidas | Total |
|---|---|---|
| Baseline | 3 | 9 |
| selected_context | 6 | 9 |
| all_context | 5 | 9 |
Esses números precisam de cuidado.
Eles não demonstram que Context Engineering seja “duas vezes mais confiável”. A amostra é pequena e algumas falhas estavam relacionadas não ao conteúdo da revisão, mas ao contrato estruturado da resposta e aos validators.
O resultado que considero mais importante foi outro: nas execuções válidas, as versões com contexto conseguiram identificar requisitos específicos da empresa e relacioná-los à documentação utilizada.
Uma contradição que não precisava de contexto
Context Engineering também não tornou o prompt inútil.
Considere um briefing que pede uma landing page:
A página não deve possuir formulário.
Precisamos capturar nome e e-mail dos visitantes.
Existe um conflito dentro do próprio briefing.
Não é necessário conhecer regras da empresa para percebê-lo.
A baseline conseguiu identificar esse tipo de problema em execuções válidas.
Isso ajudou a deixar mais claro que contexto e prompt estavam exercendo funções diferentes.
Também tirei a política empresarial do prompt
A etapa seguinte do workflow precisava recomendar o que fazer com o briefing.
As ações possíveis eram:
PROCEED_TO_ESTIMATION
REQUEST_CLARIFICATION
REJECT_OUT_OF_SCOPE
HUMAN_REVIEW
Poderia simplesmente colocar todas as regras no prompt. Mas decidi mantê-las em uma política separada.
O modelo escolhia a regra aplicável. O software resolvia essa escolha contra o documento original.
LLM → qual regra parece se aplicar? software → qual é o texto canônico dessa regra?
Isso evitou depender de o modelo reproduzir perfeitamente uma regra empresarial.
A interpretação continuava probabilística. A evidência persistida, não.
Quando tornar o sistema mais rigoroso revelou mais falhas
Uma das partes mais úteis do experimento não foi um resultado positivo.
Foi começar a enxergar erros que antes poderiam passar despercebidos.
Em uma execução, por exemplo, o modelo produziu um campo em formato diferente do exigido pelo structured output. A execução falhou.
Repetir a mesma chamada, sem mudar código ou prompt, posteriormente funcionou.
Eu poderia adicionar retry e transformar isso em uma execução aparentemente normal. Preferi registrar a falha.
Também ocorreram situações em que uma resposta parecia semanticamente plausível para uma pessoa, mas não conseguia provar a relação exata com o contexto exigida pelo validator.
structured output + schemas + context evidence + validators → novas fronteiras observáveis de falha
Auditabilidade não elimina erros. Ela muda quais erros conseguimos enxergar.
Um prompt menor resolveria?
Depois que boa parte do conhecimento empresarial estava no contexto, testei uma hipótese adicional.
Talvez não fosse mais necessário um prompt tão detalhado.
Comparei o prompt utilizado anteriormente com uma versão reduzida:
Review the briefing using only the supplied
operational context.
Return structured findings for ambiguity,
missing information, conflict, and unverifiable
requirements.
When a finding depends on company documentation,
cite the exact document path and exact requirement text.
Do not invent company requirements.
Return findings only.
Ele era consideravelmente menor, mas preservava a tarefa essencial.
Foram nove execuções para cada variante:
| Prompt | Execuções válidas | Total |
|---|---|---|
| short | 3 | 9 |
| expanded | 5 | 9 |
O prompt curto conseguiu produzir revisões úteis quando funcionava, mas não preservou a mesma consistência observada no prompt expandido.
Em uma execução específica, também aconteceu algo contraintuitivo:
| Variante | Input tokens | Output tokens |
|---|---|---|
| short | 421 | 1630 |
| expanded | 541 | 1318 |
Reduzir tokens de entrada não garantiu menor quantidade total de tokens naquela execução.
Isso não permite generalizar custos. Mas foi suficiente para rejeitar uma interpretação simplista de que um contexto melhor permitiria simplesmente eliminar instruções detalhadas.
O que o experimento me mostrou
Comecei com uma comparação aparentemente simples:
Prompt Engineering vs. Context Engineering
Terminei entendendo que essa oposição não descrevia muito bem o problema.
Um prompt responde principalmente:
Como o modelo deve executar esta tarefa?
Contexto responde:
Que informações, regras, estado e evidências estão disponíveis para executar essa tarefa?
E o software ainda precisa responder:
O que não deveria depender apenas do comportamento probabilístico do modelo?
No experimento, algumas responsabilidades acabaram ficando assim:
Prompt → orienta a tarefa Contexto → fornece conhecimento operacional LLM → interpreta linguagem e contexto Pydantic / schemas → restringem a forma da resposta Validators → verificam determinadas evidências Código determinístico → resolve relações que podem ser verificadas
Essa divisão foi mais importante do que descobrir uma técnica “vencedora”.
Limitações
O experimento foi deliberadamente pequeno.
- Foram usados três briefings nas principais comparações.
- O contexto empresarial possuía apenas dois documentos de serviço.
- As comparações utilizaram um único modelo.
- Houve variação entre execuções equivalentes.
- Structured output e validação também contribuíram para algumas falhas.
- A telemetria de tokens não estava completa em todas as execuções.
- Os dados de latência não devem ser tratados como benchmark.
Também não foram comparados:
- grandes bases de conhecimento;
- busca vetorial;
- diferentes modelos;
- uso em produção;
- políticas empresariais complexas;
- avaliação humana em escala.
Por isso, as conclusões devem permanecer dentro do escopo testado.
Conclusão
O experimento não demonstrou que Context Engineering substitui Prompt Engineering.
Também não demonstrou que fornecer mais contexto sempre melhora uma resposta.
O que observei foi uma divisão de responsabilidades mais útil.
Prompts são importantes para instruir o comportamento.
Contexto é importante quando a resposta depende de conhecimento, regras ou evidências específicas.
E, quando uma regra pode ser verificada deterministicamente, talvez ela não deva depender exclusivamente de uma LLM.
A questão deixou de ser:
“Qual é o melhor prompt?”
e passou a ser:
“Que informação pertence ao prompt, que informação pertence ao contexto e que responsabilidade deveria continuar no código?”
Essa foi a principal conclusão do experimento.