Laravel 13: AI SDK, PHP Attributes và những thay đổi đáng chú ý — hoatq.dev

cat blog/.md

Laravel 13: AI SDK, PHP Attributes và những thay đổi đáng chú ý

date: tags: laravel, php, ai, backend

Laravel 13 đã chính thức ra mắt ngày 17/03/2026. Taylor Otwell announce tại Laracon EU với tagline khá tự tin: “zero breaking changes, 10 phút upgrade”.

Sau gần một tháng dùng thử trong side project, mình thấy bản này không phải kiểu release “thêm vài helper rồi bump version”. Có những thay đổi thật sự ảnh hưởng đến cách viết code hằng ngày — đặc biệt là PHP Attributes và AI SDK.

Bài này mình tổng hợp những thứ đáng chú ý nhất, kèm code example thực tế.

Yêu cầu: PHP 8.3+

Điều đầu tiên cần biết: Laravel 13 yêu cầu PHP 8.3 trở lên. Nếu server hoặc Docker image của bạn đang chạy 8.2, cần upgrade trước khi nghĩ đến chuyện gì khác.

php -v
# PHP 8.3.x trở lên là OK

1. PHP Attributes thay thế class properties

Đây là thay đổi mình thích nhất. Thay vì khai báo $table, $fillable, $hidden rải rác trong model, giờ bạn có thể dùng PHP attributes gọn gàng hơn nhiều.

Trước (Laravel 12):

class Product extends Model
{
    protected $table = 'products';
    protected $fillable = ['name', 'price', 'sku', 'description'];
    protected $hidden = ['internal_notes'];
    protected $casts = [
        'price' => 'decimal:2',
        'metadata' => 'array',
        'is_active' => 'boolean',
    ];
}

Sau (Laravel 13):

use Illuminate\Database\Eloquent\Attributes\{Table, Fillable, Hidden, Cast};

#[Table('products')]
#[Fillable('name', 'price', 'sku', 'description')]
#[Hidden('internal_notes')]
#[Cast('price', 'decimal:2')]
#[Cast('metadata', 'array')]
#[Cast('is_active', 'boolean')]
class Product extends Model
{
    // Model sạch hơn hẳn — logic ở đây, config ở attributes
}

Attributes được hỗ trợ ở hơn 15 nơi trong framework, không chỉ model. Controller cũng dùng được:

use Illuminate\Routing\Attributes\{Middleware, Authorize};

#[Middleware('auth:sanctum')]
#[Authorize('admin')]
class AdminProductController extends Controller
{
    // Không cần $this->middleware() trong constructor nữa
}

Job queue cũng vậy:

use Illuminate\Queue\Attributes\{Tries, Backoff, Timeout};

#[Tries(3)]
#[Backoff(30)]
#[Timeout(120)]
class ProcessOrderJob implements ShouldQueue
{
    public function handle(): void
    {
        // Job config nằm ngay trên class declaration
    }
}

Điều hay là cách cũ vẫn hoạt động. Attributes là optional — bạn migrate dần được, không bắt buộc refactor hết cùng lúc.

2. Laravel AI SDK — first-party, production-stable

Đây là feature “headline” của bản release này. Laravel AI SDK chuyển từ beta sang stable cùng ngày ra mắt v13, trở thành first-party package chính thức.

Nó cung cấp một interface thống nhất, provider-agnostic cho:

  • Text generation
  • Tool-calling agents
  • Image generation
  • Audio synthesis
  • Embeddings
  • Vector store integrations
use Laravel\AI\Facades\AI;

// Text generation — đổi provider chỉ cần đổi config
$response = AI::text('Tóm tắt đơn hàng này cho khách hàng', [
    'context' => $order->toArray(),
]);

echo $response->text;

Phần mình ấn tượng nhất là agent với tool-calling. Bạn define agent bằng attributes:

use Laravel\AI\Agent;
use Laravel\AI\Attributes\{Provider, Model, MaxSteps, Temperature};
use Laravel\AI\Contracts\AgentInterface;

#[Provider('anthropic')]
#[Model('claude-haiku-4-5-20251001')]
#[MaxSteps(10)]
#[Temperature(0.7)]
class CustomerSupportAgent implements AgentInterface
{
    public function instructions(): string
    {
        return 'Bạn là trợ lý hỗ trợ khách hàng cho cửa hàng online...';
    }

    public function tools(): array
    {
        return [
            new LookupOrderTool(),
            new CheckInventoryTool(),
            new CreateTicketTool(),
        ];
    }
}

Rồi gọi agent chỉ cần:

$result = AI::agent(new CustomerSupportAgent())
    ->run('Đơn hàng ORD-123 của tôi đang ở đâu?');

Trước đây, muốn làm điều này phải dùng package bên thứ ba hoặc tự wrap API. Giờ Laravel cung cấp sẵn, tích hợp với queue, events, logging — đúng kiểu “Laravel way”.

3. Vector search với pgvector

Laravel 13 hỗ trợ native vector query cho semantic search. Nếu bạn dùng PostgreSQL + pgvector, giờ có thể query similarity search trực tiếp từ Eloquent:

