37 pontos por GN⁺ 2026-03-20 | 6 comentários | Compartilhar no WhatsApp
  • Em resposta à afirmação de que, com codificação agêntica, “documentos de especificação podem substituir código”, aponta-se uma limitação fundamental: quando a especificação se torna suficientemente precisa, ela inevitavelmente converge para a mesma forma do código
  • Ao observar o projeto Symphony da OpenAI, vê-se que o respectivo SPEC.md não é uma especificação, mas na prática pseudocódigo em Markdown
  • Na prática, ao tentar uma implementação em Haskell com base na especificação do Symphony, surgiram vários bugs e problemas de confiabilidade, como espera infinita do agente
  • O trabalho de especificação originalmente exige um nível de reflexão mais profundo do que programar, mas, no atual ambiente da indústria otimizado para velocidade, forma-se uma estrutura que produz em massa especificações de baixa qualidade geradas por IA
  • O princípio de “garbage in, garbage out” também se aplica integralmente a agentes de codificação, e, com documentos sem clareza e detalhamento, é impossível gerar código confiável

Dois equívocos sobre codificação agêntica

  • Existem dois equívocos centrais nos quais os defensores da codificação agêntica se apoiam
    • Equívoco 1: documentos de especificação são mais simples do que o código correspondente — uma visão de terceirização segundo a qual engenheiros podem ser transformados em gestores que escrevem especificações e delegam o trabalho a uma equipe de agentes
    • Equívoco 2: trabalho de especificação é necessariamente mais criterioso do que trabalho de programação — a alegação de que passar por um documento de especificação melhora a qualidade e promove práticas de engenharia melhores

Código disfarçado de especificação: análise do caso Symphony

  • O projeto Symphony da OpenAI é apresentado como um orquestrador de agentes gerado a partir de um documento de especificação (SPEC.md), mas, na prática, o conteúdo do SPEC.md está mais próximo de pseudocódigo em Markdown do que de uma especificação
  • Tipos de conteúdo incluídos no SPEC.md:
    • Dump em prosa do esquema de banco de dados — enumeração de campos como session_id, thread_id, codex_input_tokens etc.
    • Conversão em prosa de código — fórmulas como available_slots = max(max_concurrent_agents - running_count, 0) para controle de concorrência e a fórmula de backoff de retry (delay = min(10000 * 2^(attempt-1), agent.max_retry_backoff_ms))
    • Seções redundantes como "Config Fields Summary (Cheat Sheet)", adicionadas explicitamente para ajudar o modelo a gerar código
    • A seção “Reference Algorithms”, que é praticamente o próprio código, como a função start_service()
  • Alegar que o documento de especificação é um substituto para o código, quando ele próprio é lido como código, é enganoso
  • Para tornar um documento de especificação suficientemente preciso, é inevitável transformá-lo em uma forma de código ou escrevê-lo em um inglês formal altamente estruturado

O argumento da “interface estreita” de Dijkstra

  • Citando Dijkstra, argumenta-se que a escolha da interface não é uma simples divisão de trabalho, e que há um custo adicional de colaboração e comunicação através da interface
  • São apresentados exemplos históricos: a matemática grega estagnou por permanecer em atividades linguísticas e visuais; a álgebra islâmica decaiu ao regressar a um estilo retórico; e a Europa Ocidental saiu das “vãs tentativas de precisão linguística” do escolasticismo medieval e avançou graças aos sistemas simbólicos formais de Vieta, Descartes, Leibniz, Boole e outros
  • Os codificadores agênticos não podem evitar a “interface estreita” (= código) exigida pelo trabalho de engenharia; no máximo, podem transformar esse trabalho em outra forma que pareça diferente na superfície, mas exija a mesma precisão

Instabilidade: problemas de confiabilidade na geração de código a partir de especificações

  • Seguindo a recomendação do README do Symphony, foi solicitado ao Claude Code que implementasse o sistema em Haskell, mas o resultado não funcionou
    • Surgiram vários bugs, exigindo correções via prompt (o que pode ser verificado no histórico de commits)
    • Mesmo quando aparentemente “funcionava” sem mensagens de erro, o agente codex ficava esperando indefinidamente sem qualquer progresso diante de um ticket simples do Linear (“criar um repositório git vazio”)
  • Tomando de empréstimo a expressão de Dijkstra, confirma-se que as “vãs tentativas de precisão linguística” do Symphony ainda falham em gerar implementações confiáveis
  • O problema não se limita ao Symphony — até especificações como a YAML spec, extremamente detalhadas, amplamente usadas e acompanhadas de suítes de testes de conformidade, ainda assim têm a maioria das implementações de YAML incapazes de cumprir totalmente a especificação
  • A especificação do Symphony já chega a 1/6 do tamanho da implementação em Elixir incluída; se for expandida ainda mais, chega-se a uma situação como a alegoria de Borges em “Sobre o rigor na ciência” — um mapa do tamanho do império que acaba se tornando inútil
  • Em resposta ao argumento de que “o resultado seria melhor se fosse gerado em uma linguagem mais mainstream”, afirma-se que, se o agente tem dificuldade para gerar código em Haskell, isso sugere falta de capacidade de generalização para além dos dados de treinamento

