Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 27 жовтня 2026

URL AI Transformer від Spatie: сторінки за списком URL через Laravel AI SDK

Spatie має пакет laravel-url-ai-transformer, який робить одну просту річ: завантажує сторінки за списком URL, віддає їхній текст AI-моделі з вашими інструкціями і зберігає відповідь у базі. На нього звернув увагу Laravel News, і привід є: у липні версія 2.0.0 замінила Prism на офіційний Laravel AI SDK, а 19 жовтня 2.1.0 додала підтримку laravel/ai 1.x.

Це не чат-бот і не демо - це фонова обробка контенту з чергами, повторною генерацією і журналом помилок. Типові сценарії: згенерувати schema.org JSON-LD для власних сторінок, зробити короткі резюме статей або витягнути з чужої сторінки товару назву, ціну й наявність у поля, за якими можна робити запити.

Встановлення

Поточні версії потребують PHP 8.4 і Laravel 13. Laravel News пише про «Laravel 12 або 13», але, за гайдом з оновлення, Laravel 12 підтримує лише 2.0.0 - для нього треба зафіксувати саме цю версію.

  composer require spatie/laravel-url-ai-transformer
  php artisan vendor:publish --tag="url-ai-transformer-migrations"
  php artisan migrate

Конфіг публікувати не обов'язково (--tag="url-ai-transformer-config"), але API-ключ провайдера потрібен. За замовчуванням це OpenAI, тож у .env додаємо OPENAI_API_KEY.

Реєстрація URL і запуск

URL і трансформери для них реєструються через клас Transform, зазвичай у сервіс-провайдері:

  use Spatie\LaravelUrlAiTransformer\Support\Transform;
  use Spatie\LaravelUrlAiTransformer\Transformers\LdJsonTransformer;

  Transform::urls(
      'https://example.com/about',
      'https://example.com/products',
  )->usingTransformers(new LdJsonTransformer, new SummaryTransformer);

urls() приймає і closure. Він виконується лише тоді, коли запускається трансформація, тож вибірка з бази не додає запит до кожного HTTP-запиту застосунку:

  Transform::urls(
      fn () => Article::published()->pluck('url')->toArray()
  )->usingTransformers(new LdJsonTransformer);

Так само пакет поєднується зі spatie/crawler: у closure обходимо сайт через Crawler::create(url('/'))->internalOnly()->foundUrls() і перетворюємо отримані CrawledUrl на рядки через array_map(). Так трансформація охоплює всі внутрішні сторінки без ручного списку.

Запускає все Artisan-команда:

  php artisan transform-urls
  php artisan transform-urls --url="*/blog/*" --transformer="ldJson"
  php artisan transform-urls --force
  php artisan transform-urls --now

Команда завантажує кожен URL один раз, синхронно, і ставить у чергу окреме завдання на кожен трансформер, зареєстрований для цієї сторінки. Тому потрібен воркер черги, або --now, щоб виконати все одразу. --url і --transformer підтримують wildcard, тож можна перегенерувати лише частину сайту. --force ігнорує shouldRun() - метод, яким трансформер може пропустити сторінку, наприклад, якщо вже успішно обробив її менше ніж 30 днів тому.

Результат читається за URL і типом трансформера. Тип за замовчуванням - назва класу в camelCase без суфікса Transformer, але можна передати й сам клас:

  use Spatie\LaravelUrlAiTransformer\Models\TransformationResult;

  $ldJson = TransformationResult::forUrl('https://example.com/about', 'ldJson');

findForUrl() повертає саму модель. На ній є regenerate() (знову в чергу) і regenerateNow(), а якщо трансформер упав, у полях latest_exception_message і latest_exception_trace лежить причина, і спрацьовує подія TransformerFailed. Щоб результати не застарівали, команду ставлять у розклад у routes/console.php.

Свій трансформер

