Technical Architecture · v1.0

Распределённая архитектура агента для Ozon и Wildberries

Проектирование флота автономных агентов с единым центром управления, изолированными серверами кабинетов и гибридной моделью исполнения для организации «РЫСЬ-ИНСТРУМЕНТ».

📅 Октябрь 2026 🏢 Организация: РЫСЬ-ИНСТРУМЕНТ 🏷️ Проект: SellerOS Platform

Наша схема рабочая и более правильная с точки зрения изоляции, чем «один большой сервер на все кабинеты». Но проектировать её необходимо не как «много независимых агентов, которые просто смотрят в одну базу», а как распределённую систему с центральным управлением и удалёнными исполнителями.

Если коротко:

Правильная архитектура для «РЫСЬ-ИНСТРУМЕНТ» — это центральный «мозг» + удалённые агенты-исполнители на серверах под кабинеты + единая база знаний/состояния/аудита.

То есть не каждый агент сам по себе, а:

Ниже разберём архитектуру подробно с учётом специфики наших магазинов: Техбензо, ЭиБ, Техносад.

• • •

1.Что меняется по сравнению с прошлой архитектурой

В изначальном документе предполагалось примерно следующее:

Теперь применяется другая модель:

Это меняет архитектуру в лучшую сторону по изоляции, но добавляет требования к:

То есть теперь главный вопрос не «как запустить браузер в контейнере», а:

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

2.Рекомендуемая архитектура: Hub-and-Spoke

Система строится по схеме центр + исполнители.

2.1. Центральная часть — Control Plane

Это один главный сервер или группа серверов, где находятся:

  1. Чат-интерфейс пользователя
    Open WebUI, веб-кабинет, мобильный PWA-доступ.
  2. Оркестратор задач
    LangGraph или аналогичный агентный движок.
  3. Единая база данных
    PostgreSQL + pgvector.
  4. Очередь задач и событий
    NATS JetStream, Redis Streams или RabbitMQ.
  5. Хранилище артефактов
    MinIO/S3 для скриншотов, файлов, выгрузок, отчётов.
  6. API-шлюз
    FastAPI или другой сервис, через который общаются агенты.
  7. Секреты и доступы
    Желательно отдельный Vault или хотя бы шифрованное хранилище.
  8. Мониторинг
    Prometheus + Grafana + Loki.
  9. Система деплоя
    Ansible, Docker Compose, systemd.
  10. Модуль обучения
    Анализ истории действий, извлечение алгоритмов, обновление инструкций.

То есть центр — это «директор». Он:

2.2. Удалённые серверы — Worker Nodes

Каждый сервер под кабинет — это исполнитель. На нём находятся:

  1. Агент-демон — служба, которая слушает очередь задач.
  2. Браузерный профиль кабинета — для Ozon, Wildberries и других площадок.
  3. Локальный кэш сессии — cookies, localStorage, profile directory.
  4. Playwright / Chromium / Nstbrowser / обычный браузер — в зависимости от задач.
  5. Локальные скрипты RPA — для типовых операций.
  6. Локальный логгер — записывает каждый шаг.
  7. Скриншот-модуль — делает снимки до/после действий.
  8. Модуль отправки событий в центр — через NATS, HTTP API или очередь.
  9. Минимальный набор секретов — только для этого кабинета.
  10. Локальный журнал действий — чтобы при обрыве связи не потерять состояние.

То есть удалённый сервер не должен быть «умным» целиком. Он должен быть скорее руками. Он:

3.Как должны общаться агенты с центральной базой

Вот здесь важный момент.

Плохой вариант

Каждый агент на каждом сервере напрямую подключается к одной базе данных. Например:

worker-tehbenzo -> PostgreSQL
worker-eib       -> PostgreSQL
worker-tehnosad  -> PostgreSQL
worker-wb-1      -> PostgreSQL

Это просто на старте, но плохо по безопасности и управлению. Минусы:

Правильный вариант

Агенты не ходят напрямую в базу. Они общаются с центром через:

  1. Очередь задач
  2. API Control Plane
  3. Событийный канал

Например:

User -> Open WebUI -> LangGraph Orchestrator -> NATS -> Worker-Tehbenzo
Worker-Tehbenzo -> NATS/MinIO/API -> Control Plane -> PostgreSQL

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

4.Что должно быть в единой базе

Единая база нужна обязательно. Но нужно разделить типы данных.

4.1. Реестр кабинетов

Таблица кабинетов:

account_id
marketplace = ozon / wildberries
shop_name
client_id
assigned_worker_id
status
ip_address
browser_profile_id
timezone
locale
api_key_ref
created_at
updated_at

Пример для наших магазинов:

account_id: ozon_tehbenzo
marketplace: ozon
shop_name: Техбензо
assigned_worker: server-ozon-tehbenzo
status: active
browser_profile: profile_ozon_tehbenzo

account_id: ozon_eib
marketplace: ozon
shop_name: ЭиБ
assigned_worker: server-ozon-eib
status: active
browser_profile: profile_ozon_eib

account_id: ozon_tehnosad
marketplace: ozon
shop_name: Техносад
assigned_worker: server-ozon-tehnosad
status: active
browser_profile: profile_ozon_tehnosad

Это нужно, чтобы оркестратор понимал:

4.2. Реестр серверов/воркеров

worker_id
hostname
ip_address
capacity
assigned_accounts
status
last_heartbeat
version
cpu_usage
ram_usage
browser_count

Пример:

