agent-desktop: computer use для ИИ-агентов через accessibility tree

· 6 мин чтения
ai-agents computer-use desktop-automation accessibility cli
📂 Исходный код на GitHub

Computer use для ИИ-агентов: CLI и C-библиотека, через которые агент читает и управляет десктопными приложениями на macOS, Windows и Linux через accessibility tree операционной системы.

agent-desktop: computer use для ИИ-агентов через accessibility tree

agent-desktop — проект Vercel Labs для computer use: ИИ-агент читает и управляет десктопными приложениями на macOS, Windows и Linux. Основной канал — accessibility tree, дерево специальных возможностей операционной системы. Агент не всматривается в скриншоты: элементы интерфейса приходят ему структурированным JSON-списком. Проект распространяется как CLI-утилита и C-библиотека под лицензией Apache-2.0.

Зачем accessibility tree вместо пикселей

Классический подход computer use устроен так: скриншот, модель ищет глазами, где кнопка, клик по координатам. Это медленно и ненадёжно. Меняется масштаб, тема или разрешение — координаты плывут.

agent-desktop идёт другим путём. Команда snapshot снимает дерево специальных возможностей и возвращает JSON, где у каждого интерактивного элемента есть роль, название и ref — короткая ссылка вида @s8f3k2p9:e8. Агент действует по ref и снимает новый снапшот, чтобы проверить результат. Никакого сопоставления пикселей. Цикл «наблюдай — действуй — проверяй» остаётся внутри вашего агента: инструмент не решает за него, а только даёт глаза и руки.

Каждый вызов CLI работает в отдельном процессе. Даже в headless-режиме запрещены захват фокуса и синтезированный физический ввод — так инструмент не мешает человеку за тем же компьютером.

Установка и разрешения

Пакет ставится через npm:

npm install -g agent-desktop
agent-desktop version

Bun, Yarn и pnpm тоже подходят. Внутри пакета — нативные бинарники и платформенные хелперы для x64 и ARM64. Если нужен запуск без JavaScript-лаунчера, скачайте нативный архив со страницы GitHub Releases и положите хелпер рядом с исполняемым файлом. Официальные пакеты Homebrew и Scoop готовятся, но в каталогах их пока нет.

Разрешения зависят от операционной системы:

  • macOS нужен доступ к Accessibility: мастер проведёт через настройку по команде agent-desktop permissions --guide.
  • Windows ничего дополнительного не требует для приложений того же уровня целостности (integrity level), что и ваш терминал.
  • Linux нужна графическая сессия пользователя и сервис at-spi2-core.

Подробности про пакетные менеджеры, архивы релизов и сборку из исходников — в docs/install.md.

Быстрый старт

Три шага: снапшот, действие по ref, контрольный снапшот.

agent-desktop snapshot --app Finder -i      # интерактивные элементы, у каждого ref
agent-desktop click @s8f3k2p9:e8            # действие по ref из снапшота
agent-desktop snapshot --app Finder -i      # снова смотрим, что изменилось

Каждая команда печатает один JSON-конверт (envelope):

{
  "ok": true,
  "command": "snapshot",
  "data": {
    "app": "Finder",
    "window": { "id": "w-204749", "title": "Downloads" },
    "snapshot_id": "s8f3k2p9",
    "ref_count": 59,
    "complete": true,
    "tree": {
      "role": "window",
      "name": "Downloads",
      "children": [
        { "role": "treeitem", "name": "Documents", "ref_id": "@s8f3k2p9:e8", "available_actions": ["Click"] }
      ]
    }
  }
}

Дерево может быть глубоким, поэтому у snapshot есть режимы от простого к детальному. Сначала карта интерфейса без мелочей: snapshot --skeleton --app Slack -i --compact. Затем один нужный регион целиком: snapshot --root @s8f3k2p9:e3 -i --compact.

Refs и обработка ошибок

Refs живут внутри своего снапшота. Сокращение вроде @e8 без префикса вернёт ошибку INVALID_ARGS. Когда интерфейс изменился, действие вернёт STALE_REF или AMBIGUOUS_TARGET — агент просто снимает новый снапшот и работает с его refs.

Если открыто несколько окон одного приложения, вернётся AMBIGUOUS_TARGET. Список окон-кандидатов лежит в error.details, конкретное окно передают флагом --window-id.

Контракт ошибок строгий. Каждый конверт содержит ok и дальше либо data, либо error с кодом (code), распоряжением (disposition) и обычно подсказкой (suggestion). Повторять попытку можно только когда error.disposition.retry равен safe. Полный разбор конверта, кодов ошибок и кодов выхода — в docs/json-output.md.