php artisan make:transformer SummaryTransformer створює клас в app/Transformers. Мінімально потрібен лише instructions() - це системний промпт агента, а текст сторінки пакет передає як промпт користувача:

  namespace App\Transformers;

  use Spatie\LaravelUrlAiTransformer\Transformers\Transformer;
  use Stringable;

  class SummaryTransformer extends Transformer
  {
      public function instructions(): Stringable|string
      {
          return 'Summarize this webpage content in 3 concise bullet points.';
      }
  }

Для машиночитаних даних трансформер реалізує контракт HasStructuredOutput з AI SDK і описує schema(): відповідь перевіряється за схемою і зберігається як JSON. Вбудований LdJsonTransformer іде трохи хитрішим шляхом, бо JSON-LD не має фіксованої форми: схема містить одне обов'язкове рядкове поле json, а resultFrom() декодує його з JSON_THROW_ON_ERROR. Невалідний JSON кидає виняток, трансформація позначається як невдала, і завдання в черзі пробує ще раз.

Трансформер може взагалі обійтися без AI: перевизначте transform() і порахуйте результат сам, наприклад кількість слів на сторінці. Для тестів досить Http::fake() для сторінки і SummaryTransformer::fake([...]) для відповіді моделі.

Під капотом - Laravel AI SDK

Перша версія ходила до моделей через Prism. Друга зробила базовий Transformer агентом Laravel AI SDK, тож усе, що ви знаєте про агентів SDK, працює і тут. Якщо з ним ще не знайомі, почніть з нашого розбору агента, що стоїть за There There - це теж проєкт Spatie на тому самому SDK.

У конфігу задаються провайдер з енума Lab і модель: рядком або Model::Cheapest / Model::Smartest. За замовчуванням - OpenAI і найдешевша модель. Окремий трансформер перевизначає це атрибутами SDK:

  use Laravel\Ai\Attributes\Model;
  use Laravel\Ai\Attributes\Provider;
  use Laravel\Ai\Attributes\Temperature;
  use Laravel\Ai\Enums\Lab;

  #[Provider(Lab::Anthropic)]
  #[Model('claude-haiku-4-5-20251001')]
  #[Temperature(0.1)]
  class FactsTransformer extends Transformer
  {
      // ...
  }

#[UseSmartestModel] змінює лише модель, лишаючи провайдера з конфігу, а методи provider() і model() дозволяють обрати їх під час виконання. Провайдери - ті, що підтримує сам SDK: документація пакета згадує OpenAI, Anthropic і Gemini.

У composer.json стоїть laravel/ai: ^0.11.0|^1.2.3, тож оновлювати SDK заради пакета не обов'язково. Якщо оновлюєтеся до 1.x, Spatie радить спершу прочитати UPGRADE.md SDK, особливо якщо у вас збережені розмови, власні middleware агентів, MCP або Bedrock. І ще одне: Model::Cheapest тепер може вказувати на іншу модель, ніж раніше, тож якщо результати мають бути стабільними, зафіксуйте назву моделі в url-ai-transformer.ai.model.

Обмеження і вартість

  • 6000 символів. Перед відправкою PrepareUrlContentAction вирізає скрипти й стилі, знімає HTML-теги, стискає пробіли і обрізає текст до 6000 символів. Для довгих статей модель побачить лише початок. Змінити це можна в content() окремого трансформера або власною дією в конфігу, наприклад взявши лише вміст <main>.
  • Кожна пара «URL + трансформер» - окремий запит. Сайт на 500 сторінок із двома трансформерами - це 1000 запитів до моделі на кожен прогін. Щоденний розклад разом із краулером без shouldRun() швидко стає помітним рахунком.
  • Завантаження сторінок не в черзі. Повтори, backoff і обмеження частоти запитів (RateLimited у власному ProcessTransformerJob) діють на AI-запит, а сторінки команда тягне синхронно. Довгий список URL - довга команда.
  • Старі версії могли слати моделі JavaScript. У 2.0.1 виправили випадок, коли великі inline-скрипти впиралися в ліміт PCRE і до моделі доходив код замість тексту сторінки. Якщо сидите на старішій версії і бачите дивні результати, причина може бути тут.