worker_id: worker-ozon-tehbenzo
hostname: ozon-node-tehbenzo
ip: 185.x.x.10
capacity: 1 cabinet
status: online
last_heartbeat: 2026-10-03 14:22:10
version: agent-0.3.1

worker_id: worker-ozon-eib
hostname: ozon-node-eib
ip: 185.x.x.11
capacity: 1 cabinet
status: online
last_heartbeat: 2026-10-03 14:22:12
version: agent-0.3.1

worker_id: worker-ozon-tehnosad
hostname: ozon-node-tehnosad
ip: 185.x.x.12
capacity: 1 cabinet
status: online
last_heartbeat: 2026-10-03 14:22:14
version: agent-0.3.1

Это нужно для мониторинга и маршрутизации.

4.3. Таблица задач

task_id
user_id
account_id
task_type
payload_json
priority
status
requires_approval
created_at
started_at
finished_at
worker_id
result_json
error_message

Пример задачи:

{
  "task_id": "task_12345",
  "account_id": "ozon_tehbenzo",
  "task_type": "change_prices",
  "payload": {
    "shop": "Техбензо",
    "change_type": "percent",
    "value": 5,
    "scope": "all_active_products",
    "category": "бензопилы"
  },
  "requires_approval": true,
  "priority": "normal"
}

4.4. История действий / аудит

event_id
task_id
worker_id
account_id
step_number
action_type
status
screenshot_url
extracted_data_json
timestamp

Пример:

{
  "event_id": "evt_998877",
  "task_id": "task_12345",
  "account_id": "ozon_tehbenzo",
  "step_number": 4,
  "action_type": "click_save_button",
  "status": "success",
  "screenshot_url": "s3://artifacts/ozon_tehbenzo/task_12345/step_4.png"
}

Это очень важно для обучения и разбора ошибок.

4.5. Алгоритмы и процедуры

Это самая ценная часть для обучения.

procedure_id
name
marketplace
account_scope
description
steps_json
prompt_template
version
status
created_from_task_id
success_count
failure_count
last_used_at

Пример процедуры:

{
  "procedure_id": "proc_ozon_change_price_tehbenzo",
  "name": "Изменение цены товара в Ozon для Техбензо",
  "marketplace": "ozon",
  "account_scope": "ozon_tehbenzo",
  "version": 12,
  "steps": [
    { "step": 1, "action": "open_seller_cabinet", "target": "https://seller.ozon.ru" },
    { "step": 2, "action": "navigate", "target": "Цены и скидки" },
    { "step": 3, "action": "search_product", "target": "SKU бензопилы или название" },
    { "step": 4, "action": "update_price", "field": "price_input" },
    { "step": 5, "action": "click", "target": "Сохранить" },
    { "step": 6, "action": "verify", "condition": "price_saved_success" }
  ]
}

Это и есть «обучение»: система записывает действия, превращает их в процедуры и потом переиспользует.

4.6. Векторная память

Для обучения и понимания команд нужна векторная база. Можно использовать:

Что хранить:

Пример:

Пользователь: "Подними цены в Техбензо на 7% на все бензопилы"
Векторная память находит:
- процедуру изменения цен для Техбензо;
- нужный кабинет ozon_tehbenzo;
- прошлый успешный сценарий;
- ограничения по подтверждению.

4.7. Секреты и ключи

Это отдельный критичный блок. Нужно хранить:

Но нельзя хранить их в открытом виде в общей базе.

Минимально правильный вариант:

  1. Секреты шифруются.
  2. В базе хранится только ссылка на секрет.
  3. Реальный секрет выдаётся только нужному воркеру.
  4. Каждый воркер получает только свои секреты.
  5. Все выдачи логируются.

Из бесплатных/условно бесплатных инструментов:

Лучше всего:

Control Plane -> Vault -> Worker получает секрет только на время выполнения

5.Почему не стоит давать каждому агенту прямой доступ ко всей базе

Это важный архитектурный момент.

Если у нас несколько серверов под магазины «РЫСЬ-ИНСТРУМЕНТ» (Техбензо, ЭиБ, Техносад), и каждый сервер имеет прямой доступ к общей базе, то:

Правильнее:

Агент не знает лишнего.
Агент получает только задачу для своего кабинета.
Агент отправляет только результат.
Всю общую логику хранит центр.

То есть база одна, но доступ к ней централизованный.

6.Как лучше организовать очередь задач

Для распределённых агентов нужна нормальная очередь. Не стоит делать так:

агент каждые 5 секунд спрашивает базу: есть задача?

Это будет грязно и неэффективно. Лучше использовать очередь событий.

Рекомендуемые варианты

1. NATS JetStream — лучший вариант для нашей схемы

Плюсы:

Пример каналов:

tasks.ozon.tehbenzo
tasks.ozon.eib
tasks.ozon.tehnosad
tasks.wb.main
events.worker-ozon-tehbenzo
events.worker-ozon-eib
events.worker-ozon-tehnosad
approvals.tasks
worker.heartbeat

2. Redis Streams

Плюсы:

Минусы:

3. RabbitMQ

Плюсы:

Минусы:

Рекомендация

Для проекта «РЫСЬ-ИНСТРУМЕНТ»:

NATS JetStream — основной транспорт задач и событий.
PostgreSQL — состояние, аудит, процедуры, кабинеты.
Redis — кэш, блокировки, быстрые статусы.
MinIO — файлы, скриншоты, отчёты.

7.Как должна идти задача от пользователя до сервера

Разберём на примере команды:

