ZennoPoster AI Fallback Helper - Одношаговые AI-команды для резервной автоматизации

MelD

Client
Регистрация
10.10.2019
Сообщения
2
Благодарностей
3
Баллы
3
141166





Этот проект появился из-за периодической необходимости отслеживать некрупные изменения на сайтах, вроде переименования элементов или их небольшого изменения. При этом для такой задачи использовать полноценный ИИ-агент кажется избыточным, ведь нужно решить одну конкретную задачу - найти элемент на странице. А далее уже либо получить обновленный селектор и использовать его, либо просто нажать конкретную кнопку на основании скриншота.

Zennoposter AI Fallback Helper — это небольшая библиотека одношаговых AI-действий для ZennoPoster. Каждый метод решает свою задачу самостоятельно: собирает данные из браузера, при необходимости выполняет несколько попыток (например, прокручивая страницу для захвата нужной области), отправляет запрос к API и возвращает результат. Никакой внешней оркестрации не требуется. А так же не требуется каких-то дорогих моделей, при работе с текстом большинстве случаев справляются даже локальные модели. При желании можно самостоятельно дополнять библиотеку своими действиями.

Задачи, которые решаются на данный момент:

  • Найти XPath элемента по его текстовому описанию — без написания селектора вручную, ответ можно использовать далее в программе для какого-либо действия уже с помощью самого Zennoposter.
  • Кликнуть по элементу, который модель находит визуально по скриншоту исходя из текстового описания - на случай если структура страницы поменялась, но мы знаем какую кнопку все таки нужно нажимать.

Оба метода работают через единый интерфейс провайдера — можно использовать OpenAI, DeepSeek, локальную модель через LM Studio или любой OpenAI-совместимый эндпоинт.

Если технические детали не интересны — листайте сразу к разделу 4 с примерами использования или к разделу 5 для работы через плагин.



Содержание

  1. Архитектура: одношаговый подход и провайдеры
  2. Описание методов: FindXPath и ClickByView
  3. Конфигурация: AiActionConfig
  4. Примеры использования в C# коде
  5. Использование как плагин ZennoPoster



1. Архитектура: одношаговый подход и провайдеры

Главное архитектурное решение — один вызов — одна задача. Каждый публичный метод класса AiActions решает свою задачу самостоятельно — при необходимости выполняя несколько внутренних запросов к API: например, при поиске XPath модель может получить несколько попыток с историей предыдущих ошибок, а при ClickByView с включённой прокруткой — отдельный запрос на каждую позицию страницы. Но всё это происходит внутри одного вызова метода, прозрачно для вызывающего кода.

  1. Собирает данные из браузера (HTML страницы или скриншот)
  2. При необходимости выполняет внутренние итерации — например, прокрутку страницы для захвата нужной области скриншота
  3. Формирует запрос к API и получает ответ
  4. Разбирает ответ и возвращает результат или выбрасывает исключение

Метод либо вернул результат — либо упал с исключением. Промежуточных состояний нет.

Связь с API реализована через интерфейс IActionApiProvider. Это позволяет менять провайдера не затрагивая логику методов:

ПровайдерЭндпоинтОсобенности
ResponsesApiProvider/v1/responsesИспользуется по умолчанию. Читает ответ из output[].content[type=output_text]. Поддерживает flex service tier
CompletionsApiProvider/v1/chat/completionsУниверсальный. Читает ответ из choices[0].message.content. Совместим с DeepSeek, Mistral, LM Studio, Ollama



2. Описание методов: FindXPath и ClickByView

FindXPath

Находит XPath элемента по его текстовому описанию. Алгоритм работы:

  1. Забирает HTML активной вкладки и очищает его согласно XPathHtmlClean
  2. Опционально делает скриншот как дополнительный контекст (при XPathIncludeScreenshot = true)
  3. Отправляет HTML и описание элемента модели, извлекает XPath из тега <xpath>...</xpath> в ответе
  4. Проверяет найденный XPath на живой странице через FindElementByXPath
  5. Если элемент не найден — передаёт модели описание ошибки и повторяет, до XPathMaxAttempts раз

