Автор: A.Ankalaev
Cистемный администратор с опытом более 20 лет
Среди специалистов по разработке, особенно тут на Хабре, бытует мнение, что большие языковые модели (LLM) не способны генерировать полноценные приложения «под ключ». Сам работаю с нейросетями со времён GPT, бесконечное количество раз применял их в своей работе для:
обучения персонала безопасности в сети
проектирования концепций
математических вычислений (нагрузка, мощность, распределение)
личного карьерного роста.
Если верить данным в сети:
Запущенный в июне 2022 GitHub Copilot имеет 1,3 миллиона платных пользователей (по состоянию на февраль 2024 года, более свежие данные отсутствуют).
По данным DemandSage, опубликованным 16 апреля 2025 года, ЧатGPT достиг 800 миллионов еженедельных активных пользователей, что подтверждается заявлениями CEO OpenAI Сэма Альтмана на TED 2025
Согласно статье Bloomberg, Cursor AI имеет около 1 миллиона пользователей (по состоянию на апрель 2025 года).
Большой спрос на ИИ, благодаря конкретным способностям, вполне оправдан. Но несмотря на устрашающие возможности, какна деле, так и в нашем сознании, ни один ИИ‑агент, включая крупных игроков, не пишет даже простой проект (15–30 файлов) самостоятельно, даже если скормить ему суперидеальное «ТЗ» и направляющие (аля «назначение роли») во всякие «Rules» подобные механизмы.
Что я только не пробовал подавать на вход, чтоб получить идеальный выход
Назначение роли в Project Rules
Цель проекта в Project Rules
Стек технологий и фреймворков в User Rules
Ограничения и запреты в User Rules
Принципы проектирования в User Rules
Документацию в Docs
Идеальный промпт на 47+ тысяч символов
Не идеальный, но подробный промпт на 10 тысяч символов
 # Техническое задание на разработку плагина AIWP-Processor (Часть 1) ## 1. Общая информация Наименование плагина: AIWP-Processor   Платформа: WordPress   Интеграция: Google Gemini API   Назначение: Автоматизация создания и редактирования контента с помощью искусственного интеллекта   Документация API: [Google Gemini API FAQ](../doc/gemini-api-faq.md) ## 2. Функциональные требования ### 2.1. Основной функционал 1. Интеграция с Google Gemini API:    - Подключение к REST API сервиса Google Gemini.    - Настройка и валидация API-ключа.    - Получение и сохранение списка доступных моделей.    - Выбор модели для для каждого генератора отдельно (Text_Generator, Image_Generator). 
Взаимодействие с WordPress:
Создание/редактирование заголовков постов post_title.
Создание/редактирование содержимого постов post_content.
Генерация и установка изображений featured_image.
Логирование всех операций и ошибок.
Пользовательский интерфейс:
Метабокс для чат-интерфейса для ввода запросов и получения результатов metabox-chat.php.
Интеграция метабокса в классический редактор WordPress и в редактор Gutenberg.
Административная панель с вкладками для управления плагином dashboard.php.
1. Верхняя панель метабокса
<div>
    <h3>AI Content Generator</h3>
    <div>
        <button title="Clear chat history">
            <span></span>
        </button>
        <button title="Show help">
            <span></span>
        </button>
    </div>
</div>
2. Панель управления генерацией
<div>
    <div>
        <label>
            <input name="generate_title" id="generate_title" type="checkbox">
            <span>Generate Title</span>
        </label>
        <label>
            <input name="generate_content" id="generate_content" type="checkbox">
            <span>Generate Content</span>
        </label>
        <label>
            <input name="generate_image" id="generate_image" type="checkbox">
            <span>Generate Featured Image</span>
        </label>
    </div>
</div>
3. Область чата
<div>
    <div id="aiwp_chat_messages">
        
    </div>
    <div>
        <textarea rows="3" placeholder="Enter your prompt here..." id="aiwp_prompt"></textarea>
        <button id="aiwp_send">
            <span>Send</span>
            <span></span>
        </button>
    </div>
</div>
4. Панель результатов
<div>
    <div>
        
    </div>
    <div>
        <button data-type="title">
            Apply Title
        </button>
        <button data-type="content">
            Apply Content
        </button>
        <button data-type="image">
            Apply Featured Image
        </button>
    </div>
</div>
1. Основные размеры и отступы
.aiwp-metabox {
    min-height: 400px;
    max-height: 800px;
    display: flex;
    flex-direction: column;
}
.aiwp-chat-container {
    flex: 1;
    min-height: 300px;
    display: flex;
    flex-direction: column;
}
.aiwp-chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
}
2. Стили сообщений чата
.aiwp-message {
    margin-bottom: 15px;
    max-width: 85%;
}
.aiwp-message-user {
    margin-left: auto;
    background: #e9ecef;
    border-radius: 15px 15px 0 15px;
}
.aiwp-message-ai {
    margin-right: auto;
    background: #f8f9fa;
    border-radius: 15px 15px 15px 0;
}
3. Стили элементов управления
.aiwp-generation-controls {
    padding: 10px;
    border-bottom: 1px solid #ddd;
}
.aiwp-checkbox {
    display: inline-flex;
    align-items: center;
    margin-right: 15px;
}
.aiwp-actions {
    display: flex;
    gap: 10px;
    padding: 10px;
    border-top: 1px solid #ddd;
}
1. Основной контейнер
<div>
    <h1>AIWP Processor Dashboard</h1>
    
    <div>
        <nav>
            <a href="#dashboard">Dashboard</a>
            <a href="#google-api">Google API</a>
            <a href="#settings">Settings</a>
            <a href="#logs">Logs</a>
        </nav>
        
        <div>
            
        </div>
    </div>
