← voltar

📊 Benchmark honesto

🇬🇧 Read in English

Comparação ferramenta contra ferramenta — Polypus, OpenCode e Aider — rodando o mesmo modelo (deepseek-v4-flash), nas mesmas tarefas, na mesma máquina. O veredito é objetivo (testes unitários reais), e o custo é medido por fonte neutra (a API da OpenRouter, uma chave dedicada por ferramenta) — nunca pelo que cada ferramenta se auto-reporta. Filosofia: diagnóstico primeiro, marketing depois. O objetivo original era achar onde o Polypus quebra — e ele achou (veja os bugs corrigidos abaixo).

🇬🇧 In short: a tool-vs-tool benchmark (Polypus, OpenCode, Aider) on the same model, same tasks, same machine. Verdict is real unit tests; cost is measured from a neutral source (OpenRouter API, one dedicated key per tool), never self-reported. Diagnostic-first: the point was to find where Polypus breaks — and it did.

18/18
sessões passaram (3 ferramentas × 6 tarefas), 100% dos subtests
6
tarefas: algoritmos, edge cases, debugging e multi-arquivo
6
bugs/gaps achados pelo benchmark — todos endereçados (5 corrigidos + 1 virou feature nova)
~$0,04
custo total da rodada inteira (as 3 ferramentas)

Metodologia

Modelodeepseek/deepseek-v4-flash (via OpenRouter) — o mesmo para as três, provedor único (sem variância de roteamento).
Vereditonode --test — testes unitários reais. Score parcial X/N (quantos subtests passaram), não só passa/falha.
CustoDelta de gasto na API da OpenRouter, uma chave dedicada por ferramenta. Fonte neutra, imune ao auto-reporte.
IsolamentoCada tarefa roda num workspace git descartável. Prompt idêntico para as três.
Anti-trapaçaHash dos arquivos de teste antes/depois: se a ferramenta editar o teste para "passar", vira desclassificado.
ReprodutívelScripts abertos em bench/demo/ no repositório. Rode ./run-all.ps1.

Uma tarefa é uma pasta com PROMPT.md (instrução idêntica), a(s) fonte(s) e *.test.mjs. As ferramentas recebem só o prompt e o workspace — descobrem sozinhas o que fazer. As tarefas vão de algoritmos simples (ano bissexto) a debugging (código já vem quebrado) e multi-arquivo (o bug está num de dois arquivos e a ferramenta precisa achar qual).

Resultados por tarefa

TarefaTipo Polypus OpenCode Aider
leapbissexto7/77/77/7
rleencode/decode12/1212/1212/12
romanedge cases14/1414/1414/14
anagramcase + traps8/88/88/8
fix-flattendebugging8/88/88/8
stats-bugmulti-arquivo7/77/77/7

Correção: empate perfeito. Nessa dificuldade, com um modelo forte, as três ferramentas resolvem tudo. Na tarefa multi-arquivo, as três acharam o arquivo certo e deixaram o outro (o "chamariz") intacto. Onde elas se separam é em eficiência.

O que é cada tarefa
  • leap — "é ano bissexto?", pelas regras do calendário gregoriano (÷4, exceto ÷100, exceto ÷400). Algoritmo curto.
  • rlerun-length encoding: comprimir "AAAB""3A1B" e descomprimir de volta.
  • roman — inteiro → algarismo romano (1–3999) com notação subtrativa (4=IV, 9=IX). Cheio de casos de borda.
  • anagram — dada uma palavra e candidatas, achar os anagramas (ignorando maiúsculas, excluindo a própria palavra).
  • fix-flattendebugging: o código de achatar array aninhado já vem QUEBRADO; a ferramenta tem que achar e corrigir o bug.
  • stats-bugmulti-arquivo: o bug está numa função que importa de outro arquivo; a ferramenta precisa descobrir em qual dos dois está.
Como ler os números
  • 7/7 — subtests que passaram / total (score parcial, não só passou/falhou).
  • Na tabela de tokens: total de tokens processados na tarefa (menos = mais eficiente).

Custo da rodada (6 tarefas)

Aider
$0,0008
Polypus
$0,0204
OpenCode
$0,0204

Tokens processados por tarefa

TarefaPolypusOpenCodeAider
leap18.37827.0951.067
rle26.90219.6622.400
roman18.82021.0581.474
anagram25.03528.1521.622
fix-flatten26.95836.0632.500
stats-bug (multi)63.49645.1181.827

A nuance honesta por trás dos números. O Aider é ~25× mais barato — mas parte disso é porque ele exige que você diga quais arquivos editar; ele não navega, recebe tudo mastigado e resolve em um tiro. Polypus e OpenCode são agentes de verdade: leem o repositório, rodam os testes e iteram sozinhos — e pagam por isso em tokens. Isso fica gritante na tarefa multi-arquivo (stats-bug): o Polypus gastou 63k tokens descobrindo qual arquivo tinha o bug; o Aider gastou 1,8k porque recebeu os dois arquivos de bandeja. São categorias diferentes de ferramenta — a comparação de custo tem que levar isso em conta.

O que os dados dizem

✅ Correção equivalente

Polypus entrega a mesma taxa de acerto que ferramentas consagradas, no mesmo modelo. A tese "qualidade equivalente" se sustenta nos dados — não é opinião.

