symfony/ai-bedrock-platform
AWS Bedrock bridge for Symfony AI. Invoke Bedrock foundation models (Claude, Llama, Nova, and more) via the Bedrock Runtime API, with helpers aligned to Bedrock request/response schemas for easy integration into Symfony apps.
Install the Package
composer require symfony/ai-bedrock-platform aws/aws-sdk-php
Ensure aws/aws-sdk-php is installed for AWS Bedrock API interactions.
Configure AWS Credentials
Add AWS credentials to your .env file:
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-east-1 # or your Bedrock region
Publish Configuration Publish the default configuration:
php artisan vendor:publish --provider="Symfony\AiBedrock\BedrockServiceProvider"
This creates a config/bedrock.php file. Update it to define your default model and AWS settings:
return [
'models' => [
'default' => 'anthropic.claude-v2', // Default model to use
],
'aws' => [
'region' => env('AWS_DEFAULT_REGION'),
],
];
Register the Service Provider
In config/app.php, add the Bedrock service provider to the providers array:
Symfony\AiBedrock\BedrockServiceProvider::class,
First Invocation Use the Bedrock client in a Laravel controller or service:
use Symfony\AiBedrock\Client\BedrockClientInterface;
use Symfony\AiBedrock\Client\ModelClient;
public function generateText(BedrockClientInterface $bedrockClient)
{
$modelClient = new ModelClient($bedrockClient, 'anthropic.claude-v2');
$response = $modelClient->invoke([
'prompt' => 'Write a Laravel assessment for symfony/ai-bedrock-platform.',
'max_tokens_to_sample' => 100,
]);
return $response->getContent();
}
List Available Models (Optional) Use the CLI command to list available Bedrock models:
php artisan ai:bedrock:list
This syncs the model catalog with the Bedrock API.
ModelClient for a specific model (e.g., anthropic.claude-v2).prompt, max_tokens_to_sample).$bedrockClient = app(BedrockClientInterface::class);
$claudeClient = new ModelClient($bedrockClient, 'anthropic.claude-v2');
$response = $claudeClient->invoke([
'prompt' => 'Explain Laravel dependency injection in simple terms.',
'max_tokens_to_sample' => 150,
'temperature' => 0.7,
]);
$content = $response->getContent();
Provider abstraction to encapsulate model-specific logic.BedrockClientInterface to route requests based on conditions.// Define a provider for Claude
$claudeProvider = new class implements ProviderInterface {
public function supports(string $modelId): bool
{
return str_starts_with($modelId, 'anthropic.claude');
}
public function getClient(BedrockClientInterface $bedrockClient, string $modelId): ModelClient
{
return new ModelClient($bedrockClient, $modelId);
}
};
// Register the provider with the Bedrock client
$bedrockClient->addProvider($claudeProvider);
// Route a request to Claude
$modelClient = $bedrockClient->getModelClient('anthropic.claude-v2');
ClaudeModelClient for models like Anthropic Claude that support structured output.use Symfony\AiBedrock\Client\ClaudeModelClient;
$claudeClient = new ClaudeModelClient($bedrockClient, 'anthropic.claude-v2');
$response = $claudeClient->invoke([
'prompt' => 'Generate a JSON summary of this Laravel assessment.',
'max_tokens_to_sample' => 200,
'anthropic_version' => 'bedrock-2023-05-31',
'output_format' => [
'type' => 'json_object',
],
]);
$structuredData = json_decode($response->getContent(), true);
use Illuminate\Support\Facades\Queue;
Queue::later(now()->addMinutes(5), function () use ($bedrockClient, $prompts) {
foreach ($prompts as $prompt) {
$modelClient = new ModelClient($bedrockClient, 'amazon.titan-text-express');
$response = $modelClient->invoke([
'inputText' => $prompt,
'textGenerationConfig' => [
'maxTokenCount' => 100,
'stopSequences' => ['\n\n'],
],
]);
// Store or process the response
}
});
Laravel Service Container
Bind the BedrockClientInterface to a concrete implementation in AppServiceProvider:
public function register()
{
$this->app->bind(BedrockClientInterface::class, function ($app) {
return new BedrockClient($app['config']['bedrock']);
});
}
Facades for Clean Syntax Create a facade to simplify Bedrock interactions:
// app/Facades/Bedrock.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Bedrock extends Facade
{
protected static function getFacadeAccessor()
{
return 'bedrock';
}
}
Register the facade in AppServiceProvider:
Facade::register(BedrockFacade::class, Bedrock::class);
Model Catalog Caching Cache the list of available models to avoid repeated API calls:
$models = Cache::remember('bedrock.models', now()->addHours(1), function () {
return $bedrockClient->listFoundationModels();
});
Error Handling Wrap Bedrock calls in try-catch blocks to handle AWS-specific exceptions:
try {
$response = $modelClient->invoke($payload);
} catch (\Aws\Bedrock\Exception\BedrockException $e) {
Log::error('Bedrock error: ' . $e->getMessage());
// Fallback logic or retry
}
Environment-Specific Config Use Laravel’s environment-specific configurations to switch models or AWS regions:
// config/bedrock.php
return [
'models' => [
'default' => env('BEDROCK_DEFAULT_MODEL', 'anthropic.claude-v2'),
'staging' => 'amazon.titan-text-lite',
],
'aws' => [
'region' => env('BEDROCK_REGION', 'us-east-1'),
],
];
AWS Credentials and Permissions
BedrockExceptions.bedrock:InvokeModel and bedrock:ListFoundationModels permissions. Example policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:ListFoundationModels"
],
"Resource": "*"
}
]
}
Model-Specific Payload Requirements
anthropic_version, while Titan uses textGenerationConfig.How can I help you explore Laravel packages today?