«Подними цены в Техбензо на 5% на все бензопилы»

Шаг 1. Пользователь пишет в чат

Например:

Подними цены в кабинете Ozon «Техбензо» на 5% для всех активных бензопил.

Шаг 2. Центр принимает команду

Оркестратор получает сообщение и начинает разбор. Он определяет:

Шаг 3. Центр находит нужный кабинет

По базе:

account_name = Техбензо
marketplace = ozon
assigned_worker = worker-ozon-tehbenzo

Шаг 4. Центр выбирает способ выполнения

Тут важно помнить трёхуровневую модель из прошлого документа:

  1. Сначала API
  2. Потом RPA/UI
  3. Потом VLM/Computer Use

Для изменения цен на Ozon лучше сначала пробовать официальный API. Если есть полный API-доступ, то часто даже не нужно открывать браузер. Пример:

1. Получить список товаров Техбензо.
2. Получить текущие цены.
3. Отфильтровать категорию "бензопилы".
4. Рассчитать новые цены (+5%).
5. Показать пользователю план изменений.
6. Получить подтверждение.
7. Отправить новые цены через API.
8. Проверить результат.

Это быстрее, безопаснее и стабильнее.

Шаг 5. Центр формирует план изменений

Перед любыми изменениями система должна показать план. Например:

Кабинет: Ozon Техбензо
Товаров к изменению: 47 (бензопилы)
Метод: +5% к текущей цене
Способ: Ozon Seller API
Риск: средний
Требуется подтверждение: да

И таблица:

Бензопила Штиль MS-180: 18 900 ₽ -> 19 845 ₽
Бензопила Хускварна 236: 24 500 ₽ -> 25 725 ₽
Бензопила Партнер 350: 9 900 ₽ -> 10 395 ₽
...

Шаг 6. Пользователь подтверждает

В чате появляется кнопка или запрос:

Подтвердить изменение цен в Техбензо?
[Подтвердить] [Отклонить]

Пока подтверждения нет, задача не выполняется. Это и есть Human-in-the-Loop.

Шаг 7. Центр отправляет задачу на worker

Если задача через API:

Control Plane -> NATS -> worker-ozon-tehbenzo -> Ozon API

Если задача через браузер:

Control Plane -> NATS -> worker-ozon-tehbenzo -> Playwright -> Ozon Seller UI

Шаг 8. Worker выполняет задачу

Worker делает:

  1. Вход/проверку сессии.
  2. Открытие нужного раздела.
  3. Поиск товаров.
  4. Применение изменений.
  5. Скриншоты.
  6. Проверку результата.
  7. Отправку статуса в центр.

Шаг 9. Центр сохраняет результат

В базу пишется:

Задача завершена
Кабинет: Техбензо
Изменено товаров: 47
Ошибок: 0
Скриншоты: есть
Время выполнения: 2 минуты

Шаг 10. Пользователь получает отчёт

В чат приходит:

Готово.
Цены обновлены в кабинете Ozon «Техбензо».
Изменено: 47 товаров (бензопилы).
Ошибок: 0.
Отчёт: ссылка.

8.Какие компоненты должны быть на центральном сервере

Ниже практичный бесплатный/самодостаточный стек.

8.1. Операционная система

Ubuntu Server 24.04 LTS

Для центра лучше именно Server, не Desktop.

8.2. Контейнеризация

Для центра:

Docker Compose

или

Podman Compose

На старте Docker Compose проще.

8.3. База данных

PostgreSQL 16 + pgvector

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

8.4. Очередь

NATS JetStream

Для задач, событий, статусов, подтверждений.

8.5. Объектное хранилище

MinIO

Хранит: скриншоты, PDF, Excel-выгрузки, отчёты, видео/записи действий, если будут.

8.6. Оркестратор

Python + FastAPI + LangGraph

или:

Python + FastAPI + Qwen-Agent

Но для сложного управления состояниями, подтверждениями и самокоррекцией LangGraph лучше.

8.7. Чат-интерфейс

Open WebUI

Плюсы:

Если нужен более кастомный интерфейс с кнопками, таблицами и подтверждениями, можно дополнительно сделать:

Next.js + AG-UI / CopilotKit

Но для старта лучше Open WebUI.

8.8. Мониторинг

Prometheus
Grafana
Loki
Node Exporter

Опционально:

Uptime Kuma
Alertmanager

8.9. Авторизация

Минимально:

Open WebUI auth + API tokens

Лучше:

Authentik

или

Keycloak

Если будет много пользователей и разные права доступа.

8.10. Секреты

Лучше:

Vault

Минимально:

SOPS + age + Ansible

8.11. Деплой

Ansible

Обязательно. Если серверов много, руками их замучаешься настраивать.

9.Какие компоненты должны быть на сервере под кабинет

На каждом удалённом сервере должен быть минимальный, но одинаковый набор.

9.1. ОС

Ubuntu Server 24.04 LTS

Desktop нужен только если требуется визуальный браузер с GUI, но чаще можно работать через headless браузер или виртуальный дисплей.

9.2. Агент-демон

Например:

/opt/agent/agent-daemon
/etc/agent/config.yaml
/var/log/agent/

Он запускается через systemd:

systemctl start marketplace-agent

9.3. Браузер

Для UI-задач:

Chromium

или:

Playwright Chromium

или:

Nstbrowser / антидетект-профиль

Если задача только через API, браузер может вообще не запускаться.

9.4. Локальный профиль кабинета

Например:

