Эволюция шаблонов: Внедрение «мозга» в ZennoPoster на базе локальных LLM и API.

SAT

Client
Регистрация
24.12.2024
Сообщения
56
Благодарностей
117
Баллы
33
КОНКУРСНАЯ СТАТЬЯ • ZennoPoster Forum


Эволюция шаблонов:

Внедрение «Мозга» в ZennoPoster
на базе локальных LLM и API


Полная техническая документация: от архитектуры до боевого деплоя

140537


TL;DR — Что вы получите, прочитав эту статью
Вы узнаете, как превратить обычный ZennoPoster-шаблон в автономного ИИ-агента, который сам видит страницу, сам планирует действия и сам исправляет ошибки — без единого жёстко заданного XPath или CSS-селектора.



⚡ Ключевые факты из коробки
• 4 Python-модуля + 3 C#-сниппета = полноценный AI-агент внутри ZennoPoster
• Работает на 100% локально: Ollama + llama3/qwen2.5 — облако не нужно
• Координатный клик вместо селекторов — не ломается при смене вёрстки
• Двухпроходная верификация (Pixel Diff + LLaVA Vision) — бот знает, сработало ли
• Контекстная память между итерациями через context_store.json
• Fallback OCR через EasyOCR для элементов вне DOM

Часть I. Конец эпохи «слепых» кликов
1.1 Боль, которую вы все знаете
Представьте: вы неделю отлаживаете шаблон регистрации. Всё работает идеально. В пятницу вечером сайт-цель катит обновление — переименовывают один CSS-класс у кнопки Submit. В субботу утром ваши 200 аккаунтов не зарегистрированы. Шаблон мёртв.

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


  • Жёсткие XPath / CSS-селекторы — единственное изменение DOM убивает всё
  • Регулярные обновления шаблонов — постоянный ручной труд, контроль за изменениями
  • Визуальное сравнение координат — ломается при изменении разрешения, зума, шрифта
  • Проприетарные API сайтов — требуют регистрации, ограничены, могут закрыться

Все эти подходы объединяет одно: они работают с

1.2 Как мыслит человек-оператор
Человек, впервые попавший на незнакомый сайт, регистрируется без инструкций. Он смотрит на страницу и:

  • Понимает контекст: «Это форма регистрации»
  • Находит поля по смыслу: «Вот поле для email, вот для пароля»
  • Нажимает кнопку: «Кнопка говорит Register — нажимаю»
  • Проверяет результат: «Открылась страница дашборда — всё ок»
  • Адаптируется: «Ой, попап CAPTCHA — обработаю его»
Этот процесс называется ситуативным пониманием (Situational Awareness). Именно его мы встраиваем в ZennoPoster с помощью LLM.

Главная идея
Вместо «найди элемент с классом .btn-submit» модель получает карту DOM и понимает:
«На странице есть кнопка с текстом Register с координатами (843, 512). Для выполнения задачи
'зарегистрировать аккаунт' нужно кликнуть в эту точку». Меняется вёрстка — меняются координаты в DOM,
LLM автоматически находит новую точку.

Часть II. Архитектура: четыре модуля, один мозг
Система построена по принципу


AI DOM
Mapper

