Fazer um agente de inteligência artificial operar um aplicativo de computador costumava exigir um ritual caro e impreciso: tirar uma captura de tela em alta resolução, enviá-la para um modelo de visão, torcer para ele adivinhar que o botão "Salvar" está na coordenada (412, 89) e simular um clique físico no mouse. Quando os números de teste do agent-desktop (abre em nova aba), ferramenta de código aberto da Vercel Labs divulgada no fim de outubro de 2026, vieram a público, a diferença de custo chamou a atenção imediatamente. Segundo métricas divulgadas por Lahfir, criador do projeto na Vercel Labs, inspecionar uma janela densa como o Apple Maps por meio de um esqueleto da árvore de acessibilidade com aprofundamento seletivo consome 273 tokens por leitura, contra 3.811 tokens ao ler a janela inteira de uma vez. Em uma tarefa simulada de 52 etapas, esse método reduziu o consumo total de 198 mil para 31 mil tokens, sem capturar um único pixel da tela.
O segredo por trás dessa economia não é um modelo multimodal novo, mas uma infraestrutura que já existe há décadas dentro do seu sistema operacional. O macOS possui a Accessibility API, o Windows conta com o UI Automation e o Linux utiliza o AT-SPI. Essas interfaces foram criadas para que leitores de tela saibam exatamente onde estão botões, menus, caixas de texto e listas, além de quais ações cada componente aceita. O agent-desktop, escrito em Rust e distribuído sob licença Apache-2.0, consulta diretamente essa árvore nativa, transforma a interface em um JSON estruturado e atribui identificadores determinísticos (chamados de refs) para cada elemento interativo.
Neste guia prático, vamos dissecar como o agent-desktop funciona por baixo do capô, instalar o binário nativo (evitando uma armadilha silenciosa do npm que adiciona mais de 100 ms por chamada), executar o ciclo de observação e ação via linha de comando e integrar a ferramenta a agentes autônomos.
Como a árvore de acessibilidade substitui o clique por coordenada
Quando você pede para um modelo de visão clicar em um item de uma tabela no Finder ou no Slack, três problemas acontecem ao mesmo tempo. O primeiro é o custo de observação: imagens inteiras pesam no contexto e demoram para ser processadas. O segundo é a deriva espacial: se uma notificação empurrar a janela alguns pixels para o lado ou uma linha for removida da lista um milissegundo antes do clique, o agente clica no lugar errado sem perceber. O terceiro é a intrusão física: mover o cursor real do sistema impede que você use o computador enquanto o agente trabalha.
O agent-desktop resolve esses três pontos tratando a árvore de acessibilidade como a única fonte da verdade para observação e interação semântica. Em vez de olhar para a aparência visual da janela, o binário pergunta ao sistema operacional quais objetos estão instanciados na memória daquela aplicação.
Cada leitura gera um snapshot (um retrato estrutural daquele instante) identificado por um código curto. Dentro desse retrato, os elementos que aceitam interação recebem uma referência qualificada em ordem de busca em profundidade (depth-first), no formato @<id_do_snapshot>:e<numero>, como @s8f3k2p9:e1 ou @s8f3k2p9:e8.
Apenas 18 papéis semânticos (roles) interativos recebem referências acionáveis:
- Controles básicos:
button,textfield,checkbox,radiobutton,switch,link. - Navegação e menus:
menuitem,menubutton,tab,dockitem. - Seleção e dados:
combobox,listbox,option,treeitem,cell,slider,incrementor,colorwell.
A parte mais interessante da engenharia do projeto está na garantia de integridade dessas referências. No macOS, por exemplo, as chamadas da CLI reutilizam um processo host de comando privado por namespace de snapshot e versão compilada do binário. Esse host mantém os objetos nativos de acessibilidade retidos na memória (e encerra sozinho após 15 minutos de inatividade). Por que isso importa? Porque se uma linha de uma tabela for apagada entre o momento em que o agente leu a tela e o momento em que ele enviou o comando de clique, o objeto nativo invalida a referência. O agent-desktop não deixa o clique recair silenciosamente sobre a linha sobrevivente que ocupou o mesmo espaço: ele aborta a operação e retorna um erro estruturado STALE_REF.
Além disso, as ações sobre referências são headless por padrão. Como o comando aciona a API de acessibilidade diretamente no objeto da interface, o ponteiro físico do seu mouse não se move e a janela do aplicativo não precisa roubar o foco do teclado. Você pode continuar escrevendo código em um monitor enquanto o agente preenche formulários ou navega em menus em outra janela.
Pré-requisitos
O agent-desktop atingiu a versão 1.0.0 em 27 de outubro de 2026 (quando ganhou suporte oficial ao Linux) e chegou à versão 1.0.2 em 30 de outubro de 2026. Antes de instalar, confira o que o seu ambiente precisa para rodar os binários sem atrito.
O pacote distribui executáveis nativos para seis combinações de arquitetura, acompanhados de binários auxiliares (helpers) específicos para cada plataforma que ficam no mesmo diretório da CLI:
| Plataforma | Arquiteturas | Binário auxiliar instalado junto à CLI |
|---|---|---|
| macOS | arm64, x64 | agent-desktop-macos-helper |
| Linux (glibc) | x64, arm64 | agent-desktop-linux-clipboard-owner |
| Windows | x64, arm64 | Nenhum (none) |
Se você pretende usar a biblioteca compartilhada via FFI (Foreign Function Interface) com ABI em C para carregar o agent-desktop diretamente dentro de processos em Python, Swift, Go, Ruby, Node, C ou C++ sem precisar criar subprocessos (forking), saiba que os arquivos libagent_desktop_ffi.dylib, .so ou agent_desktop_ffi.dll não vêm dentro do pacote do npm. Eles são distribuídos em arquivos separados na página de lançamentos (Releases) do GitHub ou compilados do código-fonte no diretório target/release-ffi/.
Passo a passo: instalação, observação e operação
Vamos configurar a ferramenta, entender como inspecionar aplicativos reais economizando tokens e conectar as instruções nativas ao seu agente.
Passo 1: Instalar o binário nativo (e destravar o postinstall)
A maneira mais rápida de instalar a ferramenta na documentação oficial do agent-desktop (abre em nova aba) é globalmente via npm:
npm install -g agent-desktopSe você não passar a flag -g, o executável ficará restrito a ./node_modules/.bin e precisará ser chamado com npx agent-desktop.
Aqui mora um detalhe técnico crucial que separa uma instalação rápida de uma instalação lenta. O pacote do npm traz um lançador em JavaScript e um script de postinstall cuja única função é substituir esse lançador do Node por um link direto para o binário nativo em Rust. Se o seu gerenciador de pacotes bloquear scripts de pós-instalação por política de segurança, o comando continuará funcionando, mas toda chamada inicializará o runtime do Node.js antes de chamar o Rust. Isso adiciona mais de 100 ms de latência em cada comando executado pelo agente.
Caso o terminal exiba um aviso único na saída de erro padrão (stderr) informando que o lançador Node está ativo, aprove o script e reinstale conforme a versão do seu npm:
# No npm 12:
npm install-scripts approve agent-desktop
# No npm 11:
npm install -g agent-desktop --allow-scripts=agent-desktopSe você prefere não depender do ecossistema Node em servidores ou ambientes enxutos, pode baixar o arquivo compactado diretamente do GitHub Releases para o seu sistema, extrair o executável principal e o helper da sua plataforma no mesmo diretório do seu PATH e validar a autenticidade da compilação com a CLI do GitHub:
gh attestation verify <arquivo-baixado> --repo vercel-labs/agent-desktopPara quem precisa compilar do código-fonte (por exemplo, para auditar o código ou gerar a biblioteca FFI), clone o repositório oficial e compile tanto o pacote principal quanto o binário auxiliar do seu sistema operacional:
git clone https://github.com/vercel-labs/agent-desktop && cd agent-desktop
cargo build --release -p agent-desktop
# Compile também o helper específico do seu SO e mantenha-o ao lado do binário principal:
# No macOS:
cargo build --release -p agent-desktop-macos --bin agent-desktop-macos-helper
# No Linux:
cargo build --release -p agent-desktop-linux --binsPasso 2: Capturar o primeiro snapshot estruturado
Com o binário pronto, vamos observar como o agent-desktop enxerga uma janela. A ferramenta possui 60 comandos divididos entre observação, interação, teclado, mouse, notificações, área de transferência (clipboard), gerenciamento de janelas, ciclo de vida de sessão e exportação de rastros (traces).
Para ler a estrutura de um aplicativo aberto, como o Finder no macOS ou o Safari, execute o comando snapshot:
agent-desktop snapshot --app Finder -iToda resposta da CLI devolve um envelope JSON padronizado contendo a versão do protocolo ("2.5"), um booleano "ok" indicando sucesso ou falha, o nome do comando e o objeto "data" (ou "error"). Dentro do snapshot do Finder, você verá o identificador do retrato, a contagem total de referências e a árvore de nós. Um elemento acionável dentro dessa árvore aparece estruturado assim:
{
"role": "treeitem",
"name": "Documents",
"ref_id": "@s8f3k2p9:e8",
"available_actions": ["Click"]
}Observe que o agente não precisa deduzir se o texto "Documents" é um título estático ou uma pasta clicável: o sistema operacional já informou que o papel do elemento é treeitem, que ele aceita a ação Click e que o endereço exato dele neste snapshot é @s8f3k2p9:e8.
Passo 3: Usar travessia progressiva de esqueleto em aplicativos densos
Se você rodar um snapshot completo em um aplicativo complexo cheio de painéis, abas e listas, a árvore JSON resultante será enorme. É aqui que entra o recurso de Progressive Skeleton Traversal (travessia progressiva de esqueleto), responsável pela queda de 3.811 para 273 tokens por leitura demonstrada nos testes com o Apple Maps. As análises técnicas que publicamos no IA.com.br mostram que o gargalo financeiro e de latência dos agentes raramente está na execução da ação em si, mas no excesso de contexto injetado no prompt a cada turno de observação.
Em vez de despejar toda a hierarquia da janela na janela de contexto do modelo de linguagem, instrua seu fluxo a operar em duas fases:
- Mapear a superfície: Peça apenas o esqueleto raso da janela usando a flag
--skeleton(ou combine com--compactpara reduzir ainda mais a verbosidade):
agent-desktop snapshot --app Safari --skeleton- **Perfurar a região de interesse (drill down):** Depois que o agente identificar qual contêiner ou barra lateral importa para a tarefa atual, faça um novo snapshot apontando a flag
--rootapenas para a referência daquela sub-região:
agent-desktop snapshot --app Safari --root @s8f3k2p9:e2Com isso, o agente lê exclusivamente os botões e campos da área onde precisa agir, ignorando dezenas de outros menus abertos na mesma janela.
Passo 4: Executar ações sobre referências e fechar o ciclo
Depois de localizar a referência desejada, o agente executa a ação correspondente passando o identificador completo:
agent-desktop click @s8f3k2p9:e8O ciclo operacional desenhado pela Vercel Labs segue uma regra rígida: observar, agir sobre uma referência e observar novamente (snapshot -> act -> snapshot). Após o clique na pasta "Documents", a estrutura da janela muda. O agente executa um novo snapshot para confirmar que o conteúdo da pasta abriu e para obter as novas referências dos arquivos internos.
Se você estiver rodando múltiplos agentes ou fluxos em paralelo na mesma máquina, isole os retratos usando escopos de sessão por meio da flag --session ou da variável de ambiente AGENT_DESKTOP_SESSION. Uma referência criada dentro de uma sessão fica confinada àquele namespace e não pode ser acionada por fora.
Passo 5: Ensinar o agente a usar a ferramenta (Skills embutidas)
Você não precisa escrever um prompt gigantesco do zero explicando todos os 60 comandos e códigos de erro para o seu LLM. O próprio binário do agent-desktop carrega sua documentação técnica embutida, sempre sincronizada com a versão exata instalada na máquina.
Se você usa um harness de agente compatível com o diretório skills.sh, pode instalar a habilidade diretamente:
npx skills add --skill agent-desktopSe você estiver configurando um arquivo AGENTS.md ou montando o prompt de sistema do seu próprio agente codificador, basta instruí-lo a rodar os comandos de autodescoberta antes de iniciar a tarefa:
# Carrega as regras centrais do loop, sistema de refs, verificação e retentativas:
agent-desktop skills get desktop
# Imprime a tabela completa de capacidades e diferenças específicas do SO atual:
agent-desktop skills get platform
# Consulta flags específicas de qualquer comando:
agent-desktop <comando> --helpComo verificar a instalação e as permissões
Antes de colocar um agente em produção para operar interfaces gráficas, verifique se o binário correto está respondendo e se o sistema operacional liberou as permissões de acessibilidade necessárias.
Execute os dois comandos de diagnóstico abaixo:
agent-desktop version
agent-desktop statusO comando version confirma a versão do protocolo JSON, a versão do binário, o sistema operacional e a arquitetura alvo:
{
"version": "2.5",
"ok": true,
"command": "version",
"data": {
"os": "linux",
"target": "x86_64",
"version": "1.0.1"
}
}Já o comando status faz uma checagem completa do estado das permissões (accessibility, automation e screen_recording), informa o diretório raiz onde o estado é salvo (state_root) e lista exatamente quais superfícies (supported_surfaces) aquele sistema operacional consegue ler:
{
"version": "2.5",
"ok": true,
"command": "status",
"data": {
"permissions": {
"accessibility": { "state": "granted" },
"automation": { "state": "not_required" },
"screen_recording": { "state": "not_required" }
},
"platform": "linux",
"ref_count": null,
"session_id": null,
"snapshot_id": null,
"state_root": "/home/user/.agent-desktop",
"supported_surfaces": ["window", "sheet", "alert", "menu"]
}
}Verifique se "accessibility" aparece com "state": "granted". Nota importante: repare que "screen_recording" aparece como "not_required" no fluxo padrão, comprovando que a ferramenta opera a interface sem precisar gravar ou capturar pixels da tela.
Erros comuns e como resolvê-los
Mesmo com uma arquitetura determinística, a automação de desktop lida com interfaces vivas que mudam de estado o tempo todo. Abaixo estão os problemas mais frequentes documentados no projeto e como tratá-los no código do seu agente ou no seu ambiente.
1. Rejeição por INVALID_ARGS ao abreviar referências
Um erro clássico de modelos de linguagem tentando economizar caracteres é mandar agent-desktop click @e8 em vez de @s8f3k2p9:e8. O agent-desktop rejeita referências nuas sem o prefixo do snapshot imediatamente com o código INVALID_ARGS. O ID do snapshot embutido na referência é obrigatório justamente para garantir que o comando seja autodescritivo e nunca aponte para uma leitura antiga por engano.
2. Falha STALE_REF ou AMBIGUOUS_TARGET quando a tela muda
Se o aplicativo atualizar a interface enquanto o LLM estava "pensando" na próxima ação, a referência antiga deixa de valer. Quando a CLI retorna STALE_REF ou AMBIGUOUS_TARGET, o envelope JSON de erro traz um code, uma disposition e um campo suggestion legível por máquina. Não tente repetir o clique na mesma referência: o fluxo correto de recuperação é capturar um novo snapshot, localizar o novo identificador do elemento e tentar novamente.
3. Conflito de versão com instalações antigas do Homebrew ou Scoop
Se você atualizou o pacote via npm mas o comando agent-desktop version continua exibindo uma versão antiga, você provavelmente caiu em um conflito de PATH. O agent-desktop não possui mais pacotes oficiais no Homebrew (macOS/Linux) nem no Scoop (Windows): o tap customizado e o bucket foram removidos na versão 1.0.1. Instalações antigas feitas por esses gerenciadores ficam congeladas na versão antiga e podem sombrear (shadow) o comando instalado pelo npm. Descubra qual binário está rodando e remova a versão órfã:
# No macOS e Linux:
command -v agent-desktop
# No Windows (PowerShell):
Get-Command agent-desktop4. Retorno de Partial Observation em janelas gigantescas
Em aplicativos extremamente pesados ou com árvores de acessibilidade profundas demais, um comando de snapshot pode esgotar seu orçamento de tempo (time budget) antes de varrer todos os nós. O glossário de conceitos do projeto define isso como uma Partial Observation: o comando não trava infinitamente, mas devolve o que conseguiu ler até o limite de tempo e relata o grau de completude na resposta. Quando isso acontecer, use --skeleton e --root @ref para focar apenas na sub-região necessária.
5. Vazamento acidental de dados privados em logs e traces
Quando vale a pena usar (e quando evitar)
O agent-desktop muda a equação de custo e confiabilidade para agentes que precisam sair do terminal e interagir com softwares gráficos, mas ele depende diretamente da qualidade da árvore de acessibilidade exposta pelos aplicativos.
| Critério | Abordagem via agent-desktop (Árvore de Acessibilidade) | Abordagem tradicional via Captura de Tela (Visão / Pixels) |
|---|---|---|
| Consumo de tokens (ex.: Apple Maps) | 273 tokens por leitura (usando esqueleto + drill down) vs. 3.811 na janela cheia | Elevado (exige envio constante de imagens inteiras a cada etapa) |
| Consumo em tarefa longa (52 passos) | 31 mil tokens (simulação divulgada pelo criador do projeto) | 198 mil tokens na leitura completa sem filtragem estrutural |
| Precisão de clique | Determinística via referência (@s8f3k2p9:e1); falha de forma segura com STALE_REF se a UI mudar | Probabilística; sujeita a erros de coordenada se a janela mover ou redimensionar |
| Interferência no uso humano | Headless por padrão (não move o cursor físico nem rouba o foco da janela) | Move o mouse físico e exige que a janela esteja visível em primeiro plano |
| Dependência de modelo remoto | Nenhuma na CLI nativa (o uso de modelo de visão é restrito ao helper opcional JEV do repositório) | Obrigatória (depende de um LLM multimodal capaz de estimar coordenadas em imagens) |
Quando vale a pena:
- Automação de aplicativos nativos e corporativos bem estruturados: Ferramentas no macOS, Windows e Linux que implementam corretamente as APIs nativas (Accessibility API, UI Automation e AT-SPI), como gerenciadores de arquivos, navegadores, clientes de e-mail, editores e aplicativos de produtividade.
- Agentes rodando em segundo plano na máquina do desenvolvedor: Como as ações via referência são headless por padrão, é a escolha ideal para assistentes de código (como Claude Code, Cursor ou agentes customizados) que precisam inspecionar ou operar um app auxiliar sem sequestrar o seu mouse.
- Fluxos longos com orçamento restrito de tokens e latência: Se o seu agente executa dezenas de passos repetitivos, trocar imagens ou árvores inteiras por snapshots de esqueleto (
--skeletone--root) reduz drasticamente a conta da API e o tempo de resposta. - Integração direta em linguagens compiladas ou scripts via FFI: Quando você precisa embutir controle de desktop dentro de uma aplicação em Python, Go, Rust ou Swift carregando a biblioteca C-ABI uma única vez na memória.
Quando não vale a pena:
- Jogos, canvas customizados (OpenGL/WebGL) ou apps sem suporte a acessibilidade: Se um software desenha toda a sua interface diretamente em um canvas gráfico e não expõe papéis semânticos (
button,textfield, etc.) para leitores de tela do sistema operacional, a árvore de acessibilidade estará vazia ou incompleta. Nesses casos, o comando de captura de tela separado (ou o helper opcional JEV presente no repositório) ainda será necessário. - Ambientes onde o usuário não pode conceder permissões de acessibilidade: Em máquinas travadas por políticas de TI onde o binário não consegue obter
"state": "granted"na permissão de acessibilidade do sistema operacional, a ferramenta não conseguirá ler a árvore das janelas.
Perguntas frequentes
O agent-desktop precisa de um modelo de visão ou de chave de API da OpenAI/Anthropic para rodar?
Não. O binário nativo do agent-desktop roda 100% localmente, não exige nenhum serviço de modelo remoto e apenas traduz a árvore de acessibilidade do sistema operacional em JSON estruturado (e executa ações de volta). Existe um utilitário opcional exclusivo do repositório chamado JEV helper que envia descrições de tela para um provedor de modelo, mas a CLI principal é totalmente independente de provedores de IA.
Qual a diferença entre usar a CLI via subprocesso e usar a biblioteca C-ABI (FFI)?
A CLI nativa em Rust já é rápida e não possui dependências de runtime (desde que o script de postinstall tenha substituído o lançador do Node.js). Porém, se o seu agente for escrito em Python, Swift, Go, Ruby, Node, C ou C++ e fizer centenas de chamadas por minuto, carregar a biblioteca dinâmica (libagent_desktop_ffi.dylib, .so ou agent_desktop_ffi.dll) via FFI permite invocar as funções dentro do mesmo processo, eliminando totalmente o custo de criação de novos processos (forking) no sistema operacional.
Como saber quais recursos da árvore de acessibilidade funcionam no meu sistema operacional?
Como as APIs subjacentes diferem entre macOS (Accessibility API), Windows (UI Automation) e Linux (AT-SPI), o suporte a certas superfícies e ações pode variar. Em vez de procurar em documentações externas que podem ficar desatualizadas, execute agent-desktop skills get platform e agent-desktop status diretamente no seu terminal: o próprio binário imprimirá a tabela exata de capacidades e superfícies suportadas no sistema operacional em que está rodando.