</div>
2. Стилизация панели
.aiwp-dashboard {
    max-width: 1200px;
    margin: 20px auto;
}
.aiwp-container {
    min-height: 700px;
    background: #fff;
    border: 1px solid #ccd0d4;
    box-shadow: 0 1px 1px rgba(0,0,0,.04);
}
.aiwp-tab-content {
    padding: 20px;
}
.aiwp-section {
    padding: 10px;
    margin-bottom: 20px;
}
1. Dashboard
<div id="dashboard">
    <div>
        <h2>System Status</h2>
        <div>
            <div>
                <h4>API Connection</h4>
                <div></div>
            </div>
            
        </div>
    </div>
    
    <div>
        <h2>Available Models</h2>
        <table>
            
        </table>
    </div>
</div>
2. Google API
<div id="google-api">
    <div>
        <h2>API Configuration</h2>
        <form action="options.php" method="post">
            <table>
                <tbody><tr>
                    <th>API Key</th>
                    <td>
                        <input value="<?php echo esc_attr(get_option('aiwp_google_api_key')); ?>" name="aiwp_google_api_key" type="password">
                    </td>
                </tr>
                
            </tbody></table>
            
        </form>
    </div>
</div>
3. Settings
<div id="settings">
    <div>
        <h2>General Settings</h2>
        <form action="options.php" method="post">
            <table>
                <tbody><tr>
                    <th>Email Notifications</th>
                    <td>
                        <label>
                            <input value="1" name="aiwp_email_notifications" type="checkbox">
                            >
                            Enable email notifications
                        </label>
                    </td>
                </tr>
                
            </tbody></table>
            
        </form>
    </div>
</div>
4. Logs
<div id="logs">
    <div>
        <div>
            <h2>Operation Logs</h2>
            <div>
                <button id="clear_logs">Clear Logs</button>
                <button id="export_logs">Export Logs</button>
            </div>
        </div>
        
        <div>
            <table>
                <thead>
                    <tr>
                        <th>Timestamp</th>
                        <th>Level</th>
                        <th>Message</th>
                        <th>Context</th>
                    </tr>
                </thead>
                <tbody id="logs_content">
                    
                </tbody>
            </table>
        </div>
    </div>
</div>
Стандартный запрос: "You are a content generator. Generate a post with the title: {title} and content: {content}"
При выборе опции "Generate Title": генерация и заполнение поля заголовка
При выборе опции "Generate Content": генерация и заполнение поля содержимого
При выборе опции "Generate Featured Image": "You are a content generator. Make image: {title}"
Применение результатов происходит только после подтверждения пользователем
1. Процесс формирования запроса:
При инициализации метабокса метод is_new_post() определяет, что запись новая
Класс Metabox_Chat через метод format_prompt() собирает базовый контекст:
$context = [
    'post_type' => get_post_type($post_id),
    'category' => get_the_category($post_id),
    'tags' => get_the_tags($post_id),
    'title' => get_the_title($post_id),
    'content' => get_post_field('post_content', $post_id),
    'featured_image' => get_post_thumbnail_id($post_id)
];
2. Последовательность обработки при выборе всех опций:
JavaScript формирует начальный запрос:
const requestData = {
    prompt: userPrompt,
    options: {
        generateTitle: true,
        generateContent: true,
        generateImage: true
    }
};
На сервере запрос обрабатывается в следующем порядке:
Генерация заголовка (приоритет 1)
Генерация контента с учетом заголовка (приоритет 2)
Генерация изображения на основе заголовка/контента (приоритет 3)
Класс Google_API_Processor выполняет запросы последовательно:
// 1. Генерация заголовка
$title = $api->generate_text([
    'prompt' => "You are a content generator. Generate a post with the title: {title}",
    'max_tokens' => 50
]);
// 2. Генерация контента с учетом заголовка
$content = $api->generate_text([
    'prompt' => "You are a content generator. Generate a post with the title: {title} and content: {content}",
    'max_tokens' => 1000
]);
// 3. Генерация изображения
$image = $api->generate_image([
    'prompt' => "You are a content generator. Make image: {title}",
    'size' => '1248x1024',
    'responseModalities' => ["Text", "Image"]
]);
3. Передача данных между компонентами:
Клиентская часть → Сервер:
metabox-chat.js → AJAX запрос → wp_ajax_aiwp_chat_request
Данные передаются в формате JSON через POST запрос
Включается nonce для безопасности
Внутренняя обработка:
Metabox_Chat->handle_ajax_chat_request() → Google_API_Processor
Результаты сохраняются во временное хранилище через WP_Session
Логи записываются в aiwp-logs.json
Сервер → Клиентская часть:
Структурированный JSON-ответ с результатами
WebSocket для real-time обновления статуса генерации
События прогресса для длительных операций 4. Обработка результатов:
Класс Google_Response_Handler форматирует и валидирует полученные данные
Временные файлы создаются в защищенной директории
Создаются превью для изображений
Результаты кэшируются для повторного использования
При выборе "Generate Title": формирование запроса "You are a content generator. Rewrite the title: {title}"
При выборе "Generate Content": формирование запроса "You are a content generator. Rewrite the content: {content}"
При выборе опции "Generate Featured Image": формирование запроса "You are a content generator. Make image: {title}"
При выборе нескольких опций: комбинированный запрос для редактирования всех выбранных элементов
Все автоматически сформированные запросы можно редактировать перед отправкой
1. Процесс формирования запроса для существующей записи:
Метод format_prompt() собирает текущие данные:
$current_data = [
    'title' => get_the_title($post_id),
    'content' => get_post_field('post_content', $post_id),
    'image' => get_post_thumbnail_id($post_id)
];
2. Последовательность операций при выборе всех опций:
Предварительная обработка:
// Анализ существующего контента
$content_analysis = $api->analyze_content([
    'title' => $current_data['title'],
    'content' => $current_data['content'],
    'maintain_style' => true
]);
// Формирование контекста для сохранения стиля
$style_context = $content_analysis->extract_style_patterns();
Параллельная обработка запросов:
// Асинхронная генерация всех элементов
$promises = [
    'title' => $api->async_generate_text($prompt, $style_context),
    'content' => $api->async_generate_text($prompt, $style_context),
    'image' => $api->async_generate_image($prompt, [
        'responseModalities' => ["Text", "Image"]
    ])
];
// Ожидание выполнения всех запросов
$results = Promise\all($promises)->wait();
Пост-обработка результатов:
Сравнение с оригинальным контентом
Сохранение форматирования
Объединение результатов 3. Передача данных между компонентами:
Подготовка данных:
$prepared_data = [
    'original' => $current_data,
    'generated' => $results,
    'diff' => generate_content_diff($current_data, $results)
];
Система событий:
do_action('aiwp_before_content_update', $prepared_data);
update_post_meta($post_id, '_aiwp_generation_history', $prepared_data);
do_action('aiwp_after_content_update', $prepared_data);
Клиентское отображение:
Визуальное сравнение версий
Возможность частичного применения изменений
Предпросмотр в реальном времени 4. Обработка специфических случаев:
Сохранение мета-данных:
// Сохранение истории изменений
$history = [
    'timestamp' => current_time('mysql'),
    'user_id' => get_current_user_id(),
    'changes' => $prepared_data['diff']
];
add_post_meta($post_id, '_aiwp_revision', $history);
Обработка конфликтов:
Проверка наличия несохраненных изменений
Механизм разрешения конфликтов версий
Возможность отката изменений
Валидация результатов:
// Проверка качества генерации
$quality_check = [
    'readability_score' => calculate_readability($results['content']),
    'seo_score' => analyze_seo_metrics($results),
    'similarity_score' => compare_with_original($current_data, $results)
];
Безопасность
Валидация и санитация всех пользовательских входных данных
Безопасное хранение API-ключа
Проверка прав доступа для всех операций
Защита от CSRF-атак
Производительность
Асинхронная обработка запросов к API
Кэширование результатов запросов где возможно
Оптимизация загрузки ресурсов (CSS/JS)
Учет ограничений и квот API Google Gemini
|   aiwp-processor.php
|   uninstall.php   
|           
+---Backend
|   +---Admin
|   |       class-aiwp-admin.php
|   |       class-aiwp-ajax-request.php
|   |       class-aiwp-dashboard.php
|   |       
|   +---API
|   |       class-google-processor.php
|   |       
|   +---Chat
|   |       class-metabox-chat.php
|   |       
|   \---Logger
|           aiwp-logs.json
|           class-aiwp-logger.php
|           
+---doc
|       development.md
|       gemini-api-faq.md
|       
\---Frontend
    \---assets
        +---CSS
        |       dashboard.css
        |       metabox.css
        |       
        +---JS
        |       dashboard.js
        |       metabox-chat.js
        |       
        \---pages
                dashboard.php
                metabox-chat.php
