muyki-labs/laravel-guardrails
Composer 安装命令:
composer require muyki-labs/laravel-guardrails
包简介
A safety layer for LLM input and output in Laravel: a fluent, composable pipeline of guards (PII redaction, prompt-injection detection, moderation, schema validation) plus a provider-agnostic wrapper for any LLM call.
关键字:
README 文档
README
A safety layer for LLM input and output in Laravel. Laravel Guardrails validates, sanitizes, and (optionally) blocks the data flowing in and out of language models so teams can ship AI features that are compliant and predictable — PII redaction, prompt-injection detection, moderation, and schema validation behind one fluent, composable pipeline.
use MuykiLabs\Guardrails\Facades\Guardrails; $clean = Guardrails::for($userInput) ->stripPII() // redact emails, phones, IBANs, cards, TCKN, IPs ->blockPromptInjection() // detect jailbreak / instruction-override ->maxTokens(2000) ->guard(); // returns the sanitized value or throws $response = Guardrails::for($llmOutput) ->validateSchema($rules) // structured-output / JSON shape ->blockToxic() // moderation ->noPII() // ensure the model didn't leak PII back ->onViolation('redact') // throw | redact | retry | null ->guard();
It is provider-agnostic and ships with zero required external services: regex PII detection, heuristic prompt-injection and moderation, and Laravel-validation-backed schema checks all work out of the box. Every detector is a pluggable, extend()-able manager, so you can swap in an NER service, an OpenAI moderation driver, or an LLM-as-judge without touching call sites.
Installation
composer require muyki-labs/laravel-guardrails
Publish the config:
php artisan vendor:publish --tag=guardrails-config
If you want the persisted audit log, publish and run the migration:
php artisan vendor:publish --tag=guardrails-migrations php artisan migrate
Requires PHP 8.3+ and Laravel 12 or 13.
The pipeline
Guardrails::for($value) returns a fluent pipeline. Chain guards, then terminate with one of:
guard()— run the guards, apply the violation strategy, and return the resolved value (or throw).check()— run the guards and return aGuardResult(passed,value,violations) without throwing.passes()/fails()— boolean shortcuts.
$result = Guardrails::for($input)->stripPII()->blockPromptInjection()->check(); if ($result->fails()) { foreach ($result->violations as $violation) { logger()->warning($violation->message, $violation->toArray()); } }
Input guards
| Method | What it does |
|---|---|
stripPII(array $types = [], ?string $strategy = null) |
Redact detected PII. Strategy: mask, hash, tokenize, remove. |
blockPromptInjection() |
Flag jailbreak / instruction-override attempts. |
maxTokens(int $max) |
Reject (or truncate) input over a token budget. |
maxLength(int $max) |
Reject (or truncate) input over a character length. |
allow(array $terms) |
Require the input to mention at least one allowed term. |
deny(array $terms) |
Reject input that contains a denied term. |
Output guards
| Method | What it does |
|---|---|
validateSchema(array|Closure $rules) |
Validate decoded JSON/array against Laravel rules or a callback. |
blockToxic() / moderate() |
Run moderation over the output. |
noPII(array $types = []) |
Fail if the model echoed PII back. |
Custom guards
use MuykiLabs\Guardrails\Contracts\Guard; use MuykiLabs\Guardrails\Support\GuardContext; use MuykiLabs\Guardrails\Support\GuardResult; Guardrails::for($input)->using(new MyGuard)->guard(); // Or register it by name so policies and config can reference it: Guardrails::extend('my_guard', fn (array $options) => new MyGuard($options)); Guardrails::for($input)->guardWith('my_guard', ['foo' => 'bar'])->guard();
Wrapping an LLM call
Guardrails::pipe() wraps any callable: input guards run before the call, output guards after. With the retry strategy a rejected output re-invokes the model.
$response = Guardrails::pipe(fn (string $clean) => $llm->generate($clean)) ->input(fn ($p) => $p->stripPII()->blockPromptInjection()) ->output(fn ($p) => $p->validateSchema($rules)->blockToxic()->noPII()) ->onViolation('retry') ->retries(2) ->run($userInput);
The callable is provider-agnostic, so it works with Prism, laravel/ai, or your own client. Input violations always fail closed (they cannot be "retried"); only output guards drive the retry loop.
Violation strategies
Set per pipeline with onViolation() (default comes from config('guardrails.default_strategy')).
throw— throw aGuardrailViolation(fail closed, the default).redact— return the sanitized value produced by the guards.retry— (LLM wrapper) re-run the call; in a standalone pipeline this fails closed likethrow.null— returnnullinstead of the offending value.
use MuykiLabs\Guardrails\Exceptions\GuardrailViolation; try { Guardrails::for($input)->blockPromptInjection()->guard(); } catch (GuardrailViolation $e) { $e->violations(); // list<Violation> $e->guards(); // ['prompt_injection'] }
Policies
Named, reusable guard sets live in config/guardrails.php:
'policies' => [ 'support-bot' => [ 'strategy' => 'redact', 'input' => [ 'strip_pii' => ['strategy' => 'mask'], 'prompt_injection' => [], 'max_tokens' => ['max' => 2000], ], 'output' => [ 'moderation' => [], 'no_pii' => [], ], ], ],
$clean = Guardrails::policy('support-bot')->guard($userInput); use MuykiLabs\Guardrails\Enums\GuardDirection; $safe = Guardrails::policy('support-bot', GuardDirection::Output)->guard($llmOutput);
PII detection & redaction
The built-in regex detector recognises email, phone, IBAN, Luhn-checked credit card, Turkish national ID (TCKN, checksum-validated), and IPv4. Patterns and the enabled types are configurable under guardrails.pii. Redaction strategies:
mask— replace with a label, e.g.[EMAIL].remove— strip the value entirely.hash— replace with a stable[[EMAIL:abc123...]]token.tokenize— reversible: the original is stored in a cache vault and can be restored.
Register a custom detector (e.g. an NER provider):
use MuykiLabs\Guardrails\Pii\PiiManager; app(PiiManager::class)->extend('ner', fn ($app) => new NerPiiDetector(...)); // then set GUARDRAILS_PII_DRIVER=ner
The moderation and prompt-injection subsystems work the same way via ModerationManager::extend() and InjectionManager::extend().
Events
Bind to any of these (e.g. for audit logging, dashboards, or alerting):
| Event | Fired when |
|---|---|
GuardrailPassed |
A pipeline completes with no hard violations. |
GuardrailViolated |
One or more guards reported a violation. |
InputRedacted |
An input guard sanitized the value (e.g. PII redaction). |
OutputBlocked |
An output pipeline reported a violation. |
GuardrailRetried |
The LLM wrapper re-ran the call under the retry strategy. |
Audit log
Set guardrails.audit.enabled to true to persist violations for a compliance trail (KVKK / GDPR). Drivers: database (queryable), log (writes to the Laravel logger), or null.
php artisan guardrails:prune --days=90 # remove old audit entries
Enable scheduled pruning under prune.schedule in the config.
Commands
php artisan guardrails:check "some text" --policy=support-bot # evaluate text php artisan guardrails:policies # list policies php artisan guardrails:prune --days=90 # prune audit log
Testing
composer test
composer analyse
composer format
License
The MIT License (MIT). See LICENSE.md.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 4
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-16