/opt/agent/profiles/ozon_tehbenzo/
/opt/agent/profiles/ozon_eib/
/opt/agent/profiles/ozon_tehnosad/

Внутри:

browser_profile/
cookies/
local_storage/
settings.json

Это важно: у каждого кабинета должен быть свой постоянный профиль.

9.5. Локальный кэш задач

На случай обрыва связи:

/var/lib/agent/task_queue/
/var/lib/agent/journal/

9.6. Логи

/var/log/agent/agent.log
/var/log/agent/browser.log
/var/log/agent/errors.log

9.7. Мониторинг

Минимум:

node_exporter

Или встроенный /health endpoint агента.

10.Как связать серверы между собой

Очень важно: не нужно выставлять базу, очередь и внутренние сервисы наружу.

Лучшая схема:

Все серверы соединены в приватную сеть через WireGuard / Tailscale / NetBird.

Например:

Control Plane:       10.10.0.1
PostgreSQL:          10.10.0.2
NATS:                10.10.0.3
MinIO:               10.10.0.4
Worker-Tehbenzo:     10.10.1.11
Worker-EiB:          10.10.1.12
Worker-Tehnosad:     10.10.1.13

Тогда:

Варианты приватной сети

1. WireGuard

Плюсы:

Минусы:

2. Tailscale

Плюсы:

Минусы:

3. NetBird

Плюсы:

Рекомендация

Если нужна максимальная автономность:

WireGuard

Если хочется быстро и удобно:

Tailscale

Если серверов будет много и нужна нормальная сеть:

WireGuard + Ansible

11.Безопасность в такой схеме

Это один из самых важных разделов.

11.1. Минимальные привилегии

Каждый агент должен иметь доступ только к своему кабинету.

Неправильно:

worker-ozon-tehbenzo знает ключи от ЭиБ и Техносад.

Правильно:

worker-ozon-tehbenzo знает только ключи кабинета ozon_tehbenzo.
worker-ozon-eib знает только ключи кабинета ozon_eib.
worker-ozon-tehnosad знает только ключи кабинета ozon_tehnosad.

11.2. Запрет прямого доступа к общей базе

Агенты не должны подключаться к PostgreSQL напрямую. Лучше:

Агент -> Control Plane API / NATS

11.3. Подтверждение опасных действий

Все изменения должны требовать подтверждение:

Без подтверждения можно разрешить только:

11.4. Аудит

Каждое действие должно сохранять:

11.5. Ограничение команд

Нужен белый список разрешённых операций. Например:

can_read_prices
can_change_prices
can_change_stock
can_edit_cards
can_manage_ads
can_download_reports
can_delete_products

И по пользователям «РЫСЬ-ИНСТРУМЕНТ»:

Руководитель: полный доступ ко всем кабинетам
Менеджер Техбензо: только кабинет Техбензо, чтение + выгрузки
Менеджер ЭиБ: только кабинет ЭиБ, изменение цен после подтверждения
Менеджер Техносад: только кабинет Техносад, изменение цен после подтверждения

11.6. Защита от случайных ошибок

Перед изменением цен система должна делать:

  1. Снимок текущих цен.
  2. Расчёт новых цен.
  3. Проверку минимальных/максимальных порогов.
  4. Проверку на аномалии.
  5. Подтверждение.
  6. Выполнение.
  7. Повторную проверку.

Например:

Если цена меняется больше чем на 30% за раз — требовать повторное подтверждение.
Если цена становится ниже себестоимости — стоп.
Если товаров больше 1000 — показывать сводку и давать частичный запуск.

11.7. Идемпотентность

Очень важно. Если задача «поднять цену» выполнилась, но сеть оборвалась, повторный запуск не должен поднять цену ещё раз.

Правильная логика:

1. Получить текущую цену.
2. Сравнить с целевой.
3. Если уже целевая — пропустить.
4. Если нет — обновить.
5. Записать результат.

12.Как обучать агентов при распределённой схеме

Идея обучаться на действиях пользователей очень хорошая, но обучение лучше делать централизованно.

Что собирают воркеры

Каждый сервер собирает:

  1. Команды пользователя.
  2. Шаги выполнения.
  3. Скриншоты.
  4. Селекторы, если они были.
  5. URL.
  6. Ошибки.
  7. Успешные результаты.
  8. Время выполнения.
  9. Данные до изменения.
  10. Данные после изменения.

Что делает центр

Центр:

  1. Собирает события со всех воркеров (Техбензо, ЭиБ, Техносад).
  2. Группирует похожие действия.
  3. Извлекает повторяющиеся сценарии.
  4. Создаёт процедуры.
  5. Сохраняет их в базе.
  6. Связывает с командами пользователя.
  7. Тестирует на сухом прогоне.
  8. Применяет в будущем.

Где происходит дообучение моделей

Не на каждом сервере. Дообучение лучше делать централизованно:

События со всех серверов -> центральное хранилище -> обучающий пайплайн -> обновлённая модель/промпты/процедуры

Для дообучения можно использовать:

Но на старте лучше не делать ставку на полноценное дообучение. Лучше начать с:

  1. Записи действий.
  2. Извлечения процедур.
  3. Векторного поиска.
  4. Промпт-шаблонов.
  5. Версионирования алгоритмов.

Это быстрее и надёжнее.

13.Как хранить алгоритмы действий

Это ключевая часть «обучения». Алгоритмы должны быть не просто текстом, а структурой.

Пример уровня 1: API-процедура

