- Регистрация
- 24.12.2024
- Сообщения
- 56
- Благодарностей
- 117
- Баллы
- 33
Конкурсная статья · ZennoPoster Forum · 2026
ГИБРИДНЫЕ ИИ-АГЕНТЫ:
Как связать Web, ZennoPoster и ZennoDroid
в единую интеллектуальную сеть
Теги: ZennoDroid • LLM Integration • DOM Parsing • Self-Healing • AI Agent • Android Automation
ГИБРИДНЫЕ ИИ-АГЕНТЫ:
Как связать Web, ZennoPoster и ZennoDroid
в единую интеллектуальную сеть
Теги: ZennoDroid • LLM Integration • DOM Parsing • Self-Healing • AI Agent • Android Automation
01. Вступление: что не так со старым подходом
Те, кто давно работает с ZennoDroid, знают эту боль наизусть.
Вы потратили три часа на точную настройку скрипта. Разметили все координаты, добавили поиск по картинке для каждой кнопки, расставили if-else на каждый возможный попап. Скрипт работает идеально. И тут приложение выходит с обновлением — едва заметным редизайном. Кнопка «Войти» съехала на 40 пикселей вниз. Или поменяла цвет.
Скрипт падает. Начинаем сначала.
Я прошёл через это много раз и пришёл к принципиально другому решению. Что если вместо того, чтобы точно описывать ГДЕ находится кнопка, — просто сказать агенту ЧТО нужно сделать, и дать ему самому разобраться?
| Ключевая идея Мы больше не пишем «кликни по кнопке входа на координатах (800, 860)». Мы пишем «войди в приложение» — и система сама находит кнопку, нажимает, проверяет результат и при необходимости повторяет с новыми координатами. |
02. Архитектура: три слоя, одна система
Система строится по схеме: Web → ZennoPoster → ZennoDroid. Каждый уровень занимается только своим делом и общается с соседними через простые форматы — JSON-файлы и переменные.
Web / Scripts | ZennoPoster | ZennoDroid |
Управление · Цели task.txt | Мозговой центр · LLM action_chain.json | Исполнитель · Android DOM → tap |
Роль каждого уровня
- Web / Scripts — единый интерфейс управления. Формирует задачи в task.txt, запускает циклы, собирает результаты. Управляете десятками устройств из одного окна.
- ZennoPoster — мозговой центр. Читает задачу, обращается к LLM, разбивает цель на пошаговый JSON-план (action_chain.json), управляет очередью задач.
- ZennoDroid — физический исполнитель. Цикл: DOM → выполнить шаг → верификация → при ошибке Coord Refresh → продолжить.
03. Глаза агента: DOM-парсер
Главное отличие от классической автоматизации: мы не ищем картинку «кнопки Войти» на скриншоте. Мы извлекаем полное XML-дерево текущего экрана Android и преобразуем его в компактный JSON, понятный LLM.
Каждый интерактивный элемент получает: тег, текстовый label, координаты центра (cx/cy), resource-id и флаги кликабельности/фокусируемости.
Пример вывода DOM-парсера (AiDroidForAI):
JSON:
// Что получает LLM о текущем экране
{
"elements": [
{ "tag": "EditText", "label": "Телефон или email",
"cx": 540, "cy": 620, "id": 42,
"focusable": true, "clickable": false },
{ "tag": "EditText", "label": "Пароль",
"cx": 540, "cy": 720, "id": 43,
"focusable": true, "clickable": false },
{ "tag": "Button", "label": "Войти",
"cx": 540, "cy": 860, "id": 74,
"clickable": true }
]
}
| Почему это надёжнее скриншотов XML-дерево содержит СЕМАНТИКУ, а не пиксели. Кнопка «Войти» — это всегда label="Войти" независимо от темы, масштаба экрана, DPI или редизайна. LLM находит её по названию, а координаты — просто числа для тапа. |
04. Мозг системы: LCM Prompt Builder
Когда DOM собран, формируется промпт для LLM. LCM (Logic Control Module) принимает задачу из task.txt, текущее состояние экрана и контекст предыдущих действий из context_store.json.
Ключевой принцип: ИИ не имеет права придумывать координаты. Все x/y должны браться строго из переданного списка DOM-элементов. Это исключает галлюцинации координат.
Ответ LLM — action_chain.json:
JSON:
{
"task_summary": "Войти в приложение с логином и паролем",
"confidence": "high",
"total_steps": 3,
"steps": [
{ "step_num": 1, "action": "INPUT",
"label": "Телефон или email",
"x": 540, "y": 620, "value": "user@example.com" },
{ "step_num": 2, "action": "INPUT",
"label": "Пароль",
"x": 540, "y": 720, "value": "mypassword123" },
{ "step_num": 3, "action": "CLICK",
"label": "Войти",
"x": 540, "y": 860, "wait_sec": 2 }
]
}
| Действие | Описание |
| CLICK | Тап по кликабельному элементу. Координаты строго из cx/cy DOM-парсера. |
| INPUT | Фокус + ввод текста. Поле value обязательно. CLICK перед INPUT не нужен. |
| SCROLL | Прокрутка в заданном направлении на scroll_px пикселей. |
| NAVIGATE | Переход в приложение по package name или открытие URL. x=0, y=0. |
| WAIT | Ожидание загрузки. AUTO-OK — верификация не нужна, токены экономятся. |
05. Главная магия: верификатор и самовосстановление
После каждого выполненного шага система переходит в режим рефлексии. Делается снимок DOM до и после действия, и LLM-верификатор анализирует изменения.
Рабочий цикл ZennoDroid:
Собрать DOM → AiDroidForAI |
LCM Prompt Builder → LLM → action_chain.json |
Chain Initializer → next_action.txt (шаг 1) |
Выполнить действие (CLICK / INPUT / SCROLL ...) |
Собрать DOM after → сравнить с DOM before |
Verifier Prompt Builder → LLM → verify_result.txt |
Вердикты верификатора:
| Вердикт | Реакция системы | Детали |
| ✓ OK | Следующий шаг | DOM изменился в соответствии с целью. Продолжаем цепочку. |
WAIT | Ждём N сек | Идёт загрузка. Повторяем верификацию через wait_sec секунд. |
| ↺ RETRY | Coord Refresh | DOM не изменился или элемент сместился. Запрашиваем новые x/y. |
| ✕ ERROR | Новый LCM цикл | Критическая ошибка. Перепланирование с новым task.txt. |
| Экономия токенов — трёхуровневая оптимизация WAIT / SCROLL / NAVIGATE → AUTO-OK, LLM не вызывается. | INPUT → проверяем DOM Change Level (≥1 = OK, иначе RETRY). | CLICK при DOM level=0 → FAST RETRY без LLM, сразу Coord Refresh. | CLICK при DOM level≥1 → полный LLM-анализ before/after. |
06. Coord Refresh: система не падает
Если верификатор вернул RETRY — включается Refresh System. Это ключевой механизм устойчивости всей архитектуры.
Принцип работы:
- Формируется промпт с оставшимися шагами цепочки и текущим DOM
- LLM получает запрос: найти те же элементы и вернуть свежие x/y
- Refresh Handler патчит ТОЛЬКО координаты в action_chain.json
- action / label / value / submit_enter — не трогаем! Глобальный план сохранён
| Приоритет | Метод |
1 (лучший) | Координаты от AI по step_num — наиболее точное совпадение |
2 | Координаты от AI по label элемента |
3 | DOM fallback — точное совпадение label в текущем XML-дереве |
4 (запасной) | DOM fallback — частичное совпадение label (Contains) |
07. Task Chain Planner: многоэкранные сценарии
Для задач, охватывающих несколько приложений или экранов, используется Task Chain Planner. Он принимает высокоуровневую цель и разбивает её на группы по принципу «один экран = одна группа».
Пример: «Открыть Chrome и найти свежие новости»
| # Результат разбивки на группы: task_chain/ task_01.txt ← Launcher: Click Tools → NAVIGATE com.android.chrome task_02.txt ← Chrome: type 'fresh news' in address bar → search task_plan.json ← полный план для справки # Каждый task_NN.txt = готовый промпт для LCM # Запускаются последовательно после завершения каждой группы |
| Правило разбивки Действия принадлежат одной группе, если они происходят в одном контексте экрана. Новая группа начинается только когда переход на новый экран завершён — следующие действия уже внутри нового контекста. Так Click на папку и NAVIGATE к Chrome — это одна группа (лончер), а ввод поиска в Chrome — уже другая группа. |
08. Масштабирование: ферма, а не один телефон
Вся система изначально спроектирована под жёсткий многопоток. ZennoPoster выступает диспетчером задач для всей фермы устройств.
Принцип работы:
- Список задач хранится в tasks_all.txt — по одной задаче на строку
- ZP раздаёт задачи потокам при старте или завершении предыдущей
- Каждый поток работает с отдельным ZennoDroid-устройством
- Файлы именуются по ID потока — конкурентный доступ исключён
- При ошибке поток получает следующую задачу из очереди
- Добавить устройство = добавить поток. Код не меняется.
| Важное замечание Система не привязана к конкретным приложениям. Один и тот же агент может работать с любым Android-приложением — Instagram, Telegram, банковским клиентом или корпоративным ПО. Достаточно изменить task.txt. |
09. Сравнение подходов
| Критерий | Классический подход | ИИ-агент (данный проект) |
| Привязка к UI | Хардкод / поиск по картинке | ✓ Динамично по DOM-дереву |
| Смена дизайна приложения | Скрипт падает, нужен патч | ✓ Coord Refresh находит элемент |
| Добавить новый сценарий | Новые кубики и координаты | ✓ Написать task.txt и запустить |
| Всплывающие окна / попапы | Десятки if-else | ✓ Агент видит попап в DOM |
| Масштабирование фермы | Дублирование шаблонов | ✓ Один шаблон, N потоков |
| Любое Android-приложение | Требует переработки | ✓ Работает с любым приложением |
| Порог вхождения | Низкий (знаешь ZP — сделаешь) | Средний (нужен LLM API) |
10. Файловая архитектура проекта
| project_dir/ ├── task.txt ← текущая задача (от Web/ZP) ├── tasks_all.txt ← очередь всех задач (для фермы) ├── action_chain.json ← план шагов от LLM ├── next_action.txt ← следующий шаг для выполнения ├── step_status.txt ← статус текущего шага ├── verify_result.txt ← результат верификации ├── lcm_ai_module_before ← DOM до действия ├── lcm_ai_module_after ← DOM после действия ├── context_store.json ← сохранённый контекст (данные) ├── task_refresh.txt ← промпт для Coord Refresh ├── goal.txt ← высокоуровневая цель └── task_chain/ ├── task_01.txt ← задача для экрана 1 ├── task_02.txt ← задача для экрана 2 └── task_plan.json ← полный план по экранам |
Заключение
Мы рассмотрели полноценную кросс-платформенную систему, в которой три уровня — управляющий веб-интерфейс, мозговой центр ZennoPoster и мобильный исполнитель ZennoDroid — работают как единый организм.
Что получаем в итоге:
- Ноль захардкоженных координат — агент всегда работает с актуальным DOM
- Самовосстановление при изменении UI — Coord Refresh System подхватывает
- Один промпт покрывает любое приложение — не нужно переписывать логику
- Масштабируется горизонтально — добавляй устройства, не правь код
- Экономия токенов: AUTO-OK для WAIT/SCROLL, FAST RETRY при DOM level=0
- Понятный аудит: весь план в JSON, каждый шаг верифицирован и залогирован
Это уже не автоматизация. Это автономные цифровые сотрудники. Мы дали агенту глаза (DOM-парсер) и мозг (LLM). Теперь он сам ориентируется в мобильной среде, сам восстанавливается при ошибках и сам выполняет работу от начала до конца. |
Если понравилась статья — задавайте вопросы в комментариях. Готов разобрать любую часть подробнее.
Вложения
-
122,5 КБ Просмотры: 2
-
323,8 КБ Просмотры: 14
-
267,2 КБ Просмотры: 14
Последнее редактирование:



WAIT