aiwp-processor.php                      # Основной файл плагина
Функции в aiwp-processor.php:
aiwp_activate() - активация плагина, создание необходимых директорий и файлов
aiwp_deactivate() - деактивация плагина, сохранение настроек
aiwp_init() - инициализация плагина при загрузке WordPress
aiwp_register_assets() - регистрация CSS и JavaScript ресурсов
aiwp_load_textdomain() - загрузка файлов локализации
aiwp_plugin_row_meta() - добавление метаданных плагина
aiwp_check_requirements() - проверка требований для работы плагина
aiwp_admin_notices() - отображение административных уведомлений
aiwp_add_admin_menu() - добавление пунктов меню в админ-панель WordPress
uninstall.php                           # Скрипт удаления плагина
Функции в uninstall.php:
Удаление всех опций и настроек плагина из базы данных
Удаление созданных при установке директорий и файлов
Удаление журналов логирования
Backend/
  Admin/
    class-aiwp-admin.php                # Класс для интеграции с админ-панелью WordPress
Методы класса AIWP_Admin:
__construct() - конструктор класса
init() - инициализация класса
register_hooks() - регистрация хуков WordPress
add_admin_menu() - добавление административного меню
register_settings() - регистрация настроек плагина
admin_enqueue_scripts() - подключение скриптов и стилей для админ-панели
display_admin_page() - отображение административной страницы плагина
add_metaboxes() - добавление метабокса в классический редактор и Gutenberg
add_metabox_classic() - добавление метабокса в классический редактор
add_metabox_gutenberg() - добавление метабокса в редактор Gutenberg
save_metabox_data() - сохранение данных метабокса
get_plugin_option($option_name) - получение опции плагина
update_plugin_option($option_name, $value) - обновление опции плагина
delete_plugin_option($option_name) - удаление опции плагина
    class-aiwp-dashboard.php            # Класс для страницы настроек плагина
Методы класса AIWP_Dashboard:
__construct() - конструктор класса
init() - инициализация класса
register_hooks() - регистрация хуков WordPress
render_dashboard_page() - отображение страницы дашборда
render_tab_dashboard() - отображение вкладки Dashboard
render_tab_google_api() - отображение вкладки Google API
render_tab_settings() - отображение вкладки Settings
render_tab_logs() - отображение вкладки Logs
handle_api_key_update() - обработка обновления API ключа
handle_model_selection() - обработка выбора моделей AI
handle_settings_update() - обработка обновления общих настроек
handle_logs_settings() - обработка настроек логирования
get_available_models() - получение списка доступных моделей
test_api_connection() - тестирование соединения с API
clear_logs() - очистка журнала логов
export_logs() - экспорт журнала логов
process_bulk_actions() - обработка массовых действий
  Backend/API/
    class-google-processor.php            # Класс для работы с Google Gemini API
