Why AI belongs in every modern product
Artificial intelligence is no longer a buzzword reserved for data‑science teams. Startups and agencies are expected to ship features such as text classification, image recognition, or recommendation engines within weeks, not months. Laravel gives you a solid foundation for rapid delivery, but the real challenge is wiring AI services into that foundation without creating a maintenance nightmare.
In this post we walk through a repeatable pattern that works for any Laravel 10+ codebase:
- Pick a service that matches your problem space and budget.
- Isolate the external call behind a small, testable class.
- Secure the data you send and receive.
- Cache or queue results to control cost and latency.
- Observe, log, and iterate.
The result is a production‑ready feature that can be turned on or off with a single config flag.
1. Selecting an AI provider – trade‑offs at a glance
| Provider | Strength | Pricing model | Typical latency | |----------|----------|---------------|-----------------| | OpenAI (ChatGPT, embeddings) | State‑of‑the‑art language models | Pay‑per‑token | 200‑500 ms | | AWS Rekognition | Image & video analysis, built‑in moderation | Pay‑per‑image/second | 300‑800 ms | | Google Cloud Vision | OCR, landmark detection, label detection | Pay‑per‑image | 250‑600 ms | | Hugging Face Inference API | Wide model zoo, community‑driven | Pay‑per‑request or free tier | 150‑400 ms | | Self‑hosted models (e.g., Ollama, TensorFlow) | Full control, no per‑call cost | Fixed server cost | Depends on hardware |
For most startups the safest bet is a managed SaaS API because you avoid GPU provisioning and can scale instantly. If you have a predictable load and strict data‑ residency requirements, a self‑hosted model may be cheaper in the long run.
Rule of thumb: start with a managed service, benchmark cost vs. volume, then evaluate self‑hosting only if the spend crosses a clear threshold (e.g., >$2k/month).
2. Isolating the external call – the AiClient pattern
Keep every HTTP request to the AI provider inside a dedicated class. This gives you:
- A single place to swap providers.
- Easy unit testing with fakes.
- Centralised error handling and retries.
<?php
namespace App\Services\AI;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use RuntimeException;
class OpenAiClient
{
protected string $apiKey;
protected string $endpoint;
public function __construct()
{
$this->apiKey = config('services.openai.key');
$this->endpoint = 'https://api.openai.com/v1/chat/completions';
}
/**
* Send a prompt and return the model response.
* Results are cached for 5 minutes to reduce cost.
*/
public function chat(array $messages, int $maxTokens = 300): string
{
$cacheKey = 'openai:' . md5(json_encode($messages));
return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($messages, $maxTokens) {
$response = Http::withHeaders([
'Authorization' => "Bearer {$this->apiKey}",
'Content-Type' => 'application/json',
])->post($this->endpoint, [
'model' => 'gpt-4o-mini',
'messages' => $messages,
'max_tokens' => $maxTokens,
'temperature' => 0.7,
]);
if ($response->failed()) {
throw new RuntimeException('OpenAI request failed: ' . $response->body());
}
return $response->json('choices.0.message.content');
});
}
}
?>
Why cache? Many AI calls are deterministic – the same input yields the same output. Caching for a short window (5‑15 minutes) can cut your bill by 30‑50 % without noticeable staleness.
3. Data privacy and security – never send raw PII
When you forward user data to a third‑party model you must:
- Sanitise – strip personally identifiable information (PII) that the model does not need. For text, use regexes or a library like
symfony/stringto redact emails, phone numbers, etc. - Encrypt in‑flight – all SaaS endpoints enforce TLS 1.2+, but you should still verify the certificate chain if you use a custom domain.
- Log minimally – store only request hashes for debugging; never persist raw user content.
use Symfony\Component\String\UnicodeString;
function redactPii(string $input): string
{
$patterns = [
'/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/i', // email
'/\b\d{3}[-.]?\d{2}[-.]?\d{4}\b/', // SSN‑like numbers
'/\b\d{10,}\b/', // generic long numbers
];
return preg_replace($patterns, '[REDACTED]', $input);
}
Pass the redacted string to the AiClient. If you need the original text for later business logic, keep it in your own database under strict access controls and never send it again.
4. Cost‑aware execution – async jobs and rate limiting
Even with caching, a spike in traffic can cause a sudden bill. Two mechanisms keep you safe:
- Queue the request – for non‑blocking UI (e.g., sentiment analysis of a long article) push the job to a Laravel queue. Return a placeholder to the front‑end and poll for the result.
- Rate limit per user – Laravel’s
RateLimitercan cap the number of AI calls per minute.
use App\Jobs\ProcessSentimentJob;
use Illuminate\Support\Facades\RateLimiter;
public function analyseSentiment(Request $request)
{
$user = $request->user();
$key = 'sentiment:' . $user->id;
if (!RateLimiter::tooManyAttempts($key, 5)) {
RateLimiter::hit($key, 60); // 5 attempts per minute
ProcessSentimentJob::dispatch($request->input('text'), $user->id);
return response()->json(['status' => 'queued']);
}
return response()->json(['error' => 'Rate limit exceeded'], 429);
}
The job itself uses the AiClient and stores the result in a sentiments table. Because the job runs on a worker, you can scale the number of workers independently of your web tier.
5. Observability – logs, metrics, and alerts
A production‑grade AI feature should be observable from day one. Add:
- Structured logs – include request hash, provider, latency, and success flag.
- Metrics – expose a Prometheus counter for
ai_requests_totaland a histogram for latency. - Alert thresholds – trigger a Slack/Teams notification if error rate > 2 % or average latency spikes > 1 s.
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use Prometheus\Client\CollectorRegistry;
public function chat(array $messages): string
{
$start = microtime(true);
try {
$result = $this->client->chat($messages);
$this->recordMetric('success', microtime(true) - $start);
return $result;
} catch (\Throwable $e) {
$this->recordMetric('error', microtime(true) - $start);
Log::error('AI request failed', ['error' => $e->getMessage(), 'hash' => md5(json_encode($messages))]);
throw $e;
}
}
private function recordMetric(string $outcome, float $duration): void
{
$registry = app(CollectorRegistry::class);
$counter = $registry->getOrRegisterCounter('ai_requests_total', 'Total AI requests', ['outcome']);
$counter->incBy(1, [$outcome]);
$histogram = $registry->getOrRegisterHistogram('ai_request_duration_seconds', 'AI request latency', ['outcome']);
$histogram->observe($duration, [$outcome]);
}
With these signals you can quickly spot a provider outage, a mis‑configured key, or an unexpected usage pattern.
6. Deploy and iterate – feature flags for safe roll‑out
Never ship an AI endpoint directly to all users. Wrap the call in a feature flag (e.g., using spatie/laravel-feature-flags). Enable it for internal testers, then gradually expand to 5 %, 20 %, and finally 100 % of traffic while monitoring the metrics above.
use Spatie\Feature\Feature;
if (Feature::isEnabled('ai.sentiment')) {
// invoke the AI pipeline
} else {
// fallback to a simple keyword‑based heuristic
}
The fallback ensures your product remains functional even if the provider experiences downtime, and it gives you a baseline for A/B testing the AI‑enhanced experience.
Takeaway
Integrating AI into a Laravel product is less about mastering deep learning and more about engineering discipline:
- Pick a provider that matches the problem and budget.
- Encapsulate every external call in a thin, testable service.
- Never send raw PII – redact and log responsibly.
- Use caching, queues, and rate limiting to control cost and latency.
- Instrument logs and metrics from day one.
- Roll out behind a feature flag and monitor before full launch.
Follow this checklist and you’ll turn a fancy AI idea into a reliable, bill‑friendly feature that adds real value for your users.
- Laravel
- Api
- Security
- Ai
- Product