C#:
string xpath = aiActions.FindXPath("кнопка отправки формы регистрации");
// Вернёт, например: //button[@type='submit'] или //input[@value='Зарегистрироваться']
Поскольку задача сводится к анализу текста, здесь достаточно текстовых моделей — в том числе недорогих и локальных. Качество зависит в первую очередь от точности описания элемента и чистоты HTML.

ClickByView

Кликает по элементу, определяя его координаты визуально по скриншоту. Алгоритм работы:

  1. При SendFullPageScreenshot = true — делает снимок всей страницы целиком и отправляет его модели. Модель видит всю страницу сразу и возвращает координаты элемента
  2. В обычном режиме — прокручивает страницу к накопленной позиции через window.scrollTo, делает скриншот видимой области, отправляет модели
  3. Модель отвечает одним из трёх вариантов: координаты <x>N</x><y>N</y>, SCROLL (нужна прокрутка) или ERROR (элемент не найден)
  4. При SCROLL и включённом ClickScrollEnabled — увеличивает позицию прокрутки и повторяет
  5. При получении координат — пересчитывает их в экранные с учётом масштаба и смещения, эмулирует движение мыши и клик

C#:
aiActions.ClickByView("синяя кнопка «Продолжить» в правом нижнем углу");
Важно про координаты и скроллинг

ZennoPoster работает с абсолютными координатами в пределах вьюпорта профиля. При прокрутке страницы вьюпорт смещается визуально, но система координат ZennoPoster остаётся неизменной. Кроме того, каждый вызов скриншота сбрасывает прокрутку страницы в самое начало — поэтому итеративный подход с прокруткой и повторным скриншотом требует точного восстановления позиции перед кликом, что реализовано через window.scrollTo с накоплением смещения в переменной.

По этой причине рекомендуется отправлять полный скриншот страницы целиком (SendFullPageScreenshot = true) — тогда модель видит всю страницу сразу и определяет координаты без какой-либо прокрутки.


Про выбор модели для работы с изображениями

МетодТип задачиТребования к модели
FindXPathАнализ текста (HTML)Справляются недорогие и локальные модели
ClickByViewАнализ изображенияТребует модели с поддержкой vision-модели — дешёвые и локальные модели часто ошибаются

Дешёвые модели и большинство локальных плохо справляются с обработкой изображений: они могут неверно определить координаты, перепутать похожие элементы или вернуть некорректный ответ. Чем сложнее страница визуально — тем выше вероятность ошибки. Для ClickByView рекомендуется использовать gpt-5.4 так как он показывает себя наиболее точным в распозавании изображений когда нужно находить элементы интерфейса, хотя в целом более слабые модели тоже могут справляться, важно только чтобы контекстного окна хватало для загрузки изображения.
Документация OpenAI рекомендует использовать режим original для задач управления интерфейсом — в этом режиме точность распознавания координат наиболее высокая.

В программу намеренно добавлена возможность сжатия изображения (MaxImageDimension) до нужных размеров (по наибольшей стороне) и отправки только видимой области экрана пользователя — чтобы уменьшить размер передаваемого файла для моделей с ограниченным контекстом. Однако это компромисс: меньший размер изображения снижает точность распознавания. Даже при использовании этих параметров 100% качества не гарантируется.

Практический совет: для ClickByView используйте gpt-5.4 с ImageDetail = "original" и SendFullPageScreenshot = true. Экономия на модели здесь обходится дороже, чем экономия на токенах.


Очистка HTML: HtmlCleanLevel

При работе с реальными сайтами HTML-страница может занимать сотни килобайт — большую часть из которых составляют <script>, <style>, SVG-иконки и инлайновые обработчики событий. Для задачи поиска XPath весь этот мусор бесполезен и только увеличивает расход токенов.

Параметр XPathHtmlClean управляет тем, что именно передаётся модели при вызове FindXPath. Очистка применяется последовательно — каждый следующий уровень включает предыдущий:

