- Регистрация
- 24.12.2024
- Сообщения
- 56
- Благодарностей
- 116
- Баллы
- 33
Введение: Иллюзия непогрешимости ИИ
Давайте будем честны: даже самые умные нейросети иногда откровенно галлюцинируют. Мы все с этим сталкивались. Когда вы генерируете тексты для блогов или собираете простенькие сниппеты, случайная ошибка вызывает лишь лёгкую улыбку.
Но когда автоматизация выходит на серьёзный уровень — например, когда на кону стоят реальные бюджеты в сложных схемах арбитража трафика, алгоритмической торговле на Steam или сделках на фьючерсах — слепая вера в один API может стоить очень дорого. Вы доверяете боту критически важное решение, а он на ровном месте выдаёт логический сбой.
Четыре типа критических ошибок одиночной модели:
— Галлюцинации. Модель уверенно утверждает несуществующие факты. Особенно опасно в задачах с бинарным решением — купить/не купить, кликнуть/не кликнуть.
— Недетерминизм. Один и тот же промпт в разных сессиях даёт разные ответы. Стабильность автоматизации под угрозой, отлаживать такое — настоящий кошмар.
— Слепые зоны. Каждая модель имеет своё «мёртвое пятно». То, что легко видит Claude, может не замечать GPT, и наоборот.
— Точечные сбои. API-ошибки, таймауты, перегрузка серверов. Единственный источник = единственная точка отказа всей системы.
Каково решение? Перестать надеяться на «одного гения» и заставить их договариваться. Именно так работают экспертные комитеты, коллегии судей и советы директоров. Принцип консенсуса тысячелетиями доказывал свою надёжность в человеческих системах — пришло время применить его к автоматизации.
В этом кейсе я покажу, как реализовать в ZennoPoster архитектуру «ИИ-консенсуса». Мы будем отправлять сложную задачу сразу пулу топовых моделей (Gemini, Claude, Grok, Kimi, ChatGPT), сталкивать их лбами и выводить итоговое решение на основе взаимной проверки.
Архитектура «Синдиката»: Как это работает под капотом
Название выбрано не случайно. Синдикат — это объединение, где каждый участник действует независимо, но общее решение принимается голосованием. В нашем случае «участники» — топовые ИИ-модели мирового уровня.
Пул Синдиката:
- Google Gemini — мультимодальность, анализ изображений, широкий контекст
- Anthropic Claude — рассуждения, следование инструкциям, длинные промпты
- xAI Grok — актуальные данные реального времени, интеграция с X/Twitter
- Kimi (Moonshot) — длинный контекст, мультиязычность, азиатские рынки
- OpenAI ChatGPT — следование инструкциям, широкая экосистема, плагины
В корне проекта ZennoPoster я выделил отдельную экосистему директорий:
- results_in — сюда асинхронно падают «мнения» от разных нейросетей
- prompts_out — здесь формируется итоговый мастер-промпт для финального вердикта
- all_prompts — сюда кладём промпты по отдельным задачам
Поток данных выглядит так:
- Задача / страница поступает на вход
- AI DOM Mapper v2.0 собирает полную карту страницы (Light DOM + Shadow DOM + iframe)
- DOM Preprocessor v8 сжимает JSON для контекстного окна LLM (−96% объёма)
- Параллельный опрос 5 топовых моделей → файлы в results_in/
- Consensus Controller C# собирает мастер-промпт из всех ответов
- Финальная модель-арбитр синтезирует единый вердикт
Почему файловая маршрутизация, а не прямые API-вызовы? Файлы делают систему максимально модульной: любой компонент (модель, промпт, контроллер) можно заменить независимо. Кроме того, ZennoPoster превосходно работает с файловой системой, а отладка упрощается до предела — в любой момент открой файл и посмотри, что ответила конкретная модель.
Шаг 1. Глаза бота: AI DOM Mapper v2.0
Прежде чем ИИ начнёт думать — он должен «увидеть» страницу так же, как видит её браузер. Обычный парсинг часто захлёбывается в мусоре: скрытые элементы, Shadow DOM, iframe-вставки, динамические компоненты на React/Vue/Angular. AI DOM Mapper v2.0 решает всё это в одном JavaScript-скрипте, выполняемом прямо в браузерном контексте ZennoPoster.
Что умеет DOM Mapper:
- Рекурсивный обход всего DOM-дерева, включая Shadow DOM на любой глубине
- Сбор абсолютных координат каждого элемента с учётом прокрутки страницы
- Вычисление центра клика cx/cy для FullEmulationMouseMove
- Классификация элементов: interactive, isImage, isText, isNav, isForm
- Сбор ARIA-атрибутов, data-атрибутов, вычисленных CSS-стилей
- Передача результата через base64-кодирование (защита от Unicode-проблем в DOM)
Ключевой момент по координатам: скрипт вычисляет cx и cy как абсолютные координаты страницы с учётом прокрутки:
cx = getBoundingClientRect().left + window.scrollX + width/2
cy = getBoundingClientRect().top + window.scrollY + height/2
ZennoPoster FullEmulationMouseMove принимает координаты вьюпорта, поэтому Click Analyser на следующем шаге вычитает scrollX/scrollY из итоговых координат.
Ещё одна важная деталь: рекурсия проходит не только через Light DOM, но и через Shadow DOM каждого элемента. Именно это позволяет боту «видеть» то, что скрыто от обычного парсера — веб-компоненты, кастомные элементы, изолированные фреймворки.
Полный DOM реальной страницы — это 50 000–200 000 символов JSON. Ни одна LLM-модель не переварит это эффективно в контекстном окне. Здесь в игру вступает DOM Preprocessor v8. Он фильтрует данные по следующей логике: оставляем все интерактивные элементы, видимые изображения ≥ 16px, навигационные блоки, заголовки h1–h4 и структурные контейнеры до 6-го уровня глубины. Результат: типичная страница 2000 элементов → 80–150 элементов для ИИ, сжатие ~96%.
Шаг 2. Руки бота: Click Analyser v2.0 (Python + OCR)
Стандартный клик по жёсткому XPath часто промахивается: A/B-тесты меняют вёрстку, динамические компоненты перерисовывают DOM после загрузки. Click Analyser v2.0 использует трёхслойную систему точности: логика LLM + OCR-подтверждение + scroll-коррекция координат.
Ключевое нововведение v2.0: разделение DOM на две колонки
Предыдущие версии путали лейбл над полем ввода с самим полем. Видя текст «Email» и элемент input type="email", модель могла кликнуть на заголовок вместо поля. В v2.0 DOM делится на две секции:
— INPUT_FIELDS — поля для ввода: input, textarea, select, contenteditable, role=textbox/searchbox
— CLICKABLE_ELEMENTS — кнопки и ссылки: button, a, role=button/link/menuitem/tab
Каждый элемент нормализуется в компактный формат для LLM:
[input] cx=817 cy=281 (320x4
ph="Введите email" role=textbox required=True[button] cx=960 cy=520 (200x52) text="Отправить" aria="Send form"
Системный промпт для LLM задаётся с temperature=0.05 (почти детерминированный режим) и содержит жёсткие правила матчинга:
- Если цель — поле для ввода → ищи в INPUT_FIELDS первым
- Если цель — кнопка/ссылка/таб → ищи в CLICKABLE_ELEMENTS первым
- Никогда не путай лейбл над полем с самим полем
- Координаты берутся ТОЛЬКО из DOM — никогда из OCR
- «chat input» → role=textbox, tag=textarea или input
- «send button» → кнопка с текстом «Send» или aria-label «Send»
Ответ модели — строгий JSON:
{"found": true, "x": 817, "y": 281, "label": "поле email",
"tag": "input", "reason": "input с placeholder Введите email", "confidence": "high"}
Роль OCR — подтверждение, а не источник координат. Распространённая ошибка — брать координаты из OCR. Это неверно: OCR даёт текст, но не точную позицию элемента. В Click Analyser v2.0 EasyOCR используется исключительно для подтверждения: «да, эта кнопка реально нарисована на экране прямо сейчас». Координаты — только из DOM.
После получения координат от LLM скрипт корректирует их на величину прокрутки страницы и сохраняет результат в файл coordinates.txt:
TARGET=кнопка подтверждения
FOUND=true
X=817
Y=281
ZennoPoster читает этот файл и выполняет клик.
Шаг 3. Мозг: Контроллер Консенсуса (C#)
Самая важная часть системы. Когда мы получили ответы от 3–5 разных моделей на один и тот же вопрос — кому верить? Контроллер не проводит простое голосование большинством. Он создаёт «арбитражный» мета-промпт, в котором финальная модель выступает синтезатором всех мнений — взвешивает качество аргументов, а не просто считает голоса.
Логика работы контроллера:
- Сканирует папку results_in/ на наличие .txt файлов
- Читает каждый файл — ответ одной из моделей
- Формирует структурированный мета-промпт с меткой каждого источника
- Добавляет инструкцию для арбитра: найти консенсус, отбросить галлюцинации
- Сохраняет итоговый промпт в prompts_out/ с уникальным timestamp
- Возвращает путь к файлу — ZennoPoster читает его и передаёт финальной модели
Структура мета-промпта:
Ниже представлены ответы нескольких ИИ-моделей на один и тот же запрос.
Твоя задача — выступить аналитиком-арбитром:
1. Проанализировать все варианты
2. Найти общие точки соприкосновения (консенсус)
3. Выявить и отбросить галлюцинации одиночек
4. Сформировать единый точный итоговый ответ
### Ответ ИИ #1 (01.txt) ###
[содержимое файла]
----------------------------------------------
### Ответ ИИ #2 (02.txt) ###
[содержимое файла]
----------------------------------------------
...
Синтезируй финальный результат. Структурируй ответ,
убери противоречия, выдай итоговое решение.
C#:
// --- НАСТРОЙКИ СКРИПТА ---
// Относительные пути к папкам (базируются на директории проекта Zennoposter)
string inputDirPath = Path.Combine(project.Directory, "zenno_io", "results_in");
string outputDirPath = Path.Combine(project.Directory, "zenno_io", "prompts_out");
// Удалять ли исходные файлы ответов после формирования промпта (true - да, false - нет)
bool deleteProcessedFiles = false;
// Формат расширения файлов для чтения
string fileExtension = "*.txt";
// -------------------------
// 1. Проверка существования директории с входящими данными
if (!Directory.Exists(inputDirPath))
{
project.SendErrorToLog($"Директория с ответами не найдена: {inputDirPath}", true);
throw new DirectoryNotFoundException($"Папка не существует: {inputDirPath}");
}
// 2. Создание директории для исходящих промптов, если она отсутствует
if (!Directory.Exists(outputDirPath))
{
try
{
Directory.CreateDirectory(outputDirPath);
project.SendInfoToLog($"Создана новая директория для промптов: {outputDirPath}");
}
catch (Exception ex)
{
project.SendErrorToLog($"Ошибка при создании папки {outputDirPath}: {ex.Message}", true);
throw;
}
}
// 3. Получение списка файлов из папки
string[] resultFiles = Directory.GetFiles(inputDirPath, fileExtension);
if (resultFiles.Length == 0)
{
project.SendWarningToLog($"В папке {inputDirPath} нет файлов формата {fileExtension} для обработки.", true);
return "no_files_found";
}
// 4. Формирование тела консенсус-промпта
System.Text.StringBuilder consensusPrompt = new System.Text.StringBuilder();
// Вводная системная инструкция для финальной модели
consensusPrompt.AppendLine("Ниже представлены ответы нескольких различных ИИ-моделей на один и тот же исходный запрос.");
consensusPrompt.AppendLine("Твоя задача — выступить в роли аналитика-арбитра: проанализировать все предоставленные варианты, найти общие точки соприкосновения (консенсус), выявить и отбросить возможные фактические ошибки или галлюцинации отдельных моделей, и сформировать единый, максимально точный, подробный и объективный итоговый ответ.");
consensusPrompt.AppendLine();
consensusPrompt.AppendLine("--- НАЧАЛО ОТВЕТОВ МОДЕЛЕЙ ---");
consensusPrompt.AppendLine();
int modelIndex = 1;
// 5. Чтение и объединение содержимого всех файлов
foreach (string filePath in resultFiles)
{
try
{
string fileName = Path.GetFileName(filePath);
string fileContent = File.ReadAllText(filePath, System.Text.Encoding.UTF8);
consensusPrompt.AppendLine($"### Ответ ИИ #{modelIndex} (Файл: {fileName}) ###");
consensusPrompt.AppendLine(fileContent.Trim());
consensusPrompt.AppendLine("--------------------------------------------------");
consensusPrompt.AppendLine();
modelIndex++;
}
catch (Exception ex)
{
project.SendErrorToLog($"Ошибка при чтении файла {filePath}: {ex.Message}", true);
// Продолжаем выполнение, чтобы собрать данные из оставшихся рабочих файлов
}
}
consensusPrompt.AppendLine("--- КОНЕЦ ОТВЕТОВ МОДЕЛЕЙ ---");
consensusPrompt.AppendLine();
consensusPrompt.AppendLine("Опираясь исключительно на предоставленные выше данные, синтезируй финальный результат. Структурируй его, убери противоречия и выдай итоговое решение.");
// 6. Сохранение итогового промпта
// Генерируем уникальное имя файла на основе текущего времени
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string outputFilePath = Path.Combine(outputDirPath, $"consensus_prompt_{timestamp}.txt");
try
{
File.WriteAllText(outputFilePath, consensusPrompt.ToString(), System.Text.Encoding.UTF8);
project.SendInfoToLog($"Консенсус-промпт успешно сформирован из {modelIndex - 1} файлов и сохранен: {outputFilePath}");
}
catch (Exception ex)
{
project.SendErrorToLog($"Критическая ошибка при сохранении итогового промпта: {ex.Message}", true);
throw;
}
// 7. Очистка исходных файлов (если включено в настройках)
if (deleteProcessedFiles)
{
foreach (string filePath in resultFiles)
{
try
{
File.Delete(filePath);
}
catch (Exception ex)
{
project.SendWarningToLog($"Не удалось удалить обработанный файл {filePath}: {ex.Message}", true);
}
}
project.SendInfoToLog("Очистка исходных файлов завершена.");
}
// Возвращаем путь к созданному файлу для записи в переменную Zennoposter
return outputFilePath;
Почему арбитраж лучше простого голосования? При голосовании 3:2 мы теряем нюансы: почему две модели думали иначе? Возможно, их аргументы более сильные. Арбитраж сохраняет ВСЕ аргументы и позволяет финальной модели взвесить качество рассуждений. Это ближе к тому, как работает Верховный суд, чем к выборам.
Математика надёжности: Почему это работает
Интуиция подсказывает «больше моделей = надёжнее». Теория вероятностей это строго подтверждает.
Если вероятность критической ошибки одной модели = 5%, то при независимом консенсусе пяти моделей вероятность того, что все пять ошибутся одинаково = 0.05 в пятой степени ≈ 0.0000000003125, то есть примерно одна ошибка на 3 000 000 попыток.
| Количество моделей | Формула | Вероятность ошибки |
|---|---|---|
| 1 модель | 0.05^1 | 5% (1 из 20) |
| 2 модели | 0.05^2 | 0.25% (1 из 400) |
| 3 модели | 0.05^3 | 0.0125% (1 из 8 000) |
| 5 моделей | 0.05^5 | ~0.000 000 3% (1 из 3 000 000) |
Это упрощённая оценка при условии независимости ошибок. На практике у разных моделей есть некоторые общие слепые зоны, поэтому реальное улучшение — в диапазоне 10–100× для большинства задач. Даже консервативная оценка принципиально меняет картину для критических применений.
Пять системных преимуществ консенсуса:
Защита от галлюцинаций. Если Grok «видит» несуществующую кнопку, а Claude, Gemini и ChatGPT её не находят — бот игнорирует ошибочное мнение и продолжает работу. Одиночная галлюцинация тонет в консенсусе большинства.
Устойчивость к API-сбоям. Упал один эндпоинт? Система работает на оставшихся четырёх голосах. Это встроенная избыточность — как RAID для хранения данных, но для логики принятия решений.
Самокоррекция без вмешательства. Пока вы спите, бот сам анализирует расхождения в ответах и корректирует стратегию через арбитражный мета-промпт. Нет нужды мониторить каждый шаг.
Игра на сильных сторонах каждой модели. Claude силён в рассуждениях, Gemini — в мультимодальности, ChatGPT — в следовании инструкциям, Grok — в актуальных данных. Консенсус автоматически использует лучшее от каждого.
Универсальность без переписывания. Один и тот же «Синдикат» применим для регистрации аккаунтов, анализа торговых графиков, парсинга сложных порталов, принятия решений в арбитраже. Меняется только промпт — архитектура остаётся.
Сравнение подходов
| Критерий | Один API | Ротация API | Синдикат (консенсус) |
|---|---|---|---|
| Защита от галлюцинаций | Нет | Частично | Да |
| Устойчивость к сбоям API | Нет | Да | Да |
| Самокоррекция | Нет | Нет | Да |
| Использование сильных сторон | Нет | Случайно | Да |
| Стоимость запросов | Низкая | Средняя | В 5× выше |
| Надёжность для критичных задач | Низкая | Средняя | Высокая |
| Единая точка отказа | Да | Нет | Нет |
Честно о стоимости: консенсус 5 моделей стоит в 5× дороже по количеству запросов. Это оправдано для критически важных решений — финансовые операции, сложные авторизации, торговые сигналы с реальными деньгами. Для простых задач (генерация текстов, парсинг таблиц) используйте одну модель. Синдикат — инструмент прецизионной автоматизации, а не замена для всех случаев.
Применение и адаптация под свои задачи
Архитектура намеренно спроектирована модульной. Три зоны кастомизации:
Замена моделей. Хотите добавить DeepSeek или убрать Kimi? Просто измените файловый маршрут. Контроллер не знает, чей ответ он читает — только путь к файлу txt.
Библиотека промптов. Папка all_prompts хранит промпты по задачам. Один промпт для торговли, другой для парсинга, третий для авторизации. Переключение — одна строка кода.
Порог консенсуса. Нужен суперконсенсус только при единогласии? Или достаточно 3 из 5? Логику арбитражного промпта настраивают под любой порог строгости.
Реальные кейсы применения:
Алгоритмическая торговля (Steam / фьючерсы). Бот запрашивает 5 моделей: «Покупать или ждать?» с контекстом — скриншот графика, текущая цена, история за 24ч. Расхождение мнений → повторный запрос с дополнительным контекстом. Консенсус → исполнение ордера. Нет консенсуса → пас, ждём следующей точки входа. Человеческая дисциплина, автоматизированная на уровне нейросетей.
Регистрация на сложных порталах. DOM страницы меняется после каждого A/B-теста — жёсткий XPath перестаёт работать. Click Analyser v2.0 находит кнопку «Далее» семантически — по тексту, ARIA-label, роли — а не по позиции в DOM. Пять мнений о правильном элементе: в сложных случаях это принципиально.
Анализ рекламных кабинетов. «Стоит ли масштабировать эту связку?» — консенсус аналитических моделей по скриншоту статистики даёт взвешенный ответ без субъективного bias одной нейросети.
Динамические SPA-приложения. React/Vue/Angular постоянно перерисовывают DOM. DOM Mapper захватывает актуальное состояние в момент запроса, включая Shadow DOM веб-компонентов. Работает там, где стандартный ZennoPoster «слепнет».
Практические рекомендации
С чего начать:
- Создайте структуру папок: zenno_io/results_in, prompts_out, all_prompts
- Добавьте DOM Mapper в начало вашего существующего шаблона ZennoPoster
- Начните с 3 моделей для одного критичного решения — не с пяти сразу
- Запустите Consensus Controller и изучите первые мета-промпты вручную
- Проверьте качество консенсуса на тестовых данных перед боевым запуском
- Масштабируйте до 5 моделей по мере роста доверия к системе
Честные предупреждения:
Задержка. Опрос 5 моделей параллельно занимает 30–80 секунд вместо 10–20. Для HFT или скальпинга это критично. Для большинства задач автоматизации — нет.
Зависимость от месторасположения. Все 5 сервисов должны быть доступны из вашей среды. В регионах с ограничениями часть моделей потребует прокси или альтернативных эндпоинтов.
GIGO — мусор на входе, мусор на выходе. Если все 5 моделей получили одинаково плохой контекст (страница не загрузилась полностью), консенсус воспроизведёт одинаковую ошибку. Качество входных данных критично.
Когда Синдикат НЕ нужен:
- Генерация текстового контента — одна хорошая модель справится
- Простой парсинг таблиц и структурированных данных
- Задачи с детерминированным ответом (стабильный XPath работает)
- Операции с временными ограничениями менее 2 секунд
Заключение: Новая парадигма надёжности
Одиночная модель — это гонщик Формулы-1 без запасных шин. Великолепен на прямой, беспомощен при первой нестандартной ситуации. Синдикат — это команда механиков, аналитиков и стратегов, которые работают параллельно и передают пилоту только выверенное решение.
Три компонента системы закрывают три критические задачи: DOM Mapper даёт точное зрение и видит страницу как ИИ включая всё скрытое, Click Analyser даёт точные руки через семантический поиск с OCR-подтверждением и scroll-коррекцией, Consensus Controller — железный мозг, который превращает пять разных мнений в единый вердикт.
Да, это требует чуть больше времени на настройку. Но спокойствие за проект, работающий как швейцарские часы в 3 ночи без вашего присутствия — окупает всё.
Использование консенсуса топовых моделей практически сводит вероятность фатальной ошибки к нулю. Вы получаете железобетонную логику, способную управлять самыми ответственными процессами в ZennoPoster. Адаптируйте этот «синдикат» под свои нужды, и пусть ваши боты станут по-настоящему разумными!
#ZennoPoster #AI_Consensus #BotAutomation #DOMMapper #ClickAnalyser #MultiModel #ZennoLab
Вложения
-
1,2 МБ Просмотры: 16
-
198,8 КБ Просмотры: 2
Последнее редактирование:


