1 pontos por GN⁺ 1 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Agentes LLM são fortes na geração de código com especificações flexíveis, mas ainda são frágeis para cumprir contratos de API, arquitetura, banco de dados e restrições de ORM exigidos por backends de nível de produção
  • Com a mesma especificação OpenAPI, os requisitos funcionais foram mantidos fixos, e os mesmos testes de comportamento foram aplicados a 80 tarefas greenfield e 20 tarefas de implementação de funcionalidades em 8 frameworks web
  • As restrições não funcionais foram divididas em 4 dimensões — escolha de framework, padrão de arquitetura, backend de banco de dados e integração com ORM — para isolar o impacto da complexidade estrutural
  • Constraint decay é o fenômeno em que o desempenho despenca à medida que os requisitos estruturais se acumulam; em tarefas totalmente especificadas com alta configuração, a assertion pass rate caiu em média 30 pontos
  • O núcleo das falhas está em defeitos na camada de dados, com construção incorreta de consultas e violações de runtime do ORM respondendo por cerca de 45% das falhas da lógica do agente

Problema central e configuração da avaliação

  • Agentes LLM são fortes na geração autônoma de código com especificações flexíveis, mas sua capacidade de seguir rigidamente as restrições estruturais necessárias para software backend de nível de produção ainda não foi avaliada de forma suficiente
  • Um backend de nível de produção precisa atender não apenas endpoints que seguem contratos de API, mas também requisitos além da funcionalidade, como padrões de arquitetura, integração com banco de dados e uma camada de ORM especificada
  • Benchmarks existentes muitas vezes recompensam soluções funcionalmente corretas, mas estruturalmente arbitrárias, e por isso não capturam adequadamente a dificuldade do desenvolvimento backend com múltiplos arquivos e restrições
  • Pesquisas anteriores focaram principalmente em corrigir problemas específicos em codebases existentes, geração sem restrições baseada em prompts em linguagem natural, soluções de arquivo único e preenchimento de código esqueleto, sem tratar sistematicamente o efeito de variar o grau de restrições estruturais
  • O impacto da complexidade estrutural foi isolado fixando os requisitos funcionais com a mesma especificação OpenAPI e aplicando os mesmos testes end-to-end de comportamento em todas as condições
  • O experimento é composto por 80 tarefas de geração greenfield e 20 tarefas de implementação de funcionalidades em 8 frameworks web
  • As restrições não funcionais foram divididas em 4 dimensões: escolha de framework, padrão de arquitetura, backend de banco de dados e integração com ORM
  • Na condição de referência, apenas a mesma especificação de API é fornecida; nas condições com restrições, são adicionadas exigências como clean architecture, PostgreSQL e SQLAlchemy
  • A avaliação usa testes de comportamento end-to-end em conjunto com validadores estáticos para separar a precisão funcional da conformidade estrutural

Principais resultados e significado

  • Constraint decay foi identificado como o fenômeno em que o desempenho do agente cai de forma significativa à medida que os requisitos estruturais se acumulam
  • Mesmo configurações com bom desempenho tiveram, da condição de referência até tarefas totalmente especificadas, uma queda média de 30 pontos na assertion pass rate; algumas configurações mais fracas chegaram perto de zero
  • Mesmo com o mesmo contrato de API, houve grande diferença de taxa de sucesso entre frameworks, e os agentes funcionaram melhor em frameworks mais leves e explícitos como Flask
  • Em ambientes mais baseados em convenções, como FastAPI e Django, o desempenho médio foi muito mais baixo
  • A análise de erros mostrou que defeitos na camada de dados são a principal causa, com construção incorreta de consultas e violações de runtime do ORM como exemplos representativos
  • Defeitos na camada de dados foram classificados como a causa central de cerca de 45% das falhas na lógica do agente
  • Satisfazer ao mesmo tempo requisitos funcionais e estruturais continua sendo um importante problema em aberto para agentes de programação
  • O pipeline de avaliação, o conjunto de tarefas, as trajetórias de execução dos agentes e os scripts de análise estão disponíveis em constraint-decay