Методы класса Google_API_Processor:
__construct() - конструктор класса
init() - инициализация класса с настройками
set_api_key($api_key) - установка API ключа
get_api_key() - получение API ключа
validate_api_key() - валидация API ключа
get_available_models() - получение списка доступных моделей
get_model_details($model_id) - получение детальной информации о модели
set_text_model($model_id) - установка модели для текстового генератора
set_image_model($model_id) - установка модели для генератора изображений
get_text_model() - получение текущей текстовой модели
get_image_model() - получение текущей модели изображений
format_prompt($context, $prompt, $is_new_post = false) - форматирование запроса с учетом контекста
generate_text($prompt, $options = []) - генерация текста по промпту
generate_image($prompt, $options = []) - генерация изображения по промпту
async_generate_text($prompt, $options = []) - асинхронная генерация текста
async_generate_image($prompt, $options = []) - асинхронная генерация изображения
analyze_content($data) - анализ существующего контента
rewrite_title($current_title, $prompt) - переписывание существующего заголовка
rewrite_content($current_content, $prompt) - переписывание существующего контента
check_rate_limits() - проверка ограничений и квот API
log_request($request_data) - логирование запросов к API
log_response($response_data) - логирование ответов от API
handle_api_response($response) - обработка ответа API
handle_error($error_code, $error_message) - обработка ошибок API
save_api_response($response_data) - сохранение ответа API для последующего использования
  Backend/Chat/
    class-metabox-chat.php              # Класс для метабокса в редакторе
Методы класса Metabox_Chat:
__construct() - конструктор класса
init() - инициализация класса
register_hooks() - регистрация хуков WordPress
enqueue_assets() - подключение скриптов и стилей
add_metabox() - добавление метабокса в редактор
render_metabox($post) - отображение содержимого метабокса
save_metabox_data($post_id) - сохранение данных метабокса
generate_chat_interface() - генерация интерфейса чата
handle_ajax_chat_request() - обработка AJAX-запроса из чата
format_prompt($post, $user_prompt, $options) - форматирование промпта на основе выбранных опций
process_api_response($response, $options) - обработка ответа API
is_new_post($post_id) - проверка, новая ли запись
apply_generated_title($post_id, $title) - применение сгенерированного заголовка
apply_generated_content($post_id, $content) - применение сгенерированного содержимого
apply_generated_image($post_id, $image_data) - применение сгенерированного изображения
save_chat_history($post_id, $chat_data) - сохранение истории чата для поста
get_chat_history($post_id) - получение истории чата для поста
clear_chat_history($post_id) - очистка истории чата для поста
get_generation_context_from_title($post_id) - получение контекста для генерации
get_generation_context($post_id) - получение контекста для генерации
handle_image_upload() - обработка загрузки изображения
validate_request($post_id, $nonce) - валидация запроса
  Backend/API/
    class-google-response-handler.php         # Класс для обработки ответов от API
Методы класса Google_Response_Handler:
__construct() - конструктор класса
init() - инициализация класса
process_text_response($response) - обработка текстового ответа
process_image_response($response) - обработка ответа с изображением
extract_title_from_response($response) - извлечение заголовка из ответа
extract_content_from_response($response) - извлечение содержимого из ответа
extract_image_from_response($response) - извлечение изображения из ответа
validate_response($response) - валидация ответа
format_response_for_client($response) - форматирование ответа для клиента
handle_error_response($error) - обработка ошибочного ответа
save_temporary_title($title) - сохранение временного заголовка
save_temporary_content($content) - сохранение временного содержимого
save_temporary_image($image_data) - сохранение временного изображения
cleanup_temporary_data() - очистка временных данных
  Backend/Logger/
    class-aiwp-logger.php               # Класс для логирования операций
Методы класса AIWP_Logger:
__construct() - конструктор класса
init() - инициализация класса
set_log_file($log_file) - установка файла для логирования
log($message, $level = 'info', $context = []) - основной метод логирования
log_info($message, $context = []) - логирование информационных сообщений
log_warning($message, $context = []) - логирование предупреждений
log_error($message, $context = []) - логирование ошибок
log_api_request($endpoint, $params) - логирование API запросов
log_api_response($endpoint, $response) - логирование ответов API
get_logs($limit = 100, $level = null) - получение логов
get_log_by_id($log_id) - получение записи лога по ID
clear_logs() - очистка всех логов
rotate_logs() - ротация логов для контроля размера файла
is_logging_enabled() - проверка, включено ли логирование
set_log_level($level) - установка уровня детализации логирования
get_log_level() - получение текущего уровня логирования
format_log_entry($message, $level, $context) - форматирование сообщения лога
    aiwp-logs.json                      # Файл логов
Структура файла логов:
Хранится в формате JSON
Каждая запись содержит:
ID лога
Временная метка
Уровень логирования (info, warning, error)
Сообщение
Контекст (дополнительные данные)
IP-адрес пользователя
Frontend/assets/
  CSS/
    dashboard.css                       # Стили для страницы настроек
    metabox.css                         # Стили для метабокса