УровеньЧто удаляетсяКогда использовать
Minimal<script>, <style>, HTML-комментарииСтраницы где важен SVG, meta или link — например, иконки с aria-label
StandardВсё из Minimal + <noscript>, <link>, лишние пробелы и пустые строкиПо умолчанию, подходит для большинства задач
AggressiveВсё из Standard + <svg>, <meta>, inline-атрибуты style="" и обработчики onclick=""Тяжёлые страницы, простые формы и листинги, экономия токенов

Системные промпты

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

FindXPath — модель получает роль эксперта по XPath и жёсткое требование к формату ответа:

Код:
XPath expert. Return XPath for the requested element.
Reply ONLY: <xpath>//expression</xpath>
Prefer @id/@name/@data-* or text. No indexes unless unavoidable. No explanation.
- XPath MUST be on a single line
- No explanations
- Always wrap in <xpath>...</xpath>
- Avoid complex functions unless necessary
Приоритеты выбора XPath заданы явно: сначала стабильные атрибуты (@id, [USER=98307]@Name[/USER], @data-*), затем текстовое содержимое, индексы — только если других вариантов нет. Это снижает вероятность получить хрупкий XPath вида //div[3]/span[2]/button[1], который сломается при малейшем изменении вёрстки.

ClickByView — модель получает три строго определённых варианта ответа, без каких-либо других возможностей:

Код:
Browser automation. Find the element on the screenshot and reply with EXACTLY ONE of:

1. Coordinates (element visible):    <x>N</x><y>N</y>
2. Need to scroll (not visible yet): SCROLL
3. Cannot find (black/broken page):  ERROR: reason

Rules:
- Coordinates = pixel center of the element, integers only.
- Use SCROLL if the element is likely below/above the current view.
- Use ERROR only if the page is clearly broken, black, or element cannot exist.
- No extra text, no markdown.
Три варианта ответа покрывают все возможные ситуации: элемент виден — возвращаем координаты, элемент за пределами вьюпорта — запрашиваем прокрутку, страница явно сломана или пуста — сообщаем об ошибке. ERROR намеренно ограничен крайними случаями: битая страница, чёрный экран, элемент заведомо не может существовать — чтобы модель не злоупотребляла им при малейших затруднениях.

Поскольку модели иногда отвечают не в точном формате, парсер координат поддерживает несколько вариантов записи по убыванию специфичности: <x>N</x><y>N</y>x=N, y=NNxMN,N. Аналогично для XPath: сначала ищется тег <xpath>...</xpath>, затем любое выражение начинающееся с / или .//.

3. Конфигурация: AiActionConfig

C#:
var config = new AiActionConfig
{
    // --- Подключение к API ---
    ApiKey    = "sk-...",        // Bearer-токен. Обязательное поле
    Model     = "gpt-5.4",      // Название модели. Обязательное поле
    Proxy     = "host:port",    // Прокси. Пустая строка — без прокси
    Provider  = new CompletionsApiProvider(
                    "https://api.deepseek.com/v1/chat/completions"
                ),               // По умолчанию ResponsesApiProvider
    TimeoutMs = 120_000,         // Таймаут HTTP-запроса в мс
    FlexMode  = false,           // service_tier=flex — дешевле, но медленнее, подробнее можно почитать на сайте самого OpenAI

    // --- Скриншоты ---
    // Рекомендуется: ImageDetail="original", SendFullPageScreenshot=true
    ScreenshotQuality      = 70,         // Качество JPEG 0–100
    ImageDetail            = "original", // "low" / "high" / "original"
    SendFullPageScreenshot = true,       // Снимать всю страницу — рекомендуется для ClickByView
    MaxImageDimension      = 0,          // Макс. сторона изображения. 0 = без лимита

    // --- FindXPath ---
    XPathMaxAttempts       = 3, // количество попыток поиска
    XPathIncludeScreenshot = false, // нужно ли отправлять рядом еще и скриншот для лучшего понимания моделью
    XPathHtmlMaxLength     = 12_000, // ограничние на количество символов, чтобы случайно большое количество токенов не потратилось на какой-то странице
    XPathHtmlClean         = HtmlCleanLevel.Standard, //описание вариантов есть выше в статье

    // --- ClickByView (прокрутка) ---
    // Предпочтительнее SendFullPageScreenshot=true без прокрутки.
    ClickScrollEnabled     = false,
    ClickScrollStep        = 0,
    ClickScrollMaxAttempts = 5,
};