{
  "name": "ozon_change_price_percent_tehbenzo",
  "type": "api",
  "marketplace": "ozon",
  "account_scope": "ozon_tehbenzo",
  "steps": [
    { "action": "get_products", "filter": "active", "category": "бензопилы" },
    { "action": "get_prices" },
    { "action": "calculate_new_prices", "formula": "current_price * 1.05" },
    { "action": "human_approval" },
    { "action": "update_prices" },
    { "action": "verify_prices" }
  ]
}

Пример уровня 2: UI-процедура

{
  "name": "ozon_edit_card_title_eib",
  "type": "rpa_plus_vlm",
  "marketplace": "ozon",
  "account_scope": "ozon_eib",
  "steps": [
    { "action": "open_page", "url": "https://seller.ozon.ru/app/products" },
    { "action": "find_product", "method": "search_by_name_or_sku" },
    { "action": "open_card" },
    { "action": "find_field", "field": "Название" },
    { "action": "replace_text" },
    { "action": "human_approval" },
    { "action": "click_save" },
    { "action": "verify_saved" }
  ]
}

Пример уровня 3: адаптивная VLM-процедура

{
  "name": "ozon_generic_price_change_vlm_tehnosad",
  "type": "vlm",
  "marketplace": "ozon",
  "account_scope": "ozon_tehnosad",
  "goal": "Изменить цену товара (газонокосилка/триммер) на указанное значение",
  "strategy": [
    "Сделать скриншот страницы",
    "Найти товар",
    "Найти поле цены",
    "Ввести новое значение",
    "Нажать сохранить",
    "Проверить сообщение об успехе"
  ],
  "fallback": "ask_human"
}

14.Как обновлять агентов на всех серверах

Если серверов много, обновления должны быть автоматическими.

Рекомендуемый подход

Единый образ агента + Ansible деплой

Например:

/ansible
  inventory/
  playbooks/
    install_worker.yml
    update_agent.yml
    restart_agent.yml
    setup_firewall.yml
    setup_vpn.yml

Инвентарь:

[tehbenzo_workers]
ozon-node-tehbenzo ansible_host=1.2.3.10

[eib_workers]
ozon-node-eib ansible_host=1.2.3.11

[tehnosad_workers]
ozon-node-tehnosad ansible_host=1.2.3.12

[wb_workers]
wb-node-main ansible_host=1.2.4.10

Обновление:

ansible-playbook update_agent.yml --limit tehbenzo_workers
ansible-playbook update_agent.yml --limit eib_workers
ansible-playbook update_agent.yml --limit tehnosad_workers

15.Как мониторить флот агентов

Нужен единый мониторинг.

Что мониторить

На серверах

В задачах

В кабинетах

Стек

Prometheus
Grafana
Loki
Node Exporter
Alertmanager

Для простых алертов:

Telegram webhook

Пример алерта:

Worker ozon-node-tehbenzo не выходил на связь 5 минут.
Кабинет: Ozon Техбензо.
Последняя задача: task_99812.
Статус: unknown.

16.Что делать, если сервер кабинета упал

Нужно продумать отказоустойчивость.

Вариант 1. Только задачи через API

Если задача может быть выполнена через API, то падение UI-сервера не критично. Например:

Центр может выполнить изменение цен Техбензо через Ozon API без участия конкретного сервера.

Но нужно учитывать лимиты и безопасность.

Вариант 2. Задача только через UI

Если задача требует браузерной сессии, то сервер важен. Тогда при падении:

  1. Задача ставится в очередь ожидания.
  2. Пользователь получает уведомление.
  3. Ничего не выполняется на другом сервере автоматически.
  4. После восстановления сервера задача продолжается.

Почему не стоит автоматически переносить кабинет на другой сервер? Потому что:

Вариант 3. Горячий резерв для критичных кабинетов

Для важных кабинетов можно иметь резервный сервер, но это сложнее. Нужно заранее понимать:

Поэтому для начала лучше:

Один кабинет (Техбензо, ЭиБ, Техносад) = один активный сервер-исполнитель.

17.Единая база данных: требования и риски

Плюсы одной базы

  1. Единая память.
  2. Единые алгоритмы.
  3. Единая история.
  4. Удобно обучаться.
  5. Удобно управлять.
  6. Нет рассинхрона.

Риски одной базы

  1. Единая точка отказа.
  2. Риск потери данных.
  3. Риск компрометации.
  4. Нагрузка от множества агентов.
  5. Конфликты одновременной записи.
  6. Сложность резервного копирования.

Как снизить риски

1. Не давать агентам прямой доступ

Агенты через центр/очередь.

2. Резервное копирование

Минимум:

pg_dump ежедневно
WAL-архивирование
бэкапы в S3/MinIO
проверка восстановления

Лучше:

pgBackRest или WAL-G

3. Репликация

Для начала можно без горячей реплики, но желательно иметь:

PostgreSQL primary
PostgreSQL standby

Если проект будет критичным, использовать:

Patroni
etcd
HAProxy

Но это уже высокий уровень сложности.

4. Локальный журнал на воркерах

Если база недоступна, воркер должен:

18.Как распределять кабинеты по серверам

Под каждый кабинет свой сервер. Это максимальная изоляция. Но есть несколько вариантов.

Вариант A. Один кабинет = один сервер

Плюсы:

Минусы:

Когда подходит:

Вариант B. Один сервер = несколько кабинетов

Плюсы:

Минусы:

Когда подходит:

Вариант C. Гибрид

Рекомендуется гибрид.

