Це детальний, структурований гайд для інтеграції Laravel AI SDK в Evolution CMS через пакет eAi. Він розширює README поясненнями, конфігами та операційними деталями.
- eAi — thin‑wrapper над
laravel/aiу стилі Evo. illuminate/foundationне потрібен: є мінімальні shims для сумісності SDK.- sTask — primary бекенд черг;
sync— fallback. - AI‑дії виконуються від імені сервісного користувача з роллю AI.
- Evolution CMS 3.5.2+
- PHP 8.3+
- Composer 2.2+
Опційно:
- sTask для асинхронного виконання (constraint пакета:
^1.0)
cd core
php artisan package:installrequire evolution-cms/eai "*"Auto‑publish увімкнений, але можна примусово:
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-config
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-ai-config
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-stubsМіграції:
php artisan migrateЦе конфіг Laravel AI SDK. Мінімальний приклад:
return [
'default' => 'openai',
'providers' => [
'openai' => [
'driver' => 'openai',
'key' => env('OPENAI_API_KEY'),
],
'ollama' => [
'driver' => 'ollama',
'key' => env('OLLAMA_API_KEY', ''),
'url' => env('OLLAMA_BASE_URL', 'http://localhost:11434'),
],
],
];Нотатки:
default_*визначають дефолтні провайдери для images/audio/etc.- Ключі можуть бути в
.envабо в конфігу.
Налаштування інтеграції Evo:
return [
'enable' => true,
'queue_driver' => 'stask',
'queue_failover' => 'sync',
'context' => 'auto',
'ai_actor_mode' => 'service',
'ai_actor_email' => null,
'ai_actor_autocreate' => true,
'ai_actor_block_login' => true,
'ai_actor_role' => 'AI',
'ai_actor_role_autocreate' => true,
];Пояснення:
queue_driver:stask(primary) абоsync(fallback).queue_failover: використовується, якщоstaskнедоступний.context:mgr|web|auto(контекст виконання).ai_actor_*: керує сервісним AI‑користувачем (manager user + роль AI).
conversation_user_id: реальний користувач у історії. Якщо невідомий (CLI/без сесії) — fallback =1.actor_user_id: AI service account, якщо режим увімкнено.initiated_by_user_id: хто ініціював дію (для аудиту).
Правила:
- Write‑дії виконуються лише через manager ACL, без прямих записів у БД.
- AI‑юзер — звичайний manager user з роллю AI (ApiUser‑style, без нових колонок).
- Інтерактивний логін заблокований (
user_attributes.blocked=1). - Роль AI read‑only за замовчуванням; підвищення прав — вручну.
- Для доступу до інтерфейсів пакетів видати permissions
staskта/абоsapi(групаsPackages).
- sTask — основний бекенд.
sync— fallback для середовищ без sTask. - eAi не реалізує Laravel Queue; лише сумісне dispatching для SDK.
Видимі воркери:
eai_smoke— фіксований prompteai_prompt— кастомний prompt з віджета
Внутрішній воркер:
eai— використовується queued SDK‑job’ами (не для ручного запуску)
Запуск воркера:
php artisan stask:workerQueued‑payload містить:
job_classjob_payload(серіалізація)attempts,max_attemptsactor_user_id,conversation_user_id,initiated_by_user_idcontext(mgr|web|cli)
then/catch — лише мінімальні метадані, повна Laravel‑сумісність не гарантується.
php artisan ai:testОпції:
--provider=openai|ollama|...--model=...--prompt="..."
php artisan make:agent SalesCoach
php artisan make:agent SalesCoach --structured
php artisan make:tool RandomNumberGeneratorЗгенеровані класи:
core/custom/app/Ai/Agents/*core/custom/app/Ai/Tools/*
Якщо автолоад не оновився:
composer dumpautoloaduse App\Ai\Agents\SupportAgent;
$agent = new SupportAgent();
$response = $agent->prompt('Hello from Evo');
echo $response->text;use function Laravel\Ai\agent;
$response = agent(
instructions: 'You are a helpful assistant.',
messages: [],
tools: []
)->prompt('Summarize this page');
echo $response->text;use App\Ai\Agents\SalesCoach;
$response = (new SalesCoach())->prompt('Analyze this sales transcript...');
echo $response['score'];use App\Ai\Tools\RandomNumberGenerator;
class SupportAgent implements \Laravel\Ai\Contracts\Agent, \Laravel\Ai\Contracts\HasTools
{
use \Laravel\Ai\Promptable;
public function instructions(): string { return 'You are helpful.'; }
public function tools(): iterable { return [new RandomNumberGenerator]; }
}use App\Ai\Agents\SalesCoach;
(new SalesCoach)
->queue('Analyze this transcript...')
->then(function ($response) {
// handle response
});use Laravel\Ai\Image;
$image = Image::of('A donut on the table')->generate();
$path = $image->storePubliclyAs('ai/donut.png');use Laravel\Ai\Audio;
$audio = Audio::of('Hello from Evo')->generate();
$path = $audio->storePubliclyAs('ai/hello.mp3');use Laravel\Ai\Transcription;
$text = Transcription::fromPath('/path/to/audio.mp3')->generate();use Laravel\Ai\Embeddings;
$response = Embeddings::for(['Napa Valley has great wine.'])->generate();
$vector = $response->embeddings[0];use Laravel\Ai\Reranking;
$response = Reranking::of([
'Django is a Python web framework.',
'Laravel is a PHP web application framework.',
])->rerank('PHP frameworks');
echo $response->first()->document;use Laravel\Ai\Files\Document;
use App\Ai\Agents\SupportAgent;
$stored = Document::fromPath('/path/to/report.pdf')->put();
$response = (new SupportAgent())->prompt(
'Summarize this report.',
[Document::fromId($stored->id)]
);-
Target class [prism] does not existПеревір залежності та перезбери автолоад (composer dumpautoload). Помилка виникає при відсутньому Prism‑binding. -
Rate limited by provider Це ліміт провайдера. Спробуй інший модель/провайдер або зачекай.
-
No provider with configured API key Додай ключ у
.envабоcore/custom/config/ai.php.
- Конфіг:
core/custom/config/ai.php - Evo‑налаштування:
core/custom/config/cms/settings/eAi.php - Агенти:
core/custom/app/Ai/Agents/* - Тулзи:
core/custom/app/Ai/Tools/* - Stubs:
core/stubs/*