Дополнительно параметр XPathHtmlMaxLength обрезает HTML до заданного числа символов уже после очистки. Значение -1 — без ограничения.


4. Примеры использования в C# коде
Здесь я приведу только небольшие примеры того как это работает, сам код проекта находится в прикрепленныш шаблонах, в общем коде и вы можете его самостоятельно посмотреть, он сопровождем комментариями, не стал добавлять сюда, чтобы не увеличивать сильно размеры статьи.

Важно: Так как в текущем виде весь код находится в отдельном namespace, для того чтобы можно было его вызвать в вашем проекте после копирования этого кода, нужно так же добавить using ZennoposterAiAgentCore; в "Директивы Using"​

C#:
var config = new AiActionConfig
{
    ApiKey = project.Variables["api_key"].Value,
    Model  = "gpt-5.4",
};

var ai = new AiActions(project, instance, config);

// Найти XPath кнопки по описанию и кликнуть через ZennoPoster
string xpath = ai.FindXPath("кнопка подтверждения заказа");
instance.ActiveTab.FindDomElement(xpath).Click("left", "click");

// Или кликнуть напрямую по визуальному расположению
ai.ClickByView("кнопка подтверждения заказа");

C#:
var config = new AiActionConfig
{
    ApiKey                 = project.Variables["api_key"].Value,
    Model                  = "gpt-5.4",
    ImageDetail            = "original",
    SendFullPageScreenshot = true,
    ScreenshotQuality      = 80,
};

var ai = new AiActions(project, instance, config);
ai.ClickByView("кнопка «Оформить заказ» в блоке итоговой суммы");

C#:
var config = new AiActionConfig
{
    ApiKey             = "",
    Model              = "qwen/qwen3.5-9b",
    Provider           = new CompletionsApiProvider(
                             "http://localhost:1234/v1/chat/completions"),
    XPathHtmlClean     = HtmlCleanLevel.Aggressive,
    XPathHtmlMaxLength = 5000,
};

var ai    = new AiActions(project, instance, config);
string xpath = ai.FindXPath("поле ввода email в форме регистрации");

C#:
var config = new AiActionConfig
{
    ApiKey   = project.Variables["deepseek_key"].Value,
    Model    = "deepseek-chat",
    Provider = new CompletionsApiProvider(
                   "https://api.deepseek.com/v1/chat/completions"),
};
ResponsesApiProvider подставляется по умолчанию — явно указывать его не нужно.

C#:
var config = new AiActionConfig
{
    ApiKey                 = project.Variables["api_key"].Value,
    Model                  = "gpt-5.4",
    ImageDetail            = "original",
    SendFullPageScreenshot = true,
    MaxImageDimension      = 1280, // Уменьшит файл, но снизит точность
};

var ai = new AiActions(project, instance, config);
ai.ClickByView("иконка корзины в шапке сайта");



5. Использование как плагин ZennoPoster

Для тех, кто предпочитает работать без написания C# кода — доступен плагин с графическим интерфейсом. Настройки задаются в кубике, результат передаётся в переменную проекта.

Как это работает

Плагин принимает описание элемента, выполняет один из двух режимов и записывает результат в переменную aiActionsResult:

  • Режим FindXPath — возвращает XPath найденного элемента в виде строки, например //button[@id='submit']
  • Режим ClickByView — выполняет клик и возвращает строку ok

При неудаче плагин выбрасывает исключение — выполнение шаблона прерывается стандартным образом ZennoPoster.

Описание настроек — вкладка «Главные»