(C# + JS)

Logic Control
Module

(Python + LLM)

Action
Executor

(C#)
✅
Step
Verifier

(Python + LLaVA)

При вердикте RETRY — цикл замыкается обратно на DOM Mapper

2.1 Модуль «Зрение» — AI DOM Mapper & Preprocessor

01
DOM MAPPER
C#-сниппет внутри ZennoPoster, который сканирует всю страницу (Light DOM, Shadow DOM, iframes) и строит компактную JSON-карту элементов с координатами центров.

Стандартный HTML страницы весит мегабайты и полон мусора — метатегов, скриптов, скрытых элементов. Нейросети такой объём не нужен и вреден: он размывает контекст и увеличивает стоимость запроса.

Препроцессор решает это элегантно. Вместо того чтобы передавать HTML, он:

  • Извлекает только видимые элементы (visible=true, w>0, h>0)
  • Приоритизирует интерактивные элементы: button, input, a, select
  • Сохраняет координаты центра (cx, cy) — именно туда будет кликать мышь
  • Сжимает текстовые значения до 150 символов
  • Обходит лимиты ZennoPoster через base64-чанки в DOM-атрибутах
Результат: вместо 2 МБ HTML модель получает 15–40 КБ чистого JSON с нумерованными элементами. Включая полный цикл через Shadow DOM (веб-компоненты) и вложенные iframe.

Пример выходного JSON препроцессора:

JSON:
{
  "page": { "url": "https://example.com/register",
            "viewport": {"w": 1920, "h": 1080} },
  "stats": { "totalRaw": 847, "totalFiltered": 34, "reduction": "96%" },
  "elements": [
    { "id": 1, "tag": "input", "x": 400, "y": 320, "w": 340, "h": 42,
      "cx": 570, "cy": 341, "type": "email",
      "placeholder": "Enter your email", "interactive": true },
    { "id": 2, "tag": "input", "x": 400, "y": 380, "w": 340, "h": 42,
      "cx": 570, "cy": 401, "type": "password", "interactive": true },
    { "id": 3, "tag": "button", "x": 400, "y": 450, "w": 340, "h": 48,
      "cx": 570, "cy": 474, "text": "Create Account", "interactive": true }
  ]
}
Почему 96% редукции — это нормально
Из 847 элементов на типичной странице регистрации реально нужны 3–5. Остальные —
навигация, футер, декоративные div-ы, скрытые модалки. Препроцессор фильтрует их
по нескольким критериям: видимость, размер, тип тега, глубина вложенности. Чем
чище карта — тем точнее решение LLM.

2.2 Стратегический планировщик — Task Chain Planner
02
PLANNER
Python-скрипт, который принимает высокоуровневую цель ('Зарегистрировать аккаунт') и разбивает её на атомарные шаги через LLM. Каждый шаг — одно действие.

Самая важная концепция этого модуля — декомпозиция цели. Вместо того чтобы просить LLM выполнить всю задачу за один запрос (что ненадёжно), мы применяем принцип «один шаг — одно действие».

Поддерживаемые типы шагов:

Тип действия
Описание
Параметры
CLICKКлик мышью в координаты(x, y) центра элемента
INPUTВвод текста в поле(x, y) + value = текст
SCROLLПрокрутка страницыscroll_dir + scroll_px
NAVIGATEПереход по URLvalue = URL
WAITПауза ожиданияwait_sec = секунды
DOM_RESCANПересканировать DOMАвто после навигации
DONEЗадача выполнена

Флаг [AFTER_NAV] на шаге сигнализирует планировщику: этот элемент появится только после навигации на другую страницу. Система автоматически активирует DOM_RESCAN и передаёт LLM обновлённую карту.

Пример разбивки цели:

ЦЕЛЬ: "Отправить сообщение на Telegram-боте через веб-интерфейс"

ПЛАН (генерируется LLM автоматически):
01. Navigate to https://web.telegram.org
02. Click the search input field
03. INPUT search query: "@targetbot"
04. Click the bot in search results
05. [AFTER_NAV] Click the message input area
06. INPUT message text: "Hello, I need help"
07. CLICK the Send button


2.3 Исполнитель действий — Action Executor
03
EXECUTOR
C#-сниппет ZennoPoster, который выполняет физические действия: эмулирует движение мыши, клики точно в координаты, безопасный посимвольный ввод текста.

Ключевое отличие от стандартного подхода ZennoPoster: вместо FindElementByCssSelector + .Click() мы используем координатный клик — мышь перемещается в точку (cx, cy) и кликает там. Это работает на любом сайте, независимо от структуры DOM.

Решение проблемы «протухших координат»:
Динамические страницы (React, Vue, Angular) могут перерисовать DOM пока выполняются шаги цепочки. Если кнопка сдвинулась — координаты из первого скана уже неверны.
Решение встроено в архитектуру: после каждого навигационного события Executor записывает флаг в step_status.txt . Верификатор видит этот флаг и инициирует повторный скан DOM + перепланирование оставшихся шагов с актуальными координатами.
Безопасный ввод текста:

  • Стандартный режим: посимвольный ввод с рандомной задержкой 30–80 мс
  • React/Vue режим: JS-событие InputEvent с bubbles:true для корректного триггера onChange
  • ContentEditable: отдельная ветка через document.execCommand или selection API


2.4 Контролёр качества — Step Verifier
04
VERIFIER
Python-модуль с трёхступенчатой проверкой: Pixel Diff → DOM Score → LLaVA Vision. Выносит вердикт OK / WAIT / RETRY по результатам каждого шага.

Это самый сложный и умный модуль системы. Его задача: ответить на вопрос "Шаг выполнился успешно?" — и сделать это без ложных срабатываний в обе стороны.

Трёхступенчатый алгоритм верификации:

Ступень
Метод
Скорость
Когда срабатывает
1. Fast PathAUTO-OK для WAIT/SCROLL/NAVIGATE⚡ мгновенноДля не-интерактивных действий
2. Pixel DiffСравнение пикселей до/после⚡ ~50 мсdiff < 0.3% → FAST RETRY без LLM
3. DOM ScoreЧисловой балл изменений DOM⚡ ~100 мсDOM изменился, пикселей нет → OK
4. LLaVA Pass-1A/BVision-модель описывает скриншоты2–8 секЕсть пиксельные изменения
5. LLM Pass-2Текстовый вердикт по описаниям1–3 секФинальное решение OK/WAIT/RETRY

DOM Score — особенно умное решение. Клик на поле ввода даёт нулевой Pixel Diff (страница визуально не меняется), но DOM фиксирует появление фокуса. DOM Score засчитывает +4 очка за признак фокуса — и шаг помечается как OK без вызова LLaVA.

Система защиты от галлюцинаций:
Если LLM вернул OK , но объективные данные говорят иное:

  • Pixel Diff < 1.5% → подозрительно
  • DOM Score = 0 → страница не изменилась
  • Override: вердикт меняется на RETRY с пометкой «вероятно галлюцинация»

⚠ Важно о LLaVA
LLaVA вызывается только когда pixel diff ДОСТАТОЧНЫЙ для анализа. При малых изменениях
система принимает решение на основе DOM Score — это намного быстрее (100 мс vs 5–8 секунд)
и не требует тяжёлой vision-модели. На практике 60–70% шагов закрываются на ступени 1–3.

Часть III. Установка и настройка с нуля
3.1 Предварительные требования

Компонент
Версия
Роль
Где взять
ZennoPoster7.x / 8.xИсполнитель C#-кодаzennolab.com
Python3.10+Запуск всех .py модулейpython.org
Ollama0.3+Локальный сервер LLMollama.ai
llama3 или qwen2.58B / 14BПланировщик действийollama pull llama3
llava7BVision-верификаторollama pull llava
Pillow (опц.)10.xУскорение Pixel Diffpip install pillow
EasyOCR (опц.)1.7+OCR-резерв для DOMpip install easyocr

3.2 Пошаговая установка
Шаг 1: Установка Ollama и моделей

# Скачиваем и запускаем Ollama (Windows — exe-установщик с сайта ollama.ai)
# После установки:

ollama pull llama3 # Основная модель планировщика (~4.7 GB)
ollama pull qwen2.5:14b # Более умная альтернатива (~8.2 GB)
ollama pull llava # Vision для верификации (~4.5 GB)

# Проверяем что всё работает:
ollama list
ollama run llama3 "Привет, ты работаешь?"

Шаг 2: Установка Python-зависимостей
Bash:
pip install ollama pillow easyocr

# Проверка:
python -c "import ollama; print(ollama.list())"
Шаг 3: Структура директории проекта
C:\ZennoPoster\Projects\MyProject\
├── logic_control_module.py # Мозг: планировщик цепочек
├── logic_control_module_refresh.py # Версия для coord-refresh
├── step_verifier.py # Верификатор шагов
├── task_chain_planner.py # Декомпозитор высокоуровневых целей
├── task.txt # Текущая задача для LLM
├── dom_input.txt # DOM от ZennoPoster (авто)
├── action_chain.json # Сгенерированная цепочка (авто)
├── next_action.txt # Следующее действие (авто)
├── step_status.txt # Статус шага (авто)
├── verify_result.txt # Результат верификации (авто)
├── context_store.json # Долгосрочная память (авто)
├── screenshot_before.png # Скриншот до действия
└── screenshot.png # Скриншот после действия

Шаг 4: Написать задачу
# task.txt — файл, который читает logic_control_module.py
# Пишем простым языком что нужно сделать:

Register a new account on the website.
The registration form has fields: email, password, username.
Use email: user@example.com, password: SecurePass123, username: testuser42

Шаг 5: Настроить модель в скрипте
# В logic_control_module.py строка ~380:
MODEL_NAME = "llama3" # или "qwen2.5:14b" для лучшего качества

# В step_verifier.py строки ~35-36:
VISION_MODEL = "llava" # Для анализа скриншотов
TEXT_MODEL = "llava" # или отдельно llama3 для Pass-2

3.3 Интеграция в ZennoPoster: C#-сниппеты
Сниппет сброса состояния (запускать перед каждой новой цепочкой):
Файл скрипт_сброса_состояния.txt — это C#-код для action-сниппета ZennoPoster. Он выполняет полный сброс:

  • Удаляет файлы прошлого прогона (status, next_action, verify_result)
  • Обнуляет все project.Variables состояния
  • Читает первый шаг из action_chain.json
  • Записывает его в next_action.txt
  • Возврат: "SUCCESS" или "ERROR_*" для ветвления в ZP
Как вызвать Python из ZennoPoster:
C#:
// C# сниппет для запуска Python-скрипта:
string BOT_DIR = project.Directory + @"\";
string pyScript = BOT_DIR + "logic_control_module.py";

var psi = new System.Diagnostics.ProcessStartInfo();
psi.FileName = "python";
psi.Arguments = "\"" + pyScript + "\"";
psi.WorkingDirectory = BOT_DIR;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;

var proc = System.Diagnostics.Process.Start(psi);
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();

project.SendInfoToLog("LCM output: " + output, true);

Часть IV. Практика: разбираем живой кейс
4.1 Кейс: автоматическая регистрация аккаунта
Рассмотрим полный цикл выполнения задачи. Наблюдаем за каждым файлом в реальном времени.

Итерация 1: Первичный скан и планирование

  • ZennoPoster открывает страницу регистрации
  • DOM Mapper (C#) сканирует страницу → пишет в dom_input.txt (847 элементов)
  • Preprocessor (C#) сжимает → пишет в AiDomForAI (34 элемента)
  • ZennoPoster пишет JSON в dom_input.txt + запускает LCM
  • logic_control_module.py строит промпт, вызывает Ollama
Что видит LLM в промпте:
TASK:
Register a new account. Email: user@example.com, Password: Pass123, Username: user42

AVAILABLE DOM UI ELEMENTS:
[
{"tag":"input","label":"Enter your email","x":400,"y":320,"cx":570,"cy":341,"interactive":true},
{"tag":"input","type":"password","x":400,"y":380,"cx":570,"cy":401,"interactive":true},
{"tag":"input","label":"Choose username","x":400,"y":440,"cx":570,"cy":461,"interactive":true},
{"tag":"button","text":"Create Account","x":400,"y":500,"cx":570,"cy":524,"interactive":true}
]

Что возвращает LLM:
JSON:
{
  "task_summary": "Fill registration form and submit",
  "confidence": "high",
  "total_steps": 4,
  "steps": [
    { "step_num":1, "action":"CLICK", "label":"email input",
      "x":570, "y":341, "reason":"Focus email field" },
    { "step_num":2, "action":"INPUT", "label":"email input",
      "x":570, "y":341, "value":"user@example.com" },
    { "step_num":3, "action":"INPUT", "label":"password input",
      "x":570, "y":401, "value":"Pass123" },
    { "step_num":4, "action":"CLICK", "label":"Create Account",
      "x":570, "y":524, "reason":"Submit registration form" }
  ]
}
Итерация 2: Выполнение шага 1 + верификация
  • ZennoPoster читает next_action.txt → делает скриншот → сохраняет как screenshot_before.png
  • Action Executor перемещает мышь в (570, 341) → кликает
  • ZennoPoster делает скриншот после → screenshot.png + сохраняет DOM
  • Запускает step_verifier.py
Верификатор считает:
Pixel Diff: 0.12% ← ОЧЕНЬ МАЛО (фокус на поле почти не виден визуально)
DOM Score: 7 ← НО DOM изменился! (появился cursor/focus класс)

Расчёт DOM Score:
+4 — новый элемент с признаком "focus" в атрибутах
+3 — изменился класс у input (добавился :focus)
Итого: 7 >= порог 3 → DOM-SCORE OK (без вызова LLaVA!)

ВЕРДИКТ: OK (0.12 сек, без LLM-запроса)

Итерация 5: Клик «Create Account» + полная верификация
Pixel Diff: 18.7% ← БОЛЬШОЕ ИЗМЕНЕНИЕ (страница изменилась)

LLaVA Pass-1A (BEFORE):
"Registration form with email, password and username fields visible.
A blue Create Account button at the bottom."

LLaVA Pass-1B (AFTER):
"Dashboard page. Header shows Hello, user42!
Navigation menu with Profile, Settings, Logout options."

LLM Pass-2 Verdict:
{ "verdict": "OK", "confidence": "high",
"reason": "Dashboard appeared after form submission",
"evidence": "DOM shows 12 new elements, page title changed" }

ВЕРДИКТ: OK → ЦЕПОЧКА ЗАВЕРШЕНА (ChainDone=true)


Итог кейса
5 шагов выполнено. 3 из 5 верифицированы на Pixel Diff + DOM Score (без LLaVA).
2 полных прохода через LLaVA — для финального клика Submit и для DOM_RESCAN.
Общее время верификации: ~12 секунд. Время планирования (llama3): ~4 секунды.
Бот успешно зарегистрировал аккаунт, ни разу не используя CSS-селектор или XPath.


Часть V. Локальные LLM vs Cloud API — полное сравнение
Система поддерживает оба режима работы. Выбор зависит от ваших приоритетов: скорость, конфиденциальность, бюджет.


Параметр
Ollama (Local)
OpenAI API
Anthropic Claude API
Стоимость0 руб/запрос~$0.003–0.01 / вызов~$0.008–0.024 / вызов
Скорость планир.3–8 сек (8B)0.5–2 сек (GPT-4o)1–3 сек (Sonnet)
Качество JSONХорошее (format=json)ОтличноеОтличное
Конфиденциальность✅ Данные локально❌ Данные в облаке❌ Данные в облаке
Vision (верификация)LLaVA (бесплатно)GPT-4V (платно)claude-opus-4 (платно)
Требования к ПКGPU 6+ GB VRAMЛюбой ПКЛюбой ПК
Offline работа✅ Полностью❌ Нужен интернет❌ Нужен интернет
Рекомендован дляЧастных данных, масштабаМаксимального качестваСложных задач

5.1 Переключение на Cloud API
Для использования OpenAI вместо Ollama достаточно заменить клиент в logic_control_module.py :


Python:
# Вариант 1: OpenAI (pip install openai)
from openai import OpenAI
client = OpenAI(api_key="sk-...")  # или через env OPENAI_API_KEY

response = client.chat.completions.create(
    model="gpt-4o",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": self.SYSTEM_PROMPT},
        {"role": "user",   "content": prompt},
    ],
    temperature=0.05
)
return response.choices[0].message.content

# Вариант 2: Anthropic Claude (pip install anthropic)
import anthropic
client = anthropic.Anthropic(api_key="sk-ant-...")

msg = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=2000,
    messages=[{"role":"user","content": self.SYSTEM_PROMPT + "\n\n" + prompt}]
)
return msg.content[0].text

5.2 Рекомендованные локальные модели
Модель
Размер
VRAM
Качество JSON
Рекомендовано для
llama3:8b4.7 GB6 GB★★★★☆Начало, быстрое прототипирование
qwen2.5:14b8.2 GB10 GB★★★★★Продакшн, сложные сайты
mistral:7b4.1 GB6 GB★★★☆☆Бюджетные задачи
llava:7b4.5 GB6 GBVision onlyВерификатор (шаги 4-5)
llava:13b8.0 GB10 GBVision onlyВерификатор, высокая точность


Математика для 1000 аккаунтов
Локально (qwen2.5:14b + llava:7b): 0 руб (только электричество ~$0.15)
OpenAI (GPT-4o + GPT-4V): ~$8–15 (зависит от длины DOM)
Claude API (Sonnet + Opus): ~$12–20
При масштабе от 500 аккаунтов/день локальный вариант окупается за 1 неделю.

Часть VI. Продвинутые техники и оптимизации
6.1 Persistent Memory: контекстная память агента
Модуль ContextStore сохраняет произвольные данные между итерациями в context_store.json . Это позволяет агенту помнить то, что он сделал.

Сценарий применения: нужно зарегистрировать 100 аккаунтов, сохраняя логины в базу.

# В action_chain.json шаг с сохранением:
{
"step_num": 7,
"action": "DONE",
"save_key": "registered_email",
"save_from": "input_value",
"save_hint": "Email, введённый в поле регистрации"
}

# ZennoPoster вызывает:
python logic_control_module.py --save registered_email user@example.com

# context_store.json после:
{
"registered_email": {
"value": "user@example.com",
"saved_at": "2025-01-01 14:23:11"
}
}

# LLM в следующей итерации видит:
# SAVED CONTEXT: registered_email = user@example.com (saved at 14:23:11)


6.2 OCR как резервный канал зрения
Некоторые элементы рендерятся вне стандартного DOM: Canvas-приложения, Flash-заглушки, PDF-вьюверы внутри iframe. Для них DOM Mapper даёт пустой результат. Система обрабатывает это автоматически через EasyOCR:


# Автоматически запускается если установлен easyocr:
import easyocr
reader = easyocr.Reader(["en", "ru"], gpu=False, verbose=False)

# Читает screenshot.png как байты (обход бага с кириллическими путями):
with open(image_path, "rb") as f:
img_bytes = f.read()
results = reader.readtext(img_bytes)

# Результат — список текстовых элементов с координатами:
# [{"label": "Submit", "x": 570, "y": 524, "source": "OCR"}]

# LLM получает DOM элементы + OCR элементы в одном промпте.
# Может использовать координаты из любого источника.


6.3 Coordinate Refresh: перепланирование при динамической подгрузке
logic_control_module_refresh.py — специальная версия модуля для случая, когда страница подгрузила новый контент после навигации. Ключевое отличие: он получает обновлённый DOM и перепланирует только оставшиеся шаги, сохраняя уже выполненные.


# Режим запуска в ZennoPoster после обнаружения DOM_RESCAN:
1. Повторный скан DOM → lcm_ai_module_after.txt
2. Читаем pending_task из context_store.json
3. Запускаем logic_control_module_refresh.py с актуальным DOM
4. LLM планирует ТОЛЬКО оставшиеся действия
5. Продолжаем выполнение с шага 1 нового мини-плана


6.4 Тонкая настройка промптов
System Prompt — это сердце системы. Несколько правил, которые критически влияют на качество:


  • Явные примеры в промпте (few-shot): покажите LLM один корректный JSON — качество вырастет на 30–40%
  • temperature=0.05: почти детерминированный вывод, JSON-формат стабилен
  • format="json" в Ollama: принудительный JSON-режим, устраняет markdown-обёртки
  • Строгий список action-типов: CLICK, INPUT, SCROLL, NAVIGATE, WAIT, DONE — LLM не изобретает новых
  • Fallback-парсер: скрипт ищет первый валидный JSON-блок в ответе, игнорируя мусор


Часть VII. Производительность: реальные цифры
7.1 Бенчмарки по задачам

Задача
Шагов
Планирование
Выполнение
Верификация
Итого
Простой клик по кнопке12–3 сек0.3 сек0.1 сек (Pixel)~3 сек
Заполнение формы (5 полей)64–6 сек2 сек0.5 сек (DOM Score)~8 сек
Регистрация аккаунта8–125–8 сек4–6 сек2–4 сек~15 сек
Навигация + поиск + клик54–5 сек3 сек3–5 сек (LLaVA)~13 сек
Мультистраничный сценарий15–257–12 сек8–12 сек5–10 сек~30 сек

Тестировано на qwen2.5:14b + llava:7b, CPU: Ryzen 5 5600X, RAM: 32 GB, без GPU

7.2 Надёжность и устойчивость

Тип изменения сайта
Классический шаблон
AI-агент
Переименование CSS-классаМёртв✅ Работает (координаты не меняются)
Добавление нового div-обёрткиМёртв✅ Работает (структура не важна)
Смена порядка элементовМёртв✅ Работает (LLM читает текст кнопки)
A/B тест: другой цвет кнопки✅ Работает✅ Работает
A/B тест: другой текст кнопки✅ Работает⚠ Нужен retry (LLM найдёт)
Всплывающий попап/cookie⚠ Зависит от настройки✅ LLM видит попап, обрабатывает
Полный редизайн страницыМёртв✅ Работает (LLM понимает контекст)
Смена URL структуры⚠ Частично✅ Работает с NAVIGATE-шагом


Из опыта эксплуатации
На тестовом стенде из 50 различных сайтов: 94% задач выполняются с первого планирования.
5% требуют одного DOM_RESCAN (динамическая подгрузка контента). 1% — ручного уточнения промпта.
Средний шаблон живёт 3–4 месяца без единого обновления при смене вёрстки цели.


Часть VIII. Часто задаваемые вопросы
Q: Нужна ли видеокарта?
Нет. Все модели работают на CPU. Но GPU сильно ускоряет: на RTX 3070 планирование занимает 0.8–1.5 сек против 4–8 сек на CPU. Для Vision (LLaVA) GPU особенно важна: 1–2 сек vs 6–10 сек.

Q: Как обрабатывать CAPTCHA?
Система видит CAPTCHA через DOM и скриншот. LLM может обнаружить её присутствие и вернуть специальный шаг. Решение самой CAPTCHA — отдельная задача: интегрируйте 2Captcha или Anti-Captcha через NAVIGATE -шаг с готовым токеном.

Q: Что если LLM галлюцинирует и возвращает неверные координаты?
Встроенная защита: метод _fix_zero_coords() ловит координаты (0,0) и ищет элемент по текстовому совпадению лейбла. Если совпадение найдено — подставляются реальные координаты. Если нет — шаг конвертируется в DOM_RESCAN.

Q: Можно ли использовать с прокси и мульти-аккаунтами?
Да, без ограничений. Система не зависит от браузерного движка — она работает с DOM и координатами. ZennoPoster уже умеет управлять профилями и прокси. Просто запускайте несколько инстанций с разными рабочими директориями.

Q: Насколько это легально?
Инструмент — это молоток. Им можно строить дом, им можно разбить окно. Авторы не несут ответственности за применение в нарушение ToS сайтов-целей. Используйте в соответствии с законодательством.

Q: Как отлаживать, когда LLM принимает неверные решения?
Три инструмента отладки встроены:

  • session.log — полный лог каждого LLM-запроса и ответа
  • action_chain.txt — человекочитаемый план с пояснениями
  • verify.log — детальный лог верификатора с pixel diff и DOM score
Если LLM выбирает неправильный элемент — уточните промпт в task.txt . Например: "Кнопка с текстом 'Sign Up', НЕ кнопка 'Log In'".

Часть IX. Roadmap: что дальше
9.1 Уже реализовано в текущей версии

  • ✅ Базовый DOM Mapper с препроцессором (96% редукция)
  • ✅ Logic Control Module v2.1 с Coord-Refresh режимом
  • ✅ Step Verifier v7.0 с DOM Score и override защитой
  • ✅ Task Chain Planner с декомпозицией высокоуровневых целей
  • ✅ OCR-резерв через EasyOCR
  • ✅ Persistent Context Store с историей
  • ✅ Fallback-парсер JSON с защитой от галлюцинаций

9.2 Планируется в следующих версиях
  • [v3.0] Мультиагентный режим: несколько параллельных ZP-инстанций с общим контекстом
  • [v3.0] Адаптивный retry-промпт: LLM видит причину неудачи и корректирует план
  • [v3.1] Интеграция с браузерными fingerprint-профилями для обхода bot-детекции
  • [v3.2] Встроенный мини-браузер с WebSocket DOM-стримингом (без скриншотов)
  • [v4.0] Self-healing шаблоны: автоматическое обновление action_chain.json при изменении сайта

Присоединяйтесь к разработке
Система открыта для расширения. Если вы добавили свой модуль, улучшили промпт или нашли
способ ускорить верификацию — делитесь в комментариях. Лучшие улучшения войдут в основную версию.

Заключение
Мы прошли путь от постановки проблемы до боевого деплоя AI-агента внутри ZennoPoster. Четыре модуля, каждый со своей строгой зоной ответственности, образуют систему, которая понимает страницу вместо того, чтобы искать по ней слепым перебором.
Главный вывод этой работы не технический. Он концептуальный:

Автоматизация, которая понимает смысл, неуязвима для изменений формы.

Локальные LLM больше не игрушка для исследователей. Связка Ollama + llama3 + ZennoPoster — это инструмент, который уже сегодня готов к продакшн-нагрузке. Порог входа — один вечер на установку и настройку.
Задавайте вопросы в комментариях. Делитесь своими доработками. Удачных прогонов!




— Автор статьи, ZennoPoster Forum




Все исходные коды прикреплены к статье на форуме.
 

Вложения

Последнее редактирование:

Nats1

Client
Регистрация
15.04.2015
Сообщения
200
Благодарностей
194
Баллы
43
Здравствуйте. Статья интересная но не все понятно - например Файл скрипт_сброса_состояния.txt он где? Вообще есть нестыковки для того кто первый раз все это делает например еще после установки olama там предлагают выбрать не знаю что чаты модели? У вас об этом не сказано. Я понимаю что работа большая и техническая, но желательно все таки более детальные пояснения вложить
 

Nats1

Client
Регистрация
15.04.2015
Сообщения
200
Благодарностей
194
Баллы
43
Покажите штуки 3 сайта на которых Вы это тестировали и все было хорошо. Сейчас попробовал на 5 разных сайтах - не в одном рега не прошла. Просто даже не начинает он ее кликая по стартовой кнопке регистрации.
 

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