Помощь ИИ
Необязательная помощь ИИ с вашим собственным ключом: предложения заголовков и метаописаний, объяснения проблем сканирования простым языком, переработка описания в один клик и предложение структурированных данных schema.org. По умолчанию она выключена: при выключенном флаге никакой код ИИ не выполняется.
В основе три принципа:
- Ваш ключ, ваш провайдер. Запросы идут с вашего сервера прямо к настроенному вами провайдеру: Anthropic, OpenAI, Google либо локальному или совместимому с OpenAI серверу. Если применима оплата, она списывается с вашего аккаунта. Ничего не проксируется, использование не тарифицируется и не перепродаётся пакетом; телеметрия никуда не отправляется.
- Интерактивные предложения требуют явного принятия. Выбор предложения заполняет форму; исправления в панели требуют действия Apply — так в английском интерфейсе называется кнопка «Применить». Начиная с Pro 2.42 массовый CLI по умолчанию сохраняет приватные черновики. Используйте
--auto-apply, только если намеренно хотите немедленную запись. - Ошибки не останавливают работу. Отсутствующий или неверный ключ, исчерпанный баланс, ограничение частоты или тайм-аут дают сообщение в интерфейсе. Они никогда не блокируют сохранение, отображение или сканирование.
Краткое сравнение провайдеров
Выбирайте по доступу к аккаунту, требованиям к данным и стоимости. Все четыре интеграции предоставляют одни и те же задачи, но поддержка моделей, формат вывода, скорость и качество могут различаться.
| Провайдер | Модель в конфигурации по умолчанию | Структурированный вывод | Примерная стоимость | Назначение |
|---|---|---|---|---|
| Local — Ollama / LM Studio / vLLM | llama3.1, задайте свою | По возможности, через response_format | $0 за API при самостоятельном размещении; расходы на инфраструктуру остаются | Контроль назначения данных |
| OpenAI | gpt-5.5 | Structured Outputs, если выбранная модель поддерживает | Около $0,005 за предложение при допущениях примера ниже | Существующий аккаунт OpenAI |
| Anthropic | claude-opus-4-8 | output_config.format, где поддерживается | Около $0,015 за предложение при тех же допущениях | Существующий аккаунт Anthropic |
gemini-2.5-flash | responseSchema, где поддерживается | Около $0,0005 за предложение при тех же допущениях | Аккаунт Google; проверьте квоты моделей и цены |
Эти названия описывают поставляемую конфигурацию и не гарантируют доступность моделей в вашем аккаунте сейчас. Стоимость основана на примерных допущениях пакета, а не на проверенных текущих ценах. Поведение интеграций и наблюдения из опубликованных испытаний:
- Структурированный вывод. Поддерживаемые пути OpenAI, Google и Anthropic получают JSON-схему; некорректные ответы завершаются явной ошибкой. Локальным серверам передаётся
response_formatбез гарантии соблюдения. Если параметр проигнорирован, гибкий разбор вернёт корректный список или ошибку, не применяя частичный результат. - Рассуждение меняет расход токенов. В описанном испытании Gemini на одно описание ушло около 500 скрытых токенов рассуждения и около 100 видимых; протестированные вызовы Anthropic не сообщали о скрытых токенах. Это не универсальное свойство этих семейств моделей. Скрытые токены могут оплачиваться как выходные, поэтому ниже предусмотрен минимальный бюджет для рассуждающих моделей.
- Модели настраиваются. Задайте в
SEO_PRO_AI_MODELдоступную модель, совместимую с API и параметрами адаптера. Примеры:claude-haiku-4-5,gpt-5.4-miniиgemma-3-12b-it. Перед применением ко всей коллекции проверьте поддержку и качество вывода.
Настройка
Включите возможность и поместите ключ провайдера в окружение. Для смены облачного провайдера обновите провайдера и ключ, также проверив переопределённую модель. Локальному адаптеру нужен ещё и URL сервера.
SEO_PRO_AI_ENABLED=true
SEO_PRO_AI_PROVIDER=local
SEO_PRO_AI_MODEL=llama3.1 # a model the server has pulled
SEO_PRO_AI_LOCAL_BASE_URL=http://localhost:11434/v1
SEO_PRO_AI_LOCAL_ALLOW_PRIVATE=true # required for a localhost server
# no API key needed for a local serverSEO_PRO_AI_ENABLED=true
SEO_PRO_AI_PROVIDER=openai
SEO_PRO_AI_API_KEY=sk-...
# optional: SEO_PRO_AI_MODEL=gpt-5.4-mini (default: gpt-5.5)SEO_PRO_AI_ENABLED=true
SEO_PRO_AI_PROVIDER=anthropic
SEO_PRO_AI_API_KEY=sk-ant-...
# optional: SEO_PRO_AI_MODEL=claude-haiku-4-5 (default: claude-opus-4-8)SEO_PRO_AI_ENABLED=true
SEO_PRO_AI_PROVIDER=google
SEO_PRO_AI_API_KEY=AIza... # AI Studio key: aistudio.google.com/apikey
# use a paid (billing-enabled) key for real use — the free tier is heavily rate-limited
# optional: SEO_PRO_AI_MODEL=gemma-3-12b-it (default: gemini-2.5-flash)Ключ API провайдера не связан с подпиской Claude или ChatGPT
Подписка Claude Code, Claude.ai или ChatGPT не оплачивает API. В SEO_PRO_AI_API_KEY нужен ключ API с оплатой по использованию из консоли разработчика провайдера либо ключ Google AI Studio с отдельным балансом. Аккаунт только с подпиской или без средств может пройти аутентификацию, но вернуть ошибку исчерпанного баланса или квоты: см. Устранение неполадок.
В файле конфигурации config/seo-pro.php, блоке ai, доступны timeout, max_input_chars, max_output_tokens, token_budgets, reasoning_models и reasoning_min_output_tokens, suggestion_count, bulk_model — дешёвая модель для массового заполнения, см. Стоимость, — retry, таблица pricing и подраздел local. Они описаны в разделе Лимиты и настройка.
Ключ при кешированной конфигурации
Конфигурация хранит только имя переменной окружения — api_key_env, — но не ключ. Поэтому php artisan config:cache никогда не записывает ключ в bootstrap/cache/config.php. Обратная сторона: при кешированной конфигурации .env не загружается, поэтому задайте SEO_PRO_AI_API_KEY как настоящую переменную окружения на сервере.
Локальный инференс и облачные варианты
- Самостоятельное размещение инференса избавляет от оплаты API провайдера за токены. Оборудование, электричество и эксплуатация всё равно стоят денег. Контент остаётся в вашей сети, только если настроенный сервер инференса и его зависимости тоже находятся в ней.
- У Google квоты и цены зависят от модели и тарифа. Ключ AI Studio —
aistudio.google.com/apikey, форматAIza…— может позволять испытания на бесплатном тарифе. Проверьте, подходят ли лимиты вашей нагрузке, прежде чем при необходимости включать оплату. По умолчанию поставляетсяgemini-2.5-flash. Возможности рассуждения у Gemini и Gemma неодинаковы:reasoning_modelsиспользует настроенные шаблоны имён, а не проверку возможностей.
Чтобы контролировать место выполнения инференса:
- Local / совместимость с OpenAI. Используйте
provider=localс сервером, совместимым с OpenAI Chat Completions: Ollama, LM Studio, vLLM, LocalAI — или удалённым шлюзом, например OpenRouter. Укажите корень API вSEO_PRO_AI_LOCAL_BASE_URL, к нему добавляется/chat/completions, и выберите доступнуюSEO_PRO_AI_MODEL. Удалённый шлюз получает данные за пределами вашей сети и может брать плату: название адаптераlocalне означает локальный инференс.
Локальный base_url проверяется: localhost нужно разрешить явно
base_url — привилегированная настройка, проверяемая тем же SsrfGuard, что и остальные исходящие загрузки: только http/https, без userinfo и по умолчанию с разрешением хоста в публичный адрес. Поэтому ошибочный или вредоносный base_url нельзя использовать для исследования внутренних сервисов. Настоящий локальный сервер находится на приватном адресе 127.0.0.1, поэтому ему нужно явное разрешение seo-pro.ai.local.allow_local_addresses — SEO_PRO_AI_LOCAL_ALLOW_PRIVATE=true. Для публичного шлюза вроде OpenRouter оставьте его выключенным. Путь запроса фиксирован, редиректы не выполняются, поэтому ключ нельзя перенаправить на другой хост.
Управление рассуждением в поддерживаемых моделях Ollama
Локальная рассуждающая модель может превысить стандартный тайм-аут. Если модель и версия сервера поддерживают это, ['think' => false] в seo-pro.ai.local.extra_body отключает рассуждение для предложений. Поддержка различается: проверьте документацию Ollama. При необходимости увеличьте seo-pro.ai.timeout. Пакет не отправляет temperature, поскольку некоторые модели отклоняют этот параметр.
Стоимость
Пакет не делает наценку: вы платите провайдеру напрямую. При самостоятельном размещении инференса платы за API провайдера нет, но инфраструктурные расходы остаются. Важны две суммы: стоимость одного предложения при интерактивной работе и массового заполнения всей коллекции.
Таблица seo-pro.ai.pricing в долларах США за 1 000 000 токенов переводит оценку токенов в сумму, которую показывает подтверждение массового заполнения. Это поставляемые допущения для расчёта, а не проверенные текущие публичные цены. Для точной оценки замените их текущими опубликованными ценами вашего провайдера:
| Шаблон модели | Вход, $/1 млн | Выход, $/1 млн |
|---|---|---|
claude-opus-* | 15,00 | 75,00 |
claude-sonnet-* | 3,00 | 15,00 |
claude-haiku-* | 1,00 | 5,00 |
gpt-5*mini* | 0,50 | 1,50 |
gpt-5* | 5,00 | 15,00 |
gemini-2.5-pro* | 1,25 | 10,00 |
gemini-*flash* | 0,15 | 0,60 |
Опубликованный пример использует расход токенов протестированной страницы — один заголовок и одно описание — с этими допущениями. Последний столбец применяет примерную скидку 50% за пакетную обработку в поддерживаемых адаптерах. Это не актуальные ценовые предложения.
| Провайдер / модель | Примерно за пару предложений | Примерно за 1 000 записей, массовое заполнение | Примерно за 1 000 записей, --batch |
|---|---|---|---|
Local gemma/llama — Ollama | $0 за API | $0 за API | Неприменимо: адаптер не реализует |
Google gemini-2.5-flash — платный | Около $0,001 | Около $0,40 | Неприменимо: адаптер Rankbeam не реализует |
OpenAI gpt-5.5 | Около $0,008 | Около $5,25 | Около $2,63, скидка 50% |
Anthropic claude-opus-4-8 | Около $0,03 | Около $20 | Около $10, скидка 50% |
Команда помечает оценку как приблизительную, ±50%, но это не лимит расходов и не гарантированный диапазон ошибки. Реальные входные данные, ответы и цены меняют итог. Расчёт учитывает видимый вывод; оплачиваемое скрытое рассуждение может увеличить стоимость сверх него. Для моделей без записи в таблице цен показывается только оценка токенов.
Более дешёвая массовая генерация
Задайте seo-pro.ai.bulk_model — SEO_PRO_AI_BULK_MODEL, — чтобы использовать другую модель только для массового заполнения через seo-pro:ai-fill / SeoPro::aiFill(). Filament и seo-pro:ai-suggest сохраняют model. При null массовое заполнение тоже использует model. Оценка стоимости берёт ценовой шаблон выбранной модели. Перед увеличением объёма оцените типичные результаты: более дешёвая модель не обязательно подходит.
SEO_PRO_AI_MODEL=claude-opus-4-8 # interactive: highest quality
SEO_PRO_AI_BULK_MODEL=claude-haiku-4-5 # bulk-fill: cheap tierВ примерах пакета используются anthropic claude-haiku-4-5, openai gpt-5.5-mini, google gemini-2.5-flash либо меньшая локальная модель. Ценовой шаблон может совпасть с именем, даже если провайдер не предлагает такую модель. Перед настройкой подтвердите настоящий идентификатор, совместимость API и цену.
Заполнение 100 страниц, у каждой отсутствуют и заголовок, и описание, — это 200 вызовов провайдера. Ниже сравнение качественной модели и её дешёвого варианта bulk_model по поставляемым значениям pricing и расчётному расходу на вызов: 600 входных и 150 выходных токенов.
| Провайдер | Качественная модель — 100 страниц | Дешёвая bulk_model — 100 страниц |
|---|---|---|
| Anthropic | claude-opus-4-8 ≈ $4,05 | claude-haiku-4-5 ≈ $0,27 |
| OpenAI | gpt-5.5 ≈ $1,05 | gpt-5.5-mini ≈ $0,11 |
gemini-2.5-pro ≈ $0,45 | gemini-2.5-flash ≈ $0,04 | |
| Local — Ollama / vLLM | Любая модель — $0 за API | Любая модель — $0 за API |
Это иллюстративные оценки без гарантированного диапазона ±50% и без запаса на скрытое рассуждение. Прежде чем полагаться на расчёт, обновите seo-pro.ai.pricing по опубликованным ценам выбранного провайдера.
Язык результата
Каждый промпт называет язык страницы и его код BCP-47, например: «на бразильском португальском (pt-BR), языке страницы, независимо от других языков во фрагменте». Контекст страницы, передаваемый модели, содержит строку Language:, начиная с Pro 2.34. Раньше промпты говорили «на том же языке, что и исходный контент», оставляя модели выбор по короткому или смешанному фрагменту: турецкая страница с английским названием бренда могла получить ответ по-английски. Используется локаль, в которой определены метаданные страницы, либо локаль приложения, если у страницы её нет. Для неё же выбирается лимит длины, поэтому японская страница запрашивает заголовки примерно из 30 символов на японском.
С Pro 2.36 явно заданная локаль контента совместно управляет строкой метаданных, хуками контента и языком промпта. Язык интерфейса оператора не меняется.
$ai = app(\Rankbeam\Seo\Pro\Ai\SeoSuggestionService::class);
$titles = $ai->suggestTitles($post, locale: 'it');
$descriptions = $ai->suggestDescriptions($post, locale: 'ja');
$rewrite = $ai->rewriteDescription($post, locale: 'it');
$schema = $ai->suggestSchemaType($post, locale: 'it');
$request = $ai->suggestionRequest($post, 'title', locale: 'ja');Существующие позиционные аргументы не изменены. Если не передавать locale:, используется значение по умолчанию из seoData() модели, что позволяет отдельным моделям переводов объявлять свой язык. Для выдержки используется getContentForSEO(), если он возвращает непустой контент, иначе — настроенные поля контента. Filament 1.11 автоматически передаёт локаль выбранной вкладки, в том числе в одноязычном режиме и режиме переключения страниц.
php artisan seo-pro:ai-suggest "App\Models\Post" 42 --locale=it
php artisan seo-pro:suggest-schema "App\Models\Post" 42 --locale=ja
php artisan seo-pro:ai-fill "App\Models\Post" --field=description --locale=it --batchМассовые plan(), fill() и submitBatchFill() тоже принимают завершающий locale:. Используйте одну локаль при создании FillProgress(..., locale: 'it') и отправке запуска. Каждый элемент пакета сохраняет локаль контента; сбор результатов использует её и повторно проверяет строку метаданных перед записью. Запуски с явной локалью имеют отдельные файлы контрольных точек, а маркеры обработки различают языки. Для сбора результатов повторите ту же команду. Собственные задачи должны сериализовать и передавать локаль контента.
Контрольные точки до Pro 2.36 не сохраняли локаль контента. Незавершённый старый пакет сохраняется, но автоматический сбор его результатов отклоняется. Перед удалением через --fresh сопоставьте результаты провайдера и нужную локаль, иначе повторная отправка может привести к повторной оплате той же работы. Старая последовательная контрольная точка с уже обработанными записями тоже требует сверки перед сбросом.
Оценка по языкам
Репозиторий исходного кода Pro содержит 170 входных страниц на 17 локалях и явно включаемый стенд оценки. Входные страницы проверяются структурно и эвристически по базовому языку; независимое одобрение носителями пока не получено.
Стенд проверяет и заголовки, и описания, записывает длину в графемах и сведения о языке и письменности, а также сохраняет каждый ответ провайдера до проверок. Короткие заголовки, смешанный текст и общие китайские и японские иероглифы могут оставаться неоднозначными. Определение португальского языка не подтверждает бразильский вариант, а частичные проверки китайских иероглифов не удостоверяют качество региональной письменной речи.
Для реальных запусков нужны SEO_PRO_AI_EVAL=1, явный выбор SEO_PRO_AI_EVAL_LOCALES и идентификатор SEO_PRO_AI_EVAL_RUN. Они могут повлечь оплату провайдеру; по умолчанию ничего не запускается. Доказательства каждого запуска привязаны к провайдеру, запрошенной и возвращённой модели, хешам тестовых данных, запроса и кода, а также времени. Неудачные попытки сохраняются. Возобновление использует сохранённые ответы; прерванный запрос нужно повторить явно, поскольку он уже мог дойти до провайдера.
Доказательства хранятся в storage/app/seo-ai-evals/<run-id>/ тестового окружения исходного проекта. В README.md тестовых данных описаны версионируемая схема и команды. Носители языка оценивают точные хеши результатов в отдельных записях рецензирования. Успешная автоматическая проверка не является одобрением носителя или гарантией готовности текста к публикации.
Лимиты и настройка
Все параметры находятся в блоке ai файла config/seo-pro.php:
timeout— по умолчанию15секунд, переменнаяSEO_PRO_AI_TIMEOUT. Это также предел синхронного вызова, который выполняет модальное окно предложений Filament при открытии, поэтому он короткий ради удобства работы. Медленная рассуждающая или локальная модель может превысить 15 секунд и завершиться тайм-аутом. Увеличьте значение черезSEO_PRO_AI_TIMEOUTи учтите совет Ollama сthink => falseвыше. Тайм-аут всегда некритичен: сообщение об ошибке в интерфейсе, а не блокировка сохранения.max_input_chars— по умолчанию6000. Ограничивает стоимость и объём раскрываемых данных: сколько контента страницы передаётся в одном запросе в виде обычного текста без HTML.max_output_tokens— по умолчанию1000. Базовый лимит генерируемых токенов. Ответ, достигший его, даёт отдельную ошибкуtruncated, а не незаметный полуответ.token_budgets— выходные лимиты по задачам:suggestions800,explanation600,rewrite300,schema_suggestion700. Ни одной задаче не нужен полный общий лимит, но поверх него применяется нижняя граница для рассуждения.reasoning_modelsиreasoning_min_output_tokens— по умолчанию2000. У моделей с именем, совпадающим с шаблоном*gemma*,gemini-2.5-*,o1*/o3*/o4*, выходной бюджет повышается до этой границы. Рассуждающая модель расходует скрытые токены до видимого ответа, и малый бюджет обрезал бы результат.suggestion_count— по умолчанию3. Число запрашиваемых вариантов заголовка или описания.retry— автоматические повторы только для временных ошибок: см. Обработка ответов.
В Filament
При установленных необязательных пакетах Filament — rankbeam/laravel-seo-filament >= 1.1 — включение помощи ИИ добавляет следующие действия. Ниже сохранены их названия в английском интерфейсе:
- Suggest with AI у SEO-заголовка и описания каждого ресурса с SEO-разделом на страницах редактирования. Модальное окно показывает варианты со счётчиками символов; выбор заполняет поле для проверки.
- Explain (AI) в таблице проблем панели: краткое объяснение проблемы простым языком и конкретное исправление.
- Rewrite description (AI) в таблице проблем рядом с Explain: предлагает одно улучшенное метаописание в пределах лимита страницы — 160 символов для латиницы и примерно 80 для CJK, согласно политике длины ядра. Проверьте его в модальном окне; нажатие Apply rewrite записывает значение в
seo_metaстраницы. До применения ничего не записывается. - Suggest structured data (AI) в таблице проблем: предлагает наиболее подходящий тип расширенного результата schema.org — Product, Article или Breadcrumb — и показывает построенный JSON-LD. Нажатие Apply structured data добавляет его в
seo_meta.schema_jsonldстраницы, тот же столбец, которым управляет необязательный редактор структурированных данных. Данные сохраняют совместимость с этим редактором и остаются редактируемыми. Неполное предложение, например Article без автора или изображения, показывается со списком недостающих полей и не применяется.
Последние два действия — ограниченные исправления: см. соответствующий раздел.
Ограниченные исправления: только предложение, без автоприменения
Два действия идут дальше набора вариантов: они создают одно значение с ограничениями, которое можно применить одним кликом. Оба всё равно только предлагают: ничего не сохраняется без вашего явного принятия.
- Rewrite description —
SeoSuggestionService::rewriteDescription($model, $issue?)— возвращает одно метаописание всегда в пределах лимита ядра для письменности страницы: 160 для латиницы, около 80 для CJK. Тот же лимит передаётся в промптах предложений заголовков и описаний и выбирается по итоговому значению самой страницы. Если модель превышает его, текст детерминированно обрезается по границе предложения, затем слова. Поэтому принятая переработка сама по себе не может вызвать предупреждениеdescription_too_long. Переданная проблема сканирования направляет переработку, например слишком длинное или отсутствующее описание. - Suggest structured data —
SeoSuggestionService::suggestSchemaType($model)— запрашивает у модели только рекомендацию типа и значения конечных полей, никогда не сырой JSON-LD. Затем детерминированный код собирает документ конструкторами ядраProductSchema/ArticleSchema/BreadcrumbSchemaи проверяет черезSchemaValidator. Поэтому выдуманные@type,@contextили структура не попадут на страницу. Если в собранном документе нет обязательного поля, он показывается как неполный и не применяется. В реальном испытании один провайдер предложилArticleдля малосодержательной страницы; предложение корректно отклонили из-за отсутствующих автора и изображения, тогда как другие провайдеры вообще отказались предлагать тип.
Без интерфейса
Те же возможности в JSON для скриптов и приложений без Filament:
# title + description suggestions for a model
php artisan seo-pro:ai-suggest "App\Models\Post" 42
# one field only
php artisan seo-pro:ai-suggest "App\Models\Post" 42 --field=description
# explain a scan issue (IDs from seo-pro:scan-status)
php artisan seo-pro:ai-suggest --issue=17
# suggest a schema.org type + built, validated JSON-LD for a model
php artisan seo-pro:suggest-schema "App\Models\Post" 42Вывод содержит предложения либо рекомендуемый тип, собранный JSON-LD и результат проверки, использованную модель и расход токенов на запрос: вход, выход и рассуждение. Это помогает рассчитать стоимость по тарифам провайдера; число токенов не является счётом. При любой ошибке команда возвращает ненулевой код, а ошибку помещает в JSON-оболочку. Как и другие действия помощи, seo-pro:suggest-schema только предлагает: выводит документ и ничего не записывает.
Массовое заполнение недостающих метаданных
Pro 2.42 меняет поведение CLI по умолчанию: seo-pro:ai-fill сохраняет по одному приватному черновику для каждого сгенерированного поля. Опубликованные SEO-метаданные не меняются до утверждения. Существующие значения и вычисленные резервные значения пропускаются. Актуальный ожидающий черновик используется повторно вместо новой генерации.
php artisan seo-pro:ai-fill "App\Models\Post" --field=description
php artisan seo-pro:ai-review
php artisan seo-pro:ai-review DRAFT_ID
php artisan seo-pro:ai-review DRAFT_ID --approve --reviewer="editor@example.com"
php artisan seo-pro:ai-review DRAFT_ID --reject --reviewer="editor@example.com"seo-pro:ai-review перечисляет первые 100 ожидающих черновиков в JSON. Укажите ID, чтобы прочитать значение и приватные доказательства его получения. Утверждение и отклонение работают с выключенным ИИ и не вызывают провайдера. Для утверждения нужна метка оператора; оно отклоняет черновики, если исходная запись или целевые метаданные изменились либо запись удалена. Метка фиксирует, кем представился оператор, но не доказывает содержательную проверку человеком. Для настроенной нестандартной базы используйте --connection=NAME.
--auto-apply явно возвращает немедленную публикацию всё ещё отсутствующих полей. --force пропускает подтверждение, но не проверку. --dry-run генерирует и выводит значения без сохранения черновиков или метаданных, однако всё равно вызывает провайдера и может стоить денег. --field, --limit и --locale ограничивают область генерации. После обновления осознанно пересмотрите команды в расписании.
При больших объёмах: интервалы, оценка стоимости и продолжение после сбоя
По умолчанию seo-pro.ai.fill.throttle_ms равен 200 миллисекундам. При достижении confirm_over — по умолчанию 100 записей — команда показывает оценку из seo-pro.ai.pricing и запрашивает подтверждение перед генерацией. Контрольные точки сохраняют завершённые поля при прерываниях. Тайм-аут после принятия запроса провайдером всё ещё может привести к повторному списанию; перед --fresh сверьте работу с неопределённым результатом. Запускайте одновременно только одну соответствующую массовую задачу.
use Rankbeam\Seo\Pro\Facades\SeoPro;
$summary = SeoPro::aiFill()->fill([\App\Models\Post::class], 'all', limit: 50, review: true);В собственных интеграциях передавайте review: true для подготовки черновиков. Низкоуровневый PHP API ради совместимости сохраняет apply: true, review: false, поэтому существующие вызовы всё ещё записывают сразу. apply: false даёт предпросмотр без сохранения. Ключ сводки filled считает обработанные записи, включая подготовленные в режиме проверки; CLI помечает их staged.
Пакетный режим: на 50% дешевле
--batch использует поддерживаемый асинхронный endpoint Anthropic или OpenAI. Заявленная ими скидка отражена в расчёте, но проверьте текущие цены моделей. Адаптеры Google и Local переходят к последовательной генерации. Отправьте пакет сейчас, а позже повторите ту же команду для сбора черновиков:
php artisan seo-pro:ai-fill "App\Models\Post" --field=description --batch
# Re-run the same command to collect drafts.
php artisan seo-pro:ai-fill "App\Models\Post" --field=description --batchМежду отправкой и сбором не меняйте провайдера, локаль и режим публикации. Проверка и --auto-apply используют разные контрольные точки; CLI откажется запускать другой режим, пока соответствующий пакет не завершён. Отправка с неопределённым результатом останавливает работу для сверки. Частичные успехи сохраняются; временные ошибки можно повторить. При сборе снова проверяются отсутствующие поля, а при утверждении — также снимок источника, сделанный до отправки. seo-pro.ai.fill.batch.request_timeout по умолчанию равен 120 секундам. Сбор по расписанию по умолчанию сохраняет черновики.
Учёт происхождения, миграции и фильтрация данных
Требуются Core 3.21 и Pro 2.42. Core загружает свою миграцию автоматически. До генерации сохраняемых предложений опубликуйте миграции Pro и выполните их для каждой базы данных, используемой SEO-моделями:
php artisan vendor:publish --tag=seo-pro-migrations
php artisan migrateПриватная таблица seo_ai_proposals хранит сгенерированные значения и сведения о провайдере, модели и запросе через зашифрованные приведения типов Laravel. Надёжно храните APP_KEY и его резервную копию: потеря ключа делает эти значения нечитаемыми. Идентификаторы записей, статус и сведения о решении остаются обычными столбцами базы. Варианты формы могут остаться в состоянии offered или selected, если форму бросили. Автоматической очистки нет: задайте политику хранения приложения, сохраняйте ожидающие черновики и доказательства, на которые ещё ссылается seo_meta.ai_provenance, ограничьте доступ к экспортам БД и выводу команды проверки.
Принятые предложения формы, исправления панели и массовые значения несут сведения о происхождении поля. Последующие изменения через Eloquent сохраняют origin: ai и устанавливают edited: true. Это означает, что значение изменено, а не проверено человеком. Очистка поля удаляет маркер. HTML, массивы, JSON и Inertia-вывод ядра раскрывают только имя поля, происхождение и состояние редактирования; где применимо, используется собственный метатег rankbeam:ai-origin. Идентификаторы генерации и подробности провайдера остаются приватными. Не отдавайте сырые модели SEOMeta в публичном API.
Учёт охватывает будущие поддерживаемые пути сохранения, а не исторический контент или каждую редакцию. Прямой SQL, обновления через query builder и собственные компоненты вывода могут обходить эти меры. Явно сбрасывайте происхождение, когда это оправдано независимо написанной заменой; обычные правки его сохраняют. Этот маркер не является стандартным водяным знаком, защищённой от подделки атрибуцией или заявлением о соответствии статье 50. Качество реальных ответов и собственные маркировки провайдеров требуют отдельной оценки.
При необходимости реализуйте AiPromptFilter и настройте seo-pro.ai.context_filter. Фильтр обрабатывает собранный пользовательский промпт перед синхронной или пакетной отправкой. Его ошибка предотвращает отправку и возвращает очищенное сообщение. Системные инструкции не меняются. По умолчанию стоит null, автоматического удаления чувствительных данных нет. Этот пример заменяет только одно известное значение; реализуйте и проверьте правила для своего приложения:
namespace App\Support;
use Rankbeam\Seo\Pro\Ai\AiPromptFilter;
final class RedactAiContext implements AiPromptFilter
{
public function filter(string $prompt): string
{
return str_replace('internal@example.com', '[redacted]', $prompt);
}
}
// Configure seo-pro.ai.context_filter with this class in config/seo-pro.php.
// Runtime equivalent:
config(['seo-pro.ai.context_filter' => RedactAiContext::class]);Обработка ответов
Каждый вызов возвращает единую, независимую от провайдера оболочку, поэтому поведение одинаково для всех провайдеров, включая будущие:
- Структурированный вывод, где его поддерживает провайдер. В OpenAI — нативные Structured Outputs, Google — Gemini
responseSchema, Anthropic —output_config.format— форму JSON обеспечивает API. Некорректный JSON даёт явную ошибку, без извлечения данных из произвольного текста. Локальному или совместимому с OpenAI серверу тоже передаётсяresponse_formatбез гарантии соблюдения. Сервер, игнорирующий поле, всё ещё может вернуть пригодный текст, который разбирается гибким резервным парсером. В любом случае результат — корректный список или понятная ошибка, никогда не наполовину разобранный ответ. - Обрезка — явная ошибка с понятным действием. Если ответ оборвался на лимите выходных токенов, вы получаете
truncatedс предложением увеличитьseo-pro.ai.max_output_tokens, а не незаметно укороченный заголовок. Чаще всего это случается с рассуждающими моделями; для них автоматически применяется повышенная нижняя границаreasoning_min_output_tokens. - Временные ошибки повторяются автоматически. Ограничение частоты
429или5xxвызывает повтор с ограниченной экспоненциальной задержкой. Если есть заголовокRetry-After, он учитывается в заданных пределах, чтобы вредоносное значение не могло надолго остановить запрос. Детерминированные ошибки не повторяются: неверный ключ, некорректный запрос, слишком большой объём данных, тайм-аут или исчерпанный баланс/квота. Повтор запроса с неоплаченным аккаунтом лишь тратит время ожидания. Настройте или отключите повторы черезretry; для отключения установитеmax_attemptsв0. - Ошибки типизированы и очищены. У каждой есть стабильный код:
unauthorized,quota_exceeded,rate_limited,timeout,content_too_large,bad_request,truncated,content_filtered,provider_errorи другие. Временные ошибки имеют флагretryable. Сообщение — короткая очищенная строка. Обычный путь приложения не показывает и не записывает в журнал сырое тело ответа провайдера; явно включаемый стенд оценки выше сохраняет ответы как доказательства. В Filament ошибка отображается в оформленном частичном шаблоне модального окна с подходящей подсказкой следующего шага для распространённых случаев: см. Устранение неполадок.
Устранение неполадок
Каждая ошибка некритична и показывается в интерфейсе с типизированным кодом и очищенным сообщением. Ниже распространённые случаи и способы исправления; английские сообщения сохранены как диагностические строки:
| Симптом и код | Значение | Исправление |
|---|---|---|
quota_exceeded — "the provider account is out of credit or quota" | Ключ корректен, но у API-аккаунта нет средств или квоты. Это не ограничение частоты: повторы не помогут. У провайдеров разные сообщения: Anthropic — "credit balance is too low", OpenAI — "exceeded your current quota… check your plan and billing" (insufficient_quota), Google — "prepayment credits are depleted". | Пополните баланс или включите оплату в консоли провайдера либо перейдите на локальную модель без платы за API провайдера. Подписка Claude/ChatGPT не оплачивает API. |
unauthorized — "authentication failed" | Ключ отсутствует, неверен или не подходит настроенному провайдеру. | Проверьте ключ в переменной, имя которой задаёт seo-pro.ai.api_key_env, по умолчанию SEO_PRO_AI_API_KEY: он должен быть задан, актуален и соответствовать SEO_PRO_AI_PROVIDER. |
rate_limited — "the provider rate limit was reached" | Настоящее временное ограничение частоты; сначала выполняются автоматические повторы. | Подождите и повторите либо используйте локальную модель с учётом мощности своего сервера. Для массовых запусков на младшем тарифе увеличьте seo-pro.ai.fill.throttle_ms. |
timeout — "the request timed out" | Провайдер не ответил за seo-pro.ai.timeout, по умолчанию 15 секунд. Часто бывает с медленной локальной рассуждающей моделью. | Увеличьте предел через SEO_PRO_AI_TIMEOUT; для Ollama также задайте ['think' => false] в seo-pro.ai.local.extra_body. |
truncated — "hit the max_output_tokens limit" | Ответ достиг выходного бюджета, возможно вместе со скрытым рассуждением. | Увеличьте seo-pro.ai.max_output_tokens, рассуждающим моделям может понадобиться 2000+, либо убедитесь, что имя совпадает с шаблоном reasoning_models и применяется нижняя граница. |
content_too_large — HTTP 413 | Отправленный контент страницы превысил лимит провайдера. | Уменьшите seo-pro.ai.max_input_chars, чтобы отправлять более короткую выдержку. |
bad_request | Некорректный запрос: обычно имя модели, недоступной аккаунту, или неподдерживаемый параметр. | Проверьте, что модель в SEO_PRO_AI_MODEL доступна вашему ключу или серверу у настроенного провайдера. |
content_filtered | Фильтр безопасности провайдера отказался отвечать. | Проверьте содержимое и рекомендации провайдера; не повторяйте отклонённый запрос автоматически. |
Локальному инференсу всё равно нужен рабочий сервер
SEO_PRO_AI_PROVIDER=local с самостоятельно размещённым инференсом устраняет проблемы баланса облачного провайдера. Оборудование, модель, совместимость API, тайм-аут и производительность всё ещё важны. Удалённый шлюз с этим адаптером может требовать ключ и оплату.
Что покидает ваш сервер
Только перечисленное ниже, только настроенному провайдеру и только по явному действию: нажатию действия или запуску команды.
- Предложения: короткое имя класса модели и ключ, например "Post #3", текущие итоговые заголовок и описание, канонический URL и выдержка контента обычным текстом без HTML, ограниченная
max_input_chars, по умолчанию 6000 символов. - Объяснения проблем: тип, серьёзность, поле, сообщение и URL цели; если доступна модель — также её класс и ключ, итоговые заголовок и описание, канонический URL и ограниченная текстовая выдержка.
- Переработка описания: тот же минимальный контекст страницы, что и для предложения, а при передаче проблемы сканирования — также её тип и сообщение.
- Предложение структурированных данных: тот же минимальный контекст страницы. Модель возвращает только тип и значения конечных полей; JSON-LD собирается локально.
Пакет не собирает намеренно данные посетителей, IP-адреса, заголовки запросов или учётные данные в промпты и не отправляет полный HTML. Поля контента и выдержки сами могут содержать чувствительную информацию: проверьте, что раскрывает ваше приложение. Учётные данные провайдера используются для аутентификации запроса. Правила обработки данных описаны в SECURITY.md репозитория Pro.