API-задачи выполняются централизованно или с любого доверенного узла.
UI-задачи выполняются на выделенном сервере под кабинет.

Например:

19.Что лучше: один агент на сервере или несколько контейнеров

Если сервер выделен под один кабинет, то внутри можно не усложнять. Можно запускать:

systemd service -> agent -> browser profile

Но если на сервере несколько кабинетов, тогда нужна изоляция. Варианты:

  1. Docker-контейнеры.
  2. LXC/LXD.
  3. systemd-nspawn.
  4. отдельные Linux-пользователи.
  5. отдельные X-сессии / браузерные профили.

Из прошлого документа хороший вариант — LXC/LXD, но он сложнее. Для старта проще:

Docker Compose + Playwright container

Если нужна более серьёзная изоляция:

LXC unprivileged containers

20.Какие задачи можно выполнять через API, а какие через UI

Это важно для распределения нагрузки.

Ozon через API обычно хорошо подходит для:

Через UI чаще нужно:

Важно
Если площадка даёт официальный API, всегда сначала использовать его.

21.Как должна выглядеть база знаний после обучения

После месяца наблюдений система должна иметь примерно такие сущности.

21.1. Команды пользователя

"подними цены в Техбензо на 5% на все бензопилы"
"убери скидку на триммеры в ЭиБ"
"обнови остатки по газонокосилкам в Техносад"
"скачай отчёт по продажам Техбензо за неделю"
"поменяй фото в карточке бензопилы Штиль MS-180"
"включи рекламу на генераторы в ЭиБ"

Каждая команда связывается с: кабинетом, действием, параметрами, процедурой, уровнем риска.

21.2. Процедуры

ozon_tehbenzo_price_change_percent
ozon_eib_price_change_fixed
ozon_tehnosad_stock_update_from_excel
ozon_tehbenzo_card_edit_title
ozon_eib_card_edit_photos
ozon_tehnosad_ads_enable_campaign
ozon_tehbenzo_download_sales_report

21.3. Параметры

shop_name (Техбензо / ЭиБ / Техносад)
sku
product_name
percent
fixed_price
min_price
max_price
apply_to_all
apply_to_category

21.4. Ограничения

min_price_threshold
max_change_percent
require_approval
allowed_users
allowed_time_window

21.5. История

кто запустил
когда
в каком кабинете (Техбензо / ЭиБ / Техносад)
какие товары
какие цены до
какие цены после
успех/ошибка

22.Как сделать чат-приложение удобным

Нужно, чтобы можно было зайти с ПК, телефона, браузера и написать агенту. Для этого нужно:

  1. Веб-интерфейс.
  2. Мобильный PWA.
  3. Быстрая авторизация.
  4. Список кабинетов.
  5. Список задач.
  6. Кнопки подтверждения.
  7. История действий.
  8. Уведомления.

Минимальный сценарий UX

Пользователь заходит и видит:

РЫСЬ-ИНСТРУМЕНТ
Кабинеты:
- Ozon Техбензо
- Ozon ЭиБ
- Ozon Техносад
- WB Основной

Быстрые команды:
- Поднять цены
- Опустить цены
- Обновить остатки
- Скачать отчёт
- Проверить статус задач

Пишет:

Подними цены в Техбензо на 5%

Система отвечает:

Найдено 320 товаров.
После изменения:
- минимальная цена: 590 → 619 ₽
- максимальная цена: 45 990 → 48 289 ₽
Средний рост: 5%

Подтвердить?

Пользователь жмёт:

Подтвердить

Система выполняет и возвращает:

Выполнено.
Изменено 320 товаров.
Ошибок 0.
Скриншоты доступны.

23.Как реализовать подтверждения

Это критично.

Уровни подтверждения

Уровень 1. Не требует подтверждения

Только чтение:

покажи цены Техбензо
покажи остатки ЭиБ
скачай отчёт Техносад
проверь статус

Уровень 2. Простое подтверждение

Одно действие:

поднять цену на один товар в Техбензо
изменить заголовок карточки в ЭиБ
включить кампанию в Техносад

Уровень 3. Массовое подтверждение

Много объектов:

изменить цены на 1000 товаров в Техбензо
обновить остатки по всему магазину ЭиБ

Здесь лучше показывать:

Уровень 4. Двойное подтверждение

Опасные операции:

удаление товаров
отключение магазина
снятие с продажи
массовое изменение цен больше чем на 20%
изменение бюджета рекламы выше порога

24.Как вести журнал изменений

Для маркетплейсов и бизнеса важно иметь журнал. Пример записи:

{
  "change_id": "chg_001",
  "timestamp": "2026-10-03T14:25:00Z",
  "marketplace": "ozon",
  "account": "ozon_tehbenzo",
  "object_type": "product_price",
  "object_id": "SKU-TB-2024-001",
  "product_name": "Бензопила Штиль MS-180",
  "old_value": 18900,
  "new_value": 19845,
  "initiated_by": "manager_tehbenzo",
  "approved_by": "director",
  "executed_by": "worker-ozon-tehbenzo",
  "method": "api",
  "status": "success"
}

Это даст возможность:

25.Как сделать откат изменений

Для начала можно реализовать не физический откат, а логический. Перед изменением система сохраняет:

старая цена
старый остаток
старое название
старое описание
старая ставка рекламы

Потом при необходимости:

Откатить задачу task_12345

Система предлагает:

Найдено 47 изменений в Техбензо.
Откатить все?
[Да] [Нет]

