A model-agnostic skill loading and execution framework following Claude Skill specification
Project description
Skill Loader
A model-agnostic skill loading and execution framework following the Claude Skill specification.
Features
- Model & Platform Agnostic: Works with any LLM (OpenAI, Anthropic, local models, etc.)
- Dynamic Loading: Automatically discovers and loads skills from directories
- Keyword Matching: Fast skill selection using keyword matching
- LLM Semantic Matching: Optional semantic matching using any LLM
- Project & Global Skills: Supports both project-level and global skill directories
- Auto-configuration: Automatically detects skill execution configuration
- Dependency Management: Automatically installs skill dependencies
Installation
pip install skill-loader
Quick Start
Basic Usage
from skill_loader import get_skill_loader
# Get skill loader with default global skills
loader = get_skill_loader(verbose=True)
# List available skills
print(loader.get_skills())
# ['excel-parser', 'pdf-ocr', 'web-search']
# Execute a skill
result = loader.execute_skill('excel-parser', {
'action': 'read',
'file_path': 'data.xlsx'
})
Natural Language Matching
# Find skill by natural language (keyword matching)
skill_name = loader.find_skill_by_natural_language("parse this Excel file")
# Returns: 'excel-parser' or list of candidates
# Use LLM for semantic matching
def my_llm_predict(prompt: str) -> str:
# Your LLM implementation here
return "excel-parser"
skill_name = loader.find_skill_with_llm(
"help me read this spreadsheet",
llm_predict_func=my_llm_predict
)
Project & Global Skills
from skill_loader import SkillLoader
# Use only global skills
loader = SkillLoader()
# Use project-level skills (global included automatically)
loader = SkillLoader('/path/to/project/skills')
# Explicitly specify multiple directories
loader = SkillLoader([
'/global/skills', # Global skills (loaded first)
'/project/skills' # Project skills (overrides global)
])
Creating a Skill
Directory Structure
skills/
└── my-skill/ # Skill directory (kebab-case)
├── SKILL.md # Skill metadata (required)
├── scripts/ # Scripts directory
│ ├── __init__.py
│ └── main.py # Main script
└── README.md # Documentation (optional)
SKILL.md Template
# My Skill
## Description
A brief description of what this skill does.
## Keywords
keyword1, keyword2, keyword3
## Execution
**type**: script
**script_path**: scripts/main.py
**main_class**: MySkillProcessor
**dependencies**: package1, package2
## Inputs
- param1: Description of parameter 1
- param2: Description of parameter 2
## Outputs
- result: Description of output
Skill Implementation
# scripts/main.py
class MySkillProcessor:
"""Skill processor class."""
def process(self, input_data: dict) -> dict:
"""Process the input data.
Args:
input_data: Input data dictionary
Returns:
Result dictionary with 'success' key
"""
try:
# Your processing logic here
result = do_something(input_data)
return {
'success': True,
'data': result,
'message': 'Processing completed'
}
except Exception as e:
return {
'success': False,
'error': str(e),
'message': f'Processing failed: {e}'
}
API Reference
SkillLoader
class SkillLoader:
def __init__(self, skills_dir: Union[str, List[str]] = None, verbose: bool = False):
"""Initialize skill loader.
Args:
skills_dir: Skill directory path(s). Project-level takes priority.
verbose: Enable verbose logging.
"""
def get_skills(self) -> List[str]:
"""Get list of available skill names."""
def get_skill(self, skill_name: str) -> Optional[Skill]:
"""Get a specific skill by name."""
def execute_skill(self, skill_name: str, input_data: dict) -> dict:
"""Execute a skill with the given input data."""
def find_skill_by_natural_language(self, query: str) -> Union[str, List[tuple]]:
"""Find skill using keyword matching."""
def find_skill_with_llm(self, query: str, llm_predict_func: Callable, candidates: List[tuple] = None) -> Optional[str]:
"""Find skill using LLM semantic matching."""
get_skill_loader
def get_skill_loader(skills_dir: Union[str, List[str]] = None, verbose: bool = False) -> SkillLoader:
"""Get skill loader instance (singleton pattern)."""
Why Skill Loader?
Model Agnostic
Unlike other skill frameworks, Skill Loader doesn't tie you to any specific LLM or platform:
# Works with OpenAI
import openai
def openai_predict(prompt):
return openai.ChatCompletion.create(...)
# Works with Anthropic
import anthropic
def anthropic_predict(prompt):
return anthropic.messages.create(...)
# Works with local models
def local_predict(prompt):
return my_local_llm.generate(prompt)
# All work with Skill Loader
loader.find_skill_with_llm("query", openai_predict)
loader.find_skill_with_llm("query", anthropic_predict)
loader.find_skill_with_llm("query", local_predict)
No External Dependencies
Skill Loader uses only Python standard library, making it:
- Easy to install and deploy
- Compatible with any environment
- Lightweight and fast
License
MIT License - see LICENSE for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file skill_loader-0.1.0.tar.gz.
File metadata
- Download URL: skill_loader-0.1.0.tar.gz
- Upload date:
- Size: 15.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2356254427c8bb5fc480b00865a2193a4f05dccc14f94c78e6ce66ec7ba39d86
|
|
| MD5 |
40f905b793ffe74d8826d4dd19d1ec73
|
|
| BLAKE2b-256 |
60c8791ae6e6b0fa42c0a8d74d3f5207d210d305a8d53b3c8231d14b88b982e8
|
File details
Details for the file skill_loader-0.1.0-py3-none-any.whl.
File metadata
- Download URL: skill_loader-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be50d6164af1545b0d38e3e2d87599e0fb2e632f51cb19f42af676fc59a26027
|
|
| MD5 |
2cbe1a80ded1fb4ec1c874c885f0d97e
|
|
| BLAKE2b-256 |
81a5cb8c1b79e5377a989126c0855b3bf1d969b948b868c7e3ff20cfd25cfdf0
|