1 comentários

 
GN⁺ 1 시간 전
Comentários do Hacker News
  • Eu era totalmente cético em relação à geração de código por LLM, mas agora mais de 80% do código que uso no trabalho é gerado
    Ainda assim, as limitações ficaram bem claras, começaram a aparecer em alguns projetos, e este texto parece confirmar minhas suspeitas
    Quanto mais complexa a tarefa, mais acabo adicionando restrições em especificações Markdown, regras, skills, guias de estilo, condições de contorno, tratamento de erros e diretrizes de otimização
    Em certo ponto, parece que estamos transferindo a complexidade do mundo mais formal e determinístico das linguagens de programação para o mundo informal e não determinístico da linguagem natural
    O ganho de velocidade de escrita é enorme, e os negócios naturalmente veem isso como aumento de produtividade, mas o custo é claro, e muita gente parece ignorá-lo

    • Esse é exatamente o problema de que ninguém fala. A codebase está crescendo com arquivos Markdown cheios de instruções, diretrizes e pedidos gerados para LLM, e isso só vai se acumulando
      Ninguém revisa 100%, e mesmo quando revisa, é algo muito subjetivo
      É ambígua a diferença entre “siga uma abordagem RESTful”, “nós usamos REST e não usamos GraphQL” e “90% dos endpoints são orientados a recursos, mas alguns parecem RPC, então ignore isso”
      Tudo isso parece bem idiota
    • É parecido com usar um compilador que, a cada execução, gera código com significado diferente
      Na prática, você está compilando programas cheios de comportamento indefinido, mas que na maior parte do tempo “parecem funcionar”
      O fato de o negócio ver isso como aumento de produtividade dá a sensação de que estamos voltando a medir “produtividade” por linhas de código por segundo
    • Não tenho sofrido tanto assim, mesmo em codebases muito grandes e complexas. Em escalas de mais de 50 MB de código-fonte bruto, tipos estáticos fortes parecem ajudar bastante, mas não acho que seja só isso
      Quando a codebase sai daquele nível em que cabe nos primeiros 20% da janela de contexto e é totalmente reproduzível em uma única inferência, o harness de execução e as técnicas de patch de código passam a ser muito mais importantes
      A abordagem de apply_patch que a OAI vem refinando nos modelos parece ser a melhor para codebases gigantes
      Métodos baseados em intervalo de linhas ou simples localizar-e-substituir quebram nas bordas, e para lidar com casos complicados como arquivos cshtml são necessárias várias âncoras espaciais
      O comportamento de prepare/commit é ideal para iterar sobre contexto ambíguo distribuído por muitos arquivos grandes e refinar as âncoras
    • Se 80% do código gerado vem de LLM, isso fica mais próximo de recombinar o que já existe e, no fim, é slop
      LLM não consegue criar algo novo
  • “Um estudo sistemático revela o fenômeno de degradação de restrições em agentes de programação baseados em LLM. Os modelos atuais são excelentes em geração sem restrições, mas perdem desempenho quando precisam seguir regras arquiteturais explícitas. Para o usuário final, essa dicotomia significa que agentes são confiáveis para prototipagem rápida, mas ainda são difíceis de confiar para desenvolvimento de backend em nível de produção.”
    A grande fraqueza deste estudo é que, por questão de custo, ele não testou suficientemente os modelos de ponta, então os números específicos de desempenho devem ser vistos com cautela
    Ainda assim, a conclusão de que o desempenho do modelo cai quando tanto o comportamento quanto a arquitetura precisam estar corretos é interessante e vale acompanhar

    • Isso parece um efeito a jusante do problema de “não dá para otimizar dois objetivos diferentes ao mesmo tempo”
      Se você só tem requisitos funcionais, isso equivale a uma espécie de síntese de programas, e reinforcement learning pode otimizar isso de forma muito forte
      Quando requisitos funcionais e não funcionais se misturam, você está basicamente dando ao modelo uma especificação incompleta, e ele precisa adivinhar em algum grau a intenção do usuário para preencher as lacunas
      É por isso que incluir exemplos do estilo de código desejado no prompt é tão poderoso
    • Vi um fenômeno parecido em livros escritos com ajuda de IA. No começo funciona bem, mas depois de alguns capítulos o início de cada capítulo passa a repetir o fim do capítulo anterior, e os traços característicos de LLM aparecem com mais frequência
      Quanto mais material há para consultar, mais ele depende de repetir o que veio antes
      Também é possível que os autores prestem menos atenção e invistam menos esforço de edição nos capítulos mais para o fim
      Há um volume enorme de livros na Amazon, mas LLM ainda não está em um estágio em que escreve bem
    • Passei por algo parecido ao planejar com o Opus em várias interações
      Quando ele propõe soluções incompatíveis e eu adiciono mais contexto e requisitos, ele tende a ficar preso à arquitetura original e tem dificuldade de se adaptar
      Às vezes até tenta inserir às escondidas mudanças para o plano original
    • Pode ser o mesmo problema que aparece quando o prompt tenta impor “alinhamento” ou “guardrails”. O desempenho cai
      Parece que grandes partes do espaço de soluções possíveis ficam inacessíveis
      Por exemplo, há cerca de um ano, quando aplicavam guardrails em geradores de imagem, todas as pessoas começavam a parecer parecidas, e geradores de histórias passaram a usar só alguns poucos nomes padrão
      Fico curioso se isso ainda acontece nos modelos de ponta
    • Mesmo o GPT 5.2, que foi o modelo de ponta mais forte usado neste estudo, eu considero apenas minimamente utilizável para programação em estilo agente
      Não tenho muito interesse em análises das fraquezas desse tipo de modelo. Pela minha experiência, quando o modelo fica mais forte e o esforço de raciocínio aumenta, muitas fraquezas desaparecem completamente
      Isso vale ainda mais quando você diz claramente qual comportamento deseja, e não é surpresa que a taxa de falha suba quando os critérios de aceitação aumentam
  • A situação é pior. O agente não só sofre mais sob “restrições estruturais”, como é ainda pior quando a própria restrição estrutural precisa mudar
    Ao projetar um sistema ou componente, estabelecemos ideias que se tornam invariantes
    Algumas invariantes são grandes, como a arquitetura geral, e outras são pequenas, como a escolha de uma estrutura de dados
    Mas inevitavelmente chega um momento em que queremos adicionar uma funcionalidade que entra em conflito com essas invariantes
    Nesse ponto, normalmente há três opções: não adicionar a funcionalidade, encaixá-la de forma deselegante ou ineficiente por cima da invariante, ou voltar atrás e mudar a invariante
    Em geral, só uma dessas está certa, e pelo menos uma está muito errada e leva a maus resultados
    Agentes são muito ruins em perceber o momento em que as restrições precisam mudar, mesmo quando conseguem seguir as restrições

    • Tenho expectativas muito limitadas em relação à programação com agentes, mas já usei o suficiente para concordar totalmente com isso
      Esta é uma das fronteiras entre reconhecimento de padrões e raciocínio, e apesar do marketing sobre processo de pensamento, LLM não raciocina nem um pouco
      Toda tentativa de fazê-lo parecer que raciocina me parece mais um esforço recursivo de isolamento no harness para engarrafar um raio
  • Lembra um artigo recente que delegou ao LLM tarefas de edição de documentos em várias áreas https://arxiv.org/abs/2604.15597
    Nesse artigo, a visão era que a programação era praticamente a única área em que a maioria dos LLMs conseguia realizar tarefas de horizonte longo sem acumular erros e sem estragar o documento
    Ainda só li o resumo deste artigo, mas parece que ele olha para a programação com mais precisão e mostra um fenômeno semelhante
    Ainda assim, em vez de tarefas de horizonte longo, isso parece mais próximo de um “horizonte longo de estilo” para um conjunto maior de restrições estruturais
    Discussão relacionada: https://news.ycombinator.com/item?id=48073246

    • LLMs não são bons em coisas que não podem ser verificadas com facilidade
  • É um artigo muito interessante e concordo totalmente, mas não acho que seja exatamente novidade
    Já se desviava um pouco da expectativa inicial de que bastaria jogar alguma solução de programação agentiva em um projeto e passar uma lista de tarefas para que ela seguisse magicamente as restrições predefinidas do projeto
    Não acredito que qualquer stack de programação agentiva consiga fazer isso no estado padrão
    O agente ainda precisa de mecanismos adequados para compreender contexto, restrições e objetivos de forma estável, e o fato de os principais laboratórios de IA continuarem atualizando ferramentas, skills e processos mostra que isso ainda está em desenvolvimento
    Essa camada adicional pode acabar sendo muito mais lucrativa do que o modelo puro e o consumo de tokens
    Acho que até modelos abertos como os que parecem ter sido testados atualmente já conseguem produzir código de produção que segue as restrições desejadas, se forem operados corretamente
    Fico curioso para saber como tem sido o código de produção de vocês nos últimos meses

  • Tenho experimentado bastante com programação agentiva de horizonte longo https://medium.com/@vishvananda/i-spent-2-billion-tokens-wri... e também vi que impor certos padrões arquiteturais piora o desempenho do agente
    Funciona um pouco melhor quando as restrições são introduzidas durante o processo, em vez de serem adicionadas depois
    Há um efeito colateral que chamo de calcificação: quando algum padrão começa a aparecer no codebase, o agente passa a segui-lo, ele domina o contexto e vai se autorreforçando
    Em codebases existentes, isso pode ser uma força ou uma fraqueza, dependendo da qualidade do código
    Acho que haverá mais insights quando terminarem execuções em codebases novos que já incluam diretrizes de arquitetura desde o início

    • Também vi isso. Agentes e modelos têm estilos próprios, e em geral isso se resume a verbosidade excessiva
      Além disso, o modelo modulariza razoavelmente bem quando tem espaço para “planejar” a implementação, mas raramente decide por conta própria que abstrações ajudariam depois
      Isso é especialmente verdade depois de várias iterações em um codebase novo ou quando ele é colocado em um codebase legado, e muitas vezes resulta em arquivos gigantes
      Quando o usuário aponta isso, o modelo faz a crítica corretamente, o que é bem engraçado quando foi ele mesmo que escreveu o código
  • Parece outra versão de “quanto mais longa a conversa, mais borradas ficam as guardrails”
    A razão de não dar para usar a janela de contexto inteira é que, no fim, a saída deixa de respeitar as restrições ou as guardrails
    Mas, para produzir código de nível de produção de forma confiável, o modelo precisa ter uma visão ampla, e isso enche a janela de contexto muito rápido
    É como dizer “faça essa mudança tendo em mente tudo nestes 6 diretórios”, só que só de manter tudo isso em mente a janela de contexto já fica cheia e o modelo perde a capacidade de seguir as restrições

    • Não é um problema novo. Foi exatamente por isso que começamos a usar código modular e interfaces rígidas
    • Será que não bastaria dar guardrails mais fortes? Coisas como Sonarcube
      Só que, nesse caso, o modo de falha provavelmente mudaria para algo focado em satisfazer o linter enquanto vai esquecendo aos poucos os requisitos
      A repetição de tentativa/erro também não deve ajudar em nada o contexto
  • O estudo usou linguagens de tipagem dinâmica como Python e JS
    Pela minha experiência, codebases com tipagem estática são mais fáceis de manter até para humanos, então talvez também sejam para agentes
    Já vi incontáveis vezes, ao usar Codex ou Claude Code em código Go, o agente fazer uma mudança, rodar o build, encontrar erros e corrigir de novo

    • Basta adicionar tipos às regras do harness e executar ty depois de cada mudança
      Hoje em dia os modelos lidam muito bem com tipos em Python
    • É estranho que as pessoas considerem Python, por padrão, uma linguagem de tipagem dinâmica
      Já faz anos que Python oferece tipagem estática forte como opção, e isso simplesmente deveria ser o padrão
  • Eles falam em “tarefas cobrindo 8 frameworks web”, e fiquei curioso se alguém teve a experiência de que LLMs produzem melhor HTML+CSS+JS puro do que trabalhando com frameworks existentes

    • Frameworks web parecem ter entrado numa “situação complicada” desde o gpt-5.4. Agora é difícil imaginar usar algo como React
      A combinação mais impressionante que vi recentemente foi Razor Pages com aprimoramento progressivo em JavaScript
      Nessa configuração, os modelos mais recentes julgam bastante bem o que deve acontecer no lado do servidor (cshtml) e o que deve acontecer no lado do cliente (js)
  • Recomendo gastar um tempo ajustando primeiro algumas partes do codebase para uma forma idiomática e depois marcar esses arquivos com @ como arquivos de exemplo
    Funciona muito melhor do que tentar controlar isso com Markdown
    No caso de algo como FastAPI, até que funciona bem, mas JavaScript parece ser o pior caso
    Mesmo com instruções e exemplos, há uma tendência de tentar colocar um monte de código inútil inline em vez de usar a API especificada