Hashline vs Replace: o formato de edição importa?

Tradução automática Artigo original.


conteúdo

O artigo O problema do harness, de Can Bölük, mostrou que edições no estilo hashline (ancoradas em números de linha, como 4#WB) superam as edições tradicionais no modo replace (correspondência old_string/new_string) em agentes de programação. Tenho experimentado criar meu próprio harness (tau) e queria verificar esse resultado e ver se deveria considerar usar hashline como estratégia padrão de edição nele. Por isso, criei o edit-bench para testar isso por conta própria em várias linguagens e modelos.

Configuração

O edit-bench gera testes baseados em mutações a partir de bases de código existentes. Você aponta um script para um diretório, e ele gera mutações como excluir uma instrução, inverter um booleano, trocar a ordem dos argumentos etc.

  • Linguagens: Python (do hive), TypeScript (do oh-my-pi), Rust (do irradiate)
  • Modelos: gpt-4.1-mini, google/gemini-3-flash-preview, qwen/qwen3.5-397b-a17b
  • Modos de edição: replace (old_string/new_string) vs hashline (ancorado em números de linha)
  • 20 tarefas por linguagem, execuções one-shot, com uma única tentativa
  • Também adicionei recentemente correspondência aproximada a tau (trim em cascata: trim_end → trim_both → unicode normalization) e queria ver se isso ajuda

Resultados

Modo replace:

Modelo Python TypeScript Rust
gemini-3-flash 95% 80% 95%
qwen3.5-397b 90% 85% 85%
gpt-4.1-mini 65% 75% 45%

Modo hashline (de execuções anteriores):

Modelo Python TypeScript Rust
gemini-3-flash 70% 85% 90%
qwen3.5-397b 85% 85% 90%
gpt-4.1-mini 50% 70% 55%

O hashline piora os resultados em Python de forma perceptível e parece ter um efeito aproximadamente neutro em TypeScript e Rust. A dependência da linguagem é interessante — o papel sintático dos espaços em branco em Python pode tornar as edições ancoradas em linhas mais propensas a erros.

A correspondência aproximada ajuda?

Aparentemente, não.

Adicionei a coleta de rastros de execução para ver se o trim em cascata do tau chega a ser acionado nas execuções em modo replace. Ao longo de 114 edições bem-sucedidas e 20 edições malsucedidas (3 modelos × 3 linguagens), a correspondência aproximada foi acionada zero vezes.

Das 20 edições malsucedidas:

  • 1 tinha espaços em branco ao final (teoricamente corrigível)
  • ~8 incluíam números de linha em old_string (erro do modelo)
  • ~11 tinham conteúdo completamente alucinado

Quando os modelos acertam old_string, também acertam os espaços em branco. Quando erram, erram feio — o trim em cascata não ajuda.

(Detalhes da análise dos rastros de execução)

Conclusões

  1. Não há um vencedor claro entre hashline e replace. O efeito depende da linguagem e do modelo. Python penaliza o hashline; TypeScript é neutro; em Rust, qualquer um dos dois pode ganhar.

  2. É difícil generalizar os resultados de Can. O react-edit-benchmark usa apenas JavaScript e um LSP para fornecer feedback de validação. Nossa configuração (sem LSP, com várias linguagens) mostra um cenário diferente. O ciclo de feedback do LSP, em particular, provavelmente atua como fator de confusão. Fornecer ao modelo erros de tipo para orientar novas tentativas traz um ganho significativo que interage com o formato de edição.

  3. A correspondência aproximada não é um problema para os modelos atuais. Os LLMs ou reproduzem o texto-fonte com exatidão ou alucinam algo completamente diferente. O caso de uma divergência mínima nos espaços em branco, que a correspondência aproximada busca resolver, basicamente não ocorre na prática.

  4. Para os modelos da geração atual em harnesses contemporâneos, o formato de edição não é o gargalo. A diferença entre os modelos (gemini-3-flash com 90%+ vs gpt-4.1-mini com 55-65%) é muito maior que a diferença entre os formatos de edição. Invista na seleção do modelo e na engenharia de prompts antes de se preocupar com o formato de edição.

Ressalva obrigatória: n pequeno, sem rigor estatístico, considere isso ao interpretar os resultados.

Todos os dados: nwyin/edit-bench, issues #13 e #14.