symfony/ai-generic-platform
Generic Symfony AI platform package providing an extensible foundation to integrate AI providers and workflows in Symfony apps. Offers reusable abstractions, configuration-first setup, and a base for building chats, assistants, and other AI-powered features.
Installation Add the package via Composer:
composer require symfony/ai-generic-platform
Ensure your project uses Symfony 7.0+ (or PHP 8.2+).
Basic Setup
Register the bridge in your config/packages/ai.yaml:
framework:
ai:
platforms:
generic: true
First Use Case: Embedding Generation
Use the AiClient to interact with generic AI platforms:
use Symfony\AI\Client\AiClient;
use Symfony\AI\Client\AiClientInterface;
// In a service or controller
public function __construct(private AiClientInterface $aiClient) {}
public function generateEmbedding(string $text): array
{
$response = $this->aiClient->embed([
'model' => 'generic-embedding-model',
'input' => $text,
]);
return $response->getEmbedding();
}
Where to Look Next
src/Symfony/AI/Client/GenericPlatformClient.php for low-level API details.Embedding Generation for Search
// Generate embeddings for a list of documents
$documents = ['doc1', 'doc2', 'doc3'];
$embeddings = collect($documents)->map(fn($doc) =>
$this->aiClient->embed(['input' => $doc])->getEmbedding()
);
Chat Completions with Context
// Use chat history for context-aware responses
$history = [
['role' => 'user', 'content' => 'Previous question'],
['role' => 'assistant', 'content' => 'Previous answer'],
];
$response = $this->aiClient->chat([
'model' => 'generic-chat-model',
'messages' => array_merge($history, [['role' => 'user', 'content' => 'New question']]),
]);
Batch Processing
// Process embeddings in parallel (using Symfony Messenger or similar)
$embeddingTasks = array_map(fn($text) => new GenerateEmbeddingTask($text), $texts);
$dispatcher->dispatch($embeddingTasks);
Laravel Service Providers
Bind the AiClientInterface in AppServiceProvider:
$this->app->bind(AiClientInterface::class, function ($app) {
return new GenericPlatformClient($app['config']['ai.platform']);
});
Configuration Management Use Laravel’s config system to switch between platforms:
# config/ai.php
platforms:
generic:
endpoint: 'https://api.generic-ai-provider.com/v1'
api_key: '%env(AI_GENERIC_API_KEY)%'
Caching Responses Cache embeddings/chat responses to avoid redundant API calls:
$cacheKey = 'embedding_'.md5($text);
return Cache::remember($cacheKey, now()->addHours(1), fn() =>
$this->aiClient->embed(['input' => $text])->getEmbedding()
);
Error Handling Wrap API calls in try-catch blocks:
try {
$response = $this->aiClient->embed(['input' => $text]);
} catch (AiException $e) {
Log::error('AI Embedding Failed', ['error' => $e->getMessage()]);
throw new \RuntimeException('Failed to generate embedding', 0, $e);
}
Platform-Specific Quirks
GenericPlatformClient:
class CustomGenericClient extends GenericPlatformClient {
protected function decodeResponse(array $data): mixed {
// Override to handle custom responses
return $data['custom_key'] ?? parent::decodeResponse($data);
}
}
Rate Limiting
use Symfony\Component\AI\Exception\RateLimitExceededException;
try {
$response = $this->aiClient->chat($prompt);
} catch (RateLimitExceededException $e) {
sleep(2 ** $this->retryCount++);
retry();
}
Cost Management
if (strlen($text) > 5000) {
throw new \InvalidArgumentException('Input too long for embedding');
}
Dependency Conflicts
symfony/ai and symfony/http-client versions are compatible. Avoid:
composer require symfony/ai:^1.0 symfony/http-client:^6.4
(Check Symfony’s docs for version pairs.)Enable API Logging
Configure HTTP client logging in config/packages/http_client.yaml:
framework:
http_client:
logging: true
Validate API Responses
Use dd() to inspect raw responses:
$response = $this->aiClient->embed(['input' => $text]);
dd($response->toArray()); // Debug raw data
Mocking for Tests
Use Symfony\AI\Client\MockAiClient in PHPUnit:
$mockClient = new MockAiClient();
$mockClient->expects('embed')->andReturn(new EmbeddingResponse([1, 2, 3]));
$this->app->instance(AiClientInterface::class, $mockClient);
Custom Platform Clients
Extend GenericPlatformClient for provider-specific logic:
class OpenAIPlatformClient extends GenericPlatformClient {
protected function getEndpoint(): string {
return 'https://api.openai.com/v1';
}
}
Middleware for AI Requests Add request/response modifiers:
$client = new GenericPlatformClient($config, [
new AddAuthHeaderMiddleware('Bearer %env(AI_TOKEN)%'),
new RetryMiddleware(),
]);
Event Listeners
Subscribe to AI events (e.g., AiClientEvent):
$dispatcher->addListener(AiClientEvent::PRE_REQUEST, function (AiClientEvent $event) {
if ($event->getRequest()->getUri() === 'embed') {
$event->setRequest($event->getRequest()->withHeader('X-Custom-Header', 'value'));
}
});
Laravel Scout Integration Use embeddings with Laravel Scout for vector search:
use Laravel\Scout\Searchable;
class Post extends Model implements Searchable {
public function toSearchableArray() {
return [
'title' => $this->title,
'embedding' => $this->aiClient->embed(['input' => $this->content])->getEmbedding(),
];
}
}
How can I help you explore Laravel packages today?