{"id":745,"date":"2026-09-27T18:33:52","date_gmt":"2026-09-27T21:33:52","guid":{"rendered":"https:\/\/yellowkode.com\/blog\/tinyaiarena-como-funciona-arena-agentes-llm-grid-8x8\/"},"modified":"2026-09-27T18:33:52","modified_gmt":"2026-09-27T21:33:52","slug":"tinyaiarena-como-funciona-arena-agentes-llm-grid-8x8","status":"publish","type":"post","link":"https:\/\/yellowkode.com\/blog\/tinyaiarena-como-funciona-arena-agentes-llm-grid-8x8\/","title":{"rendered":"TinyAIArena: como funciona uma arena de agentes LLM num grid 8&#215;8"},"content":{"rendered":"<p>Um projeto novo apareceu no Hacker News em 27 de setembro de 2026 chamado TinyAIArena. A proposta \u00e9 simples: em vez de mais um benchmark com tabela de acertos, voc\u00ea abre o navegador e assiste quatro modelos de linguagem se enfrentando num tabuleiro 8&#215;8. \u00c9 um Show HN publicado pelo usu\u00e1rio hp6, com c\u00f3digo aberto em github.com\/hp6\/ai-arena.<\/p>\n<p>Este artigo n\u00e3o \u00e9 sobre se o TinyAIArena \u00e9 bom ou ruim como benchmark. Isso ainda n\u00e3o d\u00e1 para afirmar. O artigo \u00e9 sobre o mecanismo por tr\u00e1s dele, porque a mesma arquitetura aparece em v\u00e1rios projetos parecidos e vale entender de verdade como isso funciona por baixo.<\/p>\n<h2>O que foi publicado<\/h2>\n<p>TinyAIArena d\u00e1 \u00e0s batalhas entre agentes de IA os aparatos familiares de um esporte: um leaderboard, hist\u00f3rico de partidas, replays e um conjunto de controles para avan\u00e7ar frame a frame. O projeto apareceu no Hacker News em 27 de setembro, publicado por um desenvolvedor com o handle hp6. A submiss\u00e3o tinha 80 pontos e 36 coment\u00e1rios no momento em que escrevo.<\/p>\n<p>O site rotula seu leaderboard com nome do modelo, Elo, partidas jogadas, vit\u00f3rias, taxa de vit\u00f3ria, kills, dano causado e recebido, e coloca\u00e7\u00e3o m\u00e9dia. A tabela de hist\u00f3rico mostra data, vencedor, rounds, a\u00e7\u00f5es e kills por lutador. \u00c9 esse conjunto de sinais que interessa: o que precisa existir por baixo para que essas colunas tenham valor.<\/p>\n<h2>Como uma arena de agentes LLM funciona por baixo<\/h2>\n<p>A arquitetura t\u00edpica desse tipo de sistema tem quatro pe\u00e7as que precisam encaixar. Vou passar por cada uma.<\/p>\n<h3>1. O motor de jogo determin\u00edstico<\/h3>\n<p>No centro existe um simulador do jogo em si. No caso do TinyAIArena, \u00e9 um grid 8&#215;8 com quatro agentes, hit points, dano, movimento e ataques. Esse motor \u00e9 a \u00fanica fonte de verdade sobre o estado: onde cada agente est\u00e1, quanto de vida tem, de quem \u00e9 o turno, quem j\u00e1 morreu.<\/p>\n<p>\u00c9 importante que ele seja determin\u00edstico. Dado o mesmo estado inicial e a mesma sequ\u00eancia de a\u00e7\u00f5es, ele produz exatamente o mesmo resultado. Isso \u00e9 o que permite o replay funcionar: voc\u00ea n\u00e3o regrava um v\u00eddeo, voc\u00ea grava s\u00f3 a sequ\u00eancia de a\u00e7\u00f5es e o cliente reconstr\u00f3i a partida rodando de novo o motor.<\/p>\n<h3>2. A ponte entre o motor e o modelo<\/h3>\n<p>O modelo de linguagem n\u00e3o v\u00ea o grid. Ele v\u00ea texto. Algu\u00e9m precisa traduzir o estado do jogo em algo que o LLM entenda, e traduzir a resposta do LLM em uma a\u00e7\u00e3o v\u00e1lida no motor.<\/p>\n<p>Pense num jogo de xadrez por correspond\u00eancia. O tabuleiro est\u00e1 na casa de um dos jogadores. O outro recebe um cart\u00e3o descrevendo a posi\u00e7\u00e3o (pe\u00e3o em e4, cavalo em f3) e responde com uma jogada em nota\u00e7\u00e3o (Cxe5). Um funcion\u00e1rio dos correios traduz a jogada para o tabuleiro f\u00edsico e escreve a pr\u00f3xima descri\u00e7\u00e3o. A analogia quebra num ponto importante: no xadrez as jogadas legais s\u00e3o um conjunto pequeno e bem definido, num jogo com movimento cont\u00ednuo e v\u00e1rias a\u00e7\u00f5es por turno o espa\u00e7o de sa\u00edda \u00e9 maior e a chance de o modelo produzir uma resposta inv\u00e1lida cresce.<\/p>\n<p>Na pr\u00e1tica, essa ponte \u00e9 implementada como tool calls. O sistema descreve em texto:<\/p>\n<pre><code>Voc\u00ea \u00e9 o agente RED em (2,4). HP: 80\/100.\nOutros: BLUE em (5,1) HP:60, GREEN em (7,7) HP:100, YELLOW morto.\nA\u00e7\u00f5es dispon\u00edveis: move(dx,dy), attack(target), wait().\nSua vez. Responda chamando exatamente uma ferramenta.<\/code><\/pre>\n<p>E define um schema JSON para a resposta. O modelo emite algo como <code>{\"tool\": \"move\", \"args\": {\"dx\": 1, \"dy\": 0}}<\/code>. A ponte valida esse payload contra o schema, verifica se a a\u00e7\u00e3o \u00e9 legal no estado atual (n\u00e3o pode andar em cima de outro agente, n\u00e3o pode atacar quem est\u00e1 fora do alcance) e s\u00f3 ent\u00e3o aplica no motor.<\/p>\n<p>Um projeto irm\u00e3o, o AI Arena de AyushChangedia, deixa isso expl\u00edcito ao descrever seu harness: o payload \u00e9 validado por schema e despachado. Uma chamada malformada \u00e9 um erro real que o agente tem que se recuperar, n\u00e3o uma exce\u00e7\u00e3o. Essa distin\u00e7\u00e3o \u00e9 o cora\u00e7\u00e3o da coisa. Se voc\u00ea deixa passar chamada quebrada silenciosamente, seu leaderboard mede outra coisa.<\/p>\n<h3>3. O gerador de partidas e o ranking Elo<\/h3>\n<p>Elo veio do xadrez. A ideia \u00e9 que cada jogador tem uma pontua\u00e7\u00e3o, e depois de cada partida a pontua\u00e7\u00e3o sobe ou desce em fun\u00e7\u00e3o da diferen\u00e7a entre o resultado esperado e o resultado real. Se um modelo com Elo 1600 ganha de um com Elo 1400, ele sobe pouco (era esperado). Se perde, cai muito (era muito esperado ganhar).<\/p>\n<p>A f\u00f3rmula cl\u00e1ssica para dois jogadores: <code>novo_elo = elo + K * (resultado - esperado)<\/code>, onde <code>esperado = 1 \/ (1 + 10^((elo_oponente - elo)\/400))<\/code>. Com quatro jogadores por partida em vez de dois, precisa adaptar. A abordagem mais comum \u00e9 converter a coloca\u00e7\u00e3o final (1\u00ba, 2\u00ba, 3\u00ba, 4\u00ba) em uma s\u00e9rie de resultados dois a dois, ou usar uma variante como TrueSkill.<\/p>\n<p>Elo \u00e9 uma forma familiar de atualizar rankings depois de resultados competitivos, mas a nota precisa de contexto: as regras do jogo, como os oponentes s\u00e3o selecionados, quantas partidas cada modelo jogou, e se posi\u00e7\u00f5es iniciais ou times rotacionam. A interface vis\u00edvel do TinyAIArena menciona Elo e mostra categorias de estat\u00edsticas de partidas. A documenta\u00e7\u00e3o dispon\u00edvel n\u00e3o explica a f\u00f3rmula de rating, o processo de gera\u00e7\u00e3o de partidas, os provedores de modelo suportados ou o processo de submiss\u00e3o de agentes. Guarde essa informa\u00e7\u00e3o, ela volta na se\u00e7\u00e3o sobre limita\u00e7\u00f5es.<\/p>\n<h3>4. O gravador e o player de replay<\/h3>\n<p>O replay n\u00e3o \u00e9 um v\u00eddeo. \u00c9 um log estruturado. Para cada frame (ou para cada a\u00e7\u00e3o, dependendo do design), o sistema grava o estado do jogo mais a a\u00e7\u00e3o escolhida, e opcionalmente o racioc\u00ednio do modelo se ele exp\u00f4s isso. O front-end l\u00ea esse log e renderiza. \u00c9 por isso que o site do TinyAIArena aceita atalhos de teclado (setas para avan\u00e7ar frame, espa\u00e7o para auto, home\/end para come\u00e7o e fim). O que voc\u00ea est\u00e1 fazendo \u00e9 caminhar por uma linha de tempo de estados discretos, n\u00e3o fazer scrub num v\u00eddeo.<\/p>\n<h2>O que isso significa na pr\u00e1tica<\/h2>\n<p>Se voc\u00ea quer construir uma arena parecida, o esqueleto m\u00ednimo tem cinco arquivos: motor de jogo, adapter para o LLM (com schema de tool call), loop de partida, atualizador de Elo, gravador de replay. Cada um faz uma coisa. O mais delicado, na minha experi\u00eancia, \u00e9 o adapter.<\/p>\n<p>Um exemplo do loop principal, em pseudoc\u00f3digo:<\/p>\n<pre><code>state = engine.initial_state(agents)\nlog = []\nwhile not engine.is_over(state):\n agent = state.current_agent\n prompt = adapter.render(state, agent)\n action = adapter.request_action(agent.model, prompt)\n if not engine.is_legal(state, action):\n action = engine.default_action() # ou penaliza\n state = engine.apply(state, action)\n log.append((state.snapshot(), action))\nranking = engine.final_ranking(state)\nelo.update(agents, ranking)\nstorage.save_replay(log)<\/code><\/pre>\n<p>Quando constru\u00ed uma extens\u00e3o de navegador que escrevia direto num CRM, aprendi que essa parte do <code>is_legal<\/code> n\u00e3o \u00e9 opcional. Uma chamada de API bem-sucedida (o LLM respondeu 200, o JSON parseou) n\u00e3o diz nada sobre o payload fazer sentido no dom\u00ednio. Aqui \u00e9 a mesma coisa: o modelo pode devolver <code>attack(YELLOW)<\/code> quando YELLOW j\u00e1 morreu, ou <code>move(50,50)<\/code> num grid 8&#215;8. O motor tem que rejeitar.<\/p>\n<h2>Onde quebra<\/h2>\n<p>Tr\u00eas problemas concretos aparecem em qualquer arena desse tipo, e valem para o TinyAIArena.<\/p>\n<p><strong>Assimetria de custo.<\/strong> Rodar 100 partidas com quatro modelos cada uma s\u00e3o 400 chamadas de LLM por partida no m\u00ednimo (uma por turno por agente vivo), vezes o n\u00famero de turnos. Um \u00fanico torneio decente entra na casa de milhares de chamadas. Se voc\u00ea mistura GPT-5 e um modelo local, a conta de lat\u00eancia e dinheiro fica desbalanceada e isso influencia decis\u00f5es de design (voc\u00ea vai reduzir o contexto? cortar a quantidade de partidas? isso enviesa o Elo).<\/p>\n<p><strong>Prompt como vari\u00e1vel escondida.<\/strong> Cada modelo responde melhor a um estilo de prompt diferente. Se voc\u00ea usa o mesmo prompt para todos, est\u00e1 medindo em parte qu\u00e3o bem o prompt casa com cada modelo. Se voc\u00ea adapta o prompt por modelo, est\u00e1 medindo o prompt engineer, n\u00e3o o modelo. N\u00e3o tem sa\u00edda limpa, s\u00f3 escolha expl\u00edcita.<\/p>\n<p><strong>O jogo \u00e9 um dom\u00ednio, n\u00e3o um teste geral.<\/strong> Ser bom num grid 8&#215;8 t\u00e1tico n\u00e3o diz que o modelo \u00e9 bom em racioc\u00ednio geral. Diz que \u00e9 bom em racioc\u00ednio espacial de curto horizonte com espa\u00e7o de a\u00e7\u00e3o pequeno. Um replay pode mostrar o que aconteceu dentro de uma partida espec\u00edfica. Uma pontua\u00e7\u00e3o Elo pode resumir resultados atrav\u00e9s de partidas. Nenhum dos dois, sozinho, estabelece que os agentes enfrentaram condi\u00e7\u00f5es equivalentes ou que o ranking diz muito sobre desempenho al\u00e9m desse jogo.<\/p>\n<h2>O que ainda n\u00e3o d\u00e1 para afirmar<\/h2>\n<p>N\u00e3o sei quais modelos exatamente est\u00e3o competindo no TinyAIArena hoje, porque a documenta\u00e7\u00e3o p\u00fablica n\u00e3o lista. N\u00e3o sei que variante de Elo \u00e9 usada com quatro jogadores. N\u00e3o sei se as posi\u00e7\u00f5es iniciais s\u00e3o sorteadas ou fixas, o que muda muito o resultado num tabuleiro pequeno. N\u00e3o sei se cada modelo joga a mesma quantidade de partidas contra os mesmos oponentes. O pr\u00f3ximo passo \u00fatil para o projeto n\u00e3o \u00e9 um r\u00f3tulo de ranking mais elaborado; \u00e9 detalhe p\u00fablico suficiente para outra pessoa entender como uma partida \u00e9 produzida e o que a pontua\u00e7\u00e3o pode sustentar. At\u00e9 l\u00e1, o valor do site \u00e9 como demonstra\u00e7\u00e3o e ferramenta de inspe\u00e7\u00e3o, n\u00e3o como benchmark que decide algo.<\/p>\n<h2>Como testar isso voc\u00ea mesmo<\/h2>\n<p>Um caminho pequeno para experimentar, em um fim de semana:<\/p>\n<ul>\n<li>Escolha um jogo simples com regras determin\u00edsticas e estado observ\u00e1vel. Tic-tac-toe estendido, Connect Four, ou um grid 4&#215;4 com dois agentes. Fuja de jogos com informa\u00e7\u00e3o oculta no primeiro prot\u00f3tipo.<\/li>\n<li>Implemente o motor em Python puro. Uma fun\u00e7\u00e3o <code>apply(state, action)<\/code>, uma <code>legal_actions(state)<\/code>, uma <code>is_terminal(state)<\/code>, uma <code>winner(state)<\/code>. Sem framework.<\/li>\n<li>Escreva o adapter. Uma fun\u00e7\u00e3o que recebe o estado e devolve um prompt em texto, e outra que recebe a resposta do LLM (use tool calls ou JSON mode) e devolve uma a\u00e7\u00e3o estruturada. Valide contra <code>legal_actions<\/code> antes de aplicar.<\/li>\n<li>Rode 10 partidas entre dois modelos diferentes via OpenRouter ou provider parecido. Loge cada turno em um JSON linha a linha.<\/li>\n<li>S\u00f3 depois disso pense em Elo. Antes disso, olhe os replays. Voc\u00ea vai ver os modelos fazendo coisas absurdas e vai entender por que o adapter \u00e9 onde mora a complexidade.<\/li>\n<\/ul>\n<p>Quando voc\u00ea tiver rodado esse prot\u00f3tipo, olhar para o TinyAIArena vai fazer muito mais sentido, porque voc\u00ea vai reconhecer as mesmas pe\u00e7as e vai saber que perguntas fazer sobre o que ainda n\u00e3o est\u00e1 documentado.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como o TinyAIArena coloca quatro modelos brigando num grid 8&#215;8: mecanismo turn-based, tool calls, ranking Elo e replay frame a frame.<\/p>\n","protected":false},"author":2,"featured_media":744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-745","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/745","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/comments?post=745"}],"version-history":[{"count":0,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/745\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media\/744"}],"wp:attachment":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media?parent=745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/categories?post=745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/tags?post=745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}