Кому варто спробувати

Пакет має сенс, коли треба регулярно отримувати з багатьох сторінок однотипний результат і зберігати його: SEO-розмітка для контентного сайту, резюме для пошуку чи карток, нормалізовані дані з каталогів. Для разової обробки кількох сторінок він зайвий - вистачить агента SDK і циклу.

Почніть з --now на двох-трьох URL і дешевої моделі, подивіться на результат у transformation_results і лише потім вмикайте розклад. А згенерований JSON-LD перед виведенням у <script type="application/ld+json"> варто вибірково перевірити: розмітка, що не відповідає вмісту сторінки, пошуковикам не допоможе, а json_decode() гарантує лише валідний синтаксис, а не правдивість.

0

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Новини 27 жовтня 2026

Filament v5.11.0: поля й віджети на React, Vue і Svelte та жорсткіший захист Livewire

Filament v5.11.0 дозволяє писати власні поля форм, компоненти схем і віджети на React, Vue, Svelte або чистому JavaScript. Паралельно v5.11.0 і v4.16.0 закривають для клієнта внутрішні Livewire-методи та стан і додають опційні ліміти для репітерів і пагінації таблиць.

2
Новини 27 жовтня 2026

Livewire 4.4.8 закриває обхід #[Authorize], а NativePHP Mobile - сім вразливостей

Livewire 4.4.8 виправляє GHSA-mhf7-xp6r-6qrc (CVSS 6.5): атрибут #[Authorize] можна було обійти й виконати дію над чужим записом. Того ж тижня NativePHP опублікувала сім попереджень для NativePHP for Mobile - виправлення в nativephp/mobile 4.6.1 і 3.3.11, але до користувачів вони дійдуть лише з новою збіркою застосунку.

1

Вакансії за темою

Middle Backend Engineer PHP/Laravel

Розробка бекенду для нової платформи запису й редагування відео з AI: REST API для керування контентом (S3-завантаження, метадані, мініатюри, планування), оркестрація задач обробки відео на AI-воркерах RunPod, інтеграції з платежами, аналітикою та AI-сервісами, WebSocket-синхронізація з клієнтами та фонові черги. Потрібен досвід із бекенд-фреймворками, проєктуванням баз даних, автентифікацією й безпекою API, роботою з вебхуками та Docker, Git і CI/CD.

SoftHouseGroup Нова
2 дні тому

PHP Software Engineer

Розробник буде частиною full-stack команди, яка розвиває велику складну систему у страховому домені з багатьма модулями та інтеграціями з платіжними провайдерами. Щодня потрібні розробка нових модулів, підтримка існуючих, виправлення багів та перевірка коду, згенерованого AI. Ключові вимоги: понад 4 роки досвіду PHP, Laravel або Yii2, знання ООП і патернів проєктування, MySQL, REST API, фронтенд (HTML, CSS, JavaScript, jQuery, Vue.js), Git і англійська на рівні Pre-Intermediate для читання.

Full Stack Developer (PHP / React) Middle / Middle+

Full Stack розробник розвиватиме та підтримуватиме власний аналітичний продукт для перевірки контрагентів і оцінки ризиків, працюючи зі складною бізнес-логікою та великими обсягами даних. Основний стек: PHP 8.x, Laravel або Symfony, MySQL, React; також потрібні проєктування API, оптимізація SQL-запитів, Docker, CI/CD. Вимоги: комерційний досвід від 3 років, досвід підтримки legacy-коду, англійська B1+ для читання документації.

Пакети за темою

Laravel Sitemap

spatie/laravel-sitemap

Простий пакет для створення та генерування sitemap для вашого Laravel-додатку.

2,619 8.2.0 13 7

Kalimera

welldigit/kalimera

Interactive installer that scaffolds Laravel applications the Well Digit way.

v1.0.0 15