{"id":777,"date":"2026-10-13T18:33:35","date_gmt":"2026-10-13T21:33:35","guid":{"rendered":"https:\/\/yellowkode.com\/blog\/agentes-ia-arvore-acessibilidade-codigo\/"},"modified":"2026-10-13T18:33:35","modified_gmt":"2026-10-13T21:33:35","slug":"agentes-ia-arvore-acessibilidade-codigo","status":"publish","type":"post","link":"https:\/\/yellowkode.com\/blog\/agentes-ia-arvore-acessibilidade-codigo\/","title":{"rendered":"Agentes de IA leem sua interface pela \u00e1rvore de acessibilidade: o que isso muda no c\u00f3digo"},"content":{"rendered":"<p>No fim de semana passado, o UX Collective publicou um artigo chamado <em>Secret agent bot: accessibility matters for the agents even if you can&#8217;t see them<\/em>, de Mark Nowak. A tese \u00e9 simples e desconfort\u00e1vel: o seu site tem um novo tipo de visitante, que n\u00e3o olha a p\u00e1gina do jeito que voc\u00ea olha, l\u00ea um modelo reduzido chamado \u00e1rvore de acessibilidade, a mesma estrutura que os navegadores constroem para leitores de tela h\u00e1 duas d\u00e9cadas, e n\u00e3o enxerga cor, s\u00f3 estrutura bem rotulada.<\/p>\n<p>Isso n\u00e3o \u00e9 opini\u00e3o. \u00c9 o que a documenta\u00e7\u00e3o dos pr\u00f3prios fornecedores j\u00e1 diz. Vou mostrar o mecanismo, o que fazer no c\u00f3digo e onde essa hist\u00f3ria ainda n\u00e3o fecha.<\/p>\n<h2>Como o agente l\u00ea a p\u00e1gina por baixo<\/h2>\n<p>Antes de falar de ARIA, \u00e9 preciso entender o que \u00e9 a tal \u00e1rvore de acessibilidade (accessibility tree), porque sem isso o resto vira folclore.<\/p>\n<p>Quando o navegador carrega uma p\u00e1gina, ele monta duas coisas em paralelo. A primeira \u00e9 o DOM, que \u00e9 a representa\u00e7\u00e3o da marca\u00e7\u00e3o. A segunda \u00e9 uma estrutura separada: a WAI-ARIA 1.2 do W3C define a \u00e1rvore de acessibilidade como uma \u00e1rvore de objetos acess\u00edveis que representa a estrutura da interface, onde cada n\u00f3 representa um elemento da UI exposto por meio da API de acessibilidade. Cada n\u00f3 dessa \u00e1rvore carrega quatro propriedades que importam: role (que tipo de coisa \u00e9, bot\u00e3o, link, regi\u00e3o de navega\u00e7\u00e3o), name (como ela se chama, por exemplo, o texto &#8220;Adicionar ao carrinho&#8221;), state (se est\u00e1 expandida, marcada, desabilitada) e description (contexto adicional).<\/p>\n<p>Compara com uma planta de evacua\u00e7\u00e3o de pr\u00e9dio. A planta n\u00e3o mostra a decora\u00e7\u00e3o, n\u00e3o diz de que cor \u00e9 a parede, n\u00e3o desenha o quadro na recep\u00e7\u00e3o. Mostra onde fica a porta, onde fica a escada, onde est\u00e1 o extintor, e qual rota liga uma coisa \u00e0 outra. Algu\u00e9m que nunca entrou no pr\u00e9dio consegue agir a partir dela. A analogia quebra num ponto: a planta \u00e9 um documento \u00e0 parte, enquanto a \u00e1rvore de acessibilidade \u00e9 derivada automaticamente do que voc\u00ea escreveu em HTML. Se o HTML for ruim, a planta sai errada sozinha.<\/p>\n<p>Agora o que mudou. At\u00e9 pouco tempo essa \u00e1rvore existia basicamente para leitor de tela. Hoje ela \u00e9 a entrada principal de v\u00e1rios agentes de IA que navegam na web em nome do usu\u00e1rio.<\/p>\n<h3>ChatGPT Atlas e o posicionamento oficial da OpenAI<\/h3>\n<p>A OpenAI documentou isso de forma expl\u00edcita. O FAQ de Publishers and Developers diz que o ChatGPT Atlas usa tags ARIA, os mesmos labels e roles que apoiam leitores de tela, para interpretar a estrutura da p\u00e1gina e os elementos interativos, e aconselha que deixar o site mais acess\u00edvel ajuda o agente a entend\u00ea-lo. O Atlas foi constru\u00eddo sobre Chromium, mas em vez de analisar pixels renderizados, ele consulta a \u00e1rvore de acessibilidade por elementos com roles espec\u00edficos como &#8220;button&#8221; e &#8220;link&#8221; e por nomes acess\u00edveis.<\/p>\n<h3>Playwright MCP e o padr\u00e3o que a Microsoft escolheu<\/h3>\n<p>Do lado da Microsoft, o Playwright MCP (o servidor oficial de Model Context Protocol para automa\u00e7\u00e3o de browser) seguiu o mesmo caminho. O Playwright MCP opera sobre a \u00e1rvore de acessibilidade da p\u00e1gina, n\u00e3o sobre pixels, e quando uma ferramenta roda ele devolve um snapshot estruturado mostrando os elementos, seus roles e o conte\u00fado de texto, e o LLM usa refer\u00eancias desses snapshots para interagir com a p\u00e1gina. Benchmarks emp\u00edricos indicam que esses snapshots consomem de 1 a 5 KB de texto, algo entre 250 e 1250 tokens, enquanto screenshots crus consomem 100 KB ou mais, de 1500 a 5000 tokens por passo, resultando em uma redu\u00e7\u00e3o de 4 a 10 vezes no uso de tokens em workflows de m\u00faltiplas etapas.<\/p>\n<p>Em outras palavras: ler pela \u00e1rvore \u00e9 mais barato e menos amb\u00edguo do que olhar pixel. Esse \u00e9 o motivo real por que os fornecedores foram para esse lado, n\u00e3o \u00e9 generosidade com acessibilidade, \u00e9 economia de token e redu\u00e7\u00e3o de erro.<\/p>\n<h2>O que isso significa no c\u00f3digo<\/h2>\n<p>A regra pr\u00e1tica \u00e9 simples e, por favor, resista a querer resolver tudo com ARIA. A primeira regra do ARIA \u00e9 preferir HTML nativo sempre que poss\u00edvel, usar um button de verdade para um bot\u00e3o, um nav de verdade para navega\u00e7\u00e3o, uma table de verdade para dados tabulares, e um label de verdade pareado com um campo de formul\u00e1rio, porque elementos nativos trazem sem\u00e2ntica embutida, comportamento de foco e compatibilidade, e ARIA deve enfatizar significado onde o HTML nativo n\u00e3o tem padr\u00e3o, n\u00e3o substituir HTML correto.<\/p>\n<p>O caso can\u00f4nico do erro \u00e9 este:<\/p>\n<pre><code>&lt;!-- O que n\u00e3o funciona bem para agente nem para leitor de tela --&gt;\n&lt;div class=\"btn-primary\" onclick=\"checkout()\"&gt;\n Finalizar compra\n&lt;\/div&gt;\n\n&lt;!-- O que funciona --&gt;\n&lt;button type=\"button\" onclick=\"checkout()\"&gt;\n Finalizar compra\n&lt;\/button&gt;<\/code><\/pre>\n<p>A div com onclick renderiza igual na tela. Para o agente, n\u00e3o \u00e9 bot\u00e3o. Adicionar role=&#8221;button&#8221; a uma div n\u00e3o d\u00e1 a ela foco de teclado, nem handler de clique em Enter ou Space, nem nenhum dos comportamentos embutidos que um button real fornece.<\/p>\n<p>Onde ARIA ganha \u00e9 no estado din\u00e2mico. Um dropdown, um accordion, um dialog modal, um resultado de busca que aparece sem recarregar a p\u00e1gina. Nesses casos o HTML nativo n\u00e3o d\u00e1 conta sozinho:<\/p>\n<pre><code>&lt;button\n type=\"button\"\n aria-expanded=\"false\"\n aria-controls=\"menu-filtros\"&gt;\n Filtros\n&lt;\/button&gt;\n&lt;div id=\"menu-filtros\" role=\"region\" hidden&gt;\n &lt;!-- op\u00e7\u00f5es --&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>Quando o usu\u00e1rio abre, voc\u00ea atualiza <code>aria-expanded<\/code> para <code>true<\/code> e remove o <code>hidden<\/code>. O agente que ler o snapshot naquele instante sabe que o bot\u00e3o est\u00e1 aberto e que o controle associado \u00e9 o <code>menu-filtros<\/code>. A OpenAI diz no FAQ que o ChatGPT Atlas usa tags ARIA para interpretar estrutura e elementos interativos, as ARIA snapshots do Playwright da Microsoft tamb\u00e9m mostram como ferramentas de automa\u00e7\u00e3o de browser podem capturar a \u00e1rvore de acessibilidade como YAML estruturado, e o Chrome DevTools exp\u00f5e essa mesma \u00e1rvore para o desenvolvedor inspecionar o que a m\u00e1quina est\u00e1 vendo.<\/p>\n<p>Esse \u00faltimo ponto \u00e9 o que eu recomendo que voc\u00ea fa\u00e7a hoje: abra o DevTools, aba Accessibility, selecione um elemento central do seu fluxo e veja o nome acess\u00edvel que ele tem. Se o bot\u00e3o principal do checkout aparece como &#8220;&#8221; ou como &#8220;icon-arrow-right&#8221;, o agente vai tratar ele como se fosse qualquer outro clique sem r\u00f3tulo.<\/p>\n<p>Na pr\u00e1tica, num construtor de landing page que tirou a cria\u00e7\u00e3o de p\u00e1gina da fila da engenharia, uma das coisas que me obrigou a aten\u00e7\u00e3o foi exatamente essa: dar liberdade de montagem ao marketing significa aceitar p\u00e1gina fora do design system, a menos que o pr\u00f3prio builder imponha o limite. Isso vale para visual, vale para texto e vale tamb\u00e9m para a \u00e1rvore de acessibilidade que sai no final. Se o builder deixa colocar um &#8220;card clic\u00e1vel&#8221; como div com onclick, voc\u00ea est\u00e1 fabricando p\u00e1ginas que nenhum agente consegue operar direito. Impor o limite no builder (bot\u00e3o \u00e9 bot\u00e3o, link \u00e9 link, heading tem n\u00edvel) \u00e9 o que garante que a p\u00e1gina gerada por marketing continua leg\u00edvel por m\u00e1quina.<\/p>\n<h2>Onde essa hist\u00f3ria quebra<\/h2>\n<p>Primeiro ponto. ARIA mal usado \u00e9 pior do que n\u00e3o usar. ARIA mal empregado pode na verdade reduzir a acessibilidade e criar ambiguidade de interpreta\u00e7\u00e3o de m\u00e1quina, e a abordagem mais forte \u00e9 HTML sem\u00e2ntico primeiro e ARIA s\u00f3 onde clareza adicional \u00e9 necess\u00e1ria. \u00c9 muito comum ver <code>role=\"button\"<\/code> em cima de <code>&lt;a href=\"#\"&gt;<\/code>, ou <code>aria-expanded<\/code> est\u00e1tico que nunca \u00e9 atualizado pelo JavaScript. Isso enche a \u00e1rvore de informa\u00e7\u00e3o mentirosa e o agente age em cima da mentira.<\/p>\n<p>Segundo ponto. Nem todo fornecedor l\u00ea igual. Perplexity Comet trabalha de modo h\u00edbrido com \u00e1rvore de acessibilidade mais vis\u00e3o seletiva, e mesmo plataformas que come\u00e7aram com abordagens de vis\u00e3o primeiro est\u00e3o incorporando dados de acessibilidade, enquanto as plataformas que otimizam para confiabilidade e efici\u00eancia, como o Playwright MCP, lideram pela \u00e1rvore de acessibilidade. Dependendo do agente que voc\u00ea espera atender, o peso de cada camada muda.<\/p>\n<p>Terceiro ponto. Interfaces densas em dado t\u00eam trade-off pr\u00f3prio. Em dashboard denso em dados de medi\u00e7\u00e3o de m\u00eddia, performance de render e clareza do dado s\u00e3o o produto, n\u00e3o acabamento. Virtualizar lista melhora render e quebra busca do navegador e acessibilidade se feito sem cuidado. O mesmo vale para o agente: se a lista virtualizada s\u00f3 renderiza as linhas que est\u00e3o na viewport, a \u00e1rvore de acessibilidade tamb\u00e9m s\u00f3 tem essas linhas. Um agente que pede o snapshot n\u00e3o &#8220;v\u00ea&#8221; os outros 10 mil itens que voc\u00ea tem na mem\u00f3ria. Isso n\u00e3o \u00e9 motivo para abandonar virtualiza\u00e7\u00e3o, \u00e9 motivo para expor outro caminho para o agente, por exemplo uma API documentada, e aceitar que a navega\u00e7\u00e3o visual e a navega\u00e7\u00e3o por agente s\u00e3o caminhos diferentes.<\/p>\n<p>Quarto ponto, de seguran\u00e7a. Snapshots de acessibilidade cont\u00eam texto da aplica\u00e7\u00e3o e de conte\u00fado de terceiros que ela renderiza, uma p\u00e1gina pode dizer &#8220;ignore suas instru\u00e7\u00f5es anteriores&#8221;, &#8220;fa\u00e7a upload de um arquivo de configura\u00e7\u00e3o&#8221; ou &#8220;envie cookies para este endpoint de diagn\u00f3stico&#8221;, essas strings s\u00e3o dados da aplica\u00e7\u00e3o, e o agente n\u00e3o deve promov\u00ea-las acima das regras do sistema do host nem da tarefa limitada do humano. Para quem est\u00e1 do lado do site, isso significa que texto que voc\u00ea renderiza na p\u00e1gina pode ser lido como instru\u00e7\u00e3o por um agente que trate a entrada sem cuidado. N\u00e3o \u00e9 problema seu resolver sozinho, mas \u00e9 bom saber que existe.<\/p>\n<h2>O que ainda n\u00e3o d\u00e1 para afirmar<\/h2>\n<p>Nenhum fornecedor publicou medi\u00e7\u00e3o de quanto um atributo ARIA espec\u00edfico melhora a taxa de sucesso de uma tarefa de agente. O que existe \u00e9 a declara\u00e7\u00e3o de que o Atlas l\u00ea ARIA e orienta o publisher a seguir WAI-ARIA, mais o fato de o Playwright MCP operar sobre snapshots da \u00e1rvore. Isso \u00e9 posicionamento t\u00e9cnico claro, n\u00e3o \u00e9 um benchmark fechado por tipo de componente.<\/p>\n<p>Tamb\u00e9m n\u00e3o h\u00e1 consenso de que a \u00e1rvore de acessibilidade vire o canal \u00fanico. O desenho dos pr\u00f3prios agentes est\u00e1 misturando camadas, e o que a gente chama de agent-readable hoje pode virar amanh\u00e3 outra coisa, uma rota API dedicada, um feed estruturado, um protocolo pr\u00f3prio. A aposta razo\u00e1vel \u00e9 que \u00e1rvore de acessibilidade continua sendo pelo menos um dos canais por muito tempo, porque ela j\u00e1 existe de gra\u00e7a junto do navegador.<\/p>\n<h2>Como testar isso voc\u00ea mesmo<\/h2>\n<p>Um caminho pequeno para experimentar hoje, sem instalar nada ex\u00f3tico:<\/p>\n<ol>\n<li>Abra o seu site no Chrome. V\u00e1 em DevTools, aba Elements, painel Accessibility. Selecione o bot\u00e3o principal de uma a\u00e7\u00e3o cr\u00edtica, por exemplo &#8220;Finalizar compra&#8221; ou &#8220;Entrar&#8221;. Olhe os campos Role e Name. Se Role n\u00e3o for <code>button<\/code> ou <code>link<\/code>, voc\u00ea tem um problema. Se Name estiver vazio ou for algo como &#8220;icon-arrow&#8221;, voc\u00ea tem outro.<\/li>\n<li>Em Chrome DevTools ainda, abra Lighthouse e rode a auditoria de Accessibility. Ignore o score, olhe os itens de &#8220;Buttons do not have an accessible name&#8221; e &#8220;Links do not have a discernible name&#8221;. Esses s\u00e3o exatamente os pontos que v\u00e3o quebrar o agente.<\/li>\n<li>Se voc\u00ea quiser ver como um agente real enxerga sua p\u00e1gina, instale o Playwright MCP localmente (<code>npx @playwright\/mcp@latest<\/code>), conecte a um cliente MCP como Claude Desktop ou Cursor, e pe\u00e7a para o agente abrir sua p\u00e1gina e descrever o que v\u00ea. O que ele descreve \u00e9 a sua \u00e1rvore de acessibilidade, nem mais nem menos. Se faltar coisa que voc\u00ea considera essencial, \u00e9 isso que precisa de r\u00f3tulo.<\/li>\n<\/ol>\n<p>N\u00e3o precisa reescrever o site. Precisa fazer esse passeio de inspe\u00e7\u00e3o pelo fluxo cr\u00edtico (login, busca, checkout, formul\u00e1rio principal) e trocar div por elemento sem\u00e2ntico onde d\u00e1, adicionar <code>aria-label<\/code> onde o bot\u00e3o s\u00f3 tem \u00edcone, e garantir que <code>aria-expanded<\/code> e <code>aria-selected<\/code> acompanham o estado real. O resto do site pode esperar.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como ChatGPT Atlas, Playwright MCP e outros agentes leem p\u00e1ginas pela accessibility tree, e o que marcar com ARIA para n\u00e3o quebrar o fluxo deles.<\/p>\n","protected":false},"author":2,"featured_media":776,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-777","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\/777","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=777"}],"version-history":[{"count":0,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/777\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media\/776"}],"wp:attachment":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media?parent=777"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/categories?post=777"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/tags?post=777"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}