Инструкция по настройке AGD Flow
Настройте publishing pipeline: сбор источников, RAG-контекст, AI-шаги, проверка и структурная публикация в WordPress или CMS.
🧭 Общая логика работы панели
AGD Flow работает как AI content pipeline для web publishing: вы подключаете сайт, подключаете AI-провайдера, готовите правила и ключевые слова, собираете шаблон pipeline, тестируете flow, а затем запускаете задачу публикации.
WordPress — установите файл
api.php в корень WordPress, см. раздел WordPress API.OfferCMS / собственный CMS — установите клиентский комплект
.cms, см. раздел Подключение сайта.- 🌐 Domains — подключаете сайт, указываете API URL, токен и доменный AI-промпт.
- 🎨 Внешний шаблон сайта — после установки клиентского комплекта настройте
.cms/temp: шапку, меню, карточки, сайдбар, стили, метрику и футер. - 🤖 AI Providers — добавляете OpenAI, Gemini, Anthropic, xAI, DeepSeek, Qwen или Custom OpenAI-compatible API.
- 📝 Prompts — сохраняете повторяемые инструкции: SEO-правила, стиль, ограничения, формат статьи.
- 🔍 Keywords — создаёте наборы ключевых слов для генерации.
- ⚙️ Templates — собираете pipeline из шагов: поиск, парсинг, RAG, AI-генерация, обработка и финальная форма статьи.
- ▶️ Tasks — связываете домен, шаблон и набор ключей, выбираете режим публикации и запускаете задачу.
- 📝 Articles — смотрите, создаёте и редактируете статьи вручную, если это нужно.
.cms/temp, затем AI-провайдер, затем промпты и ключи, после этого pipeline-шаблон, тест pipeline и только потом рабочая задача..cms/temp или весь клиентский комплект .cms можно загрузить в ИИ и попросить создать новый внешний шаблон, переделать дизайн под нишу, изменить карточки, меню, цвета, футер, статические страницы и рекламные/метрические вставки. Главное — не ломать системные переменные шаблона: $row, $posts, $post, $tophost, $incpage, $currentLang.🌐 Подключение сайта и клиентского .cms
Для публикации статей на внешний сайт используется клиентский комплект .cms. Это маленькая CMS/API-часть, которая принимает публикации из панели, сохраняет статьи, изображения и дополнительные поля, а также отдаёт публичные URL.
Где взять комплект
- Откройте вкладку 🌐 Domains.
- Нажмите кнопку Скачать клиент (.zip).
- Распакуйте архив. Внутри будет комплект файлов сайта:
index.php,classes/,pages/,temp/,vendor/и другие служебные файлы.
Вариант 1: установка в отдельную папку blog
- Создайте в корне нужного сайта папку
blog. - Скопируйте в неё содержимое клиентского архива.
- Проверьте, что API открывается по адресу
https://example.com/blog/api.php. - Если хостинг возвращает 404, настройте rewrite так, чтобы запросы внутри
/blog/обрабатывались клиентскимindex.php. - В панели в настройках домена укажите API URL:
https://example.com/blog/api.php.
Этот вариант безопаснее, если на домене уже есть сайт и вы не хотите смешивать файлы основной системы с клиентским комплектом.
Вариант 2: установка от корня сайта
- Скопируйте содержимое клиентского архива прямо в корень сайта.
- Используйте этот вариант только если сайт должен полностью работать на комплекте OfferCMS или если вы точно понимаете, какие файлы будут объединены с текущим сайтом.
- В панели в настройках домена укажите API URL:
https://example.com/api.php.
API Token
- На сайте откройте файл
classes/integration.php. - В функции
cms_get_api_token()замените стандартное значение на уникальную длинную строку. - В панели откройте 🌐 Domains → Добавить домен или редактирование домена.
- В поле API Token вставьте ту же строку.
function cms_get_api_token(): string
{
return 'your-unique-secret-token-here';
}
Authorization: Bearer API_TOKEN. Если токен на сайте и токен в панели отличаются, публикация вернёт ошибку авторизации.🌐 Domains — управление сайтами
Вкладка Domains отвечает за сайты, на которые панель будет публиковать готовые материалы.
- Скачать клиент (.zip) — скачивает актуальный клиентский комплект для установки на сайт. Если появилась новая версия, рядом с кнопкой может отображаться отметка NEW.
- Добавить домен — открывает форму подключения сайта.
- ✏️ — редактирование домена.
- 🗑️ — удаление домена из панели.
Поля домена
- Домен — доменное имя без лишних параметров, например
example.com. - API URL — полный адрес API клиента:
https://example.com/api.phpилиhttps://example.com/blog/api.php. - API Token — секретная строка из
cms_get_api_token()на сайте. - Системный промпт домена — правила именно для этого сайта: язык, тон, аудитория, тематика, структура, запреты и требования к публикациям.
Доменный промпт можно использовать внутри AI-шагов через переменную {{domain_aiprompt}}. Это удобно, когда один и тот же шаблон должен работать на разных сайтах с разной тематикой.
🤖 AI Providers — подключение моделей
AI-провайдеры вынесены отдельно от шаблонов. Благодаря этому один шаблон можно быстро переключать между разными ключами, аккаунтами и моделями.
Кнопки и действия
- Добавить провайдера — создаёт новое подключение.
- ✏️ — редактирует сохранённого провайдера.
- 🧪 — отправляет тестовый запрос и показывает HTTP-код, модель, текст ответа и подсказки по ошибкам.
- 🗑️ — удаляет провайдера. Если шаблон использовал этого провайдера, такой шаблон будет требовать внимания.
Поля провайдера
- Тип провайдера — Gemini, OpenAI, Anthropic, xAI, DeepSeek, Qwen или Custom.
- Название — понятное имя подключения. Можно оставить автоматически созданное или назвать по аккаунту/ключу.
- Регион Qwen — появляется только для Qwen.
- API URL — появляется для Custom OpenAI-compatible API.
- Доступные модели — список моделей, по одной в строке. Именно из этого списка потом выбирается модель в LLM-шаге шаблона.
- 🔄 Обновить список моделей — кнопка возле поля моделей. Она запрашивает каталог моделей у провайдера, показывает предпросмотр и позволяет вставить полученный список.
- API ключ — ключ провайдера.
- Активен — только активные провайдеры доступны для новых LLM-шагов.
Карточка провайдера показывает ID, тип, возможности, количество моделей, статус активности и возможную последнюю критическую ошибку: недостаточно средств, неверный ключ, rate limit, model not found, timeout и другие.
📝 Prompts — глобальные правила
Глобальные промпты нужны для повторяемых инструкций, которые используются в разных шаблонах: SEO-правила, редакционный стиль, требования к источникам, запреты, формат ответа, правила разметки.
- Создать промпт — добавляет новый reusable prompt.
- Название — имя, по которому промпт будет вставляться в шаблон.
- Содержимое — сам текст правил.
- Категория — необязательная группировка, например
seo,style,html,review.
В LLM-шаге промпт вставляется макросом:
{{prompt:"seo_article_rules"}}
Так можно держать большую стабильную инструкцию в одном месте и не копировать её вручную в каждый шаблон.
🔍 Keywords — наборы ключевых слов
Вкладка Keywords хранит базы ключевых слов. Одна задача может использовать один или несколько наборов.
- Создать / добавить базу — создаёт новый набор или пополняет существующий.
- Название базы — понятное имя набора, например
Founders CRM ENилиCBD Reviews PT. - Drag & drop .txt — загрузка файла со списком ключей.
- Ручной ввод — вставка ключей в textarea, по одному ключу на строку.
- Переименовать — меняет название выбранной базы.
- Очистить — удаляет ключи внутри базы, но оставляет сам набор.
- Удалить базу — удаляет набор полностью.
В pipeline текущий ключ доступен через переменную {{keyword}}. При запуске задачи система проходит по ключам выбранных наборов и для каждого ключа выполняет шаблон.
⚙️ Templates — сборка pipeline
Template — это схема генерации. Он описывает, что именно нужно сделать с ключевым словом: собрать выдачу, загрузить страницы, построить RAG-контекст, сгенерировать статью, извлечь поля и отправить финальные данные на публикацию.
Основные элементы окна шаблона
- Название шаблона — имя pipeline в списке.
- Тип —
Новые статьи,Обновление статейилиКлючевые слова. После создания тип фиксируется, потому что он определяет обязательную финальную форму. - Палитра шагов — разделена на четыре группы: Функции, Источники, Логика и Результат. Это отделяет обработку данных, внешние источники, управляющие конструкции и финальную форму workflow.
- Функции — ИИ, RegExp, преобразование, RAG-контекст, проверка текста и JavaScript.
- Источники — поиск, новости, картинки, видео, извлечение статьи и HTML по URL.
- Логика — IF/ELSE, WHILE, FOR EACH, объединение ветвей и STOP.
- Результат — форма новой статьи, форма обновления статьи или форма ключевых слов в зависимости от типа шаблона.
- Canvas — визуальная карта шагов. Карточки можно раскладывать удобнее для чтения.
- − / + / 100% - масштаб canvas. Масштаб, позиция и фокус сохраняются при редактировании шага.
- Маршрут выполнения - связи между карточками. Шаг можно перетащить, вставить в середину flow и явно назначить следующий переход.
- К первой ошибке — помогает перейти к шагу, где макрос ссылается на отсутствующий или будущий шаг.
- Показать/скрыть JSON редактор — ручное редактирование JSON шагов. Обычно удобнее работать визуально, JSON нужен для точечной правки или переноса шаблона.
next, on_true, on_false, on_pass, on_fail, body и after.🧭 Типы шаблонов и задач
У каждого шаблона один тип workflow. В Tasks сначала выбирается тот же тип, после чего в списке остаются только совместимые шаблоны.
- Новые статьи — входом служит ключевое слово. Финальная форма
article_formсобирает заголовок, описание, Markdown, изображение и дополнительные поля для новой публикации. - Обновление статей — входом служит существующая статья, выбранная на подключенном сайте. Финальная форма
article_update_formготовит новую версию именно для этой статьи. - Ключевые слова — входом служат один или несколько seed-запросов. Финальная форма
keywords_formнормализует сгенерированные строки и добавляет их в выбранный набор ключей.
Безопасность обновления статей
Шаблон обновления сохраняет ID статьи, slug, язык, статус и исходную дату публикации. Результат по умолчанию — Сначала показать изменения: генерация заканчивается, но сайт не меняется, пока в подробностях задачи не выбраны Применить или Пропустить.
Перед применением панель проверяет, не менялась ли исходная статья после попадания в очередь. Если менялась, возникает конфликт вместо перезаписи ручной правки. Применённую версию можно откатить, пока доступен её снимок.
🧱 Типы шагов pipeline
🤖 ИИ
LLM-шаг отправляет промпт выбранному AI-провайдеру и сохраняет текстовый ответ в output шага.
- ID шага — короткое имя, например
query_plan,article_mode,final_article. - Провайдер — активное подключение из AI Providers.
- Тип — текст, text batch, картинки, видео или музыка, если провайдер поддерживает такие возможности.
- Модель — выбирается из списка моделей провайдера.
- Роль —
userилиsystem. - Глобальный промпт — удобный выбор сохранённого prompt, который вставляется макросом.
- Промпт — основной текст инструкции. В нём можно использовать переменные и результаты предыдущих шагов.
- Переменные — кнопка возле поля промпта, которая вставляет доступные макросы.
- Вставить блок кеша — оборачивает стабильную часть промпта в
AIPANEL_CACHE. Подробности и ограничения описаны в разделе кеширования. - Температура — уровень вариативности ответа. Оставьте Авто, чтобы модель использовала значение по умолчанию.
- Лимит токенов ответа — ограничение длины ответа.
- Рассуждение — дополнительное усилие для моделей, которые это поддерживают. Подробнее в разделе «Рассуждение и thinking».
- Дополнительные параметры запроса — показываются только для подключения Custom API. Здесь задаются только не системные параметры конкретного провайдера.
- Ожидание batch, секунд — появляется для
text batch. Batch дешевле, но результат может прийти позже.
🔎 / 📰 / 🖼️ / 🎞️ Источники
Collector-шаги получают данные из поисковой выдачи, новостей, картинок, видео или по конкретным URL.
- Поиск — web SERP: Google, Bing, Yandex, Yahoo.
- Новости — новостная выдача.
- Картинки — поиск изображений.
- Видео — YouTube или Yandex video.
- Статья по URL — загружает страницы по указанным URL и извлекает основное содержимое для следующих шагов pipeline.
- HTML по URL — загружает исходный HTML страницы по URL, когда следующему шагу нужна полная разметка, а не только очищенный текст статьи.
- Источник запроса — ключ, текст или переменная предыдущего шага, например
{{keyword}}или{{step.query_plan.output}}. - Лимит результатов SERP — сколько результатов брать на запрос, от 1 до 100.
Выход поисковых collector-шагов — структурированный объект: results, related, total_items. У результатов есть query, rank, link, title, content, date, thumb. Шаг Статья по URL возвращает массив документов с основным текстом, заголовком и ссылкой.
🧪 Обработка / RegExp
Regexp-шаг извлекает или заменяет фрагменты текста.
- Источник — строка или output предыдущего шага.
- Паттерн — регулярное выражение.
- Флаги — модификаторы регулярного выражения.
- Извлечь первое совпадение — берёт первое найденное значение.
- Извлечь все совпадения — возвращает список совпадений через перенос строки.
- Заменить совпадения — выполняет замену по регулярке.
🧩 Преобразование
Transform-шаг чистит и подготавливает данные между collector и AI-шагами.
- Удалить дубли строк, Объединить в одну строку, Обрезать по символам, Перемешать массив, Обрезать массив, Убрать HTML, Trim.
- Извлечь из JSON — берёт нужный фрагмент из JSON.
- Строку в массив и Массив в JSON — меняют формат данных для следующих шагов.
📚 Создать RAG контекст
Самостоятельная функция в палитре Функции. Она собирает компактный evidence-контекст из документов, полученных шагом Статья по URL.
В настройках RAG можно ограничить общий объём контекста, количество источников, объём материалов с одного сайта и размер обрабатываемых фрагментов.
RAG собирает наиболее полезные фрагменты найденных материалов в компактный контекст для следующего AI-шага. Он не публикует материал самостоятельно.
🔀 IF/ELSE и маршруты
Шаг IF/ELSE сравнивает левое и правое значения и выбирает on_true или on_false. Поддерживаются операторы eq, neq, lt, lte, gt, gte, contains, not_contains, empty, not_empty, regex, truthy, falsy.
🛡️ Проверка текста
Выберите сервис проверки, задайте допустимый порог и настройте маршруты для трёх результатов: проверка пройдена, не пройдена или произошла ошибка.
🔁 WHILE и FOR EACH
WHILE повторяет ветку, пока условие истинно и не достигнут max_iterations. FOR EACH обходит массив из items_source. Внутри тела доступны {{loop.item}}, {{loop.index}}, {{loop.iteration}} и варианты с ID цикла, например {{loop.section_loop.iteration}}. Последний шаг тела обязан маршрутом вернуться в loop; после завершения выполняется after.
🧩 JavaScript
JavaScript-шаг получает input, outputs в steps, безопасный context и helpers clone, jsonParse, jsonStringify, toArray, unique. Запрещены сеть, файловая система, process/runtime API, imports, eval, async/Promise и доступ к prototype. Ограничиваются время выполнения, размер кода и размер результата.
⋈ Merge и ■ STOP
Merge не запускает ветви параллельно. Это общая точка продолжения, которая получает результат реально пришедшей ветви в merge.output. STOP завершает текущий маршрут и сохраняет причину остановки в журнале.
📝 Форма статьи
Финальный шаг для публикации. Он собирает данные из предыдущих шагов в структуру статьи.
- Заголовок статьи — например
{{step.title_extract.output}}. - Описание статьи — meta description или краткое описание.
- Изображение — URL главного изображения или переменная из image-шагов.
- Содержимое (Markdown) — готовый текст статьи.
- Дополнительные поля — пары ключ/значение, которые уйдут в
xfields_json.
en, pt, blog или reviews.🔄 Форма обновления статьи
Финальный шаг шаблона обновления. Он сопоставляет сгенерированные заголовок, описание, Markdown и дополнительные поля с существующей статьёй перед применением или проверкой изменений.
🔑 Форма ключевых слов
Финальный шаг шаблона ключевых слов. Он принимает массив найденных или сгенерированных ключей и передаёт их в выбранный набор ключевых слов.
🔗 Переменные и макросы
Макросы связывают шаги между собой. Они подставляют ключевое слово, домен, доменный промпт, глобальные промпты и output предыдущих шагов.
{{keyword}}— текущее ключевое слово.{{domain}}— домен сайта.{{domain_aiprompt}}— системный промпт домена.{{prompt:"prompt_name"}}— глобальный промпт из вкладки Prompts.{{step.step_id.output}}— полный выход предыдущего шага.{{step.images.1.link}},{{step.search.output}}и похожие переменные — конкретные поля структурированных результатов, если они доступны.
Входные переменные по типу workflow
- Новые статьи — используйте
{{keyword}}вместе с доменными переменными выше. - Обновление статей — доступны
{{article.id}},{{article.url}},{{article.slug}},{{article.lang}},{{article.title}},{{article.description}},{{article.markdown}},{{article.main_image}},{{article.xfields_json}},{{article.published_at}},{{article.updated_at}}и{{article.age_days}}. - Ключевые слова — используйте
{{seed.keyword}}и{{seed.set_name}}. Доменные переменные доступны, если в задаче выбран домен.
Кнопка Переменные в редакторе шага показывает доступные макросы с учётом текущего шага и предыдущих результатов.
Уже вставленная переменная выделяется цветом. Если один макрос использован несколько раз, рядом показывается количество вхождений. Макросы можно вставлять подряд без принудительного переноса строки, например {{keyword}}{{domain}}.
🧭 Маршруты, ограничения и проверка JSON
Явные переходы
next- следующий шаг для ИИ, collector, RegExp, transform, JavaScript, Merge и формы статьи.on_true/on_false- две ветви IF/ELSE.on_pass/on_fail/on_error- маршруты проверки текста.body/after- тело цикла и маршрут после завершения.stopилиendв качестве target завершает маршрут без отдельной карточки STOP.
Для новых шаблонов указывайте маршруты явно: так порядок выполнения остаётся понятным при добавлении ветвей и циклов.
Проверка перед сохранением
Редактор и backend не сохраняют граф с пустыми или повторяющимися ID, отсутствующими target, незамкнутым телом loop или циклом, который не проходит через ограниченный loop. Во время выполнения действует дополнительный предел на общее число посещённых узлов. Для loop разрешено от 1 до 1000 итераций; для JavaScript - 50-5000 мс и ограниченный размер output.
Проверка JSON
steps_json и xfields_json проверяются строгим jsonlint-совместимым валидатором. Ошибка содержит понятное описание, строку и контекст, а повторяющиеся JSON-ключи считаются ошибкой. Корень steps_json должен быть массивом шагов; xfields_json должен быть объектом или массивом. Макросы внутри xfields_json разрешены и проверяются до подстановки.
🚀 Рекомендуемый pipeline SEO-статьи
Для качественной SEO-статьи обычно лучше использовать не один AI-шаг, а цепочку research → context → generation → extraction → article form.
- 🤖 query_plan — AI создаёт 3–5 поисковых запросов по
{{keyword}}с учётом{{domain_aiprompt}}. - 🔎 search — collector собирает SERP по запросам из
{{step.query_plan.output}}. - 🧩 clean_search — transform удаляет дубли, ограничивает массив или вытаскивает нужные ссылки.
- 📄 articles — collector Статья по URL загружает страницы из найденных URL.
- 🧩 rag_context — transform Создать RAG контекст сжимает найденные материалы в компактный контекст.
- 🖼️ images — collector картинок ищет главное изображение или идеи изображений по ключу.
- 🤖 final_article — AI пишет финальную статью с учётом RAG, доменного промпта, SEO-правил и нужного формата.
- 🧪 title_extract / description_extract / content_extract — regexp-шаги извлекают поля, если AI вернул статью в одном блоке.
- 📝 article_form — собирает title, description, markdown, image и дополнительные поля для публикации.
Для простого шаблона можно оставить только: 🤖 final_article → 📝 article_form. Но для более полезных статей лучше добавлять поиск, загрузку источников и RAG.
<!-- AIPANEL_CACHE -->
Постоянные правила шаблона:
- структура статьи;
- требования к SEO;
- стиль;
- запреты;
- формат ответа.
<!-- AIPANEL_CACHE_END -->
Keyword: {{keyword}}
Domain rules: {{domain_aiprompt}}
Research context: {{step.rag_context.output}} 🧠 Рассуждение и thinking
Некоторые текстовые модели могут потратить дополнительные токены на планирование перед тем, как вернуть итоговый текст. В панели это называется Рассуждение. Оно может улучшить сложные инструкции, структурированные тексты и многошаговый анализ, но увеличивает время и стоимость.
- Авто — не отправляет принудительную настройку. Это обычный вариант для существующих шаблонов: провайдер сам выбирает стандартное поведение модели.
- Выключено — просит совместимую модель отключить reasoning. Некоторые современные модели этого не разрешают; шаг остановится с понятной причиной, а не изменит запрос скрытно.
- Минимальное, Низкое, Среднее, Высокое, Очень высокое, Максимальное — уровни усилия, которые переводятся в API выбранного провайдера. Начинайте с Низкого или Среднего и тестируйте шаблон до массового запуска.
- Бюджет рассуждений — доступен только там, где API и модель принимают числовой thinking budget. Оставьте поле пустым для значения по умолчанию у провайдера.
В output шага всегда попадает только итоговый ответ. Внутреннее рассуждение не передается в следующие шаги, журналы задачи, RAG и публикацию.
Параметры Custom API
Для Custom API доступны Дополнительные параметры запроса типов Строка, Число, Да/Нет и JSON. Они нужны для документированных параметров провайдера, например формата ответа или sampling-настроек. Панель защищает model, prompt, authentication, endpoint, stream, reasoning и token limits; для них используйте основные поля LLM-шага.
💰 Кеширование промптов (AIPANEL_CACHE)
AIPANEL_CACHE - это разметка стабильной части промпта. Панель использует ее только там, где это безопасно и поддерживается выбранным провайдером. Если провайдер или режим не поддерживает кеш, маркеры удаляются перед запросом, а сам текст промпта остается.
Как это работает по провайдерам
- Google Gemini - платный explicit context cache через
cachedContentsв панели отключен. Для Gemini маркерыAIPANEL_CACHEвырезаются перед запросом, объект кеша у Google не создается. Это относится и к text batch. Автоматический implicit cache, если он применим у Google, работает без действий пользователя. - OpenAI / xAI / DeepSeek - используют автоматический prompt cache провайдера, когда повторяется стабильный префикс промпта.
- Anthropic Claude - использует короткий ephemeral cache. Он подходит для близких по времени запусков и не рассчитан на долгосрочное хранение.
- Qwen - поведение зависит от конкретного API и модели; если кеш не применяется, запрос уходит обычным промптом без маркеров.
Когда это выгодно
Кеширование имеет смысл, если один и тот же большой стабильный блок повторяется во многих запросах: SEO-правила, стиль, структура статьи, запреты, формат ответа. Экономия не гарантируется: итог зависит от провайдера, модели, размера блока и частоты повторов.
Как использовать
В редакторе LLM-шага есть кнопка Вставить блок кеша. Она оборачивает выделенную часть промпта в маркеры. Можно также вставить вручную:
<!-- AIPANEL_CACHE -->
Здесь - постоянные правила, которые не меняются от запроса к запросу:
- SEO-требования, стиль, структура, запреты, формат ответа
<!-- AIPANEL_CACHE_END -->
Keyword: {{keyword}}
Domain rules: {{domain_aiprompt}}
Research context: {{step.rag_context.output}}
AIPANEL_CACHE гарантированной экономией. Это только разметка стабильного блока. Перед массовыми запусками проверьте биллинг и документацию выбранного провайдера.🧪 Тестирование шаблона
Перед рабочим запуском протестируйте шаблон прямо в окне Templates. Поля теста зависят от типа шаблона.
- Новые статьи — выберите подключённый домен, затем одно ключевое слово из его набора или введите его вручную.
- Обновление статей — выберите подключённый домен и одну существующую статью. Панель проверяет соединение и читает актуальные данные статьи для макросов
{{article.*}}, но не изменяет её. - Ключевые слова — введите один seed-запрос или выберите его из набора. Домен для такого теста необязателен.
После выбора входных данных нажмите Запустить тест.
Во время теста панель показывает прогресс по шагам. После выполнения можно открыть отладку шага и посмотреть входные данные, итоговый промпт, ответ провайдера, результат regexp/transform, RAG-контекст и финальную структуру статьи.
▶️ Tasks — запуск генерации и публикации
Задача запускает сохранённый шаблон по зафиксированной очереди входных данных. Сначала выберите тип: Новые статьи, Обновление статей или Ключевые слова.
Создание задачи
- Тип — определяет доступные поля ввода и совместимые шаблоны.
- Домен — сайт, куда публикуем.
- Шаблон — pipeline генерации. Шаблоны со статусом Требует внимания нельзя запускать, пока не исправлены провайдеры или макросы.
- Наборы ключевых слов — можно выбрать один или несколько. Если оставить пусто, задача запускается без ключей.
- Режим публикации — сразу все, только N статей или отложенный режим.
- Количество статей для публикации — используется в режиме лимита.
- Количество статей / Период (часы) — используется в отложенном режиме.
- Язык / раздел URL — принудительный сегмент URL, например
en,pt,blog,reviews. - Пропускать использованные ключевые слова — защищает от повторной генерации по уже обработанным ключам.
- Информировать Google и Информировать Bing — отправляет уведомления после успешной публикации.
Входные данные по типам
- Новые статьи — выберите один или несколько наборов ключей и режим: сразу, с лимитом или по расписанию.
- Обновление статей — выберите статьи вручную через поиск и постраничный список, статьи старше указанного числа месяцев или диапазон даты публикации. Дополнительно доступны фильтры языка и статуса, а также лимит количества статей. В очереди сохраняются выбранные ID, а полный текст заново загружается непосредственно перед обработкой.
- Ключевые слова — введите seed-запросы вручную или используйте существующие наборы. Выберите набор назначения либо укажите название нового.
Статистика и статусы
- Всего, В работе, Завершено, Ошибок — общая статистика задач.
- Слотов — доступные, занятые и свободные слоты выполнения.
- Не хватает — сколько задач ждут свободных слотов.
- Ожидает, В работе, Ждет batch, Ожидает проверки, Завершено, Ошибка, Приостановлено, Отменено — основные состояния задачи.
Действия с задачей
- Подробности — показывает прогресс, результаты, URL, ошибки, поисковые уведомления и лог выполнения. У обновления статей здесь доступны исходная и предложенная версии, а также действия «Применить», «Пропустить» и «Откатить», если они доступны.
- Редактировать — меняет параметры задачи.
- Приостановить — останавливает дальнейшее выполнение.
- Возобновить/перезапустить — продолжает или повторно запускает задачу, если есть свободный слот.
- Отменить — отменяет выполнение.
- Удалить задачу — удаляет задачу и связанные данные.
📝 Articles — ручная работа со статьями
Вкладка Articles нужна для просмотра и ручной правки материалов. Она полезна, если статью нужно создать без pipeline или проверить уже готовые записи.
- Фильтр домена — показывает статьи конкретного сайта.
- Фильтр статуса — draft, ready for review или published.
- Обновить — перезагружает список.
- Создать статью — открывает ручную форму статьи.
Поля статьи
- Статус — черновик, готово к проверке или опубликовано.
- Язык — например
en,pt,ru. - Slug — URL-часть статьи.
- Заголовок — H1/title статьи.
- Описание — meta description или краткое описание.
- Содержимое — Markdown-контент.
- Главное изображение — загрузка файла, вставка URL или base64.
- Дополнительные поля — произвольные поля, которые сохраняются в JSON.
🎨 .cms/temp — внешний шаблон сайта
Папка .cms/temp — это не pipeline-шаблон из вкладки Templates, а внешний шаблон сайта. Именно здесь настраивается то, как опубликованные статьи будут выглядеть для посетителя: шапка, меню, главная/листинг, карточки постов, страница статьи, сайдбар, футер, цвета, CSS, метрика и рекламные вставки.
.cms/temp на сайте отвечает за внешний вид опубликованного сайта. Это две разные части системы, и обе нужно настроить.Главные файлы шаблона
temp/temp.php— основной HTML-шаблон сайта. В нём обычно настраиваются<head>, title/description, canonical, JSON-LD, шапка, меню, главный контейнер, вывод статьи, вывод сайдбара и футер.temp/css/style.css— стили сайта: цвета, ширина контейнера, карточки, меню, типографика, адаптивность, кнопки, пагинация, сайдбар.temp/short.php— маленькая карточка статьи для главной, языковых страниц, листингов и пагинации.temp/sidebar.php— карточка похожей/случайной статьи в боковом блоке на странице публикации.temp/metric.php— счётчики, аналитика, рекламные скрипты, пиксели и другие вставки перед закрытием</head>или внутри шаблона.pages/— статические страницы:about,contact,privacy,terms,cookies,disclaimer,legal. Их тоже нужно адаптировать под конкретный сайт.
Что обязательно поменять под свой сайт
- Откройте
.cms/temp/temp.php. - Замените название сайта, например
$siteName,$defaultTitleи$siteTagline. - Проверьте пункты меню: Home, Blog, About, Contact, Privacy, Terms. Уберите лишнее или добавьте нужные разделы.
- Проверьте тексты hero-блока на главной/листинге. Они должны соответствовать нише сайта, языку и аудитории.
- Проверьте футер: название проекта, описание, контакты, юридические ссылки.
- Откройте
.cms/temp/css/style.cssи настройте палитру в блоке:root: фон, основной цвет, акцент, ширина контейнера, радиусы, отступы. - Откройте
.cms/temp/metric.phpи замените или удалите чужие счётчики, рекламные коды и пиксели. Нельзя оставлять чужой Google AdSense, Yandex.Metrika или другие чужие ID. - Откройте файлы в
.cms/pages/и замените стандартные тексты на страницы конкретного проекта.
Настройка формы обратной связи через Telegram
contact отображается сразу, но по умолчанию отправка отключена. Пока владелец сайта не укажет данные своего Telegram-бота, посетитель получит сообщение о том, что форма не настроена, а его сообщение никуда не отправится.- Создайте собственного бота через
@BotFatherи получите токен бота. - Отправьте боту любое сообщение, затем получите ID нужного личного чата или группы через метод Telegram
getUpdates. - Откройте файл
.cms/classes/send.php. - Укажите токен в переменной
$telegram_api_token, а ID чата в переменной$chat_id. - Откройте страницу
contactна сайте и отправьте тестовое сообщение. Оно должно появиться только в указанном вами Telegram-чате.
$telegram_api_token = 'YOUR_TELEGRAM_BOT_TOKEN';
$chat_id = 'YOUR_TELEGRAM_CHAT_ID';
pages/, temp/, JavaScript или публичном репозитории. Если токен стал известен посторонним, перевыпустите его через @BotFather. Укажите обработку формы и передачу имени, email, сообщения, IP и домена в Telegram в политике конфиденциальности сайта.Какие данные доступны внутри шаблона
$row['title']— заголовок текущей страницы или статьи.$row['description']— meta description или краткое описание.$row['html_content']— готовый HTML статьи или список карточек на главной/листинге.$row['image_url']— главное изображение статьи, если оно передано или найдено системой.$row['date']/$row['public_date']— дата публикации, если она есть в записи.$row['sidebar']— HTML сайдбара со случайными/похожими статьями, если он был собран.$posts— массив постов на главной, языковой странице или странице пагинации.$post— один пост внутриshort.phpилиsidebar.php.$tophost,$hostname,$incpage,$currentLang,$pagePath— служебные переменные URL, домена, языка и текущей страницы.
short.php или sidebar.php, помните: там используется переменная $post. Если меняете temp.php, основная переменная страницы — $row.Как движок использует файлы temp
- Для главной страницы и страниц пагинации движок собирает список опубликованных материалов, каждый материал прогоняет через
short.php, а затем выводит общий результат черезtemp.php. - Для страницы статьи движок загружает статью, подготавливает
$row['html_content'], собирает$row['sidebar']черезsidebar.phpи затем подключаетtemp.php. - Если в папке шаблона есть
fullpage.php, он может использоваться для отдельных внутренних страниц вместо стандартногоtemp.php. metric.phpобычно подключается изtemp.php, поэтому все счётчики и рекламные скрипты удобно держать в одном отдельном файле.
Минимальный чек-лист перед публикацией
- Открывается главная страница сайта.
- Открывается статья по публичному URL.
- Картинки не ломают верстку на телефоне.
- Меню ведёт на существующие страницы.
- В футере нет чужого бренда, чужих ссылок и тестового текста.
- В
metric.phpнет чужих ID рекламных сетей и аналитики. - В
.cms/classes/send.phpуказаны данные собственного Telegram-бота, и тестовое сообщение получено. - В исходном коде страницы есть нормальные
title,meta description, canonical и, если нужно, JSON-LD. - Страницы
privacy,terms,contact,aboutзаполнены под конкретный сайт.
WordPress API — подключение моста
Для публикации на сайты под управлением WordPress используется специальный мост api.php. Панель отправляет публикации, проверяет уникальность URL, обновляет записи и загружает медиафайлы через этот файл.
Установка и настройка
- Скачайте файл плагина/моста: в шапке документации или в настройках домена выберите Скачать клиент WordPress (требуется авторизация).
- Скопируйте скачанный файл
api.phpв корневую директорию вашей установки WordPress (туда, где находитсяwp-load.php). - Откройте файл
wp-config.phpвашего WordPress и добавьте секретный токен:define('AIPANEL_API_TOKEN', 'ваш-сложный-секретный-токен'); - В панели управления AGD Flow при добавлении домена укажите:
- API URL:
https://yourdomain.com/api.php - API Token: тот же токен, который вы указали в
wp-config.php
- API URL:
Возможности моста
- Действия (actions): поддерживает проверку связи (
ping), публикацию статьи (publish_post), редактирование (edit_post), удаление (delete_post) и проверку занятости slug (check_slug). - Поддержка SEO-плагинов: автоматически записывает SEO-заголовок и описание в мета-поля популярных плагинов Yoast SEO (
_yoast_wpseo_title,_yoast_wpseo_metadesc) и Rank Math (rank_math_title,rank_math_description). - Категории и теги: поддерживает передачу массивов категорий и тегов в поле
xfields_json(структура:{"categories": ["Категория 1", "Категория 2"], "tags": ["Тег 1", "Тег 2"]}). Если категорий или тегов нет на сайте, они будут созданы автоматически. - Типы записей (Custom Post Types): по умолчанию публикации создаются как стандартные посты (
post). Вы можете переопределить это, передав тип записи вxfields_json(например,{"post_type": "product"}или{"post_type": "page"}). - Изображения: автоматически скачивает главное изображение по ссылке или декодирует base64-строку, создавая вложение в медиабиблиотеке WordPress и устанавливая его в качестве "Featured Image" (изображения записи).
📋 Примеры готовых JSON Pipeline
Здесь представлены готовые шаблоны pipeline в формате JSON, которые вы можете импортировать через кнопку Показать/скрыть JSON-редактор во вкладке ⚙️ Templates.
1. Простая SEO статья (Simple SEO Article)
Минимальный шаблон: отправляет промпт в ИИ, вырезает теги заголовка, описания и контента с помощью RegExp, а затем передает их в форму публикации.
[
{
"id": "draft_article",
"type": "llm",
"provider_id": 0,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\n\n{{prompt:\"seo_article_rules\"}}\n{{prompt:\"article_output_contract\"}}\n\nWrite a practical SEO article for the keyword. Vary the number of sections naturally; include FAQ only when it helps the topic.\n",
"temperature": 0.4,
"max_tokens": 4096,
"output_key": "output"
},
{
"id": "extract_title",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.draft_article.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_description",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.draft_article.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_content",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.draft_article.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "article",
"type": "article_form",
"title": "{{step.extract_title.output}}",
"description": "{{step.extract_description.output}}",
"markdown": "{{step.extract_content.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "[]",
"public": 1
}
]
2. Расширение ключевых слов (Keyword Expansion)
Шаблон типа "Keywords" для генерации связанных тем на основе одного главного ключа.
[
{
"id": "expand_keywords",
"type": "llm",
"provider_id": 0,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Seed keyword: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\n\nGenerate 20 useful long-tail keyword ideas for content planning. Keep them specific, natural, and suitable for article topics.\nReturn one keyword per line, no numbering, no commentary.\n",
"temperature": 0.35,
"max_tokens": 2048,
"output_key": "output"
},
{
"id": "keywords",
"type": "transform",
"operation": "split_to_array",
"arg1": "{{step.expand_keywords.output}}",
"delimiter": "\n",
"array_limit": 20,
"output_key": "output"
}
]
3. Обзорный Affiliate-шаблон с поиском и RAG (Advanced)
Сложный шаблон для написания обзоров товаров и сервисов: делает запросы в Google, скачивает контент страниц, строит контекст (RAG) и отдает на вход ИИ.
[
{
"id": "affiliate_queries",
"type": "llm",
"provider_id": 0,
"ai_capability": "text_batch",
"model": "",
"prompt_role": "user",
"prompt_text": "Affiliate review idea: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\n\nGenerate 5 focused web search queries that support an affiliate review. Return one query per line only.\n",
"temperature": 0.2,
"max_tokens": 1024,
"output_key": "output"
},
{
"id": "affiliate_split_queries",
"type": "transform",
"operation": "split_to_array",
"arg1": "{{step.affiliate_queries.output}}",
"delimiter": "\n",
"array_limit": 5,
"output_key": "output"
},
{
"id": "affiliate_search",
"type": "collector",
"channel": "web",
"engine": "google",
"query_source": "{{step.affiliate_split_queries.output}}",
"serp_limit": 5,
"output_key": "output",
"concurrency": 6
},
{
"id": "affiliate_slice_search_results",
"type": "transform",
"operation": "slice_array",
"arg1": "{{step.affiliate_search.output}}",
"array_limit": 3,
"output_key": "output"
},
{
"id": "affiliate_html",
"type": "collector",
"channel": "article",
"engine": "article",
"query_source": "{{step.affiliate_slice_search_results.output}}",
"output_key": "output"
},
{
"id": "affiliate_rag",
"type": "transform",
"operation": "rag_builder",
"arg1": "{{step.affiliate_html.output}}",
"array_limit": 5,
"output_key": "output",
"max_total_chars": 16000,
"max_sources": 10,
"chunk_size": 900
},
{
"id": "affiliate_generate",
"type": "llm",
"provider_id": 0,
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\nResearch context:\n{{step.affiliate_rag.output}}\n\n{{domain_aiprompt}}\n\nWrite a practical affiliate review. Format output inside tags:\n<TITLE>[title]</TITLE>\n<DESCRIPTION>[description]</DESCRIPTION>\n<CONTENT>[content]</CONTENT>",
"temperature": 0.45,
"max_tokens": 6144,
"output_key": "output"
},
{
"id": "affiliate_extract_title",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.affiliate_generate.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "affiliate_extract_description",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.affiliate_generate.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "affiliate_extract_content",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.affiliate_generate.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "affiliate_article",
"type": "article_form",
"title": "{{step.affiliate_extract_title.output}}",
"description": "{{step.affiliate_extract_description.output}}",
"markdown": "{{step.affiliate_extract_content.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "[]",
"public": 1
}
]
4. Статья с исследованием и RAG (Research + RAG Article)
Пайплайн статьи на основе исследования: генерирует поисковые запросы, опрашивает Google, загружает страницы источников, строит RAG-контекст и пишет обоснованную статью.
[
{
"id": "research_queries",
"type": "llm",
"provider_id": 0,
"ai_capability": "text_batch",
"model": "",
"prompt_role": "user",
"prompt_text": "Ключевое слово: {{keyword}}\nДомен: {{domain}}\n\n{{domain_aiprompt}}\n\n\nСгенерируйте 6 целевых поисковых запросов, которые поддерживают информативную статью по ключевому слову. Верните по одному запросу на строку, без нумерации и комментариев.\n",
"temperature": 0.2,
"max_tokens": 1024,
"output_key": "output"
},
{
"id": "research_split_queries",
"type": "transform",
"operation": "split_to_array",
"arg1": "{{step.research_queries.output}}",
"delimiter": "\n",
"array_limit": 6,
"output_key": "output"
},
{
"id": "research_search",
"type": "collector",
"channel": "web",
"engine": "google",
"query_source": "{{step.research_split_queries.output}}",
"serp_limit": 5,
"output_key": "output",
"concurrency": 6
},
{
"id": "research_slice",
"type": "transform",
"operation": "slice_array",
"arg1": "{{step.research_search.output}}",
"array_limit": 4,
"output_key": "output"
},
{
"id": "research_html",
"type": "collector",
"channel": "article",
"engine": "article",
"query_source": "{{step.research_slice.output}}",
"output_key": "output"
},
{
"id": "research_rag",
"type": "transform",
"operation": "rag_builder",
"arg1": "{{step.research_html.output}}",
"array_limit": 5,
"output_key": "output",
"max_total_chars": 16000,
"max_sources": 10,
"chunk_size": 900
},
{
"id": "research_writer",
"type": "llm",
"provider_id": 0,
"model": "",
"prompt_role": "user",
"prompt_text": "Ключевое слово: {{keyword}}\nДомен: {{domain}}\nКонтекст исследования:\n{{step.research_rag.output}}\n\n{{article_structure_hint}}\n\n{{domain_aiprompt}}\n\n\nНапишите практическую статью на основе предоставленного контекста. Опирайтесь на источники; не выдумывайте факты. Оформите вывод внутри тегов:\n<TITLE>[заголовок]</TITLE>\n<DESCRIPTION>[мета-описание]</DESCRIPTION>\n<CONTENT>[полный текст статьи в markdown]</CONTENT>\n",
"temperature": 0.45,
"max_tokens": 6144,
"output_key": "output"
},
{
"id": "research_extract_title",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.research_writer.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "research_extract_description",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.research_writer.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "research_extract_content",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.research_writer.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "research_article",
"type": "article_form",
"title": "{{step.research_extract_title.output}}",
"description": "{{step.research_extract_description.output}}",
"markdown": "{{step.research_extract_content.output}}",
"lang": "en",
"slug": "",
"main_image": "",
"xfields_json": "[]",
"public": 1
}
]
5. Мультиязычная публикация (Multilingual Publishing)
Публикует одну статью на двух языках из общего исходного материала: шаг написания на английском и шаг написания на русском, каждый со своей article form. Адаптируйте второй язык, промпты и правила домена под проект.
[
{
"id": "shared_draft",
"type": "llm",
"provider_id": 0,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Ключевое слово: {{keyword}}\nДомен: {{domain}}\n\n{{domain_aiprompt}}\n\n\nСоставьте краткую структуру статьи для ключевого слова: вступление, 3-5 секций H2 и блок FAQ только если он помогает теме. Верните только структуру нумерованным списком.\n",
"temperature": 0.3,
"max_tokens": 1024,
"output_key": "output"
},
{
"id": "writer_en",
"type": "llm",
"provider_id": 0,
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\nOutline:\n{{step.shared_draft.output}}\n\n{{domain_aiprompt}}\n\n\nWrite a practical English article following the outline. Format output inside tags:\n<TITLE>[title]</TITLE>\n<DESCRIPTION>[meta description]</DESCRIPTION>\n<CONTENT>[full article markdown]</CONTENT>\n",
"temperature": 0.45,
"max_tokens": 4096,
"output_key": "output"
},
{
"id": "extract_title_en",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_en.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_description_en",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_en.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_content_en",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_en.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "article_en",
"type": "article_form",
"title": "{{step.extract_title_en.output}}",
"description": "{{step.extract_description_en.output}}",
"markdown": "{{step.extract_content_en.output}}",
"lang": "en",
"slug": "",
"main_image": "",
"xfields_json": "[]",
"public": 1
},
{
"id": "writer_ru",
"type": "llm",
"provider_id": 0,
"model": "",
"prompt_role": "user",
"prompt_text": "Ключевое слово: {{keyword}}\nДомен: {{domain}}\nСтруктура:\n{{step.shared_draft.output}}\n\n{{domain_aiprompt}}\n\n\nНапишите практическую статью на русском языке по этой структуре. Оформите вывод внутри тегов:\n<TITLE>[заголовок]</TITLE>\n<DESCRIPTION>[мета-описание]</DESCRIPTION>\n<CONTENT>[полный текст статьи в markdown]</CONTENT>\n",
"temperature": 0.45,
"max_tokens": 4096,
"output_key": "output"
},
{
"id": "extract_title_ru",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_ru.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_description_ru",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_ru.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "extract_content_ru",
"type": "regexp",
"mode": "extract",
"input_source": "{{step.writer_ru.output}}",
"pattern": "\\s*(.*?)\\s* ",
"flags": "si",
"output_key": "output"
},
{
"id": "article_ru",
"type": "article_form",
"title": "{{step.extract_title_ru.output}}",
"description": "{{step.extract_description_ru.output}}",
"markdown": "{{step.extract_content_ru.output}}",
"lang": "ru",
"slug": "",
"main_image": "",
"xfields_json": "[]",
"public": 1
}
]
6. Запись товара WordPress (WordPress Product Post)
Генерирует товар в стиле WooCommerce и публикует его как custom post type product с категориями, тегами, ценой, артикулом, SEO-мета и изображением записи. WordPress-мост читает эти поля из xfields_json.
[
{
"id": "product_brief",
"type": "llm",
"provider_id": 0,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Ключевое слово товара: {{keyword}}\nДомен: {{domain}}\n\n{{domain_aiprompt}}\n\n\nСгенерируйте структурированное описание товара по ключевому слову. Верните только валидный JSON (без markdown-ограждений) с ключами:\n{\"title\": \"\", \"short_description\": \"\", \"description\": \"\", \"price\": \"\", \"sku\": \"\", \"categories\": [\"\"], \"tags\": [\"\"]}\n",
"temperature": 0.4,
"max_tokens": 3072,
"output_key": "output"
},
{
"id": "product_title",
"type": "transform",
"operation": "json_path",
"arg1": "{{step.product_brief.output}}",
"output_key": "title"
},
{
"id": "product_description",
"type": "transform",
"operation": "json_path",
"arg1": "{{step.product_brief.output}}",
"output_key": "description"
},
{
"id": "product_short",
"type": "transform",
"operation": "json_path",
"arg1": "{{step.product_brief.output}}",
"output_key": "short_description"
},
{
"id": "product_xfields",
"type": "transform",
"operation": "json_path",
"arg1": "{{step.product_brief.output}}",
"output_key": "xfields"
},
{
"id": "product_article",
"type": "article_form",
"title": "{{step.product_title.output}}",
"description": "{{step.product_short.output}}",
"markdown": "{{step.product_description.output}}",
"lang": "en",
"slug": "",
"main_image": "",
"xfields_json": "{\"post_type\":\"product\",\"categories\":{{step.product_xfields.output.categories}},\"tags\":{{step.product_xfields.output.tags}},\"meta\":{\"_regular_price\":\"{{step.product_xfields.output.price}}\",\"_sku\":\"{{step.product_xfields.output.sku}}\",\"_visibility\":\"visible\"},\"seo\":{\"title\":\"{{step.product_title.output}}\",\"description\":\"{{step.product_short.output}}\"}}",
"public": 1
}
]
7. Готовые примеры pipeline
В разделе Templates доступны готовые примеры pipeline. Их можно открыть, изучить, скопировать и адаптировать под свой workflow.
| Шаблон | Что показывает | Ключевой маршрут |
|---|---|---|
| Example - Graph IF ELSE and Merge | IF/ELSE, две AI-ветви, Merge, JavaScript, RegExp и форма статьи. | condition → writer → merge → script → article_form |
| Example - AI Check Rewrite Loop | Строгий AI-порог, три маршрута проверки, ограниченный WHILE и STOP. | draft → check → loop/rewrite → check → article |
| Example - FOR EACH Sections | Подготовку массива, loop-переменные, обработку каждого элемента и накопление результатов. | script → for_each → AI → accumulator → loop → article |
| Example - Source RAG Quality Gate | Поиск, загрузку материалов по URL, RAG-контекст, IF и AI quality gate. | search → article → RAG → condition → writer → check → article |
IF/ELSE + Merge
Условие с оператором regex ищет признаки сравнения в keyword. Выполняется только одна ветвь. Обе ветви ведут в Merge, а JavaScript возвращает input.output из merge-объекта. Merge здесь служит точкой схождения, а не параллельным исполнителем.
{
"id": "choose_article_mode",
"type": "condition",
"left": "{{keyword}}",
"operator": "regex",
"right": "~\\b(vs|versus|compare|comparison|сравнение|против)\\b~iu",
"on_true": "comparison_writer",
"on_false": "guide_writer"
}
{
"id": "branch_merge",
"type": "merge",
"next": "unwrap_branch"
}
{
"id": "unwrap_branch",
"type": "script",
"input_source": "{{step.branch_merge.output}}",
"code": "return input && typeof input === \"object\" && \"output\" in input ? input.output : input;",
"next": "branch_title"
}
AI Check + ограниченный rewrite loop
После каждой проверки select_candidate выбирает последний rewrite, если он уже существует. При fail цикл разрешает не более трёх переписываний. Тело возвращается через rewrite_article → select_candidate → ai_quality → rewrite_loop, поэтому цикл валиден и ограничен. Исчерпание попыток и ошибка сервиса ведут в разные STOP.
{
"id": "ai_quality",
"type": "ai_check",
"input_source": "{{step.select_candidate.output}}",
"threshold_ai_percent": 30,
"comparison": "less_than",
"on_pass": "approved_title",
"on_fail": "rewrite_loop",
"on_error": "detector_error"
}
{
"id": "rewrite_loop",
"type": "loop",
"mode": "while",
"left": "{{step.ai_quality.output.passed}}",
"operator": "falsy",
"body": "rewrite_article",
"after": "rewrite_exhausted",
"max_iterations": 3
}
FOR EACH + накопление результатов
prepare_sections возвращает массив. AI пишет один раздел для текущего {{loop.item}}. Поскольку повторный output одного шага обычно содержит только последний результат, collect_sections явно добавляет новый текст к своему предыдущему массиву. После loop шаг render_markdown объединяет массив.
{
"id": "section_loop",
"type": "loop",
"mode": "for_each",
"items_source": "{{step.prepare_sections.output}}",
"body": "write_section",
"after": "render_markdown",
"max_iterations": 10
}
{
"id": "collect_sections",
"type": "script",
"input_source": "{{step.write_section.output}}",
"code": "const previous = Array.isArray(steps.collect_sections) ? steps.collect_sections : [];\nreturn previous.concat([input]);",
"next": "section_loop"
}
Источники + RAG + quality gate
Результаты поиска передаются в Статья по URL, затем в RAG. Условие не запускает writer при пустом контексте. Writer получает подготовленный контекст, после чего готовый материал проходит проверку текста.
{
"id": "article_extract",
"type": "collector",
"channel": "article",
"engine": "article",
"query_source": "{{step.evidence_search.output}}",
"next": "evidence_rag"
}
{
"id": "evidence_rag",
"type": "transform",
"operation": "rag_builder",
"arg1": "{{step.article_extract.output}}",
"max_total_chars": 15000,
"max_per_host": 2,
"max_sources": 8,
"chunk_size": 1000,
"next": "context_gate"
}
Полный JSON четырёх примеров
Ниже приведены полные JSON-массивы примеров. Их можно скопировать в JSON-редактор шаблона и адаптировать под свой workflow.
Example - Graph IF ELSE and Merge
Полный JSON: IF/ELSE, две ветви, Merge, JavaScript и форма статьи.
[
{
"id": "choose_article_mode",
"type": "condition",
"left": "{{keyword}}",
"operator": "regex",
"right": "~\\b(vs|versus|compare|comparison|сравнение|против)\\b~iu",
"on_true": "comparison_writer",
"on_false": "guide_writer",
"output_key": "output"
},
{
"id": "comparison_writer",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\nWrite a balanced comparison article. Return exactly:\n<TITLE>Title</TITLE>\n<DESCRIPTION>Meta description</DESCRIPTION>\n<CONTENT>Markdown article</CONTENT>",
"temperature": 0.4,
"max_tokens": 4096,
"output_key": "output",
"next": "branch_merge"
},
{
"id": "guide_writer",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\nWrite a practical how-to guide. Return exactly:\n<TITLE>Title</TITLE>\n<DESCRIPTION>Meta description</DESCRIPTION>\n<CONTENT>Markdown article</CONTENT>",
"temperature": 0.4,
"max_tokens": 4096,
"output_key": "output",
"next": "branch_merge"
},
{
"id": "branch_merge",
"type": "merge",
"output_key": "output",
"next": "unwrap_branch"
},
{
"id": "unwrap_branch",
"type": "script",
"language": "javascript",
"input_source": "{{step.branch_merge.output}}",
"code": "return input && typeof input === \"object\" && \"output\" in input ? input.output : input;",
"timeout_ms": 1000,
"max_output_bytes": 262144,
"output_key": "output",
"next": "branch_title"
},
{
"id": "branch_title",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.unwrap_branch.output}}",
"pattern": "<TITLE>\\s*(.*?)\\s*</TITLE>",
"flags": "si",
"output_key": "output",
"next": "branch_description"
},
{
"id": "branch_description",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.unwrap_branch.output}}",
"pattern": "<DESCRIPTION>\\s*(.*?)\\s*</DESCRIPTION>",
"flags": "si",
"output_key": "output",
"next": "branch_content"
},
{
"id": "branch_content",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.unwrap_branch.output}}",
"pattern": "<CONTENT>\\s*(.*?)\\s*</CONTENT>",
"flags": "si",
"output_key": "output",
"next": "branch_article"
},
{
"id": "branch_article",
"type": "article_form",
"title": "{{step.branch_title.output}}",
"description": "{{step.branch_description.output}}",
"markdown": "{{step.branch_content.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "{}",
"public": 1,
"output_key": "article_data",
"next": "end"
}
]Example - AI Check Rewrite Loop
Полный JSON: AI-проверка, bounded WHILE, повторное переписывание и STOP-маршруты.
[
{
"id": "initial_draft",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\n\n{{domain_aiprompt}}\n\nWrite a useful article in a natural editorial style. Return exactly:\n<TITLE>Title</TITLE>\n<DESCRIPTION>Meta description</DESCRIPTION>\n<CONTENT>Markdown article</CONTENT>",
"temperature": 0.65,
"max_tokens": 4096,
"output_key": "output",
"next": "select_candidate"
},
{
"id": "select_candidate",
"type": "script",
"language": "javascript",
"input_source": "{{step.initial_draft.output}}",
"code": "return steps.rewrite_article || input;",
"timeout_ms": 1000,
"max_output_bytes": 262144,
"output_key": "output",
"next": "ai_quality"
},
{
"id": "ai_quality",
"type": "ai_check",
"detector": "service_1",
"input_source": "{{step.select_candidate.output}}",
"threshold_ai_percent": 30,
"comparison": "less_than",
"on_pass": "approved_title",
"on_fail": "rewrite_loop",
"on_error": "detector_error",
"output_key": "output"
},
{
"id": "rewrite_loop",
"type": "loop",
"mode": "while",
"left": "{{step.ai_quality.output.passed}}",
"operator": "falsy",
"right": "",
"body": "rewrite_article",
"after": "rewrite_exhausted",
"max_iterations": 3,
"output_key": "output"
},
{
"id": "rewrite_article",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Rewrite the article below in a more natural, specific and varied editorial style. Preserve factual meaning and the TITLE, DESCRIPTION and CONTENT tags.\n\nCurrent article:\n{{step.select_candidate.output}}\n\nRewrite attempt: {{loop.iteration}} of 3",
"temperature": 0.85,
"max_tokens": 4096,
"output_key": "output",
"next": "select_candidate"
},
{
"id": "approved_title",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.select_candidate.output}}",
"pattern": "<TITLE>\\s*(.*?)\\s*</TITLE>",
"flags": "si",
"output_key": "output",
"next": "approved_description"
},
{
"id": "approved_description",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.select_candidate.output}}",
"pattern": "<DESCRIPTION>\\s*(.*?)\\s*</DESCRIPTION>",
"flags": "si",
"output_key": "output",
"next": "approved_content"
},
{
"id": "approved_content",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.select_candidate.output}}",
"pattern": "<CONTENT>\\s*(.*?)\\s*</CONTENT>",
"flags": "si",
"output_key": "output",
"next": "approved_article"
},
{
"id": "rewrite_exhausted",
"type": "stop",
"reason": "Text did not pass the AI threshold after 3 rewrites. Last AI score: {{step.ai_quality.output.ai_percent}}%",
"output_key": "output"
},
{
"id": "detector_error",
"type": "stop",
"reason": "AI text-check service failed: {{step.ai_quality.output.error}}",
"output_key": "output"
},
{
"id": "approved_article",
"type": "article_form",
"title": "{{step.approved_title.output}}",
"description": "{{step.approved_description.output}}",
"markdown": "{{step.approved_content.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "{\"ai_percent\":\"{{step.ai_quality.output.ai_percent}}\"}",
"public": 1,
"output_key": "article_data",
"next": "end"
}
]Example - FOR EACH Sections
Полный JSON: FOR EACH, loop-переменные и накопление результатов в JavaScript.
[
{
"id": "prepare_sections",
"type": "script",
"language": "javascript",
"input_source": "{{keyword}}",
"code": "return [\"Overview and definitions: \" + input, \"Practical implementation: \" + input, \"Common mistakes and checks: \" + input];",
"timeout_ms": 1000,
"max_output_bytes": 262144,
"output_key": "output",
"next": "section_loop"
},
{
"id": "section_loop",
"type": "loop",
"mode": "for_each",
"items_source": "{{step.prepare_sections.output}}",
"body": "write_section",
"after": "render_markdown",
"max_iterations": 10,
"output_key": "output"
},
{
"id": "write_section",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nSection request: {{loop.item}}\nZero-based index: {{loop.index}}\nIteration: {{loop.section_loop.iteration}}\n\n{{domain_aiprompt}}\n\nWrite only this article section in Markdown. Start with an H2 heading and avoid repeating other sections.",
"temperature": 0.45,
"max_tokens": 1536,
"output_key": "output",
"next": "collect_sections"
},
{
"id": "collect_sections",
"type": "script",
"language": "javascript",
"input_source": "{{step.write_section.output}}",
"code": "const previous = Array.isArray(steps.collect_sections) ? steps.collect_sections : [];\nreturn previous.concat([input]);",
"timeout_ms": 1000,
"max_output_bytes": 262144,
"output_key": "output",
"next": "section_loop"
},
{
"id": "render_markdown",
"type": "script",
"language": "javascript",
"input_source": "{{step.collect_sections.output}}",
"code": "const sections = Array.isArray(input) ? input : [];\nreturn sections.join(\"\\n\\n\");",
"timeout_ms": 1000,
"max_output_bytes": 262144,
"output_key": "output",
"next": "sections_article"
},
{
"id": "sections_article",
"type": "article_form",
"title": "Guide: {{keyword}}",
"description": "A structured practical guide about {{keyword}}.",
"markdown": "{{step.render_markdown.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "{\"sections\":{{step.collect_sections.output}}}",
"public": 1,
"output_key": "article_data",
"next": "end"
}
]Example - Source RAG Quality Gate
Полный JSON: источники, RAG-контекст, IF и AI quality gate.
[
{
"id": "evidence_search",
"type": "collector",
"channel": "web",
"engine": "google",
"query_source": "{{keyword}}",
"serp_limit": 8,
"output_key": "output",
"next": "article_extract"
},
{
"id": "article_extract",
"type": "collector",
"channel": "article",
"engine": "article",
"query_source": "{{step.evidence_search.output}}",
"max_total_time_sec": 300,
"output_key": "output",
"next": "evidence_rag"
},
{
"id": "evidence_rag",
"type": "transform",
"operation": "rag_builder",
"arg1": "{{step.article_extract.output}}",
"max_total_chars": 15000,
"max_per_host": 2,
"max_sources": 8,
"chunk_size": 1000,
"output_key": "output",
"next": "context_gate"
},
{
"id": "context_gate",
"type": "condition",
"left": "{{step.evidence_rag.output}}",
"operator": "not_empty",
"right": "",
"on_true": "evidence_writer",
"on_false": "no_evidence",
"output_key": "output"
},
{
"id": "evidence_writer",
"type": "llm",
"provider_id": 2,
"ai_capability": "text",
"model": "",
"prompt_role": "user",
"prompt_text": "Keyword: {{keyword}}\nDomain: {{domain}}\n\nEvidence context:\n{{step.evidence_rag.output}}\n\n{{domain_aiprompt}}\n\nUse only supported claims from the evidence context. Respect KEY_CLAIMS and VERDICT credibility signals. Add a final section named Sources used. Return exactly:\n<TITLE>Title</TITLE>\n<DESCRIPTION>Meta description</DESCRIPTION>\n<CONTENT>Markdown article</CONTENT>",
"temperature": 0.35,
"max_tokens": 6144,
"output_key": "output",
"next": "evidence_content"
},
{
"id": "evidence_content",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.evidence_writer.output}}",
"pattern": "<CONTENT>\\s*(.*?)\\s*</CONTENT>",
"flags": "si",
"output_key": "output",
"next": "evidence_quality"
},
{
"id": "evidence_quality",
"type": "ai_check",
"detector": "service_1",
"input_source": "{{step.evidence_content.output}}",
"threshold_ai_percent": 30,
"comparison": "less_than",
"on_pass": "evidence_title",
"on_fail": "quality_rejected",
"on_error": "quality_service_error",
"output_key": "output"
},
{
"id": "evidence_title",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.evidence_writer.output}}",
"pattern": "<TITLE>\\s*(.*?)\\s*</TITLE>",
"flags": "si",
"output_key": "output",
"next": "evidence_description"
},
{
"id": "evidence_description",
"type": "regexp",
"mode": "extract_one",
"input_source": "{{step.evidence_writer.output}}",
"pattern": "<DESCRIPTION>\\s*(.*?)\\s*</DESCRIPTION>",
"flags": "si",
"output_key": "output",
"next": "evidence_article"
},
{
"id": "no_evidence",
"type": "stop",
"reason": "No usable evidence context was produced.",
"output_key": "output"
},
{
"id": "quality_rejected",
"type": "stop",
"reason": "Generated article failed the AI threshold: {{step.evidence_quality.output.ai_percent}}%",
"output_key": "output"
},
{
"id": "quality_service_error",
"type": "stop",
"reason": "AI text-check service failed: {{step.evidence_quality.output.error}}",
"output_key": "output"
},
{
"id": "evidence_article",
"type": "article_form",
"title": "{{step.evidence_title.output}}",
"description": "{{step.evidence_description.output}}",
"markdown": "{{step.evidence_content.output}}",
"lang": "{{domain_lang}}",
"slug": "",
"main_image": "",
"xfields_json": "{\"ai_percent\":\"{{step.evidence_quality.output.ai_percent}}\"}",
"public": 1,
"output_key": "article_data",
"next": "end"
}
] 🛠️ Если что-то не работает
- Сайт не принимает публикацию — проверьте API URL, токен в
classes/integration.php, rewrite и доступностьapi.php. - auth_failed — токен в панели не совпадает с токеном на сайте.
- Модель не видна в LLM-шаге — откройте провайдера, загрузите список моделей кнопкой 🔄 или вставьте модели вручную.
- Шаблон требует внимания — в одном из AI-шагов нет провайдера, выбран удалённый провайдер или макрос ссылается на будущий/удалённый шаг.
- Поиск вернул 0 результатов — проверьте запрос, поисковый backend, лимит SERP и доступность прокси/источника.
- Статья по URL не загрузилась — проверьте, что предыдущий шаг действительно отдаёт URL, а не обычный текст без ссылок.
- RAG пустой — убедитесь, что шаг загрузки статей возвращает документы с HTML-контентом.
- Batch завис или завершился ошибкой ожидания — увеличьте время ожидания batch или используйте обычный текстовый режим.
- Публикация прошла, но URL странный — проверьте поле Язык / раздел URL, slug, заголовок и правила генерации slug на стороне клиента.