Классическое линейное SEO на плотности ключей и ссылочной массе больше не работает так, как раньше. Современный поиск сместился в сторону GEO (Generative Engine Optimization) и RAG-систем (Retrieval-Augmented Generation). Поисковые боты нейросетей вроде GPTBot, ClaudeBot или Perplexity больше не парсят вёрстку ради DOM-дерева — они оценивают чистую плотность и векторную релевантность знания.
Если отдавать поисковым ИИ-агентам тяжелый HTML с бандлами JS, стилями и навигационным мусором, вы просто жжёте их контекстное окно и свои серверные ресурсы.
Ниже разбор того, как мы решили эту проблему на бэкенде: построили автономный двухпоточный контур синдикации данных (v6.2.0 PURE_STERILE), который полностью снимает нагрузку с СУБД MariaDB и процессора при GET-запросах ботов.
Архитектурный принцип: Нулевая динамика на GET-хитах
Главная идея — никакой повторной выборки или генерации контента «на лету». Мы полностью исключили тяжелые SQL-запросы и сборку шаблонов в момент прихода поискового робота.
Модуль не делает собственных запросов к базе: он принимает уже полностью сформированный и подготовленный массив $rss_items напрямую из единого RSS-генератора системы (включая просчитанные Гарпуном LSI-ключи, метаданные и вложения). Сброс этих данных на диск происходит атомарно и только в момент мутации статьи (создания или редактирования).
Архитектура разделяет синдикацию на два независимых статичных потока:
[Базовый RSS-генератор]
│
└──► (Готовый массив $rss_items)
│
├──► 1. Ingestion Engine ──► /Llms-Full.txt (Очищенный Markdown для LLM)
│
└──► 2. Syndication Feed ──► /atom.xml (Atom XML 1.1 + LSI-теги Гарпуна)
Ingestion (Llms-Full.txt) — Сырое очищенное знание в Markdown для векторизации и затягивания в Context Window больших языковых моделей.
Syndication (atom.xml) — Строгий Atom XML v1.1 с оригинальным HTML внутри , медиа-контуром и LSI-тегами семантического графа «Гарпун».
Исходный код: Core Syndication & LLM Ingestion Engine v6.2.0
Скрипт написан на чистом PHP 8.2+ без внешних Composer-зависимостей. Он подхватывает готовый массив $rss_items из RSS-генератора и атомарно обновляет статические эндпоинты:
/**
* CORE SYNNDICATION & LLM INGESTION ENGINE v6.2.0 [PURE_STERILE] ✅
*
* ФУНКЦИОНАЛ:
* 1. Генерация Markdown-базы знаний (Llms-Full.txt) для RAG/LLM краулеров.
* 2. Генерация валидного Atom XML (atom.xml) с сохранением HTML разметки в CDATA.
* 3. Атомарный безопасный сброс файлов на диск (LOCK_EX + временный буфер).
* 4. Использование готового массива $rss_items из единого RSS-генератора.
* 5. Полная изоляция бизнес-логики и отсутствие внешних Composer-зависимостей.
*/
defined('CORE_ACCESS') or die('КЫШ!');
try {
// Данные $rss_items поступают в готовеньком виде из основного RSS-генератора
if (!empty($rss_items) && is_array($rss_items)) {
// Определяем системные пути к файлам выгрузки
$llms_full_file = ROOT_DIR . 'Llms-Full.txt';
$atom_file = ROOT_DIR . 'atom.xml';
$current_host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$current_date = date('c');
// --- [ 1. СБОРКА ШАПКИ MARKDOWN ДЛЯ LLM/RAG ] ---
$llms_md = "# / CORE PLATFORM SYSTEM KNOWLEDGE BASE (LLM Ingestion Endpoint)\n";
$llms_md .= "## Specification: Knowledge graph for Retrieval-Augmented Generation (RAG).\n";
$llms_md .= "## Generated: {$current_date}\n";
$llms_md .= "=====================================================================\n\n";
// --- [ 2. СБОРКА ШАПКИ Atom XML ] ---
$atom = '' . PHP_EOL;
$atom .= '' . PHP_EOL;
$atom .= ' ' . htmlspecialchars($current_host, ENT_XML1, 'UTF-8') . ' MONOLITH SYNNDICATION' . PHP_EOL;
$atom .= ' ' . PHP_EOL;
$atom .= ' ' . PHP_EOL;
$atom .= ' urn:uuid:' . md5($current_host) . '' . PHP_EOL;
$atom .= ' ' . $current_date . '' . PHP_EOL;
// --- [ 3. ЦИКЛ ОБРАБОТКИ ГОТОВЫХ ДАННЫХ ИЗ RSS-ГЕНЕРАТОРА ] ---
foreach ($rss_items as $rss_i) {
$src_module = trim((string)($rss_i['src'] ?? 'content'));
$prefix = '[' . mb_strtoupper($src_module, 'UTF-8') . '] ';
$item_id = (int)($rss_i['id'] ?? 0);
$item_url = "https://{$current_host}/?route=" . urlencode($src_module) . "&id=" . $item_id;
$clean_title = trim(strip_tags((string)($rss_i['title'] ?? '')));
$pub_date_atom = date('c', strtotime((string)($rss_i['date_add'] ?? 'now')));
$markdown_text = strip_tags((string)($rss_i['content'] ?? ''));
$raw_html_content = str_replace(']]>', ']]>', (string)($rss_i['content'] ?? ''));
// --- [ СБОРКА MARKDOWN-ПАКЕТА С МЕТАДАННЫМИ ] ---
$llms_md .= "# ARTICLE: " . $prefix . $clean_title . "\n";
$llms_md .= "## Production URL: " . str_replace('&', '&', $item_url) . "\n";
$llms_md .= "## Published At: " . date('Y-m-d H:i:s P', strtotime((string)$rss_i['date_add'])) . "\n";
if (!empty($rss_i['date_edit']) && $rss_i['date_edit'] !== $rss_i['date_add']) {
$llms_md .= "## History: \n";
$llms_md .= "### - " . date('Y-m-d H:i:s P', strtotime((string)$rss_i['date_edit'])) . ": System content mutation detected.\n";
} else {
$llms_md .= "## Status: STABLE (No mutations)\n";
}
$llms_md .= "---------------------------------------------------------------------\n";
// Чистим текст для Markdown от мусорных переносов строк
$cleaned_md = html_entity_decode($markdown_text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
$cleaned_md = preg_replace("/\n\s*\n+/", "\n\n", trim($cleaned_md));
$llms_md .= $cleaned_md . "\n";
$llms_md .= "=====================================================================\n\n";
// --- [ СБОРКА ATOM ENTRY XML (CDATA HTML) ] ---
$atom_preview = mb_strimwidth(strip_tags((string)$rss_i['content']), 0, 300, "...");
$atom .= ' ' . PHP_EOL;
$atom .= ' ' . htmlspecialchars($prefix . $clean_title, ENT_XML1, 'UTF-8') . '' . PHP_EOL;
$atom .= ' ' . PHP_EOL;
$atom .= ' urn:node:' . htmlspecialchars($src_module, ENT_XML1, 'UTF-8') . ':' . $item_id . '' . PHP_EOL;
$atom .= ' ' . $pub_date_atom . '' . PHP_EOL;
if (!empty($rss_i['date_edit'])) {
$atom .= ' ' . date('c', strtotime((string)$rss_i['date_edit'])) . '' . PHP_EOL;
} else {
$atom .= ' ' . $pub_date_atom . '' . PHP_EOL;
}
$atom .= ' ' . htmlspecialchars($atom_preview, ENT_XML1, 'UTF-8') . '' . PHP_EOL;
$atom .= ' ' . PHP_EOL;
// Интеграция LSI-ключей нашего графа в мета-структуру Atom
if (!empty($rss_i['lsi_keywords'])) {
$keywords = array_filter(array_map('trim', explode(',', (string)$rss_i['lsi_keywords'])));
foreach ($keywords as $keyword) {
$atom .= ' ' . PHP_EOL;
}
}
// Обработка вложений (Медиа-контур)
if (!empty($rss_i['f_check'])) {
$file_path = ROOT_DIR . 'storage/' . $src_module . '/' . $rss_i['f_check'];
if (file_exists($file_path)) {
$img_url = "https://{$current_host}/storage/{$src_module}/" . rawurlencode($rss_i['f_check']);
$atom .= ' ' . PHP_EOL;
}
}
$atom .= ' ' . PHP_EOL;
}
$atom .= '';
// --- [ 4. ЖЕСТКАЯ АТОМАРНАЯ ПЕРЕЗАПИСЬ (БЕЗ RACE CONDITION) ] ---
$tmp_llms = $llms_full_file . '.tmp';
if (file_put_contents($tmp_llms, $llms_md, LOCK_EX) !== false) {
@rename($tmp_llms, $llms_full_file);
}
$tmp_atom = $atom_file . '.tmp';
if (file_put_contents($tmp_atom, $atom, LOCK_EX) !== false) {
@rename($tmp_atom, $atom_file);
}
$report .= "> II_FEEDS_GEN | OVERWRITE: SUCCESS (HTML in Atom + Meta in TXT)\n";
}
} catch (Exception $e) {
$report .= "> II_FEEDS_GEN | ERROR: " . $e->getMessage() . "\n";
}
Ключевые фишки реализации:
Конвейерное повторное использование (Reusability):
Модуль не нагружает СУБД повторными выборками — он использует готовый массив $rss_items, собранный базовым RSS-генератором. Всё происходит за один цикл обработки в памяти.
Безопасность I/O и защита от Race Condition:
Файлы пишутся во временный буфер (.tmp) с эксклюзивной блокировкой LOCK_EX. После успешной записи происходит системный вызов @rename(), который подменяет рабочий файл на уровне ОС за миллисекунду. Краулеры никогда не прочитают полупустой или битый файл.
Экранирование CDATA:
Чтобы спецсимволы в исходном HTML не ломали XML-парсеры, конструкция ]]> в коде статьи экранируется через ]]>.
Нативная передача LSI-ассоциаций:
Ключевые слова, сгенерированные движком «Гарпун», пробрасываются прямо в фид через элементы . Краулерам не нужно строить семантический граф статьи с нуля — они получают готовые синапсы.
Рекордный TTA (Time to Answer):
Так как отдаются готовые статические файлы с диска, время ответа сервера составляет всего 0.0007–0.0027 секунды. Nginx отдаёт статику «с лёта», вообще не привлекая интерпретатор PHP при GET-запросах.
Ваш Админ.