Laravel AI SDK
- Вступ
- Встановлення
- Агенти
- Зображення
- Аудіо (TTS)
- Транскрипція (STT)
- Вбудовування
- Пересортування
- Файли
- Векторні сховища
- Перемикання на резервний
- Тестування
- Події
Вступ
Laravel AI SDK надає уніфікований, виразний API для взаємодії з AI-провайдерами, такими як OpenAI, Anthropic, Gemini та іншими. За допомогою AI SDK ви можете створювати інтелектуальних агентів з інструментами та структурованим виводом, генерувати зображення, синтезувати та транскрибувати аудіо, створювати векторні ембедінги та багато іншого — все це через зручний, дружній до Laravel інтерфейс.
Встановлення
Ви можете встановити Laravel AI SDK через компонувальник:
composer require laravel/ai
Далі слід опублікувати файли конфігурації та міграції AI SDK за допомогою Artisan-команди vendor:publish:
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
Нарешті, слід виконати міграції бази даних вашого застосунку. Це створить таблиці agent_conversations та agent_conversation_messages, які AI SDK використовує для зберігання розмов:
php artisan migrate
Конфігурація
Ви можете визначити облікові дані вашого AI-провайдера у файлі конфігурації вашого застосунку config/ai.php або як змінні середовища у файлі .env вашого застосунку:
ANTHROPIC_API_KEY=
COHERE_API_KEY=
ELEVENLABS_API_KEY=
GEMINI_API_KEY=
MISTRAL_API_KEY=
OLLAMA_API_KEY=
OPENAI_API_KEY=
JINA_API_KEY=
VOYAGEAI_API_KEY=
XAI_API_KEY=
Типові моделі, що використовуються для тексту, зображень, аудіо, транскрипції та embeddings, також можна налаштувати у файлі конфігурації вашого застосунку config/ai.php.
Користувацькі базові URL
За замовчуванням Laravel AI SDK підключається безпосередньо до публічної кінцевої точки API кожного провайдера. Однак, можливо, вам потрібно буде спрямовувати запити через іншу кінцеву точку — наприклад, при використанні проксі-сервісу для централізованого керування API-ключами, впровадження Обмеження частоти запитів або маршрутизації трафіку через корпоративний шлюз.
Ви можете налаштувати власні базові URL, додавши параметр url до конфігурації вашого провайдера:
'providers' => [
'openai' => [
'driver' => 'openai',
'key' => env('OPENAI_API_KEY'),
'url' => env('OPENAI_BASE_URL'),
],
'anthropic' => [
'driver' => 'anthropic',
'key' => env('ANTHROPIC_API_KEY'),
'url' => env('ANTHROPIC_BASE_URL'),
],
],
Це корисно при маршрутизації запитів через проксі-сервіс (такий як LiteLLM або Azure OpenAI Gateway) чи використанні альтернативних кінцевих точок.
Підтримуються власні базові URL-адреси для таких провайдерів: OpenAI, Anthropic, Gemini, Groq, Cohere, DeepSeek, xAI та OpenRouter.
Підтримка провайдерів
AI SDK підтримує різноманітних провайдерів для своїх функцій. У наступній таблиці наведено, які провайдери доступні для кожної функції:
| Feature | Providers |
|---|---|
| Text | OpenAI, Anthropic, Gemini, Azure, Groq, xAI, DeepSeek, Mistral, Ollama |
| Images | OpenAI, Gemini, xAI |
| TTS | OpenAI, ElevenLabs |
| STT | OpenAI, ElevenLabs, Mistral |
| Embeddings | OpenAI, Gemini, Azure, Cohere, Mistral, Jina, VoyageAI |
| Reranking | Cohere, Jina |
| Files | OpenAI, Anthropic, Gemini |
Перерахування Laravel\Ai\Enums\Lab може використовуватися для посилання на провайдерів у вашому коді замість використання звичайних рядків:
use Laravel\Ai\Enums\Lab;
Lab::Anthropic;
Lab::OpenAI;
Lab::Gemini;
// ...
Агенти
Агенти є фундаментальним елементом для взаємодії з AI-провайдерами у Laravel AI SDK. Кожен агент — це окремий PHP-клас, який інкапсулює інструкції, контекст розмови, інструменти та схему виводу, необхідні для взаємодії з великою мовною моделлю. Уявіть агента як спеціалізованого помічника — тренера з продажу, аналізатора документів, бота підтримки — якого ви налаштовуєте один раз і використовуєте за потреби у вашому застосунку.
Ви можете створити агент за допомогою Artisan-команди make:agent:
php artisan make:agent SalesCoach
php artisan make:agent SalesCoach --structured
У згенерованому класі агента ви можете визначити системний підказку / інструкції, контекст повідомлення, доступні інструменти та схему виводу (якщо застосовується):
<?php namespace App\Ai\Agents; use App\Ai\Tools\RetrievePreviousTranscripts; use App\Models\History; use App\Models\User; use Illuminate\Contracts\JsonSchema\JsonSchema; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Contracts\Conversational; use Laravel\Ai\Contracts\HasStructuredOutput; use Laravel\Ai\Contracts\HasTools; use Laravel\Ai\Messages\Message; use Laravel\Ai\Promptable; use Stringable; class SalesCoach implements Agent, Conversational, HasTools, HasStructuredOutput { use Promptable; public function __construct(public User $user) {} /** * Отримайте інструкції, яких повинен дотримуватися агент. */ public function instructions(): Stringable|string { return 'Ви є тренером з продажу, аналізуєте стенограми, надаєте зворотний зв'язок та загальну оцінку ефективності продажів.
.'; } /** * Отримати список повідомлень, що складають розмову на даний момент. */ public function messages(): iterable { return History::where('user_id', $this->user->id) ->latest() ->limit(50) ->get() ->reverse() ->map(function ($message) { return new Message($message->role, $message->content); })->all(); } /** * Отримайте інструменти, доступні агенту. * * @return Tool[] */ public function tools(): iterable { return [ new RetrievePreviousTranscripts, ]; } /** * Отримати структуроване визначення схеми виводу агента. */ public function schema(JsonSchema $schema): array { return [ 'feedback' => $schema->string()->required(), 'score' => $schema->integer()->min(1)->max(10)->required(), ]; } }
Підказки
Щоб викликати агента, спочатку створіть екземпляр за допомогою методу make або стандартної інстанціації, потім викличте prompt:
$response = (new SalesCoach) ->prompt('Проаналізуйте цей протокол продажів...'); $response = SalesCoach::make() ->prompt('Проаналізуйте цей протокол продажів...'); return (string) $response;
Метод make отримує ваш агент з контейнера, дозволяючи автоматичне впровадження залежностей. Ви також можете передати аргументи до конструктора агента:
$agent = SalesCoach::make(user: $user);
Передаючи додаткові аргументи методу prompt, ви можете перевизначити провайдера за замовчуванням, модель або HTTP-тайм-аут під час запиту:
$response = (new SalesCoach)->prompt( 'Проаналізуйте цей протокол продажів...', provider: Lab::Anthropic, model: 'claude-haiku-4-5-20251001', timeout: 120, );
Контекст розмови
Якщо ваш агент реалізує інтерфейс Conversational, ви можете використати метод messages для повернення попереднього контексту розмови, якщо це застосовно:
use App\Models\History; use Laravel\Ai\Messages\Message; /** * Отримати список повідомлень, що складають розмову на даний момент. */ public function messages(): iterable { return History::where('user_id', $this->user->id) ->latest() ->limit(50) ->get() ->reverse() ->map(function ($message) { return new Message($message->role, $message->content); })->all(); }
Запам'ятовування розмов
Перш ніж використовувати трейд RemembersConversations, слід опублікувати та виконати міграції AI SDK за допомогою команди Artisan vendor:publish. Ці міграції створять необхідні таблиці бази даних для зберігання розмов.
Якщо ви бажаєте, щоб Laravel автоматично зберігав і отримував історію розмов для вашого агента, ви можете використати трейд RemembersConversations. Цей трейд надає простий спосіб зберігати повідомлення розмов у базі даних без необхідності вручну реалізовувати інтерфейс Conversational:
<?php namespace App\Ai\Agents; use Laravel\Ai\Concerns\RemembersConversations; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Contracts\Conversational; use Laravel\Ai\Promptable; class SalesCoach implements Agent, Conversational { use Promptable, RemembersConversations; /** * Отримайте інструкції, яких повинен дотримуватися агент. */ public function instructions(): string { return 'Ви тренер з продажу...'; } }
Щоб розпочати нову розмову для користувача, викличте метод forUser перед створенням запиту:
$response = (new SalesCoach)->forUser($user)->prompt('Hello!');
$conversationId = $response->conversationId;
Ідентифікатор розмови повертається у відповіді і може бути збережений для подальшого використання, або ви можете отримати всі розмови користувача безпосередньо з таблиці agent_conversations.
Щоб продовжити існуючу розмову, використовуйте метод continue:
$response = (new SalesCoach) ->continue($conversationId, as: $user) ->prompt('Розкажіть мені про це докладніше.');
Під час використання трейту RemembersConversations попередні повідомлення автоматично завантажуються та включаються в контекст розмови під час запиту. Нові повідомлення (як користувача, так і асистента) автоматично зберігаються після кожної взаємодії.
Структурований вивід
Якщо ви бажаєте, щоб ваш агент повертав структурований результат, реалізуйте інтерфейс HasStructuredOutput, який вимагає, щоб ваш агент визначив метод schema:
<?php namespace App\Ai\Agents; use Illuminate\Contracts\JsonSchema\JsonSchema; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Contracts\HasStructuredOutput; use Laravel\Ai\Promptable; class SalesCoach implements Agent, HasStructuredOutput { use Promptable; // ... /** * Отримати структуроване визначення схеми виводу агента. */ public function schema(JsonSchema $schema): array { return [ 'score' => $schema->integer()->required(), ]; } }
Коли ви запитуєте агента, який повертає структурований вивід, ви можете отримати доступ до повернутого StructuredAgentResponse як до масиву:
$response = (new SalesCoach)->prompt('Проаналізуйте цей протокол продажів...'); return $response['score'];
Вкладення
Під час створення запиту ви також можете додати вкладення до запиту, щоб дозволити моделі переглядати зображення та документи:
use App\Ai\Agents\SalesCoach; use Laravel\Ai\Files; $response = (new SalesCoach)->prompt( 'Проаналізуйте доданий протокол продажів...', attachments: [ Files\Document::fromStorage('transcript.pdf') // Додати документ з файлової системи диска...
Files\Document::fromPath('/home/laravel/transcript.md') // Додати документ з локального шляху...
$request->file('transcript'), // Додати завантажений файл... ] );
Так само, клас Laravel\Ai\Files\Image можна використовувати для додавання зображень до запиту:
use App\Ai\Agents\ImageAnalyzer; use Laravel\Ai\Files; $response = (new ImageAnalyzer)->prompt( 'Що зображено на цьому зображенні?', attachments: [ Files\Image::fromStorage('photo.jpg') // Додати зображення з диска файлової системи... Files\Image::fromPath('/home/laravel/photo.jpg') // Додати зображення з локального шляху... $request->file('photo'), // Додати завантажений файл... ] );
Потокова передача
Ви можете транслювати відповідь агента, викликавши метод stream. Повернутий StreamableAgentResponse може бути повернутий з маршруту для автоматичної відправки потокової відповіді (SSE) клієнту:
use App\Ai\Agents\SalesCoach; Route::get('/coach', function () { return (new SalesCoach)->stream('Проаналізуйте цей протокол продажів...'); });
Метод then може бути використаний для надання замикання, яке буде викликане після того, як весь відповідь буде передано клієнту:
use App\Ai\Agents\SalesCoach; use Laravel\Ai\Responses\StreamedAgentResponse; Route::get('/coach', function () { return (new SalesCoach) ->stream('Проаналізуйте цей протокол продажів...') ->then(function (StreamedAgentResponse $response) { // $response->text, $response->events, $response->usage... }); });
Альтернативно, ви можете перебирати передані події вручну:
$stream = (new SalesCoach)->stream('Проаналізуйте цей протокол продажів...'); foreach ($stream as $event) { // ... }
Потокова передача за допомогою протоколу Vercel AI SDK
Ви можете транслювати події, використовуючи протокол потокової передачі Vercel AI SDK, викликаючи метод usingVercelDataProtocol на потоковій відповіді:
use App\Ai\Agents\SalesCoach; Route::get('/coach', function () { return (new SalesCoach) ->stream('Проаналізуйте цей протокол продажів...') ->usingVercelDataProtocol(); });
Трансляція
Ви можете транслювати потокові події кількома різними способами. По-перше, ви можете просто викликати метод broadcast або broadcastNow на потоковій події:
use App\Ai\Agents\SalesCoach; use Illuminate\Broadcasting\Channel; $stream = (new SalesCoach)->stream('Проаналізуйте цей протокол продажів...'); foreach ($stream as $event) { $event->broadcast(new Channel('channel-name')); }
Або ви можете викликати метод broadcastOnQueue агента, щоб поставити операцію агента в чергу та транслювати потокові події у міру їх надходження:
(new SalesCoach)->broadcastOnQueue( 'Проаналізуйте цей протокол продажів...' new Channel('channel-name'), );
Постановка в чергу
Використовуючи метод queue агента, ви можете надіслати запит агенту, але дозволити йому обробити відповідь у фоновому режимі, зберігаючи ваш застосунок швидким і чуйним. Методи then та catch можна використовувати для реєстрації замикань, які будуть викликані, коли відповідь стане доступною або якщо виникне виняток:
use Illuminate\Http\Request;
use Laravel\Ai\Responses\AgentResponse;
use Throwable;
Route::post('/coach', function (Request $request) {
return (new SalesCoach)
->queue($request->input('transcript'))
->then(function (AgentResponse $response) {
// ...
})
->catch(function (Throwable $e) {
// ...
});
return back();
});
Інструменти
Інструменти можуть використовуватися для надання агентам додаткової функціональності, яку вони можуть застосовувати під час відповіді на підказки. Інструменти можна створювати за допомогою Artisan-команди make:tool:
php artisan make:tool RandomNumberGenerator
Згенерований інструмент буде розміщено в директорії вашого застосунку app/Ai/Tools. Кожен інструмент містить метод handle, який буде викликаний агентом, коли йому потрібно скористатися інструментом:
<?php namespace App\Ai\Tools; use Illuminate\Contracts\JsonSchema\JsonSchema; use Laravel\Ai\Contracts\Tool; use Laravel\Ai\Tools\Request; use Stringable; class RandomNumberGenerator implements Tool { /** * Отримайте опис призначення інструменту. */ public function description(): Stringable|string { return 'Цей інструмент може використовуватися для генерації криптографічно захищених випадкових чисел.'; } /** * Виконайте інструмент. */ public function handle(Request $request): Stringable|string { return (string) random_int($request['min'], $request['max']); } /** * Отримати визначення схеми інструменту. */ public function schema(JsonSchema $schema): array { return [ 'min' => $schema->integer()->min(0)->required(), 'max' => $schema->integer()->required(), ]; } }
Після того як ви визначили свій інструмент, ви можете повернути його з методу tools будь-якого зі своїх агентів:
use App\Ai\Tools\RandomNumberGenerator; /** * Отримайте інструменти, доступні агенту. * * @return Tool[] */ public function tools(): iterable { return [ new RandomNumberGenerator, ]; }
Пошук за схожістю
Інструмент SimilaritySearch дозволяє агентам шукати документи, схожі на заданий запит, використовуючи векторні вбудовування, збережені у вашій базі даних. Це корисно для генерації з підсиленням пошуком (RAG), коли ви хочете надати агентам доступ до пошуку даних вашого застосунку.
Найпростіший спосіб створити інструмент для пошуку за схожістю — використати метод usingModel з Eloquent-моделлю, яка має векторні embeddings:
use App\Models\Document;
use Laravel\Ai\Tools\SimilaritySearch;
public function tools(): iterable
{
return [
SimilaritySearch::usingModel(Document::class, 'embedding'),
];
}
Перший аргумент — це клас моделі Eloquent, а другий аргумент — стовпець, що містить векторні вбудовування.
Ви також можете вказати мінімальний поріг схожості між 0.0 і 1.0 та closure для налаштування запиту:
SimilaritySearch::usingModel(
model: Document::class,
column: 'embedding',
minSimilarity: 0.7,
limit: 10,
query: fn ($query) => $query->where('published', true),
),
Для більшого контролю ви можете створити інструмент пошуку за схожістю з власним замиканням, яке повертає результати пошуку:
use App\Models\Document;
use Laravel\Ai\Tools\SimilaritySearch;
public function tools(): iterable
{
return [
new SimilaritySearch(using: function (string $query) {
return Document::query()
->where('user_id', $this->user->id)
->whereVectorSimilarTo('embedding', $query)
->limit(10)
->get();
}),
];
}
Ви можете налаштувати опис інструменту за допомогою методу withDescription:
SimilaritySearch::usingModel(Document::class, 'embedding') ->withDescription('Шукайте відповідні статті в базі знань.'),
Інструменти провайдера
Інструменти провайдера — це спеціальні інструменти, реалізовані нативно провайдерами ШІ, які надають можливості, такі як веб-пошук, отримання URL та пошук файлів. На відміну від звичайних інструментів, інструменти провайдера виконуються самим провайдером, а не вашим застосунком.
Інструменти провайдера можуть бути повернуті методом tools вашого агента.
Веб-пошук
Інструмент провайдера WebSearch дозволяє агентам шукати інформацію в Інтернеті в режимі реального часу. Це корисно для відповідей на запитання про поточні події, нещодавні дані або теми, які могли змінитися після дати завершення навчання моделі.
Підтримувані провайдери: Anthropic, OpenAI, Gemini
use Laravel\Ai\Providers\Tools\WebSearch;
public function tools(): iterable
{
return [
new WebSearch,
];
}
Ви можете налаштувати інструмент веб-пошуку для обмеження кількості пошуків або обмеження результатів певними доменами:
(new WebSearch)->max(5)->allow(['laravel.com', 'php.net']),
Щоб уточнити результати пошуку на основі місцезнаходження користувача, використовуйте метод location:
(new WebSearch)->location(
city: 'New York',
region: 'NY',
country: 'US'
);
Веб-запит
Інструмент-провайдер WebFetch дозволяє агентам отримувати та читати вміст веб-сторінок. Це корисно, коли потрібно, щоб агент проаналізував конкретні URL-адреси або отримав детальну інформацію з відомих веб-сторінок.
Підтримувані провайдери: Anthropic, Gemini
use Laravel\Ai\Providers\Tools\WebFetch;
public function tools(): iterable
{
return [
new WebFetch,
];
}
Ви можете налаштувати інструмент отримання з вебу, щоб обмежити кількість отримань або обмежити певними доменами:
(new WebFetch)->max(3)->allow(['docs.laravel.com']),
Пошук файлів
Інструмент-провайдер FileSearch дозволяє агентам здійснювати пошук у файлах, збережених у векторних сховищах. Це забезпечує генерацію з підкріпленням пошуком (RAG), дозволяючи агенту шукати у ваших завантажених документах релевантну інформацію.
Підтримувані провайдери: OpenAI, Gemini
use Laravel\Ai\Providers\Tools\FileSearch;
public function tools(): iterable
{
return [
new FileSearch(stores: ['store_id']),
];
}
Ви можете вказати кілька ідентифікаторів сховищ векторів для пошуку в декількох сховищах:
new FileSearch(stores: ['store_1', 'store_2']);
Якщо ваші файли мають метадані, ви можете відфільтрувати результати пошуку, вказавши аргумент where. Для простих фільтрів рівності передайте масив:
new FileSearch(stores: ['store_id'], where: [
'author' => 'Taylor Otwell',
'year' => 2026,
]);
Для більш складних фільтрів ви можете передати closure, яка отримує екземпляр FileSearchQuery:
use Laravel\Ai\Providers\Tools\FileSearchQuery;
new FileSearch(stores: ['store_id'], where: fn (FileSearchQuery $query) =>
$query->where('author', 'Taylor Otwell')
->whereNot('status', 'draft')
->whereIn('category', ['news', 'updates'])
);
Проміжне програмне забезпечення
Агенти підтримують middleware, що дозволяє перехоплювати та змінювати підказки перед їх відправленням провайдеру. Middleware можна створити за допомогою Artisan-команди make:agent-middleware:
php artisan make:agent-middleware LogPrompts
Згенерований middleware буде розміщено в директорії вашого застосунку app/Ai/Middleware. Щоб додати middleware до агента, реалізуйте інтерфейс HasMiddleware і визначте метод middleware, який повертає масив класів middleware:
<?php namespace App\Ai\Agents; use App\Ai\Middleware\LogPrompts; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Contracts\HasMiddleware; use Laravel\Ai\Promptable; class SalesCoach implements Agent, HasMiddleware { use Promptable; // ... /** * Отримати middleware агента. */ public function middleware(): array { return [ new LogPrompts, ]; } }
Кожен клас middleware повинен визначати метод handle, який отримує AgentPrompt та Closure для передачі запиту наступному middleware:
<?php namespace App\Ai\Middleware; use Closure; use Laravel\Ai\Prompts\AgentPrompt; class LogPrompts { /** * Обробити вхідний запит. */ public function handle(AgentPrompt $prompt, Closure $next) { Log::info('Prompting agent', ['prompt' => $prompt->prompt]); return $next($prompt); } }
Ви можете використати метод then у відповіді, щоб виконати код після завершення обробки агентом. Це працює як для синхронних, так і для потокових відповідей:
public function handle(AgentPrompt $prompt, Closure $next)
{
return $next($prompt)->then(function (AgentResponse $response) {
Log::info('Agent responded', ['text' => $response->text]);
});
}
Анонімні агенти
Іноді ви можете захотіти швидко взаємодіяти з моделлю без створення окремого класу агента. Ви можете створити разового, анонімного агента за допомогою функції agent:
use function Laravel\Ai\{agent}; $response = agent( instructions: 'Ви є експертом у розробці програмного забезпечення.', messages: [], tools: [], )->prompt('Розкажіть мені про Laravel')
Анонімні агенти також можуть створювати структурований вивід:
use Illuminate\Contracts\JsonSchema\JsonSchema; use function Laravel\Ai\{agent}; $response = agent( schema: fn (JsonSchema $schema) => [ 'number' => $schema->integer()->required(), ], )->prompt('Згенерувати випадкове число менше 100')
Конфігурація агента
Ви можете налаштувати параметри генерації тексту для агента за допомогою PHP-атрибутів. Доступні такі атрибути:
MaxSteps: Максимальна кількість кроків, які агент може зробити під час використання інструментів.MaxTokens: Максимальна кількість токенів, яку модель може згенерувати.Модель: Модель, яку повинен використовувати агент.Провайдер: AI-провайдер (або провайдери для резервування), які використовуються для агента.Temperature: Температура вибірки, яка використовується для генерації (від 0.0 до 1.0).Тайм-аут: HTTP тайм-аут у секундах для запитів агента (за замовчуванням: 60).UseCheapestModel: Використовуйте найдешевшу текстову модель провайдера для оптимізації витрат.UseSmartestModel: Використовуйте найпотужнішу текстову модель провайдера для складних завдань.
<?php
namespace App\Ai\Agents;
use Laravel\Ai\Attributes\MaxSteps;
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Model;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Attributes\Temperature;
use Laravel\Ai\Attributes\Timeout;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;
#[Provider(Lab::Anthropic)]
#[Model('claude-haiku-4-5-20251001')]
#[MaxSteps(10)]
#[MaxTokens(4096)]
#[Temperature(0.7)]
#[Timeout(120)]
class SalesCoach implements Agent
{
use Promptable;
// ...
}
Атрибути UseCheapestModel та UseSmartestModel дозволяють автоматично вибирати найбільш економічну або найпотужнішу модель для заданого провайдера без вказування імені моделі. Це корисно, коли ви хочете оптимізувати витрати або можливості серед різних провайдерів:
use Laravel\Ai\Attributes\UseCheapestModel; use Laravel\Ai\Attributes\UseSmartestModel; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Promptable; #[UseCheapestModel] class SimpleSummarizer implements Agent { use Promptable; // Використовуватиме найдешевшу модель (наприклад, Haiku)... } #[UseSmartestModel] class ComplexReasoner implements Agent { use Promptable; // Використовуватиме найпотужнішу модель (наприклад, Opus)... }
Зображення
Клас Laravel\Ai\Image може бути використаний для створення зображень за допомогою провайдерів openai, gemini або xai:
use Laravel\Ai\Image; $image = Image::of('Пончик, що лежить на кухонній стільниці')->generate(); $rawContent = (string) $image;
Методи square, portrait та landscape можна використовувати для керування співвідношенням сторін зображення, а метод quality дозволяє вказати моделі бажану якість фінального зображення (high, medium, low). Метод timeout можна використовувати для визначення HTTP-тайм-ауту в секундах:
use Laravel\Ai\Image; $image = Image::of('Пончик, що лежить на кухонній стільниці') ->quality('high') ->landscape() ->timeout(120) ->generate();
Ви можете додати референсні зображення за допомогою методу attachments:
use Laravel\Ai\Files; use Laravel\Ai\Image; $image = Image::of('Оновіть цю мою фотографію, щоб вона була в стилі імпресіоністського живопису.') ->attachments([ Files\Image::fromStorage('photo.jpg'), // Files\Image::fromPath('/home/laravel/photo.jpg'), // Files\Image::fromUrl('https://example.com/photo.jpg'), // $request->file('photo'), ]) ->landscape() ->generate();
Згенеровані зображення можна легко зберігати на типовому диску, налаштованому у файлі конфігурації вашого застосунку config/filesystems.php:
$image = Image::of('Пончик, що лежить на кухонній стільниці'); $path = $image->store(); $path = $image->storeAs('image.jpg'); $path = $image->storePublicly(); $path = $image->storePubliclyAs('image.jpg');
Генерацію зображень також можна поставити в чергу:
use Laravel\Ai\Image; use Laravel\Ai\Responses\ImageResponse; Image::of('Пончик, що лежить на кухонній стільниці') ->portrait() ->queue() ->then(function (ImageResponse $image) { $path = $image->store(); // ... });
Аудіо
Клас Laravel\Ai\Audio може бути використаний для створення аудіо з вказаного тексту:
use Laravel\Ai\Audio; $audio = Audio::of('Я люблю програмувати на Laravel.')->generate(); $rawContent = (string) $audio;
Методи male, female та voice можна використовувати для визначення голосу згенерованого аудіо:
$audio = Audio::of('Я люблю програмувати на Laravel.') ->female() ->generate(); $audio = Audio::of('Я люблю програмувати на Laravel.') ->voice('voice-id-or-name') ->generate();
Аналогічно, метод instructions може бути використаний для динамічного інструктування моделі щодо того, як має звучати згенероване аудіо:
$audio = Audio::of('Я люблю програмувати на Laravel.') ->female() ->instructions('Сказано як пірат') ->generate();
Згенероване аудіо можна легко зберігати на типовому диску, налаштованому у файлі конфігурації вашого застосунку config/filesystems.php:
$audio = Audio::of('Я люблю програмувати на Laravel.')->generate(); $path = $audio->store(); $path = $audio->storeAs('audio.mp3'); $path = $audio->storePublicly(); $path = $audio->storePubliclyAs('audio.mp3');
Генерацію аудіо також можна поставити в чергу:
use Laravel\Ai\Audio; use Laravel\Ai\Responses\AudioResponse; Audio::of('Я люблю програмувати на Laravel.') ->queue() ->then(function (AudioResponse $audio) { $path = $audio->store(); // ... });
Транскрипції
Клас Laravel\Ai\Transcription може бути використаний для створення транскрипції заданого аудіо:
use Laravel\Ai\Transcription;
$transcript = Transcription::fromPath('/home/laravel/audio.mp3')->generate();
$transcript = Transcription::fromStorage('audio.mp3')->generate();
$transcript = Transcription::fromUpload($request->file('audio'))->generate();
return (string) $transcript;
Метод diarize можна використовувати, щоб вказати, що ви бажаєте отримати у відповіді діаризований транскрипт разом із сирим текстовим транскриптом, що дозволяє отримати доступ до сегментованого транскрипту за спікерами:
$transcript = Transcription::fromStorage('audio.mp3')
->diarize()
->generate();
Генерацію транскрипції також можна поставити в чергу:
use Laravel\Ai\Transcription;
use Laravel\Ai\Responses\TranscriptionResponse;
Transcription::fromStorage('audio.mp3')
->queue()
->then(function (TranscriptionResponse $transcript) {
// ...
});
Вбудовування
Ви можете легко згенерувати векторні вбудовування для будь-якого рядка за допомогою нового методу toEmbeddings, який доступний через клас Stringable у Laravel:
use Illuminate\Support\Str; $embeddings = Str::of('У долині Напа є чудове вино.')->toEmbeddings();
Альтернативно, ви можете використати клас Embeddings, щоб згенерувати embeddings для декількох вхідних даних одночасно:
use Laravel\Ai\Embeddings; $response = Embeddings::for([ 'У долині Напа є чудове вино.', 'Laravel це PHP фреймворк.', ])->generate(); $response->embeddings; // [[0.123, 0.456, ...], [0.789, 0.012, ...]]
Ви можете вказати розміри та провайдера для вбудовувань:
$response = Embeddings::for(['У долині Напа є чудове вино.']) ->dimensions(1536) ->generate(Lab::OpenAI, 'text-embedding-3-small');
Запити до векторних представлень
Після того як ви згенерували ембедінги, зазвичай ви зберігаєте їх у стовпці vector у вашій базі даних для подальшого запиту. Laravel надає нативну підтримку для стовпців vector у PostgreSQL через розширення pgvector. Щоб почати, визначте стовпець vector у вашій міграції, вказавши кількість вимірів:
Schema::ensureVectorExtensionExists();
Schema::create('documents', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->vector('embedding', dimensions: 1536);
$table->timestamps();
});
Ви також можете додати векторний індекс для пришвидшення пошуку за схожістю. При виклику index для векторної колонки Laravel автоматично створить HNSW-індекс з косинусною відстанню:
$table->vector('embedding', dimensions: 1536)->index();
У вашій Eloquent моделі слід привести стовпець vector до типу array:
protected function casts(): array
{
return [
'embedding' => 'array',
];
}
Щоб виконати запит на подібні записи, використовуйте метод whereVectorSimilarTo. Цей метод фільтрує результати за мінімальною косинусною схожістю (від 0.0 до 1.0, де 1.0 означає ідентичність) і впорядковує результати за схожістю:
use App\Models\Document;
$documents = Document::query()
->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4)
->limit(10)
->get();
Змінна $queryEmbedding може бути масивом чисел з плаваючою комою або звичайним рядком. Якщо передано рядок, Laravel автоматично згенерує для нього embeddings:
$documents = Document::query() ->whereVectorSimilarTo('embedding', 'кращі виноробні в долині Напа') ->limit(10) ->get();
Якщо вам потрібно більше контролю, ви можете використовувати низькорівневі методи whereVectorDistanceLessThan, selectVectorDistance та orderByVectorDistance незалежно:
$documents = Document::query()
->select('*')
->selectVectorDistance('embedding', $queryEmbedding, as: 'distance')
->whereVectorDistanceLessThan('embedding', $queryEmbedding, maxDistance: 0.3)
->orderByVectorDistance('embedding', $queryEmbedding)
->limit(10)
->get();
Якщо ви бажаєте надати агенту можливість виконувати пошук за схожістю як інструмент, перегляньте документацію інструменту Пошук за схожістю.
Векторні запити наразі підтримуються лише для підключень до PostgreSQL з використанням розширення pgvector.
Кешування векторних представлень
Генерацію embedding можна кешувати, щоб уникнути зайвих викликів API для ідентичних вхідних даних. Щоб увімкнути кешування, встановіть параметр конфігурації ai.caching.embeddings.cache у значення true:
'caching' => [
'embeddings' => [
'cache' => true,
'store' => env('CACHE_STORE', 'database'),
// ...
],
],
Коли кешування увімкнено, векторні представлення кешуються протягом 30 днів. Ключ кешу формується на основі провайдера, моделі, розмірності та вхідного контенту, що гарантує повернення кешованих результатів для ідентичних запитів, тоді як різні конфігурації генерують нові векторні представлення.
Ви також можете увімкнути кешування для конкретного запиту за допомогою методу cache, навіть якщо глобальне кешування вимкнено:
$response = Embeddings::for(['У долині Напа є чудове вино.']) ->cache() ->generate();
Ви можете вказати власну тривалість кешування у секундах:
$response = Embeddings::for(['У долині Напа є чудове вино.']) ->cache(seconds: 3600) // Кеш на 1 годину ->generate();
Метод Stringable toEmbeddings також приймає аргумент cache:
// Кеш із тривалістю за замовчуванням... $embeddings = Str::of('У долині Напа є чудове вино.')->toEmbeddings(cache: true); // Кеш на певний термін... $embeddings = Str::of('У долині Напа є чудове вино.')->toEmbeddings(cache: 3600);
Повторне ранжування
Перерейтинґ дозволяє змінювати порядок списку документів на основі їхньої релевантності до заданого запиту. Це корисно для покращення результатів пошуку за допомогою семантичного розуміння:
Клас Laravel\Ai\Reranking може бути використаний для повторного ранжування документів:
use Laravel\Ai\Reranking; $response = Reranking::of([ 'Django — веб-фреймворк на мові Python.', 'Laravel — це фреймворк для веб-додатків на PHP.', 'React — це бібліотека JavaScript для створення користувацьких інтерфейсів.', ])->rerank('PHP frameworks'); // Доступ до найкращих результатів... $response->first()->document; // "Laravel — це фреймворк для веб-додатків на PHP." $response->first()->score; // 0.95 $response->first()->index; // 1 (початкове положення)
Метод limit може бути використаний для обмеження кількості повернених результатів:
$response = Reranking::of($documents)
->limit(5)
->rerank('search query');
Пересортування колекцій
Для зручності колекції Laravel можна перевпорядкувати за допомогою макросу rerank. Перший аргумент вказує, які поля використовувати для перевпорядкування, а другий аргумент — це запит:
// Переранжування за одним полем... $posts = Post::all() ->rerank('body', 'Уроки Laravel'); // Переранжування за кількома полями (надсилається у форматі JSON)... $reranked = $posts->rerank(['title', 'body'], 'Уроки Laravel'); // Переранжування за допомогою закриття для створення документа... $reranked = $posts->rerank( fn ($post) => $post->title.': '.$post->body, 'Уроки Laravel' );
Ви також можете обмежити кількість результатів і вказати провайдера:
$reranked = $posts->rerank( by: 'content', query: 'Уроки Laravel', limit: 10, provider: Lab::Cohere );
Файли
Клас Laravel\Ai\Files або окремі класи файлів можна використовувати для зберігання файлів у вашого AI-провайдера для подальшого використання в розмовах. Це корисно для великих документів або файлів, до яких ви хочете звертатися кілька разів без повторного завантаження:
use Laravel\Ai\Files\Document; use Laravel\Ai\Files\Image; // Зберегти файл з локального шляху... $response = Document::fromPath('/home/laravel/document.pdf')->put(); $response = Image::fromPath('/home/laravel/photo.jpg')->put(); // Зберегти файл, який зберігається на диску файлової системи... $response = Document::fromStorage('document.pdf', disk: 'local')->put(); $response = Image::fromStorage('photo.jpg', disk: 'local')->put(); // Зберегти файл, який зберігається на віддаленому URL-адресі... $response = Document::fromUrl('https://example.com/document.pdf')->put(); $response = Image::fromUrl('https://example.com/photo.jpg')->put(); return $response->id;
Ви також можете зберігати необроблений вміст або завантажені файли:
use Laravel\Ai\Files; use Laravel\Ai\Files\Document; // Зберігати необроблений вміст... $stored = Document::fromString('Hello, World!', 'text/plain')->put(); // Зберегти завантажений файл... $stored = Document::fromUpload($request->file('document'))->put();
Після збереження файлу ви можете посилатися на файл під час генерування тексту через агентів замість повторного завантаження файлу:
use App\Ai\Agents\SalesCoach; use Laravel\Ai\Files; $response = (new SalesCoach)->prompt( 'Проаналізуйте доданий протокол продажів...' attachments: [ Files\Document::fromId('file-id') // Додати збережений документ... ] );
Щоб отримати раніше збережений файл, використовуйте метод get для екземпляра файлу:
use Laravel\Ai\Files\Document;
$file = Document::fromId('file-id')->get();
$file->id;
$file->mimeType();
Щоб видалити файл з провайдера, використовуйте метод delete:
Document::fromId('file-id')->delete();
За замовчуванням клас Files використовує стандартного AI-провайдера, налаштованого у файлі конфігурації вашого застосунку config/ai.php. Для більшості операцій ви можете вказати іншого провайдера, використовуючи аргумент provider:
$response = Document::fromPath(
'/home/laravel/document.pdf'
)->put(provider: Lab::Anthropic);
Використання збережених файлів у розмовах
Після того як файл було збережено у провайдера, ви можете посилатися на нього в розмовах агента за допомогою методу fromId у класах Document або Image:
use App\Ai\Agents\DocumentAnalyzer;
use Laravel\Ai\Files;
use Laravel\Ai\Files\Document;
$stored = Document::fromPath('/path/to/report.pdf')->put();
$response = (new DocumentAnalyzer)->prompt(
'Summarize this document.',
attachments: [
Document::fromId($stored->id),
],
);
Аналогічно, збережені зображення можна використовувати за допомогою класу Image:
use Laravel\Ai\Files; use Laravel\Ai\Files\Image; $stored = Image::fromPath('/path/to/photo.jpg')->put(); $response = (new ImageAnalyzer)->prompt( 'Що зображено на цьому зображенні?', attachments: [ Image::fromId($stored->id), ], );
Векторні сховища
Векторні сховища дозволяють створювати колекції файлів з можливістю пошуку, які можна використовувати для генерації з підкріпленням пошуком (RAG). Клас Laravel\Ai\Stores надає методи для створення, отримання та видалення векторних сховищ:
use Laravel\Ai\Stores; // Створити нове векторне сховище... $store = Stores::create('Knowledge Base'); // Створити сховище з додатковими параметрами... $store = Stores::create( name: 'Knowledge Base', description: 'Документація та довідкові матеріали.', expiresWhenIdleFor: days(30), ); return $store->id;
Щоб отримати існуюче сховище векторів за його ідентифікатором, використовуйте метод get:
use Laravel\Ai\Stores;
$store = Stores::get('store_id');
$store->id;
$store->name;
$store->fileCounts;
$store->ready;
Щоб видалити векторне сховище, використовуйте метод delete у класі Stores або у екземплярі сховища:
use Laravel\Ai\Stores; // Видалити за ID... Stores::delete('store_id'); // Або видалити через екземпляр сховища... $store = Stores::get('store_id'); $store->delete();
Додавання файлів до сховищ
Після того як у вас є векторне сховище, ви можете додати до нього файли за допомогою методу add. Файли, додані до сховища, автоматично індексуються для семантичного пошуку за допомогою інструменту провайдера пошуку файлів:
use Laravel\Ai\Files\Document; use Laravel\Ai\Stores; $store = Stores::get('store_id'); // Додати файл, який уже збережено у провайдера... $document = $store->add('file_id'); $document = $store->add(Document::fromId('file_id')); // Або зберегти та додати файл за один крок... $document = $store->add(Document::fromPath('/path/to/document.pdf')); $document = $store->add(Document::fromStorage('manual.pdf')); $document = $store->add($request->file('document')); $document->id; $document->fileId;
Зазвичай, при додаванні раніше збережених файлів до векторних сховищ, повернутий ідентифікатор документа буде відповідати раніше призначеному ідентифікатору файлу; однак деякі постачальники векторних сховищ можуть повертати новий, інший "ідентифікатор документа". Тому рекомендується завжди зберігати обидва ідентифікатори у вашій базі даних для подальшого використання.
Ви можете додавати метадані до файлів під час їх додавання до сховища. Ці метадані згодом можна використовувати для фільтрації результатів пошуку за допомогою інструменту пошуку файлів:
$store->add(Document::fromPath('/path/to/document.pdf'), metadata: [
'author' => 'Taylor Otwell',
'department' => 'Engineering',
'year' => 2026,
]);
Щоб видалити файл із сховища, використовуйте метод remove:
$store->remove('file_id');
Видалення файлу з векторного сховища не видаляє його з сховища файлів провайдера. Щоб видалити файл з векторного сховища та остаточно видалити його зі сховища файлів, використовуйте аргумент deleteFile:
$store->remove('file_abc123', deleteFile: true);
Перемикання на резервний
Під час створення запитів або генерації інших медіа ви можете надати масив провайдерів / моделей, щоб автоматично переключатися на резервного провайдера / модель у разі перебоїв у роботі сервісу або досягнення ліміту запитів у основного провайдера:
use App\Ai\Agents\SalesCoach; use Laravel\Ai\Image; $response = (new SalesCoach)->prompt( 'Проаналізуйте цей протокол продажів...', provider: [Lab::OpenAI, Lab::Anthropic], ); $image = Image::of('Пончик, що лежить на кухонній стільниці') ->generate(provider: [Lab::Gemini, Lab::xAI]);
Тестування
Агенти
Щоб підробити відповіді агента під час тестування, викличте метод fake у класі агента. Ви можете додатково передати масив відповідей або замикання:
use App\Ai\Agents\SalesCoach; use Laravel\Ai\Prompts\AgentPrompt; // Автоматично генерувати фіксовану відповідь для кожного промпту... SalesCoach::fake(); // Надати список відповідей на промпти... SalesCoach::fake([ 'First response', 'Second response', ]); // Динамічно обробляти відповіді на промпти залежно від вхідного промпту... SalesCoach::fake(function (AgentPrompt $prompt) { return 'Відповідь для: '.$prompt->prompt; });
Коли викликається Agent::fake() для агента, який повертає структурований вивід, Laravel автоматично згенерує фейкові дані, що відповідають визначеній схемі виводу вашого агента.
Після запиту до агента, ви можете робити твердження щодо отриманих підказок:
use Laravel\Ai\Prompts\AgentPrompt; SalesCoach::assertPrompted('Проаналізувати це...'); SalesCoach::assertPrompted(function (AgentPrompt $prompt) { return $prompt->contains('Проаналізувати'); }); SalesCoach::assertNotPrompted('Відсутній промпт'); SalesCoach::assertNeverPrompted();
Для викликів агентів у черзі використовуйте методи перевірки для черги:
use Laravel\Ai\QueuedAgentPrompt; SalesCoach::assertQueued('Проаналізувати це...'); SalesCoach::assertQueued(function (QueuedAgentPrompt $prompt) { return $prompt->contains('Проаналізувати'); }); SalesCoach::assertNotQueued('Відсутній промпт'); SalesCoach::assertNeverQueued();
Щоб гарантувати, що всі виклики агентів мають відповідну фейкову відповідь, ви можете використати preventStrayPrompts. Якщо агент викликається без визначеної фейкової відповіді, буде згенеровано виключення:
SalesCoach::fake()->preventStrayPrompts();
Зображення
Генерацію зображень можна підробити, викликавши метод fake у класі Image. Після підробки зображення можна виконувати різні перевірки щодо зафіксованих підказок генерації зображень:
use Laravel\Ai\Image; use Laravel\Ai\Prompts\ImagePrompt; use Laravel\Ai\Prompts\QueuedImagePrompt; // Автоматично генерувати фіксовану відповідь для кожного промпту... Image::fake(); // Надати список відповідей на промпти... Image::fake([ base64_encode($firstImage), base64_encode($secondImage), ]); // Динамічно обробляти відповіді на промпти залежно від вхідного промпту... Image::fake(function (ImagePrompt $prompt) { return base64_encode('...'); });
Після створення зображень ви можете робити твердження щодо отриманих підказок:
Image::assertGenerated(function (ImagePrompt $prompt) { return $prompt->contains('sunset') && $prompt->isLandscape(); }); Image::assertNotGenerated('Відсутній промпт'); Image::assertNothingGenerated();
Для поставлених у чергу генерацій зображень використовуйте методи перевірки черги:
Image::assertQueued( fn (QueuedImagePrompt $prompt) => $prompt->contains('sunset') ); Image::assertNotQueued('Відсутній промпт'); Image::assertNothingQueued();
Щоб гарантувати, що для всіх згенерованих зображень існує відповідна фейкова відповідь, ви можете використати preventStrayImages. Якщо зображення буде згенеровано без визначеної фейкової відповіді, буде викликано виключення:
Image::fake()->preventStrayImages();
Аудіо
Аудіогенерації можуть бути підроблені шляхом виклику методу fake у класі Audio. Після підробки аудіо можна виконувати різні перевірки щодо записаних запитів на генерацію аудіо:
use Laravel\Ai\Audio; use Laravel\Ai\Prompts\AudioPrompt; use Laravel\Ai\Prompts\QueuedAudioPrompt; // Автоматично генерувати фіксовану відповідь для кожного промпту... Audio::fake(); // Надати список відповідей на промпти... Audio::fake([ base64_encode($firstAudio), base64_encode($secondAudio), ]); // Динамічно обробляти відповіді на промпти залежно від вхідного промпту... Audio::fake(function (AudioPrompt $prompt) { return base64_encode('...'); });
Після створення аудіо ви можете робити твердження щодо отриманих підказок:
Audio::assertGenerated(function (AudioPrompt $prompt) { return $prompt->contains('Привіт') && $prompt->isFemale(); }); Audio::assertNotGenerated('Відсутній промпт'); Audio::assertNothingGenerated();
Для поставлених у чергу генерацій аудіо використовуйте методи перевірки черги:
Audio::assertQueued( fn (QueuedAudioPrompt $prompt) => $prompt->contains('Hello') ); Audio::assertNotQueued('Відсутній промпт'); Audio::assertNothingQueued();
Щоб гарантувати, що всі аудіо-генерації мають відповідну фейкову відповідь, ви можете використати preventStrayAudio. Якщо аудіо згенеровано без визначеної фейкової відповіді, буде згенеровано виняток:
Audio::fake()->preventStrayAudio();
Транскрипції
Генерації транскрипцій можуть бути підроблені шляхом виклику методу fake у класі Transcription. Після підробки транскрипції можна виконувати різні перевірки щодо записаних підказок генерації транскрипції:
use Laravel\Ai\Transcription; use Laravel\Ai\Prompts\TranscriptionPrompt; use Laravel\Ai\Prompts\QueuedTranscriptionPrompt; // Автоматично генерувати фіксовану відповідь для кожного промпту... Transcription::fake(); // Надати список відповідей на промпти... Transcription::fake([ 'Перший текст транскрипції.', 'Другий текст транскрипції.', ]); // Динамічно обробляти відповіді на промпти залежно від вхідного промпту... Transcription::fake(function (TranscriptionPrompt $prompt) { return 'Транскрибований текст...'; });
Після створення транскрипцій ви можете робити припущення щодо отриманих підказок:
Transcription::assertGenerated(function (TranscriptionPrompt $prompt) {
return $prompt->language === 'en' && $prompt->isDiarized();
});
Transcription::assertNotGenerated(
fn (TranscriptionPrompt $prompt) => $prompt->language === 'fr'
);
Transcription::assertNothingGenerated();
Для поставлених у чергу генерацій транскрипцій використовуйте методи перевірки черги:
Transcription::assertQueued(
fn (QueuedTranscriptionPrompt $prompt) => $prompt->isDiarized()
);
Transcription::assertNotQueued(
fn (QueuedTranscriptionPrompt $prompt) => $prompt->language === 'fr'
);
Transcription::assertNothingQueued();
Щоб переконатися, що всі згенеровані транскрипції мають відповідну фейкову відповідь, ви можете використати preventStrayTranscriptions. Якщо транскрипція згенерована без визначеної фейкової відповіді, буде згенеровано виключення:
Transcription::fake()->preventStrayTranscriptions();
Вбудовування
Генерацію embeddings можна підробити, викликавши метод fake у класі Embeddings. Після підробки embeddings можна виконувати різні перевірки щодо збережених запитів генерації embeddings:
use Laravel\Ai\Embeddings; use Laravel\Ai\Prompts\EmbeddingsPrompt; use Laravel\Ai\Prompts\QueuedEmbeddingsPrompt; // Автоматично генерувати фіктивні векторні представлення потрібної розмірності для кожного промпту... Embeddings::fake(); // Надати список відповідей на промпти... Embeddings::fake([ [$firstEmbeddingVector], [$secondEmbeddingVector], ]); // Динамічно обробляти відповіді на промпти залежно від вхідного промпту... Embeddings::fake(function (EmbeddingsPrompt $prompt) { return array_map( fn () => Embeddings::fakeEmbedding($prompt->dimensions), $prompt->inputs ); });
Після створення embedding, ви можете робити припущення щодо отриманих підказок:
Embeddings::assertGenerated(function (EmbeddingsPrompt $prompt) {
return $prompt->contains('Laravel') && $prompt->dimensions === 1536;
});
Embeddings::assertNotGenerated(
fn (EmbeddingsPrompt $prompt) => $prompt->contains('Other')
);
Embeddings::assertNothingGenerated();
Для генерації embeddings у черзі використовуйте методи перевірки для черги:
Embeddings::assertQueued(
fn (QueuedEmbeddingsPrompt $prompt) => $prompt->contains('Laravel')
);
Embeddings::assertNotQueued(
fn (QueuedEmbeddingsPrompt $prompt) => $prompt->contains('Other')
);
Embeddings::assertNothingQueued();
Щоб гарантувати, що всі генерації embeddings мають відповідну фейкову відповідь, ви можете використати preventStrayEmbeddings. Якщо embeddings генеруються без визначеної фейкової відповіді, буде згенеровано виключення:
Embeddings::fake()->preventStrayEmbeddings();
Повторне ранжування
Операції повторного ранжування можуть бути підроблені шляхом виклику методу fake у класі Reranking:
use Laravel\Ai\Reranking; use Laravel\Ai\Prompts\RerankingPrompt; use Laravel\Ai\Responses\Data\RankedDocument; // Автоматично генерувати фіктивні повторно ранжовані відповіді... Reranking::fake(); // Надавати власні відповіді... Reranking::fake([ [ new RankedDocument(index: 0, document: 'First', score: 0.95), new RankedDocument(index: 1, document: 'Second', score: 0.80), ], ]);
Після повторного ранжування ви можете робити твердження щодо виконаних операцій:
Reranking::assertReranked(function (RerankingPrompt $prompt) {
return $prompt->contains('Laravel') && $prompt->limit === 5;
});
Reranking::assertNotReranked(
fn (RerankingPrompt $prompt) => $prompt->contains('Django')
);
Reranking::assertNothingReranked();
Файли
Операції з файлами можна підробити, викликавши метод fake у класі Files:
use Laravel\Ai\Files;
Files::fake();
Після імітації операцій з файлами ви можете робити твердження щодо завантажень і видалень, які відбулися:
use Laravel\Ai\Contracts\Files\StorableFile; use Laravel\Ai\Files\Document; // Зберігати файли... Document::fromString('Привіт, Laravel!', mimeType: 'text/plain') ->as('hello.txt') ->put(); // Виконувати перевірки... Files::assertStored(fn (StorableFile $file) => (string) $file === 'Привіт, Laravel!' && $file->mimeType() === 'text/plain'; ); Files::assertNotStored(fn (StorableFile $file) => (string) $file === 'Привіт, World!' ); Files::assertNothingStored();
Для перевірки видалення файлів ви можете передати ID файлу:
Files::assertDeleted('file-id');
Files::assertNotDeleted('file-id');
Files::assertNothingDeleted();
Векторні сховища
Операції з векторним сховищем можна підробити, викликавши метод fake у класі Stores. Підробка сховищ також автоматично підробить операції з файлами:
use Laravel\Ai\Stores;
Stores::fake();
Після імітації операцій зі сховищем ви можете виконувати перевірки щодо сховищ, які були створені або видалені:
use Laravel\Ai\Stores; // Створити сховище... $store = Stores::create('Knowledge Base'); // Make assertions... Stores::assertCreated('Knowledge Base'); Stores::assertCreated(fn (string $name, ?string $description) => $name === 'Knowledge Base' ); Stores::assertNotCreated('Other Store'); Stores::assertNothingCreated();
Для перевірки видалення сховища ви можете вказати ID сховища:
Stores::assertDeleted('store_id');
Stores::assertNotDeleted('other_store_id');
Stores::assertNothingDeleted();
Щоб перевірити, чи були файли додані або видалені зі сховища, використовуйте методи перевірки на відповідному екземплярі Store:
Stores::fake(); $store = Stores::get('store_id'); // Додати / видалити файли... $store->add('added_id'); $store->remove('removed_id'); // Виконати перевірки... $store->assertAdded('added_id'); $store->assertRemoved('removed_id'); $store->assertNotAdded('other_file_id'); $store->assertNotRemoved('other_file_id');
Якщо файл зберігається у файловому сховищі провайдера та додається до векторного сховища в тому ж запиті, ви можете не знати ідентифікатор провайдера файлу. У цьому випадку ви можете передати замикання до методу assertAdded, щоб перевірити вміст доданого файлу:
use Laravel\Ai\Contracts\Files\StorableFile; use Laravel\Ai\Files\Document; $store->add(Document::fromString('Привіт, World!', 'text/plain')->as('hello.txt')); $store->assertAdded(fn (StorableFile $file) => $file->name() === 'hello.txt'); $store->assertAdded(fn (StorableFile $file) => $file->content() === 'Привіт, World!');
Події
Laravel AI SDK надсилає різноманітні події, зокрема:
AddingFileToStoreAgentPromptedAgentStreamedAudioGeneratedCreatingStoreEmbeddingsGeneratedFileAddedToStoreFileDeletedFileRemovedFromStoreFileStoredGeneratingAudioGeneratingEmbeddingsGeneratingImageGeneratingTranscriptionImageGeneratedInvokingToolPromptingAgentRemovingFileFromStoreRerankedRerankingStoreCreatedStoringFileStreamingAgentToolInvokedTranscriptionGenerated
Ви можете прослуховувати будь-яку з цих подій, щоб реєструвати або зберігати інформацію про використання AI SDK.