Инициализация
Загрузка основного файла плагина при активации WordPress
Инициализация ключевых классов (Admin, API, Chat, Logger)
Регистрация хуков и фильтров WordPress
Взаимодействие с редактором контента
Отображение метабокса в редакторе записи
Обработка запросов пользователя в интерфейсе метабокса
Отправка данных на сервер через AJAX
Обработка запросов к AI
Валидация и форматирование запроса
Отправка запроса к Google Gemini API
Обработка и форматирование ответа
Логирование результатов операции
Работа с сгенерированными данными
Временное хранение результатов генерации
Применение результатов к записи по запросу пользователя
Сохранение сгенерированных изображений в медиа-библиотеке WordPress
Пользователь → Метабокс чата
Пользователь вводит промпт и выбирает опции генерации
Метабокс чата → AJAX Request → Backend
Отправка запроса с промптом и выбранными опциями на сервер
Backend → Google API Processor
Формирование и отправка запроса к Google Gemini API
Google API Processor → Google Gemini API
Отправка запроса к внешнему API
Google Gemini API → Google API Processor
Получение ответа от внешнего API
Google API Processor → Backend
Обработка ответа и форматирование данных
Backend → Logger
Логирование операции и результата
Backend → AJAX Response → Метабокс чата
Отправка результата обратно клиенту
Метабокс чата → Пользователь
Отображение результата в интерфейсе чата
Пользователь → Метабокс чата → WordPress
Применение результата к записи (по запросу пользователя)
Базовая интеграция с WordPress (метабокс, админ-панель)
Подключение к Google Gemini API
Реализация генерации текстового контента
Реализация генерации изображений
Система логирования
Улучшение пользовательского интерфейса
Оптимизация и повышение производительности
+-------------------+       +-------------------+       +-------------------+
|                   |       |                   |       |                   |
|  WordPress Admin  +------>+  AIWP_Admin       +------>+  Metabox_Chat     |
|                   |       |                   |       |                   |
+-------------------+       +---------+---------+       +---------+---------+
                                      |                           |
                                      |                           |
                                      v                           v
                            +---------+---------+       +---------+---------+
                            |                   |       |                   |
                            |  AIWP_Dashboard   |       |  Google_API       |
                            |                   |       |  _Processor       |
                            +---------+---------+       +---------+---------+
                                      |                           |
                                      |                           |
                                      v                           v
                            +---------+---------+       +---------+---------+
                            |                   |       |                   |
                            |  AIWP_Logger      +<------+  Response_Handler |
                            |                   |       |                   |
                            +-------------------+       +-------------------+