По умолчанию инструмент работает headless: действия идут через accessibility API без перемещения курсора и захвата фокуса. Физический ввод с настоящей мышью и клавиатурой включает глобальный флаг --headed. Нюанс для Windows-терминалов: в PowerShell все refs берут в кавычки ('@s8f3k2p9:e8'), потому что @ без кавычек — оператор splatting.

Документация живёт внутри бинарника

Инструмент несёт собственные инструкции, выверенные под свою версию:

agent-desktop skills get desktop      # цикл, refs, правила проверки и повторов
agent-desktop skills get platform     # отличия конкретной ОС
agent-desktop <command> --help        # флаги одной команды

Тексты версионируются вместе с бинарником, поэтому агент всегда читает документацию именно своей версии. Скилл ставится в любой harness одним вызовом через skills.sh:

npx skills add https://github.com/vercel-labs/agent-desktop --skill agent-desktop

Или добавьте абзац в AGENTS.md:

Use `agent-desktop` to see and operate desktop apps. Before the first use, run
`agent-desktop skills get desktop` and `agent-desktop skills get platform`, and follow them.

Команды

В CLI заявлено 60 имён команд, из них 56 рабочих. Четыре — key-down, key-up, mouse-down, mouse-up — отказываются запускаться, пока в проекте нет демона, умеющего отпустить зажатую клавишу или кнопку. Остальные сгруппированы так:

  • Наблюдение: snapshot, find, get, is, screenshot, list-surfaces
  • Действия по ref: click, double-click, right-click, type, set-value, clear, focus, select, toggle, check, expand, collapse, scroll, scroll-to
  • Клавиатура и мышь: press, hover, drag, mouse-move, mouse-click, mouse-wheel
  • Приложения и окна: launch, close-app, list-apps, list-windows, list-displays, focus-window, resize-window, move-window, minimize, maximize, restore
  • Уведомления: list-notifications, dismiss-notification, dismiss-all-notifications, notification-action
  • Буфер обмена: clipboard-get, clipboard-set, clipboard-clear
  • Ожидание и сессии: wait, session, trace, cursor-overlay
  • Система: status, permissions, version, batch, skills

Отдельно стоит open-system-surface: на macOS он открывает Dock и элементы меню-бара, на GNOME — трей и центр действий.

Поддержка платформ

Возможность macOS Windows Linux
Accessibility tree Да Да Да (AT-SPI)
Клик, ввод текста, клавиатура Да Да AT-SPI; клавиши X11 / GNOME
Ввод мышью Да Да X11, режим --headed
Скриншот Да Да Окна X11; Wayland через портал
Буфер обмена Да Да Да; на Wayland нужен wl-clipboard
Управление приложениями и окнами Да Да Запуск и список; контроль окон X11
Уведомления Да Да GNOME Shell

Точная таблица возможностей для вашей ОС печатается командой agent-desktop skills get platform.

FFI: вызовы без запуска процессов

CLI удобен для агентов, но каждая команда запускает отдельный процесс. Для встраивания каждый релиз содержит C-библиотеку libagent_desktop_ffi для всех трёх платформ: программа вызывает инструмент в своём процессе. Правила входных точек, владения памятью и работы с потоками описаны в agent-desktop skills get ffi. Минимальный пример на Python через ctypes:

import ctypes

lib = ctypes.CDLL("./lib/libagent_desktop_ffi.dylib")
lib.ad_adapter_create.restype = ctypes.c_void_p
lib.ad_adapter_destroy.argtypes = [ctypes.c_void_p]
assert lib.ad_init(7) == 0
adapter = lib.ad_adapter_create()
lib.ad_adapter_destroy(adapter)

Приватность

Снапшоты, чтение буфера обмена, скриншоты, вывод команд и артефакты отладки могут содержать приватное содержимое рабочего стола. Такие данные не стоит отправлять в публичные логи и внешние загрузки. Отдельный нюанс: опциональный JEV-хелпер отправляет текстовые описания экрана в настроенный модельный провайдер — это независимая надстройка, а не часть нативного CLI. Полный разбор — в разделе про приватность в docs/faq.md.

Словарь проекта — refs, снапшоты, сессии — собран в CONCEPTS.md. Если собираетесь встроить agent-desktop в свой агент, начните с него, а дальше пусть агент сам прочитает agent-desktop skills get desktop.

Источник: https://github.com/vercel-labs/agent-desktop