💸 Mais barato que o agente concorrente

Contra o OpenCode (o concorrente agêntico direto), o Polypus custa o mesmo ou menos — a vantagem do prompt caching aparece quando a medição é honesta.

🧭 Navegação multi-arquivo correta

Na tarefa com bug espalhado, o Polypus achou o arquivo certo e não tocou no chamariz — navegação autônoma que o one-shot não faz sem ajuda humana.

🎯 Alvo claro de melhoria

O flanco do Polypus é eficiência de tokens, sobretudo em multi-arquivo. É um gap concreto e mensurável — virou item de roadmap, não desculpa.

O benchmark achou 4 bugs reais — e a gente corrigiu

O valor de um benchmark honesto não é o gráfico bonito — é o que ele quebra. Nas primeiras rodadas o Polypus falhou, e cada falha virou uma correção:

Stress test das features (hooks + swarm)

Segunda trilha, focada nas features próprias do Polypus — não é comparação, é diagnóstico interno. Cada cenário roda num workspace descartável com timeout rígido (pega loop infinito) e verifica se a feature se comportou como especificado. Achou 2 gaps reais, ambos viraram issue.

As features testadas
  • hooks — scripts que o Polypus roda em pontos do ciclo do agente:
  • PostToolUse — roda depois de uma tool (ex.: rodar teste/lint); a saída volta pro modelo, que pode se corrigir sozinho.
  • PreToolUse — roda antes de uma tool; se o script falhar, a tool é bloqueada.
  • Stop — roda quando o agente termina (no finish).
  • swarm — quebra a tarefa em subtarefas e roda vários "workers" em paralelo, cada um numa cópia git isolada, mesclando os resultados no fim.
Os cenários
  • hook-selfcorrect — um PostToolUse exige uma correção; testa se o modelo obedece à saída injetada.
  • hook-stop — testa se o Stop realmente roda no fim.
  • hook-block — um PreToolUse tenta impedir a edição de um arquivo protegido.
  • swarm-fanout — workers criando arquivos independentes (o caso feliz do merge).
  • swarm-conflict — workers editando o MESMO arquivo (força conflito de merge).
CenárioFeatureResultadoTempoTokensO que revelou
hook-selfcorrectPostToolUseOK20,7s27,7ka saída do hook injetada dirige a auto-correção do modelo
hook-stopStopOK14,8s17kStop roda no finish (marcador criado)
swarm-fanoutswarmOK41,5s77k3 arquivos independentes, workers paralelos, merge limpo no Windows
hook-blockPreToolUseGAP42,4s66kbloqueio de arquivo contornado via run_command (#213)
swarm-conflictswarmGAP33,3s100k1 de 3 contribuições sobrevive, mas reporta "sem conflito" (#212)

Gap 2 — swarm perdia trabalho silenciosamente (#212) — CORRIGIDO ✅. Com 3 workers editando o mesmo arquivo, o swarm reportava "mesclado sem conflito" — mas só 1 das 3 contribuições sobrevivia. Causa: um git checkout -f HEAD (workaround de Windows) que descartava o merge conflitado sem deixar marcador. Corrigido em worktree.ts: o resultado passa a ser decidido inspecionando o status do git, e o conflito é reportado honestamente (branch mantido, recuperável) em vez de sumir. Retestado. Para arquivos independentes o merge sempre funcionou.

Gap 1 — hook não protege arquivo de verdade (#213) — vira feature nova (#214). Um hook PreToolUse que bloqueia edições funciona para as tools de escrita, mas o agente rota em volta via shell: mesmo bloqueado 19×, alterou o arquivo com glob + variável (sed -i $f) sem citar o nome. Lição: hook é observação/advisory, não fronteira de segurança.

A correção: proteção real de caminho (#214) — IMPLEMENTADA ✅. Nova flag --protect <globs> (e permissions.protect) que torna os arquivos read-only no nível do SO durante o run — o filesystem recusa a escrita de qualquer tool (write_file, sed, echo >, python), não só das tools diretas. No retest da mesma task que furou o hook: edit_file negado com mensagem clara e o arquivo sobreviveu intacto. Comandos que removem a proteção (attrib -r, chmod +w) agora são bloqueados como destrutivos. É assim que se protege um arquivo de verdade — enforcement no SO, não pattern-matching.

Honestidade metodológica

Este é um benchmark pequeno e transparente, não um leaderboard definitivo. Limites que assumimos de propósito: (1) um modelo só nesta rodada; (2) 6 tarefas auto-contidas — o suficiente para diagnóstico, não para ranking universal; (3) o Aider recebe os arquivos explicitamente, o que abarata o custo dele em troca de exigir um humano no loop; (4) tarefas nessa dificuldade não separam as ferramentas por correção — para isso, o próximo passo é modelo mais fraco ou tarefas maiores. Tudo é reprodutível: os scripts, as tarefas e o critério estão no repositório.

Quer reproduzir? cd bench/demo e ./run-all.ps1. Cada ferramenta usa a própria chave OpenRouter; o placar sai em runs/results.csv e o custo neutro em ./show-costs.ps1. Código aberto: github.com/GaberRB/polypus.