Для цен это реализуется хорошо. Для карточек сложнее, но тоже возможно, если сохранять старые значения.

26.Какие риски у схемы «много серверов + общая база»

Риск 1. Сложность управления

Чем больше серверов, тем сложнее: обновления, мониторинг, диагностика, конфигурация.

Решение:

Ansible + единый образ агента + версионирование.

Риск 2. Рассинхронизация кабинетов

Если один кабинет начали менять два агента одновременно, будет хаос.

Решение:

один активный исполнитель на кабинет;
блокировки по account_id;
очередь задач.

Риск 3. Падение центральной базы

Если база одна и падает, система теряет память.

Решение:

бэкапы;
репликация;
локальные журналы воркеров;
очередь с сохранением событий.

Риск 4. Компрометация одного из серверов

Если сервер взломан, он может отправлять вредные события.

Решение:

минимальные права;
подписи задач;
аудит;
изоляция секретов;
whitelist команд;
ручное подтверждение опасных действий.

Риск 5. Ошибки LLM

LLM может неправильно понять команду.

Решение:

структурированное подтверждение;
показывать план;
не выполнять без явного одобрения;
ограничивать допустимые действия.

Риск 6. Изменения интерфейсов маркетплейсов

Сайты меняются, селекторы ломаются.

Решение:

гибридная модель:
1. API
2. RPA
3. VLM fallback

27.Какой технологический стек используется

Ниже практичный бесплатный стек.

Центральные компоненты

Ubuntu Server 24.04
Docker Compose
PostgreSQL 16 + pgvector
NATS JetStream
Redis
MinIO
FastAPI
LangGraph
Open WebUI
Caddy или Traefik
Prometheus
Grafana
Loki
Ansible

Worker-серверы

Ubuntu Server 24.04
Python 3.12
Playwright
Chromium
systemd
Node Exporter
WireGuard/Tailscale
Vector или Fluent Bit для логов

Агентская часть

LangGraph — центральный оркестратор
Qwen-Agent — вспомогательные агенты
DashScope API — LLM/VLM
MCP-серверы — для Ozon и Wildberries
LLaMA-Factory — дообучение, если понадобится

Хранение знаний

PostgreSQL
pgvector
MinIO

Сеть и безопасность

WireGuard
Caddy
Authentik или Keycloak
Vault или SOPS
Ansible Vault

28.Какую модель использования DashScope выбрать

Есть доступ к 250 моделям — это отлично. Но важно распределять задачи.

Для простых команд

Использовать дешёвые/быстрые текстовые модели:

классификация команды
определение кабинета (Техбензо / ЭиБ / Техносад)
извлечение параметров
маршрутизация

Для сложного планирования

Использовать более сильные текстовые модели:

планирование задач
анализ рисков
генерация плана
объяснение ошибок

Для скриншотов и интерфейсов

Использовать VLM:

qwen-vl-max
qwen-vl-plus
qwen3-vl версии

Задачи:

Для обучения

Использовать централизованный пайплайн:

данные -> разметка -> LoRA/SFT -> оценка -> деплой

Но на старте лучше обойтись без дообучения, через:

29.Какие серверы нужны по ресурсам

Ниже ориентир.

Центральный сервер / Control Plane

Если всё в одном месте:

CPU: 8 vCPU
RAM: 16-32 GB
SSD: 500 GB NVMe
Network: 100 Mbps+

Если разделять:

Control Plane

CPU: 4-8 vCPU
RAM: 8-16 GB
SSD: 200 GB

PostgreSQL + pgvector

CPU: 4-8 vCPU
RAM: 16-32 GB
SSD: 500 GB - 1 TB NVMe

MinIO

CPU: 2-4 vCPU
RAM: 4-8 GB
SSD/HDD: 1-5 TB

Worker под кабинет

Если в основном API:

CPU: 1-2 vCPU
RAM: 2 GB
SSD: 20-40 GB

Если браузер:

CPU: 2-4 vCPU
RAM: 4-8 GB
SSD: 40-80 GB

Если тяжёлые страницы и скриншоты:

CPU: 4 vCPU
RAM: 8 GB
SSD: 80 GB

30.Примерная стоимость

Если серверы уже есть, основная стоимость — администрирование и поддержка. Если арендовать, ориентиры могут быть такими.

Маленький пилот

1 control plane
1 database
3 worker (Техбензо + ЭиБ + Техносад)

Примерно:

Control: $50-100/мес
DB: $50-120/мес
Workers: 3 x $20-50 = $60-150/мес
Итого: $160-370/мес

Средний масштаб, с учётом Wildberries и резерва

Если по серверу на кабинет:

5 workers (Техбензо, ЭиБ, Техносад, WB, резерв)
1 control
1 db
1 storage/monitoring

Примерно:

Workers: 5 x $20-40 = $100-200
Control: $80-150
DB: $80-200
Storage/monitoring: $50-100
Итого: $310-650/мес

Если своё железо/серверы уже есть

Тогда расходы:

электричество;
интернет;
резервные копии;
администрирование;
возможно прокси;
разработка.

31.Что обязательно добавить к прошлому документу

В прошлом документе хорошо описаны: гибридная автоматизация, VLM + RPA, LangGraph, HITL, изоляция, чат-интерфейс, обучение. Теперь нужно добавить:

1. Распределённую архитектуру

Control Plane + Worker Nodes

2. Реестр воркеров и кабинетов

Каждый кабинет знает свой сервер.

3. Очередь задач

NATS JetStream или аналог.

4. Запрет прямого доступа агентов к общей базе

