Configuring Multiple LLM Providers in Laravel
The latest version of the laravel/ai SDK (v0.8.1) integrates with an impressive 14 different AI providers, including giants like OpenAI, Anthropic, and Google Gemini, alongside specialized services such as Groq, Mistral, DeepSeek, xAI, Ollama, Azure OpenAI, Cohere, OpenRouter, Jina, VoyageAI, and ElevenLabs. This extensive support moves beyond simple vendor lock-in, offering developers flexibility. However, leveraging this breadth requires careful configuration, not just a simple environment variable swap. This guide details how to set up multiple providers within a single Laravel application, switch between them dynamically, manage provider-specific errors, and implement robust testing without incurring live API costs.
To begin, ensure you have the necessary prerequisites: PHP 8.3+, Laravel 12 or 13, and the laravel/ai package pinned to version ^0.8 in your composer.json. You will also need API keys for at least two different providers; for this walkthrough, we will use OpenAI and Anthropic.
First, install the SDK using Composer:
composer require laravel/ai "^0.8"
Next, publish the configuration file:
php artisan vendor:publish --tag=ai-config
This will create a config/ai.php file. Open this file. You will see a default key, which specifies the active provider. To enable multiple providers, you need to modify the providers array. Each provider configuration should include its driver (e.g., openai, anthropic), its api_key, and potentially other provider-specific settings. You can obtain API keys from the respective provider's dashboard.
For instance, to configure both OpenAI and Anthropic, your config/ai.php might look like this:
<?php
return [
'default' => env('AI_PROVIDER', 'openai'), // Set your default provider here
'providers' => [
'openai' => [
'driver' => 'openai',
'api_key' => env('OPENAI_API_KEY'),
'model' => 'gpt-4o',
],
'anthropic' => [
'driver' => 'anthropic',
'api_key' => env('ANTHROPIC_API_KEY'),
'model' => 'claude-3-opus-20240229',
],
// Add other providers here as needed
],
];
After updating the configuration, set your API keys in your .env file:
OPENAI_API_KEY=your_openai_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key
Runtime Provider Switching
The SDK allows you to switch providers dynamically at runtime using the AI::driver() method. This is crucial for scenarios where you might want to use a cheaper model for simple tasks or a more powerful one for complex queries, or even to failover to a secondary provider if the primary is unavailable.
To send a request to a specific provider, you can chain the driver() method before making your AI call:
use Illuminate\Support\Facades\AI;
// Using the default provider
$defaultResponse = AI::complete('What is the capital of France?');
// Explicitly using the OpenAI provider
$openaiResponse = AI::driver('openai')->complete('What is the capital of France?');
// Explicitly using the Anthropic provider
$anthropicResponse = AI::driver('anthropic')->complete('What is the capital of France?');
This flexibility is powerful. For example, you could implement a feature where common, low-stakes queries are routed through a cost-effective provider like Ollama or Groq, while more critical, nuanced requests are sent to OpenAI or Anthropic. The choice can be determined by request parameters, user preferences, or even real-time cost analysis.
Handling Provider-Specific Failures
When working with multiple external services, errors are inevitable. The Laravel AI SDK provides a robust way to handle these exceptions. Each provider driver can throw specific exceptions that you can catch and manage. This allows for graceful degradation or failover mechanisms.
For instance, if the OpenAI API is down or returns an error, you can catch the relevant exception and redirect the request to your secondary provider. The SDK uses exceptions that often mirror the underlying API errors, but within the Laravel framework, you can wrap your AI calls in standard PHP try-catch blocks.
use Illuminate\Support\Facades\AI;
use OpenAI\Exceptions\ErrorException as OpenAIErrorException;
use Anthropic\Error\ApiError as AnthropicApiError;
try {
// Attempt to use OpenAI
$response = AI::driver('openai')->complete('Generate a creative story.');
} catch (OpenAIErrorException $e) {
// OpenAI failed, try Anthropic
try {
$response = AI::driver('anthropic')->complete('Generate a creative story.');
} catch (AnthropicApiError $e) {
// Both failed, handle the ultimate failure
// Log the error, return a default response, etc.
report($e);
$response = 'I am sorry, I could not fulfill your request at this time.';
}
}
echo $response;
This pattern ensures that your application remains functional even when one LLM provider experiences an outage. The key is to anticipate potential errors for each driver you use and implement corresponding fallback strategies. You might decide to failover to a cheaper provider if the premium one is too slow, or vice-versa, depending on your application's requirements.
Testing LLM Integrations Without Live APIs
Testing AI integrations can be costly and time-consuming if every test hits a live API. The Laravel AI SDK supports mock responses, allowing you to simulate API behavior without making actual calls. This is critical for unit and integration testing.
You can use Laravel's testing utilities to mock the AI facade. By binding a mock implementation to the AI facade, you can assert that your application logic correctly interacts with the AI service, regardless of the underlying provider.
Here's an example using PHPUnit:
use Illuminate\Support\Facades\AI;
use Mockery;
use Illuminate\Support\Stringable;
public function test_ai_completion_uses_mock_response(): void
{
// Mock the AI facade to return a predefined response
$mockResponse = new Stringable('Mocked AI response');
AI::shouldReceive('complete')
->once()
->andReturn($mockResponse);
// Call the part of your application that uses AI
$result = $this->callGenerateContent(); // Assume this method calls AI::complete()
// Assert that the application received and used the mocked response
$this->assertEquals('Mocked AI response', $result);
}
// Example method in your service or controller
protected function callGenerateContent(): string
{
$response = AI::complete('This is a test prompt.');
return $response->toString();
}
When you need to test specific provider behaviors or failover scenarios, you can mock different drivers. For instance, you could mock the openai driver to throw an exception, and then assert that your fallback logic correctly triggers the anthropic driver.
This testing strategy is akin to using stubbed network requests in other types of integrations. It ensures your application's AI logic is sound, independent of the LLM provider's availability or performance during development and testing phases. The ability to test failure paths and provider switching without live API calls is a significant advantage for building resilient AI-powered applications.
The Broader Implications
The integration of multiple LLM providers into the Laravel AI SDK signifies a maturing ecosystem where developers demand flexibility and resilience. This approach allows applications to adapt to evolving AI model performance, pricing, and availability. Founders can build products that are not tethered to a single AI vendor, reducing long-term risk and potentially optimizing operational costs. Developers gain the power to select the best tool for specific jobs, enhancing application capabilities. For security professionals, it means a broader attack surface but also the opportunity to implement more sophisticated, resilient systems that can failover to trusted alternatives during an incident. The SDK's focus on testing and error handling provides a solid foundation for building production-ready AI features.
