Laravel AI: як відстежувати роботу агентів за допомогою Lifecycle Events

Перекладено ШІ 0 Laravel News 25 серпня, 2026

Laravel AI v0.11.0 перетворює роботу AI-агентів на прозорий процес із детальним моніторингом кожного кроку та виклику інструментів. Оновлення впроваджує наскрізні ID та нову систему подій для точного контролю таймінгів і помилок у реальному часі.

Запуск агента рідко обмежується одним викликом API. Зазвичай це цикл: модель повертає виклик інструменту, SDK його виконує, надсилає результат назад і так до завершення. До версії Laravel AI v0.11.0 цей цикл не мав проміжних подій: система фіксувала лише PromptingAgent на початку та AgentPrompted у самому кінці. Через це запуск із п’ятьма ітераціями виглядав так само, як і з одною, а помилка всередині циклу взагалі не залишала слідів, бо подія AgentPrompted не встигала спрацювати.

Завдяки серії з семи pull requests від @pushpak1300 (від #870 до #876) ситуація змінилася. Тепер кожен запуск має єдиний ID, а кожен запит до провайдера чи виклик інструменту супроводжується подіями початку та завершення з точним таймінгом.

# Єдиний ID для всього циклу

Раніше streamPrompt() генерував ID виклику на рівні запуску, а prompt() — ні. Це призводило до розбіжностей: синхронний middleware бачив $prompt->invocationId === null, тоді як стрімінговий отримував реальне значення. Крім того, при перемиканні між провайдерами (failover) кожен новий запит отримував власний ID, що заважало відстежувати єдиний процес.

Тепер prompt() генерує ID заздалегідь, а провайдер використовує надане значення (#871). Кожна подія нижче отримує цей ID як перший аргумент конструктора, що дозволяє групувати логи в один рядок:

public function __construct(
    public string $invocationId,
    public int $stepNumber,
    // ...
) {}

Подія AgentFailedOver також отримала ID: тепер обов'язковий аргумент string $invocationId є першим у конструкторі. Це не вплине на стандартні слухачі (listeners), але код, де ця подія створюється вручну, потребує оновлення.

# Події кроків (Step Events)

Події StartingStep, StepCompleted та StepFailed тепер спрацьовують при кожній ітерації (round-trip) як у синхронному, так і в стрімінговому режимах (#873).

StartingStep містить повідомлення, надіслані на поточному кроці (включаючи результати попередніх викликів інструментів), та параметри, що можуть відрізнятися від налаштувань агента (наприклад, при примусовому виборі інструменту). Також доступні stepNumber та isFinalStep:

use Laravel\Ai\Events\StartingStep;
 
Event::listen(StartingStep::class, function (StartingStep $event) {
    // $event->stepNumber, $event->model, $event->isFinalStep
    // $event->messages, $event->options
});

StepCompleted передає повний об'єкт StepResponse та час виконання float $time у мілісекундах. Формат часу збігається з QueryExecuted::$time, тож таймінги ШІ можна обробляти аналогічно до запитів у БД.

use Laravel\Ai\Events\StepCompleted;
 
Event::listen(StepCompleted::class, function (StepCompleted $event) {
    Log::info('AI step completed', [
        'invocation' => $event->invocationId,
        'step' => $event->stepNumber,
        'ms' => $event->time,
        'prompt_tokens' => $event->response->usage->promptTokens,
        'finish' => $event->response->finishReason->value,
    ]);
});

Раніше дані про використання кроків були доступні лише у фінальній події в загальному масиві $response->steps без прив'язки до часу. Тепер вартість та тривалість кожної ітерації фіксуються в реальному часі.

StepFailed спрацьовує, коли крок завершується без відповіді, передаючи Throwable та час, витрачений до виникнення помилки.

# Події інструментів (Tool Events)

Події InvokingTool та ToolInvoked існували й раніше, але мали ваду: ID інструменту зберігався у спільній властивості провайдера, яка перезаписувалася при вкладених викликах. Це призводило до того, що внутрішній агент-інструмент "затирав" ID зовнішнього виклику.

Тепер RunContext керує ідентифікацією запуску та надсилає події безпосередньо, а ID виклику інструменту генерується всередині executeTool() (#872). Інструменти можуть отримати цей ID через об'єкт запиту:

public function handle(Request $request): string
{
    $request->toolInvocationId(); // string|null
}

Нова подія ToolFailed (#874) виправляє стару проблему: раніше помилка в обробнику інструменту переривала весь цикл без фіксації завершення виклику. Тепер ToolFailed реєструє збій, використовуючи той самий toolInvocationId, що й при старті. Виключення прокидається далі, тож загальна поведінка залишається незмінною.

ToolInvoked тепер також вимагає float $time — час роботи обробника інструменту. Обидві події тепер передають екземпляр Tool замість простої назви, що дозволяє отримувати метадані безпосередньо з об'єкта:

use Laravel\Ai\Events\ToolFailed;
 
Event::listen(ToolFailed::class, function (ToolFailed $event) {
    Log::error('AI tool failed', [
        'invocation' => $event->invocationId,
        'tool_invocation' => $event->toolInvocationId,
        'tool' => class_basename($event->tool),
        'arguments' => $event->arguments,
        'ms' => $event->time,
        'exception' => $event->exception->getMessage(),
    ]);
});

# Події помилок запуску

Раніше всі події завершення в пакеті спрацьовували лише в разі успіху. Якщо шлюз видавав помилку, подія AgentPrompted не надсилалася, і відстежити крах запуску було неможливо.

AgentFailed тепер сповіщає про фінальний збій один раз за весь цикл (#876). Якщо налаштовано failover, перша помилка FailoverableException не вважається фатальною — подія спрацює лише тоді, коли весь ланцюжок провайдерів буде вичерпано. Вона передає invocationId, промпт та саме виключення.

Крім того, AgentFailedOver більше не спрацьовує для останнього провайдера в черзі. Його невдача тепер реєструється як загальна помилка запуску.

# Зв’язок дочірнього агента з батьківським

Агент, викликаний як інструмент, раніше виглядав як окремий процес. Тепер виклик інструменту відстежує свої ID запуску та інстансу протягом усієї роботи. Будь-який агент, активований під час виконання цього інструменту, отримує parentInvocationId та parentToolInvocationId (#875).

Це стосується не лише AgentTool, а й будь-яких власноруч написаних інструментів, що викликають агентів. Ідентифікатори зберігаються у статичній властивості, що дозволяє уникати зайвих даних у корисних навантаженнях черг.

Важливо: цей зв'язок не перетинає межі черги. Промпт, надісланий через promptOnQueue() зсередини інструменту, почне власний незалежний цикл без батьківського ID.

# Черги та історія повідомлень

StartingStep передає повну історію повідомлень запуску. Слухач, що реалізує ShouldQueue, буде серіалізувати всі ці дані разом із вкладеннями. Це свідоме рішення, оскільки слухачу для аналізу кроку потрібен контекст запиту. Якщо вам потрібні лише таймінги та кількість токенів, використовуйте StepCompleted — вона містить лише відповідь конкретного кроку, а не всю історію.

# Що ще почитати

Ці події з'явилися у версії v0.11.0 разом із хостингом пошуку інструментів та розширеним failover. Про те, як отримати сиру HTTP-відповідь провайдера (заголовки лімітів, ID запитів), читайте в описі raw HTTP response property з версії v0.10.3.

Більше про пакет дізнавайтеся в офіційному анонсі AI SDK та матеріалі про підтвердження дій інструментів людиною. Сирцевий код доступний на GitHub у репозиторії laravel/ai.

Популярні

Інше, що варто прочитати

60 Оновлено 26 червня, 2026

Усе, що нам відомо про Livewire 4

Нова версія Livewire 4, представленої Келебом Порзіо на Laracon US 2025, обіцяє значні покращення у швидкості та організації компонентів. Які з інноваційних функцій підкорять ваше серце? Читайте далі, щоб дізнатися більше про те, як Livewire 4 полегшить вашу роботу

15 Оновлено 26 червня, 2026

Claude Agent тепер інтегрований в AI Assistant для PhpStorm

Ви коли-небудь задумувалися, як полегшити свою роботу в Laravel? У нашій статті ми розглядаємо, як інтеграція Claude Code в PhpStorm може підвищити вашу продуктивність, спростивши процес написання коду та навчання нових розробників. Читайте далі, щоб дізнатися більше про переваги та функціональність цього потужного поєднання

13 Оновлено 26 червня, 2026

Генерація документації в Laravel за допомогою штучного інтелекту

Docudoodle — це потужний пакет для генерації документації в Laravel, який допомагає легко аналізувати вашу кодову базу та створювати документацію за допомогою обраного вами AI. Чи готові ви дізнатися, як цей інструмент може спростити вашу роботу з документуванням коду? Читайте далі!