Slop: o problema da qualidade em especificações geradas por IA

  • O trabalho de especificação deveria originalmente ser mais difícil do que programar, pois seu objetivo é levar a examinar o projeto de forma reflexiva e crítica antes de começar a codificar
  • Porém, dentro da tendência da indústria de tecnologia de reduzir e desvalorizar o trabalho, partir da premissa de que “trabalho de especificação é mais fácil do que programar” significa que o fracasso já está garantido
  • É impossível realizar o trabalho difícil e desconfortável exigido pela escrita de especificações enquanto se busca otimizar a velocidade de entrega
  • A Seção 10.5 do SPEC.md do Symphony (linear_graphql extension contract) é um exemplo representativo de slop — um produto típico de agente em que frases “parecem especificação”, mas carecem de consistência, propósito e compreensão do quadro geral
    • Regras isoladas são listadas, como query deve ser uma string não vazia e deve conter exatamente uma operação GraphQL, mas falta contexto global
  • Mesmo que esses documentos de especificação tivessem sido escritos por humanos, eles inevitavelmente seriam slop, porque foram otimizados para o tempo de entrega, e não para consistência ou clareza
  • O fato de trechos de código estarem anotados como text sem syntax highlighting também é um sinal de documento gerado por IA — presume-se que o modelo seguiu o pedido ao pé da letra, e não sua intenção

Conclusão

  • Especificações não foram originalmente projetadas para economizar tempo
  • Se o objetivo é otimizar o tempo de entrega, é melhor escrever o código diretamente do que passar por um documento intermediário de especificação
  • O princípio de “garbage in, garbage out” se aplica integralmente — se a entrada for um documento sem clareza e sem detalhes, não existe um mundo em que um agente de codificação consiga preencher essas lacunas com confiabilidade
  • Agentes de codificação não leem mentes e, mesmo que lessem, se o próprio pensamento estiver confuso, não há o que possam fazer

6 comentários

 
gracefullight 2026-03-20

Parece exatamente a mesma coisa que na época do desenvolvimento orientado por modelos.

 
wedding 2026-03-20

O desenvolvimento orientado por especificações, SDD, não existe desde sempre?

 
koreacglee 2026-03-20