При активации WordPress загружается файл aiwp-processor.php
Вызывается функция aiwp_activate(), которая: 
Создает необходимые директории для хранения логов и временных файлов
Регистрирует настройки плагина в базе данных WordPress
Инициализирует файл логов в формате JSON
При каждой загрузке WordPress вызывается функция aiwp_init(), которая: 
Создает экземпляры основных классов: AIWP_Logger, Google_API_Processor и AIWP_Admin
Регистрирует все необходимые хуки и фильтры WordPress
Проверяет наличие и валидность API-ключа Google Gemini
Класс AIWP_Admin инициализирует административный интерфейс: 
Регистрирует пункты меню в административной панели WordPress
Подключает JavaScript и CSS ресурсы плагина
Добавляет метабокс в редактор постов (классический и Gutenberg)
Класс AIWP_Admin через метод add_metaboxes() определяет тип используемого редактора: 
Для классического редактора вызывается метод add_metabox_classic()
Для редактора Gutenberg вызывается метод add_metabox_gutenberg()
Метабокс регистрируется для всех типов записей, где можно использовать AI-генерацию:
Посты (post)
Страницы (page)
Произвольные типы записей с поддержкой редактора
При рендеринге метабокса вызывается шаблон metabox-chat.php, который: 
Отображает чат-интерфейс с полем ввода промпта
Показывает чекбоксы для выбора типа генерируемого контента
Создает контейнер для вывода истории чата и результатов генерации
Скрипт metabox-chat.js инициализируется и привязывает обработчики событий к элементам интерфейса
Пользователь видит чат-интерфейс в боковой панели или под редактором
Интерфейс содержит:
Поле ввода (textarea) для промпта
Чекбоксы для выбора типа генерации:
"Generate Title" - создать заголовок
"Generate Content" - создать содержимое
"Generate Featured Image" - создать изображение-миниатюру
Кнопку "Send" для отправки запроса
Область истории чата (изначально пустая)
Класс Metabox_Chat загружает предыдущую историю чата из метаданных поста, если она существует
Метод is_new_post() определяет, является ли пост новым или существующим, для формирования правильного контекста запроса
Пользователь вводит текст запроса и выбирает нужные опции генерации
При нажатии кнопки "Send" вызывается функция handlePromptSubmission() из metabox-chat.js, которая: 
Предотвращает стандартное поведение формы
Добавляет сообщение пользователя в чат-историю
Отображает индикатор загрузки (спиннер)
Собирает данные запроса:
Текст промпта
Выбранные опции генерации (title, content, image)
ID и тип поста
Nonce для безопасности
Отправляет AJAX-запрос к WordPress через wp_ajax_aiwp_process_chat_request
На стороне сервера запрос перехватывается методом handle_ajax_chat_request() класса Metabox_Chat
Метод выполняет:
Проверку безопасности (nonce)
Валидацию входных данных
Определение типа запроса (новый пост или редактирование)
Логирование запроса через класс AIWP_Logger
Метод format_prompt() класса Metabox_Chat обрабатывает запрос пользователя: 
Если пост новый:
При выборе опции "Title" добавляет к промпту: "You are a content generator. Generate a post with the title:"
При выборе опции "Content" добавляет: "Generate post content about:"
При выборе обеих опций формирует комбинированный промпт
Если пост существующий:
При выборе опции "Title" извлекает текущий заголовок и добавляет к промпту: "You are a content generator. Rewrite the title: {current_title}"
При выборе опции "Content" добавляет: "Rewrite the content: {current_content}"
При выборе опции "Featured Image":
Добавляет к промпту: "You are a content generator. Make image: {title_or_prompt}"
Собирает контекст поста для улучшения генерации:
Категории и теги поста
Тип поста и статус
Метаданные (если есть)
Метод handle_ajax_chat_request() создает экземпляр Google_API_Processor
В зависимости от выбранных опций вызываются соответствующие методы:
Для генерации текста (заголовок и/или содержимое):
generate_text() - использует текстовую модель, выбранную в настройках плагина
Передает оптимизированный промпт и дополнительные параметры (температура, максимальная длина и т.д.)
Для генерации изображения:
generate_image() - использует модель для изображений, выбранную в настройках
Передает промпт для изображения и параметры (разрешение, стиль)
Класс Google_API_Processor формирует HTTP-запросы к Google Gemini API: 
Подготавливает заголовки запроса с API-ключом
Формирует тело запроса в формате JSON
Отправляет запрос через WordPress HTTP API (wp_remote_post)
Получает и декодирует ответ
Обрабатывает возможные ошибки и исключения
Все запросы и ответы логируются через методы log_request() и log_response() класса AIWP_Logger
Метод process_api_response() класса Metabox_Chat обрабатывает полученные от API данные: 
При генерации текста:
Извлекает заголовок и содержимое из ответа
Форматирует HTML-структуру содержимого (абзацы, заголовки)
Санитизирует текст для безопасного отображения
При генерации изображения:
Сохраняет изображение во временную директорию
Создает миниатюру для предпросмотра
Подготавливает данные для загрузки в медиа-библиотеку WordPress
Формирует структурированный JSON-ответ, содержащий:
Сгенерированный контент (заголовок, текст, URL изображения)
Статус выполнения (успех или ошибка)
Тип сгенерированного контента
Временные метки
Логирует результат операции через AIWP_Logger
Подготовленный ответ отправляется обратно клиенту через стандартный механизм AJAX WordPress
Скрипт metabox-chat.js получает ответ и обрабатывает его через функцию handleResponseActions(): 
Скрывает индикатор загрузки
Добавляет ответ от AI в историю чата
Отображает сгенерированный контент с соответствующим форматированием
Для текста: отображает заголовок и содержимое с правильной HTML-структурой
Для изображения: показывает миниатюру изображения
Активирует панель действий с кнопками:
"Apply Title" - если был сгенерирован заголовок
"Apply Content" - если было сгенерировано содержимое
"Apply Featured Image" - если было сгенерировано изображение
Функция updateChatHistory() добавляет новые сообщения в чат-интерфейс и прокручивает его вниз
История чата сохраняется в метаданных поста через AJAX-запрос к методу save_chat_history()
Пользователь может применить любой из сгенерированных элементов, нажав соответствующую кнопку
При нажатии на кнопку "Apply Title":
Вызывается функция applyTitleToPost() в metabox-chat.js
Отправляется AJAX-запрос к методу apply_generated_title() класса Metabox_Chat
Метод обновляет заголовок поста в базе данных
В интерфейсе редактора обновляется поле заголовка
При нажатии на кнопку "Apply Content":
Вызывается функция applyContentToPost() в metabox-chat.js
Отправляется AJAX-запрос к методу apply_generated_content() класса Metabox_Chat
Метод обновляет содержимое поста в базе данных
В зависимости от типа редактора:
Для классического редактора: контент вставляется в поле редактора
Для Gutenberg: контент вставляется через API редактора
При нажатии на кнопку "Apply Featured Image":
Вызывается функция applyFeaturedImageToPost() в metabox-chat.js
Отправляется AJAX-запрос к методу apply_generated_image() класса Metabox_Chat
Метод:
Загружает временное изображение в медиа-библиотеку WordPress
Создает все необходимые размеры миниатюр
Устанавливает загруженное изображение как миниатюру записи
Обновляет интерфейс с отображением выбранной миниатюры
После каждого применения отображается уведомление об успешном выполнении операции
Все операции логируются в файле aiwp-logs.json через класс AIWP_Logger
Метаданные о сеансе генерации сохраняются в посте
Обновляется статистика использования плагина для отображения на странице Dashboard:
Счетчик успешных генераций
Счетчик ошибок
Использованные токены/кредиты API
Временные метки последнего использования
Пользователь может продолжить работу с плагином, генерируя новый контент, или сохранить запись
История чата сохраняется между сеансами редактирования и доступна при повторном открытии записи
Нажатие кнопки "Send"
// metabox-chat.js
document.getElementById('aiwp_send').addEventListener('click', function(e) {
    e.preventDefault();
    handlePromptSubmission();
});
Сбор данных для запроса
// metabox-chat.js
function handlePromptSubmission() {
    const prompt = document.getElementById('aiwp_prompt').value;
    const generateTitle = document.getElementById('generate_title').checked;
    const generateContent = document.getElementById('generate_content').checked;
    const generateImage = document.getElementById('generate_image').checked;
    const postId = document.getElementById('post_ID').value;
    
    const data = {
        action: 'aiwp_process_chat_request',
        prompt: prompt,
        options: {
            generateTitle,
            generateContent,
            generateImage
        },
        postId: postId,
        _ajax_nonce: aiwpData.nonce
    };
    
    sendAjaxRequest(data);
}
Отправка AJAX запроса
// metabox-chat.js
function sendAjaxRequest(data) {
    showLoadingSpinner();
    addMessageToChat('user', data.prompt);
    
    jQuery.post(ajaxurl, data)
        .done(handleResponse)
        .fail(handleError)
        .always(hideLoadingSpinner);
}
Перехват AJAX запроса в WordPress
// class-metabox-chat.php
public function register_hooks() {
    add_action('wp_ajax_aiwp_process_chat_request', [$this, 'handle_ajax_chat_request']);
}
Начальная обработка запроса
// class-metabox-chat.php
public function handle_ajax_chat_request() {
    check_ajax_referer('aiwp_chat_nonce');
    
    $post_id = intval($_POST['postId']);
    $prompt = sanitize_textarea_field($_POST['prompt']);
    $options = $this->validate_options($_POST['options']);
    
    // Логируем входящий запрос
    $this->logger->log_info('Incoming chat request', [
        'post_id' => $post_id,
        'options' => $options
    ]);
    
    $this->process_request($post_id, $prompt, $options);
}
Форматирование промпта
// class-metabox-chat.php
private function format_prompt($prompt, $options, $post) {
    $formatted_prompt = '';
    
    if ($this->is_new_post($post)) {
        if ($options['generateTitle']) {
            $formatted_prompt .= "You are a content generator. Generate a post with the title: ";
        }
        if ($options['generateContent']) {
            $formatted_prompt .= "Generate post content about: ";
        }
    } else {
        if ($options['generateTitle']) {
            $current_title = get_the_title($post);
            $formatted_prompt .= "You are a content generator. Rewrite the title: {$current_title}";
        }
        if ($options['generateContent']) {
            $current_content = get_post_field('post_content', $post);
            $formatted_prompt .= "Rewrite the content: {$current_content}";
        }
    }
    
    if ($options['generateImage']) {
        $formatted_prompt .= "Make image: " . ($options['generateTitle'] ? '{title}' : $prompt);
    }
    
    return $formatted_prompt . $prompt;
}
Создание экземпляра API процессора
// class-metabox-chat.php
private function process_request($post_id, $prompt, $options) {
    $api = new Google_API_Processor();
    $formatted_prompt = $this->format_prompt($prompt, $options, get_post($post_id));
    
    try {
        $response = $this->generate_content($api, $formatted_prompt, $options);
        $this->handle_api_response($response, $post_id);
    } catch (Exception $e) {
        $this->handle_error($e);
    }
}
Генерация контента
// class-metabox-chat.php
private function generate_content($api, $prompt, $options) {
    $response = [];
    
    if ($options['generateTitle'] || $options['generateContent']) {
        $text_model = $api->get_text_model();
        $response['text'] = $api->generate_text($prompt, [
            'model' => $text_model,
            'temperature' => 0.7,
            'max_tokens' => 1000
        ]);
    }
    
    if ($options['generateImage']) {
        $image_model = $api->get_image_model();
        $response['image'] = $api->generate_image($prompt, [
            'model' => $image_model,
            'size' => '1024x1024',
            'quality' => 'hd'
        ]);
    }
    
    return $response;
}
Парсинг ответа
// class-metabox-chat.php
private function handle_api_response($response, $post_id) {
    $processed_response = [
        'success' => true,
        'data' => []
    ];
    
    if (isset($response['text'])) {
        $text_content = $this->process_text_response($response['text']);
        $processed_response['data']['title'] = $text_content['title'] ?? null;
        $processed_response['data']['content'] = $text_content['content'] ?? null;
    }
    
    if (isset($response['image'])) {
        $image_data = $this->process_image_response($response['image'], $post_id);
        $processed_response['data']['image'] = $image_data;
    }
    
    $this->logger->log_info('API response processed', $processed_response);
    wp_send_json_success($processed_response);
}
Обработка текстового контента
// class-metabox-chat.php
private function process_text_response($text_response) {
    return [
        'title' => wp_strip_all_tags($text_response['title'] ?? ''),
        'content' => wp_kses_post($text_response['content'] ?? '')
    ];
}
Обработка изображения
// class-metabox-chat.php
private function process_image_response($image_response, $post_id) {
    $upload_dir = wp_upload_dir();
    $temp_file = $upload_dir['path'] . '/temp_' . uniqid() . '.jpg';
    
    file_put_contents($temp_file, base64_decode($image_response['data']));
    
    return [
        'temp_path' => $temp_file,
        'preview_url' => $upload_dir['url'] . '/' . basename($temp_file)
    ];
}
Форматирование ответа для клиента
// class-metabox-chat.php
private function format_client_response($processed_data) {
    return [
        'success' => true,
        'data' => $processed_data,
        'message' => 'Content generated successfully',
        'timestamp' => current_time('mysql')
    ];
}
JavaScript обработка ответа
// metabox-chat.js
function handleResponse(response) {
    if (response.success) {
        const data = response.data;
        
        // Добавляем ответ в чат
        addMessageToChat('ai', formatAIResponse(data));
        
        // Активируем кнопки применения результатов
        if (data.title) enableApplyButton('title');
        if (data.content) enableApplyButton('content');
        if (data.image) enableApplyButton('image');
        
        // Сохраняем результаты в временное хранилище
        storeGeneratedContent(data);
    } else {
        handleError(response.message);
    }
}
Обработчики кнопок применения
// metabox-chat.js
function setupApplyButtons() {
    document.getElementById('apply_title').addEventListener('click', () => {
        const title = getStoredContent('title');
        applyTitleToPost(title);
    });
    
    document.getElementById('apply_content').addEventListener('click', () => {
        const content = getStoredContent('content');
        applyContentToPost(content);
    });
    
    document.getElementById('apply_image').addEventListener('click', () => {
        const image = getStoredContent('image');
        applyFeaturedImageToPost(image);
    });
}
Применение заголовка
// metabox-chat.js
function applyTitleToPost(title) {
    // Для классического редактора
    if (document.getElementById('title')) {
        document.getElementById('title').value = title;
    }
    // Для Gutenberg
    else if (wp.data && wp.data.select('core/editor')) {
        wp.data.dispatch('core/editor').editPost({ title });
    }
}
Применение контента
// metabox-chat.js
function applyContentToPost(content) {
    // Для классического редактора
    if (typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor) {
        tinyMCE.activeEditor.setContent(content);
    }
    // Для Gutenberg
    else if (wp.data && wp.data.select('core/editor')) {
        wp.data.dispatch('core/editor').insertBlocks(
            wp.blocks.parse(content)
        );
    }
}
Применение изображения
// metabox-chat.js
function applyFeaturedImageToPost(imageData) {
    const data = {
        action: 'aiwp_apply_featured_image',
        post_id: getCurrentPostId(),
        image_data: imageData,
        _ajax_nonce: aiwpData.nonce
    };
    
    jQuery.post(ajaxurl, data)
        .done(response => {
            if (response.success) {
                updateFeaturedImagePreview(response.data.attachment_url);
            }
        })
        .fail(handleError);
}
Почему так происходит? Давайте разберёмся вместе!
👉 Мнение лично моё, и может служить как ответом для интересующихся, так и поводом для рассуждения, для более продвинутых персон. К некоторым тут на Хабре, испытываю большую симпатию, уважение и белую зависть, за знания и умение грамотно излагать, свой опыт и мысли в текст. Прошу не бросать в меня помидоры, пишу впервые😊🙏
Нейрон - начало
Я называю его «нейроном-сперматозоидом», который в процессе своей короткой жизни должен обработать всю цепочку от «килограммового промпта» до «ответа», а ещё после (смерти) ответа, помнить мой промпт. Проблема начинается именно здесь. Хочется писать максимально просто, чтобы о проблеме могли рассуждать не только посвящённые в тонкости читатели.
В больших LLM, до получения ответа "промпт" проходит примерно такой коридор:
1. Tokenization
2. Embedding
3. Transformer layers
4. Logits
5. Softmax
6. Sampling
7. Autoregression
(Кому интересны подробности выражений, могут спросить нейросеть😊)
Всем этим процессом оперирует один «нейрон», который после присвоения определённого количества токенов нашему промпту, преобразует их в эмбеддинг, который затем проходит через N слоёв трансформера. И вот здесь наш «нейрон-сперматозоид» активирует сотни других нейронов в слоях внимания. Именно тут начинает работать концепция «цепочки мыслей» (chain-of-thought)  ответ, который почти у любой LLM будет примерно таким:
- Отлично! Я напишу структурированный базовый WordPress плагин для автоматизации публикаций в соцсети.
Одну минуту?!
Неужели я ввёл такой супер-мега-крутой промпт, который ответил бы на все вопросы рядового программиста?
Представьте:
Настоящий разработчик, получив письмо по электронной почте с просьбой: «Напиши мне базовый WordPress-плагин для автоматизации публикаций в соцсети», станет сразу писать код заказчика, не собрав данные, требования и ограничения, без анализа объема информации для выполнения задачи. 
Именно так отвечают почти все LLM, если не учиться правильно ими оперировать. Да, сегодня нужно именно учиться и пробовать разные методы, чтобы ИИ выполнял то, что вы задумали, ведь ваша мысль - это уже план, а она осталась у вас в голове. Ваш промпт, это даже не половина вашего желания, а уж тем более мысли. Любая нейросеть, даже рассуждающая, спешит исполнить ваше желание как простую математическую задачку, на которую она уже заранее знает ответ, ведь сухих данных у неё в памяти хоть отбавляй.
Как уже было сказано, даже самые продвинутые нейросети, получив на вход промпт, не работают над конечным продуктом вашего (промпта) желания, в первую очередь потому, что в большинстве случаев «промпт» содержит недостаточно входных данных, чтобы получить желаемо детализированный ответ. По сути, ИИ просто отвечает на мой «промпт» на уровне уровнения. Ведь при отсутствии, явно нужных данных, нейросеть в лучшем случае , будет заполнять код абстрактными для нас данными, которые она получала во время своего обучения. Поэтому писать проект за меня, будет проблематично, как в техническом, так и в идеологическом плане.
Задумайтесь только, ведь наша "идея" может состоять из огромного количества факторов. Но даже наша мысль, которую мы сами не обдумали в пух и прах, во всех мельчайших деталях, не сможет быть реализована и восполнена кем-то вместо нас, даже если это супернейросеть. И только после того, как мы всё соберём, и промпт будет содержать достаточно входных данных, я бы сказал: «Абсолютных Данных», по которым человек - программист, сможет выполнить проект самостоятельно.
Опираясь на сухие цифры: модель Gemini 2.5 Pro имеет входной контекст в 1 миллион токенов, но на выход только 64 тысячи. А вот модель от Anthropic (Sonnet 3.7 Think) вполне могла бы склеить всю цепочку действий почти идеально, если бы вывод не упирался в размер окна, которое тут составляет 128 тысяч токенов.
Нейрон - Один за всех, и все за одного.
Один "нейрон" вместо команды. Сегодня LLM - это один «запускающий и выполняющий всю цепочку действий элемент», и проблема заключается в том, что пока один «нейрон» вынужден быть: Архитектором и исполнителем, тестировщиком, и даже заказчиком, мы не получим того самого магического результата - готового и продуманного до мелочей проекта. Всё потому, что на текущем этапе развития LLM, количество входных и выходных токенов всё ещё ограничено. Даже если подать на вход идеальный промпт на 200 тысяч токенов, ИИ сможет составить план на 500 тысяч, но для реализации этого плана ему потребуется ещё хотя бы полмиллиона токенов на выход. А если где-то не хватит данных, увы, уточнить у меня что же я имел в виду, он уже не сможет.
Агенты - решат все проблемы?
Возможно, всё изменится, когда появятся модели-агенты, способные оперировать миллионами токенов на вход и на выход. Тогда один агент сможет создать детальный план, разложить всё по полочкам, и что важно, управлять другими агентами: назначить первого архитектором, второго — FullTask-программистом, третьего — QA-тестировщиком, четвёртого — менеджером по кофе. И вот тогда, при условии, что я всё-таки напишу в промпте исчерпывающие детали будущего проекта, может и увижу, тот самый долгожданный момент, когда ИИ напишет и протестирует проект за меня.
А может и не увижу, потому что, как показывает практика, чем совершеннее становится инструмент, тем сложнее становятся наши желания. Ну а пока продолжаем писать промпты, мечтать о будущем и с лёгкой иронией наблюдать за тем, как нейросети снова и снова предлагают нам «структурированный базовый WordPress-плагин»
Всем спасибо за внимание! Жду комментариев 😊