## Getting Started
### Minimal Steps
1. **Installation**:
```bash
composer require promptphp/deck
php artisan vendor:publish --provider="PromptPHP\Deck\Providers\DeckServiceProvider"
php artisan migrate
Create a prompt:
php artisan make:prompt order-summary
This generates a versioned structure in resources/prompts/order-summary/.
Edit prompt files:
Modify resources/prompts/order-summary/v1/system.md (or other role files) with your AI instructions, using {{ $variable }} syntax for dynamic values.
Use the prompt:
use PromptPHP\Deck\Facades\Deck;
$prompt = Deck::get('order-summary');
$messages = $prompt->toMessages(['tone' => 'friendly', 'order' => $orderDetails]);
AI Agent Integration: Create a prompt for a customer support agent, then integrate it with Laravel AI SDK:
use PromptPHP\Deck\Concerns\HasPromptTemplate;
class SupportAgent extends Agent {
use HasPromptTemplate;
// No need to define instructions() manually
}
Versioned Prompt Management:
make:prompt to scaffold new versions (v1, v2, etc.).php artisan prompt:activate order-summary v2
$prompt = Deck::get('order-summary', 'v2');
Dynamic Variable Interpolation:
{{ $variable }} syntax.$prompt->system(['tone' => 'professional', 'user' => $user]);
Role-Based Prompts:
php artisan make:prompt code-reviewer --role=assistant --role=developer
$system = $prompt->system(['var' => 'value']);
$user = $prompt->user(['var' => 'value']);
Laravel AI SDK Integration:
HasPromptTemplate trait to agents to auto-load prompts:
class OrderAgent extends Agent {
use HasPromptTemplate;
// Prompt loaded automatically from `resources/prompts/order-agent/`
}
make:agent to scaffold matching prompt directories.config/deck.php.Deck::get() with environment-specific versions (e.g., staging-v1).Prompt class to add validation logic for variables or content.Deck::shouldReceive('get')->andReturn(...).config/deck.php to log prompt usage metrics.A/B Testing:
$version = request()->has('prompt_version') ? request('prompt_version') : 'v1';
$prompt = Deck::get('order-summary', $version);
Track conversions per version in your database.
Dynamic Prompt Selection:
$promptName = auth()->user()->preferred_prompt ?? 'default';
$prompt = Deck::get($promptName);
Prompt Inheritance: Create base prompts with common variables, then extend them in child prompts:
# resources/prompts/base/system.md
You are a {{ $tone }} assistant.
# resources/prompts/support/v1/system.md
{{ $base_prompt }}
Specializing in customer support.
(Requires custom interpolation logic.)
Namespace Mismatch:
veeqtoh/prompt-deck to promptphp/deck, update all use statements from Veeqtoh\PromptDeck to PromptPHP\Deck.Version Conflicts:
--force can silently replace critical prompts. Always verify the latest version before using --force.Variable Scope:
['tone' => 'friendly'] to system() won’t affect user() unless explicitly passed again.File Permissions:
storage/logs/deck_*.log is writable if using performance tracking.Stub Overrides:
resources/stubs/ (default) or configured in deck.stubs_path. Forgetting this causes default stubs to be used.Prompt Not Found:
resources/prompts/ and the name matches exactly (kebab-case).metadata.json for typos in the name field.Variable Interpolation Failures:
{{ $var }} (no spaces).$prompt->system(['debug' => true]); // Logs unprocessed variables
Version Activation Issues:
v2/).config/deck.php for active_version overrides.Laravel AI SDK Integration:
prompt_name matches the directory name (e.g., OrderAgent → order-agent/).HasPromptTemplate is used and no instructions() method conflicts.File Extension:
deck.extension from md to txt requires regenerating all prompts:
php artisan make:prompt order-summary --force
Prompts Directory:
app/Prompts/) must be writable by the web server.Metadata Updates:
metadata.json manually may break versioning. Use make:prompt --force to regenerate.Custom Prompt Classes:
Extend PromptPHP\Deck\Prompt to add methods like:
public function validateVariables(array $variables): void {
if (!isset($variables['required_var'])) {
throw new \InvalidArgumentException('Missing required variable.');
}
}
Stub Customization:
Override stubs in resources/stubs/ or publish them:
php artisan vendor:publish --tag=deck-stubs
Event Listeners:
Listen for prompt events (e.g., PromptActivated) to log usage:
Deck::get('order-summary')->on('activated', function ($prompt) {
\Log::info("Prompt {$prompt->name} activated");
});
Variable Parsers:
Extend PromptPHP\Deck\Parsers\VariableParser to support custom syntax (e.g., {{{var}}}).
Caching:
Enable deck.cache_enabled to cache rendered prompts (useful for static prompts).
Asset Optimization: For large prompts, split into multiple files and combine them:
$prompt = Deck::get('complex-prompt');
$messages = array_merge(
$prompt->system()->toMessages(),
$prompt->user()->toMessages()
);
A/B Testing:
Use Deck::get()->trackUsage() to log which versions are used in production.
Variable Injection: Sanitize user-provided variables before interpolation to prevent template injection:
$safeVars = array_map('htmlspecialchars', $userInput);
$prompt->system($safeVars);
Prompt Isolation:
Avoid sharing prompts between environments (e.g., production-v1 vs. staging-v1) unless explicitly designed for it.
Sensitive Data:
Never store API keys or secrets in prompt files. Use environment variables and pass them via the $variables array.
```markdown
### Laravel AI SDK Integration Gotchas
1. **Trait Conflict**:
If your agent extends a class that also uses `HasPromptTemplate`, the trait may be loaded twice. Use `insteadof` in your `composer.json`:
```json
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/"
},
"files": [
"vendor/promptphp/deck/src/Concerns/HasPromptTemplate.php"
],
"classmap": [
"app/Models/"
],
"psr-4": {
"PromptPHP\\Deck
How can I help you explore Laravel packages today?