<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
  <title>Paweł Dubiel Tech Blog</title>
  <link>https://paweldubiel.com/pt</link>
  <atom:link href="https://paweldubiel.com/pt/rss.xml" rel="self" type="application/rss+xml" />
  <description>Notas sobre IA, modelos de linguagem e engenharia de software.</description>
  <language>pt</language>
  <lastBuildDate>Mon, 12 Oct 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Dei disquetes de Amiga a um agente de IA. Depois de uma noite, Pirates! rodava no Unity</title>
  <link>https://paweldubiel.com/pt/articles/port-pirates-amiga-unity</link>
  <guid isPermaLink="true">https://paweldubiel.com/pt/articles/port-pirates-amiga-unity</guid>
  <pubDate>Sun, 11 Oct 2026 22:37:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>agents</category>
  <category>coding</category>
  <category>llm</category>
  <description>Dei a um agente de programação quatro imagens de disquete com a versão para Amiga de Sid Meier&apos;s Pirates!, de 1990, e pedi que ele levasse o jogo para o Unity.</description>
  <content:encoded><![CDATA[<p>Dei a um agente de programação quatro imagens de disquete com a versão para Amiga de Sid Meier's Pirates!, de 1990, e pedi que ele levasse o jogo para o Unity. Quem trabalhou foi o Claude Opus 5.5 no Claude Code. Depois de uma noite, dava para jogar da tela de título, passando por um duelo, uma cidade e a navegação pelo mapa, até uma batalha naval, com os gráficos e o som originais. Mais importante do que o ritmo é a forma como o resultado foi verificado: o mesmo roteiro de decisões foi executado no port em C# e no código de máquina original rodando em um emulador de processador. Em 802 execuções, cerca de 6 milhões de linhas comparadas, as duas versões mostraram ao jogador a mesma coisa.</p>
<p>Descrevo aqui as etapas desse trabalho porque, juntas, elas formam um método que pode ser repetido com outro jogo e outro modelo. No fim, mostro um segundo projeto feito com o mesmo esquema, um port de Centurion: Defender of Rome do DOS para JavaScript. Os dois são projetos particulares, feitos para aprender: os jogos originais, seus gráficos e seu som continuam protegidos por direitos autorais, e eu não os distribuo.</p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-title-screen.webp" alt="Tela de título de Pirates! no port para Unity: um galeão com bandeira pirata ao pôr do sol, desenhado com os gráficos originais de 1990." loading="eager" decoding="async" width="1600" height="900"></p>
<p><em>A tela de título no Unity. A imagem é decodificada em tempo de execução a partir dos arquivos originais do jogo.</em></p>
<h2 id="da-imagem-de-disquete-ao-código-descompilado">Da imagem de disquete ao código descompilado</h2>
<p>O agente começou identificando os arquivos. Uma imagem de disquete do Amiga (ADF) é uma cópia bruta dos setores, então algumas dezenas de linhas de Python bastaram para extrair o conteúdo. O programa do jogo revelou-se um executável com overlays: um núcleo fica o tempo todo na memória, e outros três segmentos de código são lidos do disco conforme a necessidade. O Ghidra, um descompilador gratuito, não tem suporte nativo a esse formato. O agente escreveu um script que posiciona todos os segmentos em endereços fixos dentro de uma única imagem e transforma 45 saltos indiretos para os overlays em chamadas comuns. Com isso, o descompilador passou a enxergar cerca de 630 funções como um só programa.</p>
<p>Os dados do jogo trouxeram uma surpresa. Os arquivos com a extensão <code>.rez</code> têm a estrutura dos recursos dos computadores Macintosh, porque a versão para Amiga era um port da versão para Mac. Reconhecido o formato, o agente extraiu 210 textos, 82 listas de strings, os dados das cidades para seis épocas, imagens, animações, sprites e sons. Os textos se mostraram o melhor mapa do código: o número da string passada à rotina "mostrar texto" indica qual tela do jogo uma determinada função trata.</p>
<h2 id="treze-agentes-leem-o-código-nove-o-reescrevem">Treze agentes leem o código, nove o reescrevem</h2>
<p>O código descompilado tinha quase 29 mil linhas, sem nomes de funções nem de variáveis. O agente principal o cortou em pedaços de cerca de 2 mil linhas e entregou cada um a um agente separado, com o mesmo briefing por escrito. Cada um devia gravar em um arquivo a descrição de todas as funções do seu trecho: fórmulas exatas, constantes, intervalos de sorteio, os números dos textos exibidos e as variáveis globais lidas e gravadas. O briefing continha uma frase que acabou sendo decisiva: uma fórmula errada é pior do que uma lacuna sinalizada. Assim, os agentes tinham de marcar o que não conseguiram determinar e conferir os pontos obscuros no assembly. O descompilador perdia aqui muitos argumentos de função, porque o compilador de 35 anos atrás usava um tipo <code>int</code> de 16 bits.</p>
<p>A segunda etapa teve a mesma divisão. Nove agentes reescreveram as regras do jogo em C#, cada um na sua faixa de endereços. Saíram daí cerca de 16 mil linhas de código, e o estado do jogo foi parar em um array de bytes endereçado exatamente como a memória do original. Não é elegante, mas elimina toda uma classe de erros. O código antigo sobrepõe estruturas umas às outras sem cerimônia e lê tabelas a partir do byte anterior ao seu início. Um port construído sobre a imagem da memória pode ser traduzido linha por linha e comparado com o assembly, e as tabelas de constantes ficam onde o código as procura. O desenho, o som e os controles foram substituídos pelos agentes por chamadas a uma interface que o motor implementa separadamente.</p>
<h2 id="o-oráculo-o-código-original-em-um-emulador-de-processador">O oráculo: o código original em um emulador de processador</h2>
<p>Ler código descompilado não prova que o port se comporta como o original. Por isso o agente construiu uma ferramenta de comparação. O código de máquina original do processador Motorola 68000 roda no emulador Unicorn. As rotinas de sistema, isto é, menus, caixas de texto, leitura dos controles e desenho, foram trocadas por funções em Python. Essas funções respondem a cada pergunta do jogo segundo um gerador de decisões simples e registram tudo o que o jogo mostrou. O port em C# recebe a mesma sequência de decisões por meio de um "jogador roteirizado", que roda fora do Unity. No fim, os dois registros são comparados linha por linha. Os textos contêm ouro, tamanho da tripulação, datas e nomes de cidades, de modo que a coincidência dos registros é um teste forte das regras.</p>
<p>A primeira medição completa deu 800 execuções coincidentes em 802. As duas divergências tinham uma única causa: a aritmética de ponto flutuante. O jogo usa uma biblioteca em software que não arredonda como os processadores de hoje. A raiz quadrada de 81, nela, é 8,999999999999998, e o jogo trunca os resultados para inteiros, de modo que o moral da tripulação saía um ponto alto demais no port em certas proporções entre ouro e tripulação. A correção consistiu em reescrever as rotinas da biblioteca instrução por instrução: 1.572 instruções, 43 rotinas e 21.701 vetores de teste calculados pelo código original, sem nenhuma diferença. Depois dessa mudança, todas as 802 execuções coincidem, e em outras 120 o estado do jogo foi comparado quadro a quadro no duelo, na navegação e nas batalhas naval e terrestre.</p>
<p>A comparação também revelou dois bugs do próprio jogo de 1990: uma leitura do mapa por um ponteiro nulo ao atacar uma cidade na diagonal e uma divisão por zero quando a tripulação cai a zero. Nesses pontos o port precisa escolher um comportamento, e a ferramenta de comparação tem uma chave que obriga o original a seguir o mesmo caminho. O resultado também tem limites. A ferramenta não compara desenho nem som, e caminhos raros, como o casamento, o mapa do tesouro completo ou os postos mais altos, foram pouco exercitados.</p>
<h2 id="a-apresentação-e-os-acréscimos-que-não-existiam-em-1990">A apresentação e os acréscimos que não existiam em 1990</h2>
<p>A camada que o jogador vê foi construída pelos agentes no Unity a partir de código, sem cenas prontas. Imagens e animações são decodificadas dos recursos originais, os sprites recebem as cores da paleta da tela atual, e a música foi renderizada em arquivos de áudio por meio da emulação do sequenciador de quatro canais do jogo. O agente controlava o jogo em execução pela linha de comando, tirava capturas de tela e as examinava. Foi assim que apareceram alguns defeitos que nenhum teste de regras pega, como a falta de som na versão para navegador, porque a conversão de áudio exigia o programa ffmpeg, que não estava instalado no sistema.</p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-world-map.webp" alt="O mapa do Caribe no port para Unity: ilhas com cidades, o navio do jogador com o indicador de rumo e nuvens de tempestade." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>Navegação pelo mapa. O fundo é montado a partir de uma grade de terreno de 160 por 200 células e dos tiles originais.</em></p>
<p>Depois das primeiras partidas, pedi três mudanças. A pergunta sobre a data de chegada da frota do tesouro era, no original, a proteção contra cópia e exigia o manual impresso; agora o quiz continua, mas a resposta certa aparece nas "anotações do capitão". A lista de cidades mostrava apenas os dados da cidade, porque o jogo pressupunha que o jogador tinha um mapa impresso; agora a cidade escolhida é marcada em um mapa do Caribe. A tela de duelo ganhou uma tabela com a força, o moral e a arma dos dois lados, disposta como no original. Os acréscimos podem ser desligados, e os testes de comparação rodam sem eles, para que os registros continuem batendo com o código de 1990.</p>
<p><img src="https://paweldubiel.com/assets/pirates-amiga-original-duel-openretro.webp" alt="Captura de tela do jogo original no Amiga: dois esgrimistas diante de um muro e, embaixo, o título do duelo e uma tabela com Force, Morale e Weapon." loading="lazy" decoding="async" width="640" height="400"></p>
<p><em>O duelo no original. Fonte da captura de tela: OpenRetro Game Database.</em></p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-duel-panel.webp" alt="O duelo no port para Unity: esgrimistas no convés de um navio e, embaixo, o título e uma tabela com a força, o moral e a arma dos dois lados." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>A mesma tela no port. Os números da tabela são lidos em tempo real do estado do duelo.</em></p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-city-chart.webp" alt="Um mapa do Caribe com a cidade de Port-de-Paix marcada, a posição do jogador e um quadro com os dados da cidade e a bandeira francesa." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>Um acréscimo em relação ao original: a cidade escolhida em um mapa do Caribe.</em></p>
<h2 id="centurion-o-mesmo-esquema-em-javascript-com-jogabilidade-ampliada">Centurion: o mesmo esquema em JavaScript, com jogabilidade ampliada</h2>
<p>O segundo projeto é Centurion: Defender of Rome, um jogo para DOS de 1990, levado para JavaScript e para o elemento Canvas, sem emulador. Os passos foram os mesmos, com outros nomes. Primeiro foi preciso descompactar o executável, porque ele estava comprimido com a ferramenta EXEPACK. Cinco módulos do jogo (batalha terrestre, arena de gladiadores, corrida de quadrigas, batalha naval e a introdução) ficavam em um arquivo de overlays e compartilhavam um único segmento de dados. O estado da campanha roda sobre uma cópia viva dos 64 quilobytes desse segmento, porque o motor do jogo depende de estouro de 16 bits, divisão inteira e bytes com sinal, que os números de ponto flutuante do JavaScript não reproduzem sozinhos. O jogo salvo coincide byte a byte com o formato original, o que os testes verificam.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-title-screen.webp" alt="Tela de título de Centurion no port para navegador: a palavra CENTURION sobre um mapa do Mediterrâneo, um painel de créditos e os botões Start Game, Difficulty e Game Options." loading="lazy" decoding="async" width="1070" height="800"></p>
<p><em>A tela de título de Centurion no navegador, com os gráficos originais.</em></p>
<p>Aqui fui além de um port fiel. Acrescentei uma chave para regras ampliadas, desligada por padrão: fusão de legiões e várias legiões em uma mesma província, vélites de armamento leve, elefantes de guerra e desembarques pelo mar. O código desse port foi escrito por modelos diferentes dos de Pirates: principalmente o Gemini 3.8 Flash e, em parte, o <code>gpt-6.1-sol</code> da OpenAI, executado pelo Codex. A escolha veio das ferramentas que eu tinha à mão, e não de uma comparação entre modelos.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-game-options.webp" alt="O menu de opções do jogo no port de Centurion: o item Extra Features: OFF, o nível de dificuldade, salvar e carregar e, ao lado, o mandato do Senado com o posto e o saldo do tesouro." loading="lazy" decoding="async" width="1070" height="800"></p>
<p><em>O menu de opções. O primeiro item ativa as regras ampliadas, que não existiam no original.</em></p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-province-screen.webp" alt="A tela da província Italia no port de Centurion: uma vista da cidade, o menu de jogos com a construção do anfiteatro e a situação da província: ânimo, tributo, tropas." loading="lazy" decoding="async" width="1086" height="818"></p>
<p><em>A tela da província com o menu de jogos.</em></p>
<h2 id="os-problemas-que-o-gemini-encontrou-em-centurion">Os problemas que o Gemini encontrou em Centurion</h2>
<p>A maior parte do tempo foi gasta em pontos nos quais o código descompilado ou os nomes dos arquivos sugeriam algo diferente do que o jogo realmente faz. Cinco exemplos tirados das anotações do projeto:</p>
<ul>
<li><strong>Overlays sem dados.</strong> Os cinco módulos do jogo ficam em um único arquivo, <code>OVL0.OVL</code>, e são carregados no mesmo endereço, mas todos usam um segmento de dados compartilhado. Por isso, o código de um overlay aberto sozinho no Ghidra não mostrava nenhuma string nem tabela. Um script juntou cada overlay ao segmento de dados em cinco executáveis sintéticos, e só então o descompilador ligou o código dos minijogos às estruturas da campanha.</li>
<li><strong>Fronteiras das províncias conquistadas.</strong> Contornar uma província a partir do mapa das regiões clicáveis com o mouse dava linhas serrilhadas, que não combinavam com o mapa desenhado à mão. O código mostrou outro mecanismo: na imagem do mapa, cada província tem um caminho oculto, com um pixel de largura e de cor escura, e uma tabela nos dados fornece um ponto de partida para cada uma das 27 províncias. O jogo repinta esse caminho com a cor do império, começando pelo ponto de partida, e o port faz o mesmo.</li>
<li><strong>Quadros que voltam atrás.</strong> O loop original do jogo rodava a 9–12 Hz, e um navegador desenha 60 vezes por segundo. Em três pontos, um sprite recuava um quadro por um instante. O globo da introdução gira pelo deslocamento de 14 cores da paleta em 10 passos, mas o primeiro passo da tabela tem valor zero; deslocar a paleta em todos os passos fazia os continentes darem um tranco a cada volta. Nas coortes em marcha e nas investidas dos gladiadores foi preciso reproduzir a ordem com exatidão: primeiro o quadro intermediário, depois a mudança de posição.</li>
<li><strong>Nomes de arquivo enganosos.</strong> Os bitmaps <code>BB1.CBM</code> e <code>BB2.CBM</code> pareciam faixas de batalha e, desenhados no alto da tela, cobriam o campo de batalha inteiro. O código só os carrega quando o computador não tem placa VGA: são fundos de tela cheia para as placas EGA e CGA, mais antigas. A mesma rotina revelou que o posicionamento antes da batalha tem duas etapas. A escolha da formação substitui a lista de táticas disponíveis, e a manobra de Canas só aparece depois que a cunha é escolhida.</li>
<li><strong>Música quase inaudível.</strong> Depois de decodificadas as 17 faixas e os 24 instrumentos do driver da placa de som AdLib, as melodias estavam certas, mas tocavam a cerca de −55 dB. A desmontagem do driver mostrou que, a cada nota, ele subtrai um quarto do volume da nota da atenuação gravada no instrumento. Uma linha de código devolveu cerca de 32 dB. Um segundo defeito estava do lado do navegador: em notas muito curtas, o cancelamento das mudanças de volume agendadas na Web Audio API apagava o ataque do som, que ainda estava em andamento, e silenciava a nota.</li>
</ul>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-battle-tactics.webp" alt="Uma batalha terrestre no port de Centurion: uma lista de cinco táticas para a formação em cunha, entre elas a Cannae Tactic, e as unidades posicionadas no campo de batalha." loading="lazy" decoding="async" width="1086" height="818"></p>
<p><em>A segunda etapa do posicionamento antes da batalha: as táticas disponíveis para a formação em cunha.</em></p>
<p>As corridas de quadrigas no Circus Maximus foram um trabalho à parte. Ali, a quadriga não é uma imagem única. Bitmaps separados para cada combinação de três classes de quadriga, quatro cores de condutor, quatro ações, dezesseis inclinações na curva e três quadros de galope dariam mais de 2.300 quadros, então os autores do jogo montaram na memória uma árvore de nós de 16 bytes. Cada nó aponta para o próximo elemento do mesmo nível e para o seu primeiro filho, e guarda um índice de quadro, uma tabela de deslocamentos para os sucessivos quadros da animação e uma flag de visibilidade. A raiz são os quatro cavalos. A caixa do carro tem um deslocamento horizontal adicional, no qual a física da curva grava uma inclinação de 0 a 15 pixels, e o condutor é seu filho e herda essa posição. É por isso que, na curva, o condutor se inclina junto com a caixa, enquanto os cavalos continuam correndo no eixo da pista. Os ramos com o eixo que se parte e com os destroços capotando existem o tempo todo; apenas estão com a flag de visibilidade desligada.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-chariot-sprite-tree.webp" alt="Diagrama da árvore de sprites da quadriga em Centurion: o nó com os quatro cavalos, o nó da caixa em três classes, os nós dos estados de acidente, quatro animações do condutor e a quadriga montada sem inclinação e com inclinação de 12 pixels." loading="lazy" decoding="async" width="920" height="540"></p>
<p><em>A árvore de sprites da quadriga reconstruída a partir dos dados do jogo. O diagrama foi feito no projeto com os recursos originais decodificados.</em></p>
<p>A pista também não é montada com tiles. O jogo expande 72 pares de coordenadas gravados em 368 pontos de controle e divide a posição transversal na pista em 16 faixas. Da faixa depende a velocidade segura na curva, calculada como (número da faixa + 15) × 4: junto à parede interna ela é 60, junto à barreira externa, 116–120. A faixa interna é o caminho mais curto, mas entrar no grampo acima desse limite inclina a caixa, empurra a quadriga para fora e dispara um sorteio de acidente, tanto mais provável quanto maior o excesso. O marcador vermelho na barra de velocidade mostra esse limite ao jogador.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-circus-track-physics.webp" alt="A geometria da pista do Circus Maximus: retas, zonas de frenagem e grampos marcados em cores sobre a imagem do estádio e um gráfico da velocidade segura subindo de 60 na faixa interna a 120 na externa." loading="lazy" decoding="async" width="880" height="500"></p>
<p><em>Os 368 pontos da pista e a velocidade segura na curva conforme a faixa.</em></p>
<h2 id="o-que-fica-desse-trabalho-além-dos-jogos">O que fica desse trabalho além dos jogos</h2>
<p>Registrei o método como uma skill, isto é, um conjunto de instruções que o agente carrega quando recebe uma tarefa parecida. Ela contém três princípios tirados dos dois projetos. As regras do jogo são portadas com fidelidade, e a apresentação é substituída por uma interface. O port mantém o layout de memória do original. Não se confia no resultado enquanto ele não passar por uma comparação com o código original. A skill inclui ainda os briefings para os agentes de análise e de portabilidade e os scripts do projeto Pirates.</p>
<p>A conclusão mais interessante diz respeito aos fãs, não aos agentes. Quem tem um jogo de que gosta e sente falta de alguma coisa nele há anos pode hoje refazê-lo do seu jeito, de forma rápida e barata, sem o código-fonte. Em Pirates, o quiz que exigia o manual impresso agora dá a resposta, e apareceu um mapa que o jogo nunca teve. Em Centurion, acrescentei regras que o original não tinha: fusão de legiões, elefantes de guerra e desembarques pelo mar. Depois que as regras do jogo viram código comum em C# ou JavaScript, a próxima mudança é uma alteração de código comum, e não um patch no binário. Do mesmo modo dá para levar um jogo para um motor mais rápido ou para outra plataforma: Centurion roda no navegador, e Pirates é compilado para Linux e para o navegador. O método também não está preso a jogos antigos. Um descompilador, um emulador de processador e a comparação dos registros funcionam do mesmo jeito para um programa mais recente; mais código significa mais trabalho, não outra abordagem.</p>
<h2 id="fontes">Fontes</h2>
<ul>
<li>Materiais próprios dos dois projetos: anotações da análise do código, briefings para os agentes, o relatório da ferramenta de comparação (802 execuções, a lista das diferenças encontradas) e a descrição do port de Centurion com suas especificações. Não estão publicados.</li>
<li>National Security Agency, <a href="https://github.com/NationalSecurityAgency/ghidra" rel="noopener noreferrer">Ghidra</a>, o pacote de engenharia reversa usado para descompilar os dois jogos.</li>
<li><a href="https://www.unicorn-engine.org/" rel="noopener noreferrer">Unicorn Engine</a>, o emulador de processadores usado para executar o código 68000 original.</li>
<li>OpenRetro Game Database, <a href="https://openretro.org/amiga/pirates" rel="noopener noreferrer">a página de Pirates! para Amiga</a>, fonte da captura de tela do jogo original.</li>
</ul>]]></content:encoded>
</item>
<item>
  <title>Um horizonte METR mais longo não significa tarefas proporcionalmente mais difíceis</title>
  <link>https://paweldubiel.com/pt/articles/um-horizonte-metr-mais-longo-nao-significa-tarefas-proporcionalmente-mais</link>
  <guid isPermaLink="true">https://paweldubiel.com/pt/articles/um-horizonte-metr-mais-longo-nao-significa-tarefas-proporcionalmente-mais</guid>
  <pubDate>Sun, 11 Oct 2026 15:03:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>agents</category>
  <category>benchmarks</category>
  <description>Uma equipe quer saber se pode confiar tarefas de programação mais longas à próxima versão de um agente.</description>
  <content:encoded><![CDATA[<p>Uma equipe quer saber se pode confiar tarefas de programação mais longas à próxima versão de um agente. Por isso compara resultados de benchmark expressos pelo tempo de que uma pessoa precisou para fazer o trabalho. É fácil tomar um resultado assim como indicação de quanto trabalho já se pode entregar ao agente.</p>
<p>Essa interpretação exige, porém, verificar se um trabalho humano mais longo significa de fato uma tarefa proporcionalmente mais difícil para a IA. Se, em certa faixa, as tarefas têm dificuldade parecida para o agente, uma pequena melhora na taxa de sucesso pode deslocar o resultado por uma grande faixa de minutos.</p>
<p>Na escolha de um agente, precisamos então de uma informação adicional: como mudou a chance de concluir as mesmas tarefas. O multiplicador de tempo, sozinho, pode superestimar a diferença entre versões, se estivermos comparando justamente um trecho do benchmark em que o tempo distingue mal a dificuldade.</p>
<p><a href="https://metr.org/time-horizons/" rel="noopener noreferrer">A METR chama essa medida</a> de <a href="https://paweldubiel.com/pt/glossary/time-horizon">time horizon</a>. Na variante com limiar de 50%, é o tempo de trabalho humano no qual a curva ajustada prevê que metade das tentativas do agente dá certo. É uma média para as tarefas com aquele tempo, não uma garantia para cada uma delas. Não medimos aqui o tempo de funcionamento da própria IA.</p>
<p>No preprint <a href="https://arxiv.org/abs/2610.12466" rel="noopener noreferrer"><em>On the estimation and validity of AI time horizons—a statistical look at the METR plot</em></a>, Drew T. Nguyen e William Fithian analisam justamente a conversão do tempo em dificuldade. O trabalho, da área de avaliação de IA e estatística, publicado pela primeira vez em 8 de outubro de 2026, aponta nos dados da METR um trecho quase plano entre 2 e 30 minutos de trabalho humano. As tarefas dessa faixa tinham, em média, dificuldade parecida para os agentes estudados.</p>
<h2 id="uma-pequena-mudança-nas-chances-pode-deslocar-muito-o-limiar">Uma pequena mudança nas chances pode deslocar muito o limiar</h2>
<p>O exemplo a seguir é uma simplificação didática própria, não o resultado de um estudo. Temos três tarefas, A, B e C, que tomam de uma pessoa 3, 10 e 30 minutos, respectivamente. Cada um de dois agentes executa cada tarefa 100 vezes no mesmo ambiente. Registramos sucesso ou fracasso.</p>





























<table><thead><tr><th>Tarefa</th><th>Tempo humano</th><th>Sucessos do agente mais antigo</th><th>Sucessos do agente mais novo</th></tr></thead><tbody><tr><td>A</td><td>3 minutos</td><td>50 de 100</td><td>52 de 100</td></tr><tr><td>B</td><td>10 minutos</td><td>49 de 100</td><td>51 de 100</td></tr><tr><td>C</td><td>30 minutos</td><td>48 de 100</td><td>50 de 100</td></tr></tbody></table>
<p>Para simplificar, tratemos essas frequências como chances conhecidas com exatidão e liguemos os pontos com curvas decrescentes. O agente mais antigo cruza os 50% aos 3 minutos; o mais novo, aos 30. O horizonte cresce dez vezes, embora em cada tarefa a taxa de sucesso tenha subido apenas 2 pontos percentuais. Em 300 tentativas por agente, o número de sucessos passou de 147 para 153.</p>
<p>As três tarefas e todos os fracassos continuam na medição. Escolhemos apenas o ponto em que a curva cruza o limiar; não filtramos nem premiamos nada. O custo desse teste hipotético são 600 tentativas completas de agente. Em um experimento real, amostras desse tamanho não permitem tratar uma diferença de 2 pontos percentuais como certa. É preciso ajustar uma curva e estimar a incerteza.</p>
<p>O exemplo mostra a operação de ler o horizonte em uma curva quase plana. Em um estudo, a forma dela ainda precisa ser estabelecida a partir de muitas tarefas e sistemas. Se, em outra faixa, a curva cai muito mais depressa, o mesmo multiplicador de horizonte exige um aumento maior das chances de sucesso. Por isso, as passagens de 3 para 30 minutos e de 30 minutos para 5 horas não são, por definição, porções iguais de progresso.</p>
<h2 id="o-tempo-humano-precisa-ser-ajustado-à-dificuldade-para-a-ia">O tempo humano precisa ser ajustado à dificuldade para a IA</h2>
<p>O ponto de partida é a tabela de resultados: que tarefa cada agente executou, quantas vezes e com que desfecho. Conhecemos também o tempo humano e a família da tarefa. Não conhecemos um número objetivo único que descreva a dificuldade dela para a IA.</p>
<p>O baseline dos autores pressupõe que cada nova duplicação do tempo humano aumenta a dificuldade no mesmo passo. Ele usa uma inclinação comum das curvas para todos os agentes; elas diferem no nível de capacidade. É uma referência mais forte do que a regressão separada para cada sistema, usada originalmente.</p>
<p>A primeira proposta substitui o passo constante por uma curva monotônica aprendida, do tipo spline: trechos ligados suavemente, que podem crescer mais depressa ou mais devagar. Um tempo maior continua sem reduzir a dificuldade prevista, mas o crescimento não precisa ser uniforme.</p>
<p>A segunda proposta, chamada no trabalho de Modelo 2, recorre à <a href="https://paweldubiel.com/pt/glossary/item-response-theory">item response theory, IRT</a>. A partir do padrão de sucessos e fracassos, ela estima em conjunto a capacidade dos agentes e a dificuldade das tarefas. Leva em conta também a semelhança entre tarefas de uma mesma família e uma variação adicional nos resultados das tentativas. Com isso, muitas repetições do mesmo par agente–tarefa não são tratadas como outras tantas informações novas e independentes sobre o benchmark inteiro.</p>
<p>O primeiro passo em que o baseline e os novos métodos diferem é a conversão do tempo humano em dificuldade. Os resultados dos agentes usados como entrada continuam os mesmos. O novo ajuste pode, portanto, mudar o horizonte sem que mude uma única resposta da IA.</p>
<h2 id="os-mesmos-resultados-do-gpt-4o-deram-outro-horizonte">Os mesmos resultados do GPT-4o deram outro horizonte</h2>
<p>Os autores reanalisam os resultados registrados do METR Time Horizon 1.1: 228 tarefas e 26 sistemas de IA. Na figura 1, o horizonte do GPT-4o é de 7,2 minutos segundo o baseline com inclinação comum e de 4,4 minutos segundo o Modelo 2. São duas estimativas feitas com as mesmas tentativas, não uma piora no funcionamento do GPT-4o nem uma comparação do custo da sua inferência.</p>
<p>Uma curva mais flexível poderia simplesmente se ajustar melhor ao ruído. Por isso os autores verificam a previsão dos resultados em famílias inteiras de tarefas não utilizadas no ajuste. Em uma validação em cinco partes, dividem as 79 famílias, e não tentativas isoladas de uma mesma tarefa. Os dois novos métodos têm estimativas pontuais melhores em todas as 12 combinações de métrica e forma de ponderação dos resultados. Isso significa um erro menor na previsão do sucesso, não um aumento da taxa de sucesso dos próprios agentes. <a href="https://arxiv.org/html/2610.12466v1#S2.SS5" rel="noopener noreferrer">§2.4–2.5 e figura 2</a></p>
<p>A vantagem não se distribui por igual. O ajuste melhora mais para os sistemas da era do GPT-4, cujos horizontes atravessam a faixa plana apontada. Para os sistemas mais fortes, as curvas comparadas quase coincidem. As estimativas para sistemas individuais também são muito menos conclusivas do que o resultado agregado. <a href="https://arxiv.org/html/2610.12466v1#A1" rel="noopener noreferrer">Apêndice A</a></p>
<details>
<summary>Detalhes do experimento</summary>
<p><strong>Dados e configuração.</strong> Trata-se de uma reanálise dos resultados públicos da METR, não de uma nova série de execuções de agentes. As tarefas envolvem trabalho com software e têm avaliação automática do sucesso. O tempo humano é, em geral, a média geométrica dos tempos das execuções bem-sucedidas; parte dos valores vem de estimativas de especialistas. O tempo de inferência da IA não é uma variável do horizonte medido.</p>
<p><strong>Escolha do modelo e do checkpoint.</strong> Os autores não treinam novos LLMs nem escolhem o melhor checkpoint deles. Usam os resultados registrados de avaliações anteriores da METR. O GPT-4o é um modelo de API com número de parâmetros não divulgado. Esta análise não estabelece o protocolo interno de escolha dos seus pesos. Os ajustes estatísticos usam o método da máxima verossimilhança; o Modelo 2 emprega o algoritmo EM e a aproximação numérica de integrais. Os gráficos da forma das curvas usam os dados completos, e a comparação da qualidade de predição descrita acima usa a divisão por famílias.</p>
<p><strong>Métricas.</strong> O conjunto inclui o marginal log score, isto é, a <a href="https://paweldubiel.com/glossary/cross-entropy" hreflang="pl">cross-entropy [Polski]</a> binária, o Brier score e métricas suavizadas de erro nas proximidades dos limiares de 50% e 80%. A cross-entropy pune com força as previsões confiantes e erradas; o Brier score mede o quadrado da diferença entre a chance e o resultado sucesso/fracasso. Um valor menor é melhor. Cada uma das quatro métricas foi calculada com três formas de ponderação: tarefas com peso igual, famílias com peso igual e a variante intermediária usada pela METR. Não as somamos em uma única melhora percentual.</p>
<p><strong>Custo e incerteza.</strong> A nova análise exige ajustes estatísticos, inclusive separados para cada divisão de validação, mas não chamadas adicionais aos LLMs avaliados. O trabalho não relata economia de tempo nem de dinheiro decorrente da adoção do estimador. Os intervalos de incerteza da comparação principal são calculados por famílias de tarefas. Um resultado pontual melhor em cada métrica não significa que cada contraste isolado seja estatisticamente conclusivo.</p>
</details>
<h2 id="tarefas-mais-longas-exigem-verificar-a-escala-de-novo">Tarefas mais longas exigem verificar a escala de novo</h2>
<p>O trabalho não estabelece a causa do trecho plano nem mostra que ele aparecerá em todo benchmark. Tampouco prova que as tarefas da METR representam todo o trabalho de um programador. Os autores não contestam a tendência exponencial de progresso observada; eles investigam o que significam os intervalos no eixo do tempo de trabalho humano.</p>
<p>A aplicação prática é complementar o horizonte com um gráfico das chances de sucesso para faixas fixas de tarefas. Isso permite ver se um salto do horizonte corresponde a uma mudança nítida de confiabilidade. Ao acrescentar tarefas mais longas ao próprio benchmark, vale verificar, em famílias reservadas, se o tempo delas continua prevendo a dificuldade para o agente, antes de prolongar a curva usada até então.</p>
<h2 id="fontes">Fontes</h2>
<ul>
<li>Drew T. Nguyen, William Fithian, <a href="https://arxiv.org/abs/2610.12466" rel="noopener noreferrer"><em>On the estimation and validity of AI time horizons—a statistical look at the METR plot</em></a>, preprint, 2026, v1. arXiv:2610.12466; DOI: 10.48550/arXiv.2610.12466. <a href="https://arxiv.org/html/2610.12466v1" rel="noopener noreferrer">Texto completo</a>.</li>
<li>METR, <a href="https://metr.org/time-horizons/" rel="noopener noreferrer"><em>Task-Completion Time Horizons of Frontier AI Models</em></a>, definição da medida, procedimento de avaliação e limitações. A página informa que o gráfico não é mais atualizado ativamente.</li>
</ul>]]></content:encoded>
</item>
<item>
  <title>A SemiAnalysis compara os limites das assinaturas de IA</title>
  <link>https://paweldubiel.com/pt/articles/a-semianalysis-compara-os-limites-das-assinaturas-de-ia</link>
  <guid isPermaLink="true">https://paweldubiel.com/pt/articles/a-semianalysis-compara-os-limites-das-assinaturas-de-ia</guid>
  <pubDate>Sat, 10 Oct 2026 11:06:52 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <description>Na análise de 5 de outubro de 2026, a SemiAnalysis compara os limites reais das assinaturas de IA.</description>
  <content:encoded><![CDATA[<p>Na <a href="https://newsletter.semianalysis.com/p/anthropic-subscriptions-offer-5x" rel="noopener noreferrer">análise de 5 de outubro de 2026</a>, a SemiAnalysis compara os limites reais das assinaturas de IA. Os autores verificam como cada tipo de <a href="https://paweldubiel.com/glossary/token" hreflang="pl">token [Polski]</a> move os indicadores de uso e convertem a cota disponível no custo de um uso idêntico pela API.</p>
<p>Segundo as medições deles, com as proporções de tokens adotadas para o trabalho de agentes, o Claude com o Opus 5.5 oferece cerca de cinco vezes mais valor, pelas tabelas de preços da API, do que as assinaturas da OpenAI com o GPT-6.1 Sol incluídas na comparação. Essa é uma medida do uso disponível; a eficácia dos modelos na execução de tarefas não foi comparada aqui.</p>
<p>O artigo mostra também os efeitos do corte pela metade da cota de tokens no novo Pro 200 da OpenAI e descreve um teste A/B detectado pelos autores, no qual uma das contas tinha limites cerca de 20% menores. O valor de uma assinatura depende, portanto, também das regras de contabilização do uso, que mudam com o tempo.</p>
<p>A comparação final dos serviços de intermediários está disponível para assinantes pagos.</p>]]></content:encoded>
</item>
</channel>
</rss>