use Laravel\AI\Facades\AI;

// Tạo embedding từ text
$embedding = AI::embedding('Áo thun nam cotton màu xanh');

// Tìm sản phẩm tương tự
$products = Product::query()
    ->nearestNeighbors('description_embedding', $embedding, 10)
    ->where('is_active', true)
    ->get();

Đây là game changer cho ai đang xây dựng tính năng search “thông minh”. Thay vì chỉ tìm chính xác từ khóa, user gõ “áo mặc đi biển” vẫn có thể tìm được “áo thun cotton thoáng mát” — vì embedding hiểu ngữ nghĩa, không chỉ text matching.

4. Queue routing tập trung

Trước đây, config queue cho job nằm rải rác — hoặc trong class, hoặc tại chỗ dispatch. Laravel 13 thêm Queue::route() để quản lý tập trung:

// AppServiceProvider.php
use Illuminate\Support\Facades\Queue;

public function boot(): void
{
    Queue::route(ProcessOrderJob::class, 'orders', 'sqs');
    Queue::route(SendNotificationJob::class, 'notifications', 'redis');
    Queue::route(GenerateReportJob::class, 'reports', 'database');
}

Giờ muốn biết job nào chạy ở queue nào, chỉ cần mở service provider — một nơi duy nhất. Với hệ thống lớn có 20-30 job classes, đây là quality-of-life improvement rất đáng giá.

5. JSON:API support first-party

Nếu bạn từng dùng spatie/laravel-json-api hoặc tự viết resource class theo JSON:API spec, giờ Laravel xử lý sẵn:

use Illuminate\Http\Resources\Json\JsonApiResource;

class ProductResource extends JsonApiResource
{
    public function toAttributes($request): array
    {
        return [
            'name' => $this->name,
            'price' => $this->price,
            'sku' => $this->sku,
        ];
    }

    public function toRelationships($request): array
    {
        return [
            'category' => CategoryResource::make($this->whenLoaded('category')),
        ];
    }
}

Tự động handle serialization, sparse fieldsets, relationship inclusion, và response headers chuẩn spec. Ai đang build API cho mobile app hoặc SPA sẽ thấy tiện hơn hẳn.

6. Những cải tiến nhỏ nhưng hay

Cache::touch() — extend TTL mà không cần get rồi set lại:

// Trước: phải get value rồi put lại
$value = Cache::get('user:123:session');
Cache::put('user:123:session', $value, 3600);

// Laravel 13: một dòng
Cache::touch('user:123:session', 3600);

Reverb database driver — chạy WebSocket broadcasting mà không cần Redis, dùng database bình thường. Tiện cho project nhỏ hoặc môi trường không có Redis.

Passkey authentication — hỗ trợ WebAuthn/passkeys trong starter kit, giảm phụ thuộc vào password truyền thống.

Upgrade từ Laravel 12: “zero breaking changes” nhưng…

Taylor nói “zero breaking changes” và phần lớn đúng — application code thường không cần sửa gì. Nhưng có vài edge case cần lưu ý:

1. Model boot restriction

Tạo model instance trong boot() method giờ sẽ throw LogicException:

// ❌ Laravel 13 sẽ throw error
protected static function boot()
{
    parent::boot();
    $default = new static(); // LogicException!
}

2. MySQL DELETE with JOIN

Trước đây ORDER BY / LIMIT trên joined deletes bị ignore âm thầm. Giờ chúng được include trong SQL — có thể gây lỗi trên một số MySQL/MariaDB variant.

3. Cache serialization

Nếu cache chứa arbitrary objects, cần migrate sang explicit class allow-list hoặc dùng array thay vì object.

Quy trình upgrade mình khuyên:

# 1. Update composer.json
composer require laravel/framework:^13.0

# 2. Chạy test suite
php artisan test

# 3. Check deprecated warnings
php artisan serve --env=testing
# Review log cho deprecation notices

# 4. Update config nếu cần
php artisan config:publish

Với project mình, upgrade mất khoảng 15 phút — chủ yếu là chờ composer resolve dependencies.

Có nên upgrade ngay?

Tùy context:

  • Project mới: dùng Laravel 13 luôn, không có lý do gì chọn 12.
  • Project đang chạy production: Laravel 12 vẫn được support. Upgrade khi có thời gian test kỹ, không cần vội.
  • Muốn dùng AI SDK hoặc vector search: đây là lý do chính đáng để upgrade sớm.

Cá nhân mình thấy bản này có chất lượng cao. “Zero breaking changes” là cam kết đúng đắn — giúp ecosystem ổn định và giảm nỗi đau upgrade mà PHP developer đã quá quen.

AI SDK là tín hiệu rõ ràng rằng Laravel đang nghiêm túc với AI/ML integration, không chỉ trend nhất thời. Và PHP attributes thì đơn giản là viết code sạch hơn — ai mà không thích?

Happy coding!

// reactions


cat comments.log


hoatq@dev : ~/blog $