Parece que, com soluções baseadas em Python ou JavaScript, é possível obter implementações satisfatórias apenas com documentos de especificação detalhados. Trabalho na área de jogos/medicina baseada em C/C++, e ultimamente tenho pensado muito que automatizar só com documentos de especificação detalhados, quanto mais delegar a um FULL AI AGENT, ainda parece arriscado demais.

 
GN⁺ 2026-03-20
Comentários no Hacker News
  • Não concordo com a ideia de que, mesmo fornecendo documentação pouco clara, um agente de programação não consegue preencher os detalhes
    LLMs são essencialmente máquinas de interpolação/extrapolação de linguagem e são muito bons em completar detalhes ausentes
    Há muitos casos em que eles produzem código funcional só com descrições curtas e concisas
    Ainda assim, esse preenchimento de detalhes nem sempre é correto, e para garantir confiabilidade é preciso restringir explicitamente as partes importantes
    Hoje existe uma cultura de escrever código, mas quase não existe uma cultura de escrever especificações ultraprecisas, exceto em lugares como a NASA

    • LLMs conseguem gerar código a partir de descrições curtas, mas não de forma confiável
      Quanto mais curto e comum for o código, melhor funciona, mas em descrições complexas isso desmorona facilmente
      No fim, admitir que “o preenchimento de detalhes pode estar errado” significa reconhecer que a geração confiável é difícil
    • Na verdade, já temos linguagens de especificação precisa desse tipo
      Por exemplo, existem linguagens de síntese de programas como Synquid
      Elas mostram quais são os limites de gerar programas a partir de especificações matematicamente exatas
      O problema chamado specification gap, isto é, provar que um programa implementa fielmente a especificação, é a questão central
      Linguagem natural é ambígua demais para definir um programa de forma adequada
      O fato de um LLM preencher detalhes plausíveis não resolve essa lacuna
      Linguagens de especificação matemática são precisas, mas têm curva de aprendizado alta e são muito mais difíceis e intensivas em trabalho do que simplesmente escrever prompts em Markdown
    • Dizer que “o preenchimento de detalhes pode estar errado” equivale a contradizer a própria tese
    • Se você usar o ChatGPT 5.4 Pro, ao perguntar simplesmente “isso é possível?”, ele de fato cria exemplos que funcionam
      O modelo lembra meus interesses ou preenche lacunas com seu próprio conhecimento para criar apps, jogos ou whitepapers completos
      Às vezes é “exatamente o que eu queria”, e às vezes é “exatamente a sensação que eu estava descrevendo”
      Em lidar com significado, contexto e nuance, em alguns pontos ele até supera humanos
      A IA está ficando cada vez mais inteligente e capaz
    • O que os LLMs geram na maior parte do tempo é boilerplate ou extensões de algoritmos já conhecidos
      Ou seja, está mais próximo de puxar coisas dos dados de treinamento do que de criar detalhes realmente novos
  • Concordo com a frase “uma especificação suficientemente detalhada já é código”
    Isso é o mesmo argumento de No Silver Bullet, de Brooks
    Mas a maioria das pessoas não quer esse nível de detalhe
    Quando dizem “faça um app de tarefas para mim” para a IA, na prática querem dizer “faça um app melhor do que o que eu imaginei”

    • Isso acontece porque já existem inúmeros apps de tarefas nos dados de treinamento
      Mas essa abordagem não escala bem para outros tipos de software
    • Se você realmente quer criar um app, precisa explicar o que o diferencia dos apps existentes
      No fim, é preciso expressar esse diferencial como especificação
    • Em áreas visuais e concretas como frontend web, a especificação quase se confunde com o código
      Mas em áreas como bancos de dados, sistemas de arquivos e computação paralela, em que exatidão e desempenho importam, a implementação é muito mais difícil do que a especificação
      Nesses casos, fazer a IA gerar código que passe em verificação formal é um grande desafio
    • Para definir o que seria um “app melhor”, no fim você precisa de uma spec
    • Se for um app vendido comercialmente, a especificação é indispensável
      Para ganhar dinheiro ou competir, são necessários requisitos concretos
  • Vendo vibe coding pela ótica da teoria da informação, a premissa é que existe um decodificador capaz de reconstruir um espaço de programas úteis a partir de um espaço pequeno de prompts
    A taxa de compressão é justamente o ganho do vibe coding
    Um prompt como “app de comunicação em equipe baseado em canais IRC” é indecifrável se você não conhece Slack
    Portanto, é importante perceber o que está faltando
    Para programar com IA de forma eficaz, é melhor dividir os prompts em unidades curtas e fornecer junto documentação existente, código já tentado etc.

    • Isso é praticamente o mesmo que teoria algorítmica da informação
      Segundo Algorithmic Information Theory, a quantidade de informação de uma string é igual ao comprimento de sua representação autocontida mais comprimida
      Porém, a condição de “autocontida” só vale quando os pesos do modelo funcionam como codebook
    • Adoro a ideia de “reconstruir um programa com um prompt pequeno”
      Como humanos presumem muito mais contexto compartilhado do que LLMs, tendemos a superestimar os limites do decodificador
      Mas, num sistema com restrições fortes e ênfases claras, parece que a taxa de compressão do vibe coding poderia aumentar de forma explosiva
    • Não é só uma questão de concisão
      A linguagem natural oferece uma nova interface para pessoas que têm menos acesso a linguagens de programação
      O LLM não pensa por elas, mas abre um novo caminho para transformar ideias em sistemas funcionais
  • Em breve, as pessoas provavelmente vão criar um dialeto de inglês técnico tipo LLMSpeak para melhorar desempenho do modelo e eficiência de tokens
    A ideia seria reduzir ambiguidades, economizar tokens e comprimir conceitos complexos em uma única palavra
    Até regras gramaticais como a Oxford comma provavelmente surgiriam para aumentar a clareza

    • Isso no fim é praticamente reinventar uma linguagem de programação
      Se a especificação for tão minuciosa assim, não há muito motivo para usar prompts
    • Mas, se o modelo não foi treinado nesse dialeto, seria preciso enviar a definição junto toda vez
      No fim, seria necessário redefinir tudo em linguagem humana novamente, então o ganho de tokens seria limitado
    • Há também quem proponha usar uma língua não ambígua como Lojban
      Veja a wiki do Lojban e um vídeo de um falante de Lojban
    • As línguas humanas já são suficientemente eficientes para transmitir a maioria das ideias
      Tentativas de dialetos artificiais têm grande chance de fracassar, como aconteceu com o Esperanto
    • Se o LLM não foi treinado nesse tipo de dialeto, então a capacidade de interpretar linguagem humana ambígua continua sendo mais importante
      Esse tipo de linguagem pode até ser útil quando usado entre LLMs
      As linguagens de programação já exercem esse papel
  • Uma spec é como um envelope que contém todos os programas que satisfazem certas condições
    Criar esse envelope é mais difícil do que escrever um único programa
    Assim como um LLM gera um código diferente a cada vez, uma especificação permite tanto implementações boas quanto ruins
    Na prática, quando uma implementação é adotada, ela vira a especificação de fato da versão seguinte
    Em ambientes com código legado (brownfield), as especificações não são limpas, então os LLMs têm dificuldade para lidar bem com isso

    • Quando comecei a escrever especificações após 20 anos de carreira, entendi por que isso é mais difícil do que programar
      Existe uma explosão combinatória ao considerar como uma linha da especificação interage com as demais
      Mas, do ponto de vista do compilador, código também é só especificação
      No fim, dizer que “código é mais fácil do que especificação” é algo relativo
    • Dois programas podem satisfazer a mesma especificação e ainda assim ter propriedades de segurança completamente diferentes
      A especificação “armazenar credenciais de usuário” abrange desde bcrypt até cookies em texto puro
      Humanos têm um instinto de “isso não pode”, mas agentes não sabem disso se não for explicitado
      Portanto, para garantir segurança, é preciso especificar até o que não deve ser feito
    • Uma boa especificação define só “o que fazer”, não “como fazer”
      Se desempenho ou segurança forem importantes, essas propriedades precisam ser explicitadas
      Por exemplo, uma frase como “este programa deve ser O(n)” é muito mais simples do que a implementação
  • Parece que cada pessoa usa spec com um significado diferente
    Para mim, spec define “o que” fazer, plan define “como”, e build packet significa os “passos detalhados”
    Na maioria dos casos, o importante é o “o quê”
    Escrever como os dados vão de A para B, passam por C, são preservados em D e representados em formato F em E é muito mais fácil como especificação do que implementar isso em Rust

  • Quando você faz engenharia orientada por agentes, muitas vezes os documentos de especificação ficam mais longos do que o código
    Linguagem natural é imperfeita, mas código é exato
    O objetivo da especificação é preservar funcionalidades mesmo após várias rodadas de desenvolvimento iterativo
    Documentos de design em estilo waterfall foram mais eficazes do que testes ou comentários
    Desse jeito, também consegui refatorar projetos completos de vibe coding ou trocar de linguagem de forma tranquila
    Agora parece que voltamos ao fluxo de desenvolvimento dos anos 70 e 80

    • Talvez também dê para fazer isso com testes, mas se você deixar o agente mexer nos testes, existe o risco de ele alterar os próprios testes
    • Especificações em linguagem natural nem sempre precisam ser mais longas do que o código
      Uma frase como “implemente a interface TCP” é muito mais curta do que o código real
      No fim, se houver mapeamento para um schema claro, a linguagem natural também pode ser suficientemente compacta
  • O caminho Spec → LLM é ineficiente e desperdiçador
    Na prática, LLM → Spec é mais realista
    Se a especificação existir em forma compilável, o LLM pode usar esse feedback para gerar código melhor
    Tentativas de criar “inglês validado (validated English)” só aumentam a complexidade
    No fim, o que importa é código que realmente funcione

  • O código contém muito mais coisa do que a especificação
    Na maioria dos projetos, 90% é código de framework ou infraestrutura, e só 10% é lógica de negócio
    A especificação é muito mais concisa porque não trata dos detalhes de linguagem ou framework

    • Mas o código que realmente resolve o problema precisa abstrair todo o resto e deixar apenas a lógica de negócio
      Quando isso acontece, o código fica quase no mesmo nível da especificação
      Especialistas de domínio também conseguem ler, e testar fica mais fácil
    • Por exemplo, ao trocar MySQL por Postgres, a especificação continua igual
      Mas o código real muda bastante
  • O conflito entre ver a especificação como ferramenta de gestão e vê-la como ferramenta de engenharia gera dissonância cognitiva
    Gestores enxergam especificações como tickets para delegação, enquanto desenvolvedores as usam como ferramentas de pensamento para refinar raciocínio
    Alguns desenvolvedores começam adotando a visão gerencial por conveniência, mas logo percebem a diferença

    • Não importa o quanto se gerencie: no fim, é preciso construir de verdade
      Hype ou reuniões com investidores podem sustentar isso por algum tempo, mas no final os usuários querem o produto real
 
savvykang 2026-03-21

Daqui a pouco vão reinventar também o waterfall e o ágil.

 
jjw9512151 2026-03-20

Como desenvolvedor embarcado em C, primeiro elaboro a especificação de modo que seja possível verificar quase todo o fluxo de cada Feature/Subfeature por meio de charts.

Depois de revisar longamente a especificação e fechar a versão final, gero e utilizo um código que corresponde 1:1 de forma completa à especificação.
A legibilidade ao revisar pela especificação é muito superior à da revisão de código.