НастройкаОписание
Ключ APIBearer-токен для авторизации. Для локальных моделей можно оставить пустым
Имя моделиИдентификатор модели, например gpt-5.4 или deepseek-chat
Тип провайдера APIResponses — для OpenAI. Completions — для DeepSeek, LM Studio, Ollama и прочих совместимых
Адрес для вызова APIПолный URL эндпоинта. Пустое поле — используется стандартный адрес OpenAI для выбранного типа провайдера
ПроксиВ формате host:port или login:pass@host:port. Пустое — без прокси
Режим работыFindXPath или ClickByView
Описание элементаТекстовое описание того, что нужно найти или на что кликнуть
Таймаут (мс)Максимальное время ожидания ответа от API. По умолчанию 120 000 мс
Flex modeПониженный приоритет запроса — дешевле, но медленнее. Только для ResponsesApiProvider

Описание настроек — вкладка «Дополнительные»

НастройкаОписание
Макс попыток XPathСколько раз модель может предложить новый вариант XPath при неудаче. По умолчанию 3
Скриншот при поиске XPathПрикладывать скриншот к запросу FindXPath как дополнительный контекст
Макс символов HTMLЛимит символов HTML, передаваемых модели. -1 = без ограничения
Очистка HTMLMinimal / Standard / Aggressive — степень удаления мусора из HTML перед отправкой
Полный скриншот страницыСнимать всю страницу целиком, а не только вьюпорт. Рекомендуется для ClickByView
Детализация изображенияoriginal рекомендован OpenAI для управления интерфейсом — наибольшая точность координат
Макс сторона изображенияОграничить размер скриншота в пикселях. 0 = без лимита. Снижает размер файла, но и точность
Качество скриншота1–100. По умолчанию 70
Прокрутка при ClickByViewПрокручивать страницу в поисках элемента. Не рекомендуется при включённом полном скриншоте
Макс попыток прокруткиСколько раз прокручивать страницу до отказа. По умолчанию 5
Шаг прокрутки в пикселях0 = прокручивать на высоту вьюпорта за раз

Ограничения плагина

  • Результат только один: XPath-строка или ok — без токенов, стоимости и отладочного лога
  • Для получения дополнительной информации о выполнении используйте C# код напрямую


141167
141168




Что умеет библиотека:

  • Находить XPath любого элемента по его текстовому описанию
  • Кликать по элементу, который модель находит визуально на скриншоте
  • Работать с OpenAI, DeepSeek, LM Studio, Ollama и любым OpenAI-совместимым провайдером
  • Настраивать объём передаваемого HTML — от полного до агрессивно сжатого
  • Отправлять полный скриншот страницы для точного определения координат без прокрутки
  • Использоваться как плагин без написания кода

Чего библиотека не делает и о чём стоит знать:

  • Не гарантирует результат на любой странице — нестандартная вёрстка и визуально сложные интерфейсы повышают вероятность ошибки, особенно при использовании слабых или локальных моделей
  • Дешёвые и локальные модели плохо справляются с анализом изображений — для ClickByView рекомендуется gpt-5.4
  • Координаты ZennoPoster всегда абсолютные относительно видимой области — прокрутка смещает видимую область, но не систему координат; каждый скриншот сбрасывает страницу вверх, поэтому при в таком режиме приходится листатать страницу несколько раз, что отражается на времени выполнения.
  • Не работает бесплатно — каждый вызов метода это запрос к API (кроме локальных моделей), здесь экономику работы стоит подсчитывать самостоятельно, в каком проекте и когда есть смысл использовать такой код.

В прикреплённом файле находится полный исходный код, а также плагин для прямого использования в шаблонах и сам исходный код плагина для собственного редактирования. Внешних зависимостей нет — только стандартные возможности ZennoPoster и C#.​

Подробнее про установку плагинов можно прочитать в в официальной документации ZennoLab: https://zennolab.atlassian.net/wiki/spaces/RU/pages/475365697

На видео я продемонстрировал несколько примеров использования как напрямую из кода, так и с помощью плагина на lessons.zennolab.com:


Проект открыт для изучения и доработки. Используйте на свой страх и риск — автор не берёт на себя ответственность за сбои в работе или расходы на API. В коде могут иметься ошибки и баги. Будьте внимательны при его использовании.​
 

Вложения

Последнее редактирование модератором:
  • Спасибо
Реакции: deskuznetsov

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)