Практика: первый AI-агент
Соберём всё вместе: агент поддержки с tools, structured output и стримингом.
Шаг 1: Агент
php artisan make:agent SupportAgent --structured
namespace App\Ai\Agents;
use App\Ai\Tools\LookupOrder;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;
class SupportAgent implements Agent, HasTools, HasStructuredOutput
{
use Promptable;
public function instructions(): string
{
return 'Ты — агент поддержки. Помогай с заказами. Будь вежлив.';
}
public function tools(): array
{
return [new LookupOrder];
}
public function schema(JsonSchema $schema): array
{
return [
'answer' => $schema->string()->required(),
'category' => $schema->string()->enum(['billing', 'technical', 'general'])->required(),
];
}
}
Шаг 2: Tool
php artisan make:tool LookupOrder
namespace App\Ai\Tools;
use App\Models\Order;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Stringable;
class LookupOrder implements Tool
{
public function description(): Stringable|string
{
return 'Находит заказ по ID.';
}
public function schema(JsonSchema $schema): array
{
return [
'order_id' => $schema->integer()->required(),
];
}
public function handle(array $arguments): string
{
$order = Order::find($arguments['order_id']);
return $order
? "Заказ #{$order->id}: {$order->status}"
: 'Заказ не найден';
}
}
Шаг 3: Route
use App\Ai\Agents\SupportAgent;
Route::post('/support', function (Request $request) {
$response = SupportAgent::make(user: $request->user())
->prompt($request->input('message'));
return response()->json([
'answer' => $response['answer'],
'category' => $response['category'],
]);
});
Шаг 4: Streaming route
Route::get('/support/stream', function (Request $request) {
return SupportAgent::make(user: $request->user())
->stream($request->input('message'))
->usingVercelDataProtocol();
});
Шаг 5: Queue для длинных
Route::post('/support/async', function (Request $request) {
SupportAgent::make(user: $request->user())
->queue($request->input('message'))
->then(fn ($response) => $request->user()->notify(new SupportDone($response)));
return response()->json(['status' => 'queued']);
});
Итоги
- Агент с tools и structured output
- Tool с валидацией
- Route для sync, stream, queue
- Использование в реальном приложении