Агенты общаются через центр.

5. Локальный журнал на каждом воркере

На случай обрыва связи.

6. Идемпотентность операций

Чтобы повтор не сделал изменение дважды.

7. Версионирование агентов

Каждый сервер должен иметь версию.

8. Централизованный деплой

Ansible.

9. Мониторинг всех серверов

Prometheus/Grafana.

10. Стратегию восстановления

Что делать, если сервер упал.

32.Рекомендуемая итоговая архитектура

Целевая схема для «РЫСЬ-ИНСТРУМЕНТ»:

Пользователь
   |
   | HTTPS
   v
Open WebUI / Web App / PWA
   |
   v
Control Plane API
   |
   |-- PostgreSQL + pgvector
   |-- Redis
   |-- MinIO
   |-- NATS JetStream
   |-- LangGraph Orchestrator
   |-- MCP Ozon Server
   |-- MCP Wildberries Server
   |-- Monitoring
   |-- Auth
   |-- Vault/SOPS
   |
   v
Worker Servers
   |
   |-- Worker Ozon Техбензо
   |-- Worker Ozon ЭиБ
   |-- Worker Ozon Техносад
   |-- Worker WB Основной
   |-- Worker резервный

Каждый Worker:

Agent Daemon
Browser Profile
Local Journal
Playwright
Local Secrets for one cabinet
Screenshot Module
Heartbeat Module

33.Как должна выглядеть команда разработки по этапам

Этап 0. Инвентаризация

Нужно собрать:

список серверов;
список кабинетов (Техбензо, ЭиБ, Техносад, WB);
список IP;
список API-ключей;
какие задачи нужны по каждому кабинету;
какие операции можно делать через API;
какие только через UI;
кто имеет право подтверждать изменения.

Результат:

реестр кабинетов и серверов

Этап 1. Сеть и безопасность

Сделать:

WireGuard/Tailscale
firewall
SSH hardening
запрет внешних портов для БД
отдельная подсеть
бэкап-доступ

Этап 2. Центральный сервер

Поднять:

PostgreSQL
NATS
Redis
MinIO
FastAPI
Open WebUI
Caddy
Monitoring

Этап 3. Реестр и очередь

Создать таблицы:

workers
accounts
tasks
events
procedures
approvals
audit_log

Этап 4. Worker-агент

Написать агент:

регистрация
получение задач
выполнение
скриншоты
журнал
отправка событий
ожидание подтверждения

Этап 5. Первые задачи

Начать с безопасных:

выгрузка отчёта
просмотр цен
просмотр остатков
проверка статуса

Потом:

изменение одного товара
массовое изменение цен
редактирование карточек

Этап 6. Обучение

Включить:

запись действий
сохранение скриншотов
извлечение процедур
сохранение шаблонов команд

Этап 7. Масштабирование

Подключать новые кабинеты:

новый сервер -> Ansible -> регистрация -> назначение кабинета -> тест -> запуск

34.Главный вывод

Идея с отдельными серверами под каждый кабинет — хорошая и безопасная, если кабинеты действительно важные и их нужно изолировать.

Но реализовывать нужно так:

Не "много умных агентов с общей базой",
а "один центр управления и много удалённых исполнителей".

То есть:

  1. Управление — централизовано.
  2. Память — централизована.
  3. Обучение — централизовано.
  4. Подтверждения — централизованы.
  5. Исполнение — распределено.
  6. Секреты — минимально необходимые.
  7. База — одна, но доступ к ней только через доверенный центр.
  8. Каждый сервер отвечает за свой кабинет (Техбензо / ЭиБ / Техносад).
  9. Все опасные действия проходят через approval.
  10. Сначала API, потом UI, потом VLM.

35.Минимально правильная схема для старта

Чтобы начать без лишнего усложнения, схема такая:

Центр

1 сервер:
- PostgreSQL
- NATS
- Redis
- MinIO
- FastAPI
- LangGraph
- Open WebUI

Воркеры

3 сервера под кабинеты РЫСЬ-ИНСТРУМЕНТ:
- Техбензо
- ЭиБ
- Техносад

Сеть

WireGuard

Деплой

Ansible

Приоритет задач

1. Отчёты и чтение
2. Цены через API
3. Остатки через API
4. UI-задачи для одного кабинета
5. Массовые операции с подтверждением
6. Обучение и процедуры

36.Что не стоит делать

Следует избегать следующего:

  1. Не давать всем агентам прямой доступ к общей базе.
  2. Не хранить все ключи в одной таблице в открытом виде.
  3. Не позволять агентам самим выполнять опасные действия без подтверждения.
  4. Не запускать много кабинетов с одного браузерного профиля.
  5. Не полагаться только на VLM для критичных операций.
  6. Не начинать сразу с дообучения моделей.
  7. Не строить сложную систему без журнала аудита.
  8. Не делать массовые изменения без предварительного плана и проверки.
  9. Не переносить кабинет автоматически на другой сервер без понимания рисков.
  10. Не игнорировать официальные API маркетплейсов.

37.Финальная рекомендация

Для схемы с множеством серверов под кабинеты оптимальная архитектура такая:

Центр

Серверы кабинетов

Коммуникация

Хранение

Выполнение

Итог
Именно так система будет: масштабируемой, безопасной, обучаемой, управляемой из чата, пригодной для множества кабинетов РЫСЬ-ИНСТРУМЕНТ (Техбензо, ЭиБ, Техносад) и готовой к расширению на Wildberries и другие площадки.