Download the PHP package foodlz/laravel-ai-skills without Composer
On this page you can find all versions of the php package foodlz/laravel-ai-skills. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download foodlz/laravel-ai-skills
More information about foodlz/laravel-ai-skills
Files in foodlz/laravel-ai-skills
Package laravel-ai-skills
Short Description Adds a procedural knowledge skills layer to the Laravel AI SDK.
License MIT
Informations about the package laravel-ai-skills
Laravel AI Skills
Procedural knowledge skills for the Laravel AI SDK. Teach your AI agents how to behave — not just what to do.
Experimental RFC infrastructure. This package validates the Skills concept in real production use before it is proposed upstream to
laravel/ai. The goal is to gather real-world feedback and edge cases that make the proposal persuasive to maintainers.
The Problem: Knowledge vs. Action
The Laravel AI SDK models agent capabilities as tools — PHP classes that perform an action: look up a record, send a message, call an API. This works perfectly for actions.
But many agents also need procedural knowledge — guidance on how to behave in a given situation:
- "Here is how to handle a refund request."
- "Here is the tone guide for customer support replies."
- "Here is the escalation policy when a user reports data loss."
Today you have two bad options:
| Option | Problem |
|---|---|
Bake it into instructions() |
System prompt grows unboundedly. Every token is charged on every request, even guidance that's only relevant in one scenario out of ten. |
Use a regular Tool with empty schema |
Works mechanically, but it's an abuse of the Tool abstraction. Tools are for actions, not knowledge retrieval. No convention, no scaffold command, no first-class type. |
A Skill is the missing first-class concept: a callable knowledge object with no input schema, whose sole purpose is to return guidance to the model when it decides that guidance is relevant.
Features
- Three delivery modes — OnDemand (one tool per skill), Full (injected into instructions), and Lite (meta-tool pair for high-skill-count agents)
Promptvalue object — load skill content from inline text or Markdown files (%{key}or{{ key }}substitution) or Blade views (native Blade syntax:{{ $key }})- Runtime context injection — pass job-specific or conversation-specific data into skills via
withContext() - Database-driven skills —
guide()is plain PHP; return an Eloquent query result for fully editable, admin-managed content - Content caching — per-prompt or global config; disabled automatically in tests
- Full testing support —
Skill::fake(),Skill::assertInvoked(),Skill::assertNotInvoked() php artisan make:skill— scaffolding that mirrorsmake:toolandmake:agent#[WithSkills]attribute — declarative, IDE-navigable skill registration on agent classes#[AsSkill]attribute — name, description, mode, and cache in one place without override methodswithSkillInstructions(static, dynamic)— prefix-cache-friendly Static → Skills → Dynamic prompt ordering- Events —
InvokingSkillandSkillInvokedfor observability
Requirements
- PHP 8.3+
- Laravel 12+
laravel/ai ^0.6
Installation
The service provider is auto-discovered. Publish the config file if you need to customise discovery paths or cache settings:
Quick Start
1. Scaffold a skill
This creates app/Ai/Skills/SigningSkill.php (and optionally resources/skills/signing.md):
2. Attach it to an agent
The simplest case — OnDemand skills only, no other action tools:
That's it. The Skillable trait provides a default tools() implementation that exposes all attached skills to the LLM automatically.
Both are required.
implements HasToolsis the SDK's gate — it only callstools()when the agent declares that interface.use Skillableprovides the actual implementation. One without the other means no skills are loaded.
Usage
Skill Modes
Set the mode on the #[AsSkill] attribute (or override mode() on the class):
| Mode | Behaviour | When to use |
|---|---|---|
OnDemand (default) |
One zero-argument tool per skill; LLM calls it when needed | Situational knowledge |
Full |
Guide text injected directly into instructions() on every request |
Rules that always apply (e.g. signing policy) |
Lite |
Exposes two meta-tools — list_skills (returns all Lite skill names + descriptions) and skill (fetches full content by name). Requires two LLM round-trips before the model has the knowledge. |
Agents with 8+ skills — reduces tool list size at the cost of latency |
Full Mode: withSkillInstructions()
Use withSkillInstructions() when any skill uses SkillMode::Full. It structures your system prompt in the order providers recommend for prefix cache performance: Static → Skills → Dynamic.
staticPrompt— content that never changes across requests (base persona, global rules). Put this first for maximum cache reuse.- Skills — Full-mode skill content goes here automatically.
dynamicPrompt— per-request or per-user content (context, locale, user data). Goes last to keep the cached prefix as long as possible.
Both parameters are optional. Omit dynamicPrompt if you have no per-request content:
OnDemand and Lite skills are unaffected — they are exposed as tools and do not appear in instructions().
Mixing Action Tools with Skill Tools
When your agent has both action tools and skills, override tools() and use withSkillTools():
withSkillTools() merges your action tools with all skill tools and returns the combined array.
Dynamic Skills: HasSkills + skills()
For skills that need runtime data — the current user's plan, account type, locale, or any other request-time value — implement HasSkills and override skills():
The registry merges attribute skills and method skills automatically. Class strings and instances are both valid.
HasSkillsis optional. Only implement it when you need to pass runtime context into skills viaskills(). For static skill sets,#[WithSkills]on its own is sufficient.
The Prompt Value Object
Prompt implements Stringable and works anywhere a string is expected.
The %{key} and {{ key }} syntaxes both work for Prompt::text() and Prompt::file() — use whichever you prefer. Double-curly with a $ ({{ $key }}) is Blade syntax and applies only to Prompt::view().
Prompt is also usable in instructions() outside of skills:
Database-driven skill content
guide() is plain PHP — you are not limited to static files:
Skill Examples
Static skill — Markdown file, editable by non-developers
Dynamic skill — context injected at runtime
Caching
Per-prompt caching
Call .cache() on any Prompt instance to cache the resolved string output:
Global caching via config
Caching is disabled automatically in testing environments regardless of config.
Artisan Commands
| Command | Description |
|---|---|
php artisan make:skill ToneGuideSkill |
Scaffold a skill class in app/Ai/Skills/ |
php artisan make:skill ToneGuideSkill --markdown |
Scaffold class + resources/skills/tone-guide.md |
php artisan skill:list |
List all discovered skills with names, descriptions, and modes |
php artisan skill:clear |
Clear skill content and discovery caches |
Testing
Fake skill responses
Assert skills were (or were not) invoked
Unit test skill content directly
Skills are plain PHP objects — test guide() output without spinning up an agent:
Configuration
Publish the config file:
API Reference
Skillable trait
| Method | Description |
|---|---|
skills(): iterable |
Override to provide runtime skill instances. Returns [] by default. |
resolvedSkills(): array |
Returns all resolved Skill instances for this agent. |
skillTools(): array |
Returns Tool-compatible adapters for all non-Full skills (OnDemand and Lite). |
tools(): iterable |
Default implementation — returns skillTools(). Override if you have action tools. |
withSkillTools(iterable $tools): array |
Merges your action tools with skill tools. Use inside tools(). |
withSkillInstructions(static, dynamic): string |
Structures instructions as Static → Full skills → Dynamic for prefix cache optimization. |
Skill abstract class
| Method | Description |
|---|---|
name(): string |
Tool name exposed to the LLM. Defaults to snake_case class basename. |
description(): string |
When the LLM should call this skill. |
mode(): SkillMode |
Delivery mode. Defaults to OnDemand. |
guide(): Prompt\|string |
The procedural knowledge returned when this skill is invoked. Abstract. |
withContext(array $context): static |
Inject runtime context before the skill is resolved. |
context(?string $key, mixed $default): mixed |
Read injected context. |
static fake(string\|Closure $response): void |
Stub guide output in tests. |
static assertInvoked(?Closure $callback): void |
Assert the skill was called. |
static assertNotInvoked(): void |
Assert the skill was not called. |
static clearFakes(): void |
Reset all fakes and invocation records. |
Events
| Event | When |
|---|---|
Foodlz\LaravelAiSkills\Events\InvokingSkill |
Before guide() is called |
Foodlz\LaravelAiSkills\Events\SkillInvoked |
After guide() returns |
Both events carry the Skill instance and the agent.
How It Works Internally
OnDemand and Lite skills are adapted to Laravel\Ai\Contracts\Tool at runtime via an internal SkillTool adapter — the LLM never knows the difference between a tool and a skill. Full-mode skills bypass the tool call entirely and have their content appended directly into the system prompt by withSkillInstructions().
The SkillRegistry reads #[WithSkills] via reflection and merges those with any skills returned by skills() if the agent implements HasSkills. Discovery is scanned from the paths configured in ai-skills.discovery.
Roadmap
- [x]
php artisan skill:list— list all discovered skills with names, descriptions, and modes - [x]
php artisan skill:clear— clear skill content and discovery caches - [x] Discovery caching
- [x]
withSkillInstructions(static, dynamic) - [ ]
skill_read— LLM-accessible supplementary files per skill (viaresourcePath()) — prefix-cache-friendly prompt ordering - [ ]
Prompt::url()— load skill content from a remote URL
Credits
- Inspired by anilcancakir/laravel-ai-sdk-skills — a community package that explored SKILL.md file-based skills and the meta-tool
list_skills/skillpattern, which directly influenced theLitemode andPromptvalue object design in this package. - Built on the Laravel AI SDK by Taylor Otwell and the Laravel team.
License
MIT — see LICENSE.
All versions of laravel-ai-skills with dependencies
illuminate/cache Version ^12.0|^13.0
illuminate/console Version ^12.0|^13.0
illuminate/container Version ^12.0|^13.0
illuminate/contracts Version ^12.0|^13.0
illuminate/filesystem Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/view Version ^12.0|^13.0
laravel/ai Version ^0.6 || ^0.7 || ^0.9 || ^0.10 || ^0.11