Laravel Packages

LayaPHP: Self-Hosted Text Classification for PHP and Laravel

Published
LayaPHP: Self-Hosted Text Classification for PHP and Laravel image

Laya is an open-source, non-autoregressive decision model built for quick categorical choices and risk checks. Given text, it can choose a label, assign a score on a scale you define, or return a yes/no probability without generating a conversational answer. TypeSafe's Jev is built for the same kind of decisions and supports those three question types.

While Jev runs on TypeSafe's servers and is available through Laravel's AI SDK classification API, Laya runs on your infrastructure, where you pay for compute without a per-call API charge. Its laya-serve process accepts Jev-style requests at /v1/systemone.

LayaPHP, by Marc Reichel, is a PHP client for Laya. It sends text to laya-serve and returns typed PHP answers with confidence scores. Reichel says he has not yet tested the client with hosted Jev, despite the shared endpoint.

Classifying a product review

For a store that accepts product reviews, LayaPHP could be used to flag spam and abuse for moderation while recording each review's sentiment. predict() asks all three questions in one request:

use MarcReichel\Laya\Laya;
use MarcReichel\Laya\Question;
 
function classifyReview(Laya $laya, string $body): array
{
$result = $laya->predict($body, [
'spam' => Question::yesNo('Is this review spam or an advertisement?'),
'abuse' => Question::yesNo('Does this review contain insults, hate speech, or threats?'),
'sentiment' => Question::choice('What is the overall sentiment of this review?', [
'positive' => 'praises the product',
'neutral' => 'describes the product without clear praise or criticism',
'negative' => 'criticises the product',
]),
]);
 
$spam = $result->yesNo('spam');
$abuse = $result->yesNo('abuse');
$sentiment = $result->choice('sentiment');
 
$needsReview = $spam->yes()
|| $abuse->yes()
|| min($spam->answerConfidence, $abuse->answerConfidence, $sentiment->answerConfidence) < 0.7;
 
return [
'queue' => $needsReview ? 'manual-review' : 'publish',
'sentiment' => $sentiment->choice,
];
}

yes() uses a 0.5 probability threshold by default. The separate answerConfidence value measures confidence in each answer. The code sends flagged reviews and answers below 0.7 to a person. I picked that number for this example; however, before letting Laya approve reviews, it is a good idea to compare its decisions with reviews your moderators have already handled.

Consider the review "The product works, but delivery took too long." In a local test with Laya 0.3.23, the code sent it to manual review: Laya chose a negative sentiment with confidence below 0.7. An advertisement and a review that insulted the staff also went to manual review. A newer Laya model could classify these examples differently.

Question::score() handles scales such as "not urgent," "soon," and "blocking," with the levels listed from lowest to highest. The answer includes the most likely level and a numeric score. The package's decide() method maps questions defined with PHP attributes onto enum, integer, and boolean constructor properties.

Running Laya and testing the integration

LayaPHP requires PHP 8.4 or newer and a PSR-18 HTTP client like Guzzle:

composer require marcreichel/laya-php guzzlehttp/guzzle

The package repository includes a Docker Compose file for laya-serve. From that repository, run docker compose up -d --wait to start the server at http://localhost:8000. The first classification request downloads about 1 GB of model weights into a Docker volume.

With the server running, Laravel 13 or newer automatically discovers the package's service provider. Add LAYA_URL=http://localhost:8000 to .env, and you can inject Laya into a job or service. The package's php artisan laya:health command checks that the server is reachable. The same client works outside Laravel: new Laya('http://localhost:8000') connects to that server directly.

The built-in Laya::fake() lets tests check the review-routing code without starting the model. Testing whether Laya classifies the reviews correctly still requires a running server.

The LayaPHP repository has the full setup instructions and runnable examples.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Sponsored

laravelcloud logo
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud

The latest

View all →
Securing Filament plugins with Plumb image

Securing Filament plugins with Plumb

Read article
WhenMounted and BigInt Props in Inertia.js v3.8 image

WhenMounted and BigInt Props in Inertia.js v3.8

Read article
Postcodes for Laravel: GB Postcode Lookup and Geography Data image

Postcodes for Laravel: GB Postcode Lookup and Geography Data

Read article
Laravel 14 Adds a defaults() Method to Eloquent Models image

Laravel 14 Adds a defaults() Method to Eloquent Models

Read article
Laravel AI SDK and Laravel MCP Security Fixes: Update Now image

Laravel AI SDK and Laravel MCP Security Fixes: Update Now

Read article
Mailbox for Laravel: Preview and Test Rendered Email image

Mailbox for Laravel: Preview and Test Rendered Email

Read article