Як побудувати систему оркестрації AI-агентів з Laravel

Дізнайтеся, як побудувати систему оркестрації AI-агентів у Laravel для покращення ваших функцій на базі AI. Цей посібник охоплює архітектуру, кодування та найкращі практики.
Більшість розробників Laravel стикаються з однією й тією ж проблемою з AI. Ви налаштовуєте виклик OpenAI, він чудово працює для однієї функції, а потім хтось просить про контентний конвеєр, який досліджує, пише, рецензує, і оптимізує. Раптом цей один запит виконує п’ять завдань погано замість одного завдання добре. Ось тут і приходить оркестрація AI-агентів у Laravel: розподіл складної роботи між кількома спеціалізованими агентами, які працюють паралельно, передають контекст один одному та досягають результатів, яких жоден окремий запит не зміг би досягти.
Екосистема Laravel вже рухається в цьому напрямку. Polyscope Марселя Поціота дозволяє вам одночасно запускати десятки AI-агентів з клонуванням при запису. Довідник Laravel Skills тепер пропонує скіли агентів, які ви можете вписати в будь-який проект. Навіть слоган самого Laravel оновився до "Чистий стек для майстрів та агентів." Чи помітили ви це, чи ні, мультиагентна система — це напрямок, в якому все рухається.
Далі йде практичний посібник зі створення власного шару оркестрації агентів у Laravel. Ми розглянемо архітектуру, пройдемося реальним кодом і також розглянемо складні частини (збої, повторні спроби, відстеження витрат). Якщо ви створюєте функції на базі AI у вашому SaaS-додатку, цей підхід масштабується набагато краще, ніж коли ви намагаєтеся запихати все в один мегазапит.
Чому архітектури з одним агентом стикаються з проблемами
Кожна інтеграція AI починається просто. Надішліть запит, отримайте відповідь, покажіть її користувачу. Для простих функцій, таких як підсумовування тексту або генерація опису продукту, це насправді все, що вам потрібно.
Але уявіть собі контентний конвеєр, який повинен дослідити тему, написати перший проект, перевірити його на технічну точність і відшліфувати для SEO. Ви можете запхати все це в один величезний запит. Я пробував. Вихід... нормальний. Він посередній у тому сенсі, що нічого явно неправильного, але нічого й чудового. Модель розпорошує свою увагу занадто тонко, контекст плутається, і якість кожного окремого завдання страждає.
Що працює краще, так це ставитися до цього так, як ви ставитеся до команди людей. Дайте дослідження тому, хто добре вміє досліджувати. Передайте написання письменнику. Нехай рецензент просто рецензує. В термінах AI це означає окремі агенти з фокусованими системними запитами, а іноді й зовсім різними моделями. Чому платити за GPT-4o для класифікації, коли gpt-4o-mini справляється з цим так само добре за меншу вартість?
Вимірювання | Один агент | Оркестровані агенти |
|---|---|---|
Складність завдання | Один запит обробляє все | Завдання розділені на спеціалізовані етапи |
Якість | Знижується зі складністю | Кожен агент оптимізований для своєї ролі |
Затримка | Послідовна, один довгий виклик | Паралельне виконання, де це можливо |
Вартість | Один великий контекстний виклик | Менші виклики, змішування дешевих + дорогих моделей |
Надійність | Єдина точка відмови | Окремі агенти можуть повторити спробу або повернутися назад |
Спостережуваність | Одна чорна скринька | Логування та метрики, що відстежуються по агентам |
Як тільки ви почнете шукати цей шаблон, він з’являється скрізь. Конвеєри перевірки коду, які аналізують, пропонують виправлення, а потім перевіряють пропозиції. Потоки підтримки клієнтів, які класифікують наміри, витягують відповідні документи, складають відповідь і перевіряють тон перед відправкою. Завдання обробки даних, які витягують, трансформують, перевіряють і підсумовують. Це не гіпотетичні робочі процеси. Сучасні AI-продукти виконують їх тисячі разів на день.
Проектування шару оркестрації AI-агентів у Laravel
Перед тим, як перейти до коду, є чотири рухомі частини, які вам потрібно зрозуміти. Я швидко поясню, оскільки розділ реалізації — це те, де все стає цікавим.
По-перше, декомпозиція завдань. Ваш оркестратор бере загальну мету ("написати блог про стратегії кешування") і розбиває її на невеликі підзавдання: дослідити тему, написати проект, перевірити на точність. Кожне підзавдання передається агенту, який найкраще підходить для цього.
Далі є реєстр агентів, що насправді є просто модним ім’ям для "списку агентів і того, що вони можуть робити." У Laravel це природно відображається на контейнері сервісів. Ви прив’язуєте кожного агента як сервіс, оркестратор шукає їх за іменем, коли вони йому потрібні. Нічого екзотичного.
Двигун виконання визначає порядок. Деякі завдання повинні виконуватися послідовно (ви не можете рецензувати проект, якого ще не існує). Інші можуть виконуватися паралельно (досліджуючи три підтематики одночасно). Система черг Laravel з пакетами завдань обробляє обидва випадки, що насправді є однією з причин, чому цей фреймворк так добре підходить для такого роду роботи.
Нарешті, агрегація результатів збирає те, що всі агенти виробили, і об’єднує це в остаточний результат. Іноді це проста конкатенація. Іншим разом ви використовуєте спеціалізованого агента "синтезатора", який бере кілька аутпутів і переплітає їх у щось зрозуміле.
Ось візуалізація того, як ці частини поєднуються:
Добра новина? Laravel надає вам більшість необхідних компонентів безкоштовно. Завдання та черги обробляють виконання. Події дозволяють агентам спілкуватися без тісної прив’язки. Контейнер сервісів управляє з’єднаннями та впровадженням залежностей. Ви будуєте на основі фреймворку, а не працюєте навколо нього.
Побудова крок за кроком у Laravel
Досить теорії. Давайте побудуємо контентний конвеєр, який досліджує тему, пише проект і рецензує його. Три агенти, один оркестратор, реальний код.
Крок 1: Визначте контракт агента
Кожен агент реалізує один і той же інтерфейс. Це те, що робить все це масштабованим — ваш оркестратор не повинен знати (або піклуватися) про те, що конкретний агент робить всередині.
<?php
namespace App\Agents\Contracts;
interface AgentInterface
{
/**
* Виконати завдання та повернути результат.
*/
public function execute(AgentTask $task): AgentResult;
/**
* Унікальна назва цього агента.
*/
public function name(): string;
}<?php
namespace App\Agents\Contracts;
class AgentTask
{
public function __construct(
public readonly string $instruction,
public readonly array $context = [],
public readonly ?string $model = null,
) {}
}<?php
namespace App\Agents\Contracts;
class AgentResult
{
public function __construct(
public readonly string $agentName,
public readonly string $output,
public readonly array $metadata = [],
public readonly bool $success = true,
) {}
}Крок 2: Створіть конкретних агентів
Кожен агент обгортає виклик LLM з спеціалізованим системним запитом. Зверніть увагу, що ResearchAgent за замовчуванням використовує gpt-4o-mini — швидкий і дешевий, ідеальний для збору фактів. Ви, напевно, поставите свого WriterAgent на більш потужну модель, таку як gpt-4o або Claude Sonnet, де якість прози дійсно має значення.
<?php
namespace App\Agents;
use App\Agents\Contracts\{AgentInterface, AgentTask, AgentResult};
use OpenAI\Laravel\Facades\OpenAI;
class ResearchAgent implements AgentInterface
{
public function name(): string
{
return 'researcher';
}
public function execute(AgentTask $task): AgentResult
{
$response = OpenAI::chat()->create([
'model' => $task->model ?? 'gpt-4o-mini',
'messages' => [
[
'role' => 'system',
'content' => 'Ви спеціаліст з досліджень. Дано тему, '
. 'створіть структуроване резюме ключових фактів, статистики, '
. 'та останніх розробок. Будьте конкретними та наводьте джерела '
. 'де це можливо. Вихід у markdown.',
],
[
'role' => 'user',
'content' => $task->instruction,
],
],
]);
return new AgentResult(
agentName: $this->name(),
output: $response->choices[0]->message->content,
metadata: [
'tokens' => $response->usage->totalTokens,
'model' => $response->model,
],
);
}
}Ваш WriterAgent та ReviewAgent дотримуються тієї ж структури з різними системними запитами та вибором моделей. Це вся суть інтерфейсу: оркестратор просто викликає execute() і отримує результат, незалежно від того, що відбувається під капотом.
Крок 3: Побудуйте оркестратор
Це центральна частина. Оркестратор декомпозує цілі на завдання, розподіляє їх агентам і збирає все, коли вони закінчать.
<?php
namespace App\Agents;
use App\Agents\Contracts\{AgentInterface, AgentTask, AgentResult};
use Illuminate\Support\Facades\Bus;
use App\Jobs\ExecuteAgentJob;
class Orchestrator
{
/** @var array<string, AgentInterface> */
private array $agents = [];
public function register(AgentInterface $agent): void
{
$this->agents[$agent->name()] = $agent;
}
/**
* Запустіть послідовний конвеєр: кожен агент отримує
* вихід попереднього агента як контекст.
*/
public function pipeline(array $steps, string $initialInput): AgentResult
{
$context = ['input' => $initialInput];
$lastResult = null;
foreach ($steps as $agentName => $instruction) {
$agent = $this->resolve($agentName);
$task = new AgentTask(
instruction: $instruction,
context: $context,
);
$lastResult = $agent->execute($task);
$context[$agentName] = $lastResult->output;
}
return $lastResult;
}
/**
* Запустіть агентів паралельно, використовуючи пакетування завдань Laravel.
* Повертає всі результати, як тільки кожен агент завершить.
*/
public function parallel(array $tasks): array
{
$jobs = [];
$batchId = uniqid('orch_');
foreach ($tasks as $agentName => $instruction) {
$jobs[] = new ExecuteAgentJob(
agentName: $agentName,
task: new AgentTask(instruction: $instruction),
batchId: $batchId,
);
}
$batch = Bus::batch($jobs)
->allowFailures()
->dispatch();
// У виробництві ви б опитували або використовували події
// замість блокування тут
return $this->collectResults($batchId);
}
private function resolve(string $name): AgentInterface
{
return $this->agents[$name]
?? throw new \RuntimeException("Агент [{$name}] не зареєстрований.");
}
}Крок 4: Підключіть це до контейнера сервісів Laravel
Зареєструйте своїх агентів у постачальнику послуг, щоб вони були доступні по всій програмі:
<?php
namespace App\Providers;
use App\Agents\{Orchestrator, ResearchAgent, WriterAgent, ReviewAgent};
use Illuminate\Support\ServiceProvider;
class AgentServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Orchestrator::class, function () {
$orchestrator = new Orchestrator();
$orchestrator->register(new ResearchAgent());
$orchestrator->register(new WriterAgent());
$orchestrator->register(new ReviewAgent());
return $orchestrator;
});
}
}Крок 5: Запустіть контентний конвеєр
З усім підключеним, запуск повного конвеєра займає всього кілька рядків:
$orchestrator = app(Orchestrator::class);
$result = $orchestrator->pipeline(
steps: [
'researcher' => 'Досліджуйте останні тенденції в стратегіях кешування Laravel на 2026 рік',
'writer' => 'Використовуючи дослідження, надані в контексті, напишіть блог на 1500 слів',
'reviewer' => 'Перегляньте цей блог на технічну точність і запропонуйте покращення',
],
initialInput: 'Стратегії кешування Laravel для високонавантажених додатків',
);
// $result містить рецензовану, відшліфовану статтю
echo $result->output;Дослідник знаходить факти. Письменник перетворює ці факти на проект. Рецензент виявляє помилки та пропонує покращення. Вихід кожного агента автоматично стає частиною контексту наступного агента, тому інформація рухається вперед через конвеєр без того, щоб ви вручну зшивали щось разом.
Обробка збоїв, повторних спроб і спостережуваності
Ось щось, що легко забути під час захоплення від створення цього: зовнішні AI API часто виходять з ладу дуже часто. OpenAI викидає помилки обмеження швидкості 429 під час пікових навантажень. Anthropic має випадкові тайм-аути на 30 секунд. Якщо ви запускаєте конвеєр з трьох агентів, і виклик API другого агента зривається, що відбувається з усім робочим процесом? Без планування відповідь — "нічого доброго."
Розривники ланцюгів для LLM API
Харріс Рафтопулос створив Fuse for Laravel і представив його на Laracon India 2026 спеціально для цієї проблеми. Ідея запозичена з електротехніки: після певної кількості збоїв ланцюг "відкривається" і ваш додаток перестає надсилати запити до мертвого кінцевого пункту зовсім. Завдання затримуються замість того, щоб зірватися, тому ви не втрачаєте жодних даних. Коли API відновлюється, ланцюг закривається, і обробка автоматично відновлюється.
Ось спрощена версія шаблону як посередник черги:
<?php
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class AgentCircuitBreaker
{
public function __construct(
private string $service,
private int $maxFailures = 5,
private int $cooldownSeconds = 60,
) {}
public function handle(object $job, callable $next): void
{
$key = "circuit:{$this->service}";
$failures = (int) Redis::get($key);
if ($failures >= $this->maxFailures) {
// Ланцюг відкритий — поверніть завдання назад у чергу
$job->release($this->cooldownSeconds);
return;
}
try {
$next($job);
Redis::del($key); // Скинути при успіху
} catch (\Throwable $e) {
Redis::incr($key);
Redis::expire($key, $this->cooldownSeconds);
throw $e;
}
}
}Структуроване логування для рішень агентів
Коли конвеєр видає дивний результат, вам потрібно з’ясувати який агент вийшов з ладу. Це був дослідник, який витягнув погані дані? Письменник, який неправильно зрозумів дослідження? Рецензент, який зламав щось, що було в порядку? Без структурованого логування ви лише здогадуєтеся.
Log::channel('agents')->info('Агент виконано', [
'agent' => $result->agentName,
'tokens' => $result->metadata['tokens'] ?? null,
'model' => $result->metadata['model'] ?? null,
'success' => $result->success,
'duration_ms' => $durationMs,
'pipeline_id' => $pipelineId,
]);Протягніть ідентифікатор конвеєра через кожен запис журналу, і ви зможете відновити повний потік виконання після факту: який агент запускався, коли, скільки токенів кожен спалив, де все пішло не так. Підключіть це до Laravel Telescope або відправте в централізовану службу логування, і налагодження стане набагато менш болісним.
Моніторинг витрат
Це питання, яке турбує людей. Конвеєр з трьох агентів коштує приблизно в 3 рази більше, ніж один виклик API, і ця математика стає гіршою, якщо агенти повторюють спроби або якщо ви використовуєте дорогі моделі. Відстежуйте використання токенів з метаданих кожного AgentResult, агрегуйте його за конвеєром і за користувачем, і налаштуйте сповіщення, коли щоденні витрати перевищують ваші бюджетні межі. Я бачив команди, які виявили $200/день у безконтрольних циклах агентів, які ніхто не помітив протягом тижня. Не будьте тією командою.
Куди йти далі
На цьому етапі у вас є працюючий шар оркестрації AI-агентів у Laravel: агенти за чистим інтерфейсом, оркестратор, що обробляє як послідовні, так і паралельні потоки, виконання на основі черг та базова стійкість з розривниками ланцюгів.
Є багато чого, на чому можна побудувати. Ви можете додати спільну пам’ять, щоб агенти в конвеєрі могли читати та записувати в загальний контекст (хеш Redis або рядок бази даних) замість того, щоб передавати все через аргументи методів. Контрольні точки з людиною в циклі варто дослідити для робочих процесів, де ставки високі: призупиніть конвеєр, покажіть людині, що агент виробив, чекайте на схвалення, перш ніж продовжити. І якщо у вас є багато різних типів агентів, динамічна маршрутизація дозволяє вам використовувати легкий агент-класифікатор, щоб вирішити, яких спеціалістів викликати, замість того, щоб жорстко кодувати структуру конвеєра.
Ще одна річ, яку варто підкреслити: нічого з цього не пов’язано з OpenAI. Замість цього можна використовувати Anthropic, Mistral, самостійно розгорнуту модель Qwen на Ollama, що завгодно. Інтерфейс агента залишається ідентичним. Ваша логіка оркестрації не піклується про те, хто генерує токени, лише про те, що контракт виконано.
Якщо ви хочете просунутися далі і побудувати повноцінний продукт на базі AI з нуля (бекенд, фронтенд, автентифікація, платежі, розгортання, все це), курс AI Product Manager на SkillHub охоплює саме це. Шаблони оркестрації з цієї статті ідеально вписуються в архітектуру, яку ви побудуєте там.
