### Run a Basic Usage Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md
Execute the basic_usage.py example script from the repository root. This will start a Pydantic AI agent accessible at http://127.0.0.1:7932.
```bash
# from the repo root
python -m examples.basic_usage
```
--------------------------------
### Install Examples Dependency
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md
Install the 'examples' optional dependency group for pydantic-ai-skills. This command ensures all necessary packages for running the examples are available.
```bash
pip install -e ".[examples]"
# or with uv
uv sync --extra examples
```
--------------------------------
### Install Documentation Dependencies
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md
Install the project with documentation support. This is necessary for building or serving the project's documentation locally.
```bash
pip install -e ".[docs]"
```
--------------------------------
### Skills Toolset Initialization Examples
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Provides code examples for initializing the SkillsToolset with different configurations.
```APIDOC
## Usage Examples
### Initialize with File-Based Skills
```python
from pydantic_ai_skills import SkillsToolset
# Basic initialization - defaults to ./skills directory
toolset = SkillsToolset()
# Explicit single directory
toolset = SkillsToolset(directories=["./skills"])
# Multiple directories
toolset = SkillsToolset(
directories=["./skills", "./shared", "./custom"],
validate=True,
max_depth=3,
id="my-skills"
)
# Using SkillsDirectory instances directly
from pydantic_ai.toolsets.skills import SkillsDirectory
skills_dir = SkillsDirectory(
path="./skills",
validate=True,
max_depth=3
)
toolset = SkillsToolset(directories=[skills_dir])
```
### Initialize with Git Registry
```python
from pydantic_ai_skills import SkillsToolset
from pydantic_ai_skills.registries import GitSkillsRegistry, GitCloneOptions
# Clone a remote Git repository and load its skills
registry = GitSkillsRegistry(
repo_url='https://github.com/anthropics/skills',
path='skills',
target_dir='./anthropics-skills',
clone_options=GitCloneOptions(depth=1, single_branch=True),
)
toolset = SkillsToolset(registries=[registry])
# Combine with local skills
toolset = SkillsToolset(
directories=['./skills'],
registries=[registry],
)
```
### Initialize with Programmatic Skills
```python
from pydantic_ai import RunContext
from pydantic_ai.toolsets.skills import Skill, SkillsToolset
# Create a simple programmatic skill
my_skill = Skill(
name='custom-skill',
description='Custom programmatic skill',
content='Instructions for this skill...'
)
# Initialize toolset with programmatic skill
toolset = SkillsToolset(skills=[my_skill])
# Use the @skill() decorator to define skills inline
skills = SkillsToolset()
@skills.skill()
def data_analyzer() -> str:
"""Analyze data from various sources."""
return "Provide data analysis capabilities..."
@data_analyzer.resource
def get_schema() -> str:
"""Get available schema information."""
return "## Schema\n\nAvailable columns..."
@data_analyzer.script
async def analyze(ctx: RunContext[MyDeps], query: str) -> str:
"""Run analysis query."""
return await ctx.deps.database.execute(query)
```
### Mix File-Based and Programmatic Skills
```python
from pydantic_ai.toolsets.skills import Skill, SkillsToolset
```
```
--------------------------------
### Install Git-backed Registry Support
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
Install the necessary package for Git-backed registries. This requires GitPython.
```bash
pip install pydantic-ai-skills[git]
```
--------------------------------
### Environment Variable Configuration Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Provides an example of how to configure secrets using environment variables, avoiding hardcoding.
```bash
export XYZ_API_KEY="your-key-here"
```
--------------------------------
### Install S3-backed Registry Support
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
Install the necessary package for S3-backed registries. This requires boto3.
```bash
pip install pydantic-ai-skills[s3]
```
--------------------------------
### Serve Documentation Locally
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/CLAUDE.md
Starts a local web server to preview the project documentation. Changes to the documentation files will be reflected live.
```bash
mkdocs serve
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md
Install the project in editable mode with testing and Git support. This command is used for setting up the development environment.
```bash
pip install -e ".[test]"
pip install -e ".[git]"
```
--------------------------------
### SkillsCapability Integration Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/concepts.md
Demonstrates how to integrate skills into an Agent using the SkillsCapability, specifying directories where skills are located.
```python
from pydantic_ai import Agent
from pydantic_ai_skills import SkillsCapability
agent = Agent(
model='openai:gpt-5.2',
capabilities=[SkillsCapability(directories=['./skills'])]
)
```
--------------------------------
### Basic Agent Initialization and Execution
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/AGENT.md
Demonstrates how to initialize an Agent with a specific model and system prompt, and then perform both synchronous and asynchronous runs to get output.
```python
from pydantic_ai import Agent
agent = Agent(
'openai:gpt-4o',
system_prompt='You are a helpful assistant.',
retries=2,
)
# Sync run
result = agent.run_sync('What is the capital of France?')
print(result.output)
# Async run
import asyncio
async def main():
result = await agent.run('What is 2 + 2?')
print(result.output)
asyncio.run(main())
```
--------------------------------
### Basic Skill Structure Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
Illustrates the minimal directory structure for a basic skill, requiring only the SKILL.md file.
```markdown
my-skill/
└── SKILL.md # Required: Main instructions and metadata
```
--------------------------------
### Example .env File Configuration
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md
Configure environment variables for running pydantic-ai-skills examples. This includes the required Pydantic AI Gateway API key and optional Logfire token for observability.
```dotenv
# Pydantic AI Gateway (required)
PYDANTIC_AI_GATEWAY_API_KEY="your-gateway-api-key"
# Logfire observability (optional)
LOGFIRE_TOKEN="your-logfire-token"
```
--------------------------------
### Example: arXiv Search Skill Instructions
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Demonstrates how to write clear instructions for an arXiv search skill, including when to use it, how to call the script, and expected output format.
```markdown
---
name: arxiv-search
description: Search arXiv for research papers
---
# arXiv Search Skill
## When to Use
Use this skill when you need to:
- Find recent preprints in physics, math, or computer science
- Search for papers not yet published in journals
- Access cutting-edge research
## Instructions
To search arXiv, use the `run_skill_script` tool with:
1. **skill_name**: "arxiv-search"
2. **script_name**: "scripts/arxiv_search.py"
3. **args**:
- `query`: Required search query (e.g., "neural networks")
- `max-papers`: Optional, defaults to 10
## Examples
Search for 5 papers on machine learning:
```python
run_skill_script(
skill_name="arxiv-search",
script_name="scripts/arxiv_search.py",
args={"query": "machine learning", "max-papers": 5}
)
```
## Output Format
The script returns a formatted list with:
- Paper title
- Authors
- arXiv ID
- Abstract
## Adding Scripts
Scripts enable skills to perform custom operations that aren't available as standard agent tools.
### Script Location
Place scripts in either:
- `scripts/` subdirectory (recommended)
- Directly in the skill folder
```markdown
my-skill/
├── SKILL.md
└── scripts/
├── process_data.py
└── fetch_info.py
```
### Writing Scripts
Scripts should:
- Accept named command-line arguments (for example, using `argparse` in Python or an equivalent option parser in your runtime)
- Print output to stdout
- Exit with code 0 on success, non-zero on error
- Handle errors gracefully
#### Example Script
```python
#!/usr/bin/env python3
"""Example skill script."""
import sys
import json
def main():
if len(sys.argv) < 2:
print("Usage: process_data.py ")
sys.exit(1)
input_data = sys.argv[1]
try:
# Process the input
result = process(input_data)
# Output results
print(json.dumps(result, indent=2))
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
def process(data):
# Your processing logic here
return {"processed": data.upper()}
if __name__ == "__main__":
main()
```
### Script Best Practices
**✅ Do:**
- Validate input arguments
- Return structured output (JSON preferred)
- Handle errors gracefully
- Document expected inputs/outputs in SKILL.md
- Use timeouts for external calls
- Add a shebang line for interpreter portability (for example `#!/usr/bin/env python3`)
**❌ Don't:**
- Make network calls without timeouts
- Write to files outside the skill directory
- Require interactive input
- Use environment-specific paths
### Script Interpreter Selection
When filesystem scripts are executed, interpreter selection follows this order:
1. Shebang line, when present and resolvable
2. Extension-based fallback for compatibility (`.py`, `.sh`, `.bash`, `.zsh`, `.fish`, `.ps1`, `.bat`, `.cmd`)
3. Direct executable invocation fallback
This allows extensionless and custom-extension executable scripts to run while preserving compatibility with existing script names and extensions.
### Script Argument Handling
When agents call scripts via `run_skill_script()`, arguments are converted to command-line flags:
```python
```
--------------------------------
### Install Pre-commit Hooks
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
Install pre-commit hooks to automatically check code quality and style before committing.
```bash
pre-commit install
```
--------------------------------
### Reading Skill Resource Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Demonstrates how to read a resource file associated with a skill. Use for accessing API references or example data within a skill.
```python
read_skill_resource(
skill_name="api-integration",
resource_name="API_REFERENCE.md"
)
```
```python
read_skill_resource(
skill_name="api-integration",
resource_name="resources/examples.json"
)
```
--------------------------------
### Load Skill Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
An agent calls `load_skill` to retrieve the full instructions for a specific skill, such as 'arxiv-search'.
```python
# Agent calls this when a skill is relevant
result = await load_skill(ctx, "arxiv-search")
```
--------------------------------
### Dynamic Skill Refresh Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/quick-start.md
Demonstrates how to reload skills by recreating the SkillsToolset and Agent instances after filesystem changes.
```python
import asyncio
from pydantic_ai import Agent
from pydantic_ai_skills import SkillsToolset
async def main():
toolset = SkillsToolset(directories=["./skills"])
agent = Agent(
model='openai:gpt-5.2',
instructions="You are a helpful assistant.",
toolsets=[toolset]
)
# Use agent
result = await agent.run("What skills are available?")
print(result.output)
# ... User adds new skill to ./skills/ ...
# To pick up new skills, recreate the toolset and agent
toolset = SkillsToolset(directories=["./skills"])
agent = Agent(
model='openai:gpt-5.2',
instructions="You are a helpful assistant.",
toolsets=[toolset]
)
print(f"\nReloaded. Now have {len(toolset.skills)} skills")
result = await agent.run("What skills are available now?")
print(result.output)
if __name__ == "__main__":
asyncio.run(main())
```
--------------------------------
### Install pydantic-ai-skills
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
Install the package using pip. For development, include test dependencies.
```bash
pip install pydantic-ai-skills
```
```bash
pip install pydantic-ai-skills[test] # Includes pytest and coverage tools
```
--------------------------------
### run_skill_script() Tool Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Illustrates how an agent might call the `run_skill_script` tool to execute a specific script within a skill, passing arguments for the script. The example shows the agent's call and the internal toolset invocation.
```python
# Agent calls the tool
agent.run_sync('Run the arxiv search script with query "machine learning"')
# Internally calls:
# result = await toolset.run_skill_script(
# 'arxiv-search',
# 'arxiv_search',
# {'query': 'machine learning'}
# )
```
--------------------------------
### Run Skill Script Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
An agent executes a skill script, providing the skill name, script path, and a dictionary of arguments.
```python
# Agent executes scripts with arguments
result = await run_skill_script(
ctx,
"arxiv-search",
"scripts/arxiv_search.py",
{"query": "machine learning", "max-papers": 5}
)
```
--------------------------------
### Plain Text Output Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Shows how to generate output as plain text for human-readable reports or logs.
```python
output = """Analysis Results
================
Total records: 42
Average value: 123.45
Range: [10, 456]
Top 3 results:
1. Item A - 456
2. Item B - 234
3. Item C - 189
"""
print(output)
```
--------------------------------
### list_skills() Tool Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
An example of the markdown output returned by the `list_skills()` tool, which provides a formatted list of all available skills and their associated scripts.
```markdown
# Available Skills
## arxiv-search
Search arXiv for research papers (scripts: arxiv_search)
## web-research
Structured approach to web research
```
--------------------------------
### Install Development Dependencies
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
Install the project's development dependencies, including the package itself in editable mode.
```bash
pip install -e ".[dev]"
```
--------------------------------
### File-Based Skill Loading Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/types.md
Shows how to load skills from a directory using `SkillsToolset`. It iterates through the loaded skills, printing their names, descriptions, URIs, metadata, and lists of resources and scripts.
```python
from pydantic_ai_skills import SkillsToolset
toolset = SkillsToolset(directories=["./skills"])
# Access skills
for name, skill in toolset.skills.items():
print(f"\nSkill: {name}")
print(f" Description: {skill.description}")
if skill.uri: # File-based skill
print(f" URI: {skill.uri}")
# Access metadata
if skill.metadata and "version" in skill.metadata:
print(f" Version: {skill.metadata['version']}")
# List resources
if skill.resources:
print(f" Resources:")
for resource in skill.resources:
print(f" - {resource.name}")
# List scripts
if skill.scripts:
print(f" Scripts:")
for script in skill.scripts:
print(f" - {script.name}")
```
--------------------------------
### Minimal SKILL.md Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
A minimal SKILL.md file demonstrating the required YAML frontmatter for name and description, followed by Markdown instructions.
```markdown
---
name: my-skill
description: Brief description of what this skill does and when to use it
---
# My Skill
## When to Use This Skill
Use this skill when you need to:
- Do specific task A
- Handle scenario B
- Process data type C
## Instructions
1. Step 1
2. Step 2
3. Step 3
```
--------------------------------
### Example Docstring for discover_skills
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
Illustrates the expected docstring format for Python functions, including arguments, return values, exceptions, and an example usage.
```python
def discover_skills(
directories: list[str | Path],
validate: bool = True,
) -> list[Skill]:
"""Discover skills from filesystem directories.
Searches for SKILL.md files in the given directories and loads
skill metadata and structure.
Args:
directories: List of directory paths to search for skills.
validate: Whether to validate skill structure.
Returns:
List of discovered Skill objects.
Raises:
ValueError: If validation enabled and skill is invalid.
Example:
```python
skills = discover_skills(
directories=["./skills"],
validate=True
)
for skill in skills:
print(f"{skill.name}: {skill.metadata.description}")
```
"""
```
--------------------------------
### Running Skill Script Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Shows how to execute a script within a skill, passing arguments. Use for automating tasks like data analysis or visualization.
```python
run_skill_script(
skill_name="data-analyzer",
script_name="scripts/analyze.py",
args={"input": "data.csv", "output": "json"}
)
```
```python
run_skill_script(
skill_name="data-analyzer",
script_name="scripts/visualize.py",
args={"input": "data.csv", "type": "histogram"}
)
```
--------------------------------
### Example CHANGELOG Entry
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
Shows the format for adding release notes to the CHANGELOG file, including sections for Added and Fixed changes.
```markdown
## [Unreleased]
### Added
- New feature description (#PR_NUMBER)
### Fixed
- Bug fix description (#PR_NUMBER)
```
--------------------------------
### CSV Output Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Illustrates generating output in CSV format, suitable for tabular data exchange.
```python
import csv
import sys
data = [
{"id": 1, "name": "Alice", "score": 95},
{"id": 2, "name": "Bob", "score": 87}
]
writer = csv.DictWriter(sys.stdout, fieldnames=['id', 'name', 'score'])
writer.writeheader()
writer.writerows(data)
```
--------------------------------
### JSON Output Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Demonstrates how to format results as JSON, which is the recommended output format for structured data.
```python
import json
result = {
"success": True,
"data": [
{"id": 1, "value": 100},
{"id": 2, "value": 200}
],
"count": 2,
"metadata": {"query": "user_data", "timestamp": "2025-01-23"}
}
print(json.dumps(result, indent=2))
```
--------------------------------
### Dynamically Register a New Skill
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md
This example shows how to programmatically register a new skill after a toolset has been created. It uses the Skill model and an internal method for registration, which is not recommended for production.
```python
from pydantic_ai.toolsets.skills import Skill
# Create toolset
toolset = SkillsToolset()
# Register a new programmatic skill
new_skill = Skill(
name='dynamically-added',
description='Added after initialization',
content='This skill was registered dynamically'
)
toolset._register_skill(new_skill) # Internal method, use with caution
```
--------------------------------
### SKILL.md Frontmatter Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Shows how to use YAML frontmatter in a SKILL.md file to define metadata for a skill, such as its name and description.
```markdown
---
name: api-client
description: Work with the XYZ API
---
```
--------------------------------
### Custom In-Process Script Executor Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md
Provides a minimal example of setting up a custom script executor for in-process execution, suitable for local debugging. This executor uses `CallableSkillScriptExecutor` with a custom function.
```python
from pydantic_ai_skills import CallableSkillScriptExecutor, SkillsDirectory
async def in_process_executor(*, script, args=None):
# Development-only path for breakpoint debugging.
...
executor = CallableSkillScriptExecutor(func=in_process_executor)
skills_dir = SkillsDirectory(path='./skills', script_executor=executor)
```
--------------------------------
### Read Skill Resource Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
An agent uses `read_skill_resource` to access additional documentation files like FORMS.md for a given skill.
```python
# Agent loads resources only when needed
result = await read_skill_resource(ctx, "pdf-processing", "FORMS.md")
```
--------------------------------
### Programmatic Skill Creation Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/types.md
Demonstrates creating a programmatic skill using the `Skill` class and adding dynamic resources and scripts using decorators. This approach is suitable when skills are defined entirely in code.
```python
from pydantic_ai import RunContext
from pydantic_ai.toolsets.skills import Skill, SkillResource
# Assuming MyDeps is defined elsewhere
# class MyDeps:
# async def fetch_data(self) -> str:
# return "data"
# async def process(self, query: str) -> str:
# return f"processed {query}"
# Create a skill with static resources
my_skill = Skill(
name='my-skill',
description='A programmatic skill',
content='Instructions for using this skill...',
resources=[
SkillResource(
name='reference',
content='## Reference\n\nStatic documentation here...'
)
]
)
# Add dynamic resources
@my_skill.resource
def get_info() -> str:
"""Get dynamic information."""
return "Dynamic content generated at runtime"
@my_skill.resource
async def get_data(ctx: RunContext[MyDeps]) -> str:
"""Get data from dependencies."""
return await ctx.deps.fetch_data()
# Add scripts
@my_skill.script
async def process(ctx: RunContext[MyDeps], query: str) -> str:
"""Process a query.
Args:
query: The query to process
"""
result = await ctx.deps.process(query)
return f"Processed: {result}"
```
--------------------------------
### Extended Skill Structure Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
Shows an extended skill directory structure including optional files like FORMS.md, REFERENCE.md, scripts, and resources.
```markdown
my-skill/
├── SKILL.md # Required: Main instructions and metadata
├── FORMS.md # Optional: Form-filling guides
├── REFERENCE.md # Optional: Detailed API reference
├── scripts/ # Optional: executable scripts
│ ├── script1.py
│ └── script2.sh
└── resources/ # Optional: Additional files
├── templates/
└── data.json
```
--------------------------------
### Example Skill Script
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
A Python script demonstrating how to accept command-line arguments, process data, and output results as JSON. Includes basic error handling and argument validation.
```python
#!/usr/bin/env python3
"""Example skill script."""
import sys
import json
def main():
if len(sys.argv) < 2:
print("Usage: process_data.py ")
sys.exit(1)
input_data = sys.argv[1]
try:
# Process the input
result = process(input_data)
# Output results
print(json.dumps(result, indent=2))
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
def process(data):
# Your processing logic here
return {"processed": data.upper()}
if __name__ == "__main__":
main()
```
--------------------------------
### Custom Instruction Template with Skills
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Shows how to use a custom instruction template that includes a list of available skills for an agent. This template guides the agent on how to utilize specialized skills.
```python
from pydantic_ai import Agent
from pydantic_ai.toolsets.skills import SkillsToolset
custom_instructions = """
You have specialized skills available for specific domains.
Each skill includes instructions, resources, and executable scripts.
Available skills:
{skills_list}
Use `load_skill` to explore any skill that's relevant to the user's request.
"""
toolset = SkillsToolset(
directories=["./skills"],
instruction_template=custom_instructions
)
agent = Agent(
model='openai:gpt-4o',
toolsets=[toolset]
)
```
--------------------------------
### Chaining Registry Operations
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
Wrappers like `filtered` and `prefixed` can be chained for complex skill selection and naming. This example starts with a Git registry, filters for document-related skills, and then prefixes their names.
```python
registry = GitSkillsRegistry(
repo_url='https://github.com/anthropics/skills',
path='skills',
target_dir='./cached-skills',
)
doc_skills = (
registry
.filtered(lambda s: s.name in ('pdf', 'docx', 'pptx'))
.prefixed('docs-')
)
# doc_skills now has: 'docs-pdf', 'docs-docx', 'docs-pptx'
```
--------------------------------
### Serve and Build Documentation
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md
Serve the project documentation locally for preview or build it for deployment. These commands use MkDocs to manage documentation.
```bash
mkdocs serve
mkdocs build
```
--------------------------------
### Install arxiv Python Package
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md
Installs the 'arxiv' Python package using pip. This is a required dependency for the arxiv-search skill and should be installed if not already present.
```bash
pip install arxiv
```
--------------------------------
### Agent Instantiation and Basic Run
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/SKILL.md
Instantiate an agent with a model string and system prompt, then run a synchronous query.
```python
from pydantic_ai import Agent
agent = Agent(
'openai:gpt-4o', # model string: provider:model-name
system_prompt='Be helpful.',
)
result = agent.run_sync('What is the capital of France?')
print(result.output)
```
--------------------------------
### Initialize Agent with SkillsCapability
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/capability.md
Demonstrates how to initialize an Agent with SkillsCapability, specifying local skill directories and enabling auto-reloading.
```python
from pydantic_ai import Agent
from pydantic_ai_skills import SkillsCapability
agent = Agent(
model='openai:gpt-5.2',
capabilities=[
SkillsCapability(
directories=['./skills'],
auto_reload=True,
)
],
)
```
--------------------------------
### Install Pydantic AI MCP Package
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MCP.md
Install the pydantic-ai-slim package with MCP support using pip.
```bash
pip install "pydantic-ai-slim[mcp]"
```
--------------------------------
### Build Documentation
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/CLAUDE.md
Builds the static documentation files for the project. The output will be in the `site` directory.
```bash
mkdocs build
```
--------------------------------
### Agent Initialization with Dependencies
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md
Shows how to initialize an Agent with custom dependencies, which are then accessible via RunContext in skills and scripts. Ensure all required dependencies are provided.
```python
from pydantic_ai import Agent
agent = Agent(
model='openai:gpt-4o',
deps=MyDeps(
database=my_database,
cache=my_cache,
logger=my_logger
),
toolsets=[skills]
)
result = agent.run_sync('Query the user database', deps=agent.deps)
```
--------------------------------
### Agent Initialization with SkillsCapability
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/quick-start.md
Initializes an agent using SkillsCapability, pointing to a directory containing skills. This is the preferred method for integrating skills.
```python
from pydantic_ai import Agent
from pydantic_ai_skills import SkillsCapability
agent = Agent(
model='openai:gpt-5.2',
instructions='You are a helpful assistant.',
capabilities=[SkillsCapability(directories=['./skills'])]
)
result = agent.run_sync('How do I create a Pydantic AI agent with tools?')
print(result.output)
```
--------------------------------
### Circular Dependency Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Demonstrates a circular dependency anti-pattern where skills explicitly depend on each other.
```markdown
# skill-a/SKILL.md
To use this skill, first load skill-b...
# skill-b/SKILL.md
This skill requires skill-a to be loaded...
```
--------------------------------
### Hardcoded Secret Anti-Pattern
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Shows an example of hardcoding sensitive information like API keys directly in the code.
```plaintext
API_KEY = "sk-1234567890abcdef"
```
--------------------------------
### Defining and Using Function Tools
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/FUNCTION_TOOLS.md
Demonstrates defining plain tools, context-aware tools, and unreliable tools with retries using Pydantic AI decorators. Shows how to run the agent with dependencies.
```python
import random
from pydantic_ai import Agent, RunContext, ModelRetry
agent = Agent('openai:gpt-4o', deps_type=str)
@agent.tool_plain
def roll_die() -> str:
"""Roll a six-sided die and return the result."""
return str(random.randint(1, 6))
@agent.tool
def get_player_name(ctx: RunContext[str]) -> str:
"""Return the current player's name."""
return ctx.deps
@agent.tool(retries=3)
def unreliable_api(ctx: RunContext[str], query: str) -> str:
"""Call an API that might fail."""
if not query:
raise ModelRetry('Please provide a non-empty query')
return f'Result for {query}'
result = agent.run_sync('Roll the die for me!', deps='Alice')
```
--------------------------------
### Initialize SkillsToolset with SkillsDirectory Instances
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Initializes the SkillsToolset using SkillsDirectory instances for more granular control over skill discovery.
```python
from pydantic_ai_skills import SkillsToolset
from pydantic_ai.toolsets.skills import SkillsDirectory
skills_dir = SkillsDirectory(
path="./skills",
validate=True,
max_depth=3
)
toolset = SkillsToolset(directories=[skills_dir])
```
--------------------------------
### Implement Sandboxed Execution Executor
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md
Example of a custom executor that runs Python scripts in isolated sandboxes using subprocess.
```python
import subprocess
from pathlib import Path
import os
class SandboxedExecutor:
"""Execute Python scripts in isolated sandboxes."""
def __init__(self, timeout: int = 30):
self.timeout = timeout
async def execute(self, script: SkillScript, args: dict | None = None) -> str:
"""Execute script in sandbox."""
# Convert args to environment variables
env = {f"ARG_{k.upper()}": str(v) for k, v in (args or {}).items()}
try:
result = subprocess.run(
["sandbox", "--timeout", str(self.timeout), script.name],
capture_output=True,
text=True,
env={**os.environ, **env},
timeout=self.timeout + 5
)
return result.stdout or result.stderr
except subprocess.TimeoutExpired:
return f"ERROR: Script execution timed out after {self.timeout}s"
```
--------------------------------
### Initialize SkillsToolset with Multiple Directories and Options
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Initializes the SkillsToolset with multiple directories and custom validation and depth settings.
```python
from pydantic_ai_skills import SkillsToolset
# Multiple directories
toolset = SkillsToolset(
directories=["./skills", "./shared", "./custom"],
validate=True,
max_depth=3,
id="my-skills"
)
```
--------------------------------
### Markdown for Exit Code Documentation
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Example of documenting script exit codes in a SKILL.md file, explaining the meaning of each code for users.
```markdown
## Script: analyze
Executes data analysis with exit codes:
- **0**: Success
- **1**: Validation error (bad input)
- **2**: Timeout (operation too slow)
- **3**: System error (unexpected failure)
### Examples
```python
# Successful analysis
run_skill_script('data-skill', 'analyze', {'query': 'SELECT count(*) FROM users'})
# Returns: {"count": 42, "time_ms": 123}
# Invalid input (exits with code 1)
run_skill_script('data-skill', 'analyze', {'query': 'INVALID SQL'})
# Returns: ERROR: Syntax error in SQL query
```
```
--------------------------------
### Pull Request Template Example
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
A template for creating pull requests, including sections for description, type of change, and a checklist of requirements.
```markdown
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] CHANGELOG updated
- [ ] All tests pass
- [ ] Pre-commit checks pass
```
--------------------------------
### Create and Activate Virtual Environment
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md
Create a Python virtual environment and activate it to manage project dependencies.
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```
--------------------------------
### Skills Toolset Initialization
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Demonstrates various ways to initialize the SkillsToolset, including using local directories, Git registries, and programmatic skills.
```APIDOC
## Constructor: SkillsToolset
### Description
Initializes the SkillsToolset, which manages and discovers skills for AI agents. It can load skills from local directories, remote Git repositories via registries, or directly defined programmatic skills.
### Parameters
* **`skills`** (`list[Skill] | None`): Pre-loaded Skill objects. Defaults to `None`.
* **`directories`** (`list[str | Path | SkillsDirectory] | None`): Directories or SkillsDirectory instances to discover skills from. Defaults to `["./skills"]` if neither `skills` nor `directories` are provided.
* **`registries`** (`list[SkillRegistry] | None`): List of SkillRegistry instances (e.g., `GitSkillsRegistry`) to load skills from. Registries have the lowest priority.
* **`validate`** (`bool`): Validate skill structure during discovery. Defaults to `True`.
* **`max_depth`** (`int | None`): Maximum depth for skill discovery. Defaults to `3`.
* **`id`** (`str | None`): Unique identifier for this toolset. Defaults to `None`.
* **`instruction_template`** (`str | None`): Custom instruction template for skills system prompt. Must include `{skills_list}` placeholder. Defaults to `None` (uses default template).
* **`max_retries`** (`int`): Maximum number of retries for tool calls that raise `ModelRetry`. Defaults to `1`.
### Properties
* **`skills`** (`dict[str, Skill]`): Dictionary of all available skills, keyed by skill name.
### Methods
* **`get_skill(skill_name: str) -> Skill`**: Retrieve a specific skill by name. Raises `KeyError` if not found.
* **`get_instructions(ctx: RunContext[Any]) -> str | None`**: Returns formatted system prompt with skills instructions, or `None` if no skills are loaded. Called automatically by the agent.
```
--------------------------------
### Get a Skill from Combined Registries
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
When multiple registries provide a skill with the same name, the first registry in the order passed to `CombinedRegistry` wins.
```python
skill = await combined.get('pdf')
```
--------------------------------
### Agent Integration with Skills Toolset
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Demonstrates setting up an agent with a SkillsToolset, where skill instructions are automatically injected into the agent's system prompt. The agent can then be used to run tasks that leverage these skills.
```python
from pydantic_ai import Agent
from pydantic_ai_skills import SkillsToolset
toolset = SkillsToolset(directories=["./skills"])
agent = Agent(
model='openai:gpt-4o',
instructions="You are a helpful assistant.",
toolsets=[toolset]
)
# Skill instructions are injected into the agent's system prompt automatically.
result = agent.run_sync('Analyze the quarterly data')
```
--------------------------------
### Initialize S3SkillsRegistry with MinIO
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
Configure and initialize S3SkillsRegistry to connect to an S3-compatible store like MinIO. This requires building a custom boto3 client with the correct endpoint URL, credentials, and path-style addressing configuration.
```python
import boto3
from botocore.config import Config
from pydantic_ai_skills.registries import S3SkillsRegistry
client = boto3.client(
"s3",
endpoint_url="http://localhost:9000",
aws_access_key_id="minioadmin",
aws_secret_access_key="minioadmin",
config=Config(s3={"addressing_style": "path"}),
)
registry = S3SkillsRegistry(bucket="skills", boto3_client=client)
```
--------------------------------
### Initialize Skills Toolset with Directories
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Initializes a SkillsToolset by specifying directories to load skills from. Useful for organizing skills in a categorized structure.
```python
toolset = SkillsToolset(directories=[
"./skills/research",
"./skills/data-processing",
"./skills/communication"
])
```
--------------------------------
### Implement Remote Execution Executor
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md
Example of a custom executor that sends script execution requests to a remote server via HTTP POST.
```python
from pydantic_ai.toolsets.skills import SkillScript, CallableSkillScriptExecutor
import httpx
class RemoteExecutor:
"""Execute scripts on a remote server."""
def __init__(self, server_url: str):
self.server_url = server_url
async def execute(self, script: SkillScript, args: dict | None = None) -> str:
"""Send script execution request to remote server."""
async with httpx.AsyncClient() as client:
response = await client.post(
f"{self.server_url}/execute",
json={
"script_name": script.name,
"args": args or {}
}
)
return response.text
# Use in custom script definitions
from pydantic_ai.toolsets.skills import SkillScript
remote_executor = RemoteExecutor("https://api.example.com")
script = SkillScript(
name='remote-analysis',
description='Run analysis on remote server',
function=None,
executor=remote_executor # Custom executor
)
```
--------------------------------
### SkillRegistry Methods
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/registries.md
Provides documentation for the core methods available in the SkillRegistry class, including searching, retrieving, installing, updating, and listing skills.
```APIDOC
## SkillRegistry
### Description
Manages a collection of AI skills, allowing for searching, retrieval, installation, and updates.
### Methods
#### `search(query: str)`
Searches for skills matching the given query.
#### `get(skill_id: str)`
Retrieves a specific skill by its ID.
#### `install(skill_data: dict)`
Installs a new skill into the registry.
#### `update(skill_id: str, skill_data: dict)`
Updates an existing skill in the registry.
#### `get_skills()`
Returns a list of all skills available in the registry.
#### `filtered(filter_func: callable)`
Returns a filtered list of skills based on the provided filter function.
#### `prefixed(prefix: str)`
Returns skills that have a specific prefix.
#### `renamed(rename_map: dict)`
Returns skills with renamed identifiers based on the provided map.
```
--------------------------------
### Instantiate Agent with Model Settings
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MODELS.md
Instantiate an Agent with specific model inference parameters like temperature and max_tokens using ModelSettings.
```python
from pydantic_ai import Agent
from pydantic_ai.settings import ModelSettings
agent = Agent(
'openai:gpt-4o',
model_settings=ModelSettings(temperature=0.2, max_tokens=1024),
)
```
--------------------------------
### Optional SKILL.md Frontmatter Fields
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/concepts.md
Provides an example of a SKILL.md file's YAML frontmatter with optional fields like version, author, and category.
```yaml
---
name: arxiv-search
description: Search arXiv for research papers
version: 1.0.0
author: Your Name
category: research
---
```
--------------------------------
### Skill Structure with API Reference (Version 2)
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md
Illustrates a skill directory structure including a separate API reference file.
```markdown
api-client/
├── SKILL.md
└── API_REFERENCE.md
```
--------------------------------
### Create and Combine Skills in Toolset
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Demonstrates creating a programmatic skill and combining it with file-based skills in a SkillsToolset. The total number of loaded skills is then printed.
```python
programmatic_skill = Skill(
name='runtime-skill',
description='Created at runtime',
content='Dynamic skill content...'
)
toolset = SkillsToolset(
directories=["./skills"], # File-based skills from directory
skills=[programmatic_skill], # Programmatic skills
max_depth=3 # Limit directory discovery depth
)
@toolset.skill()
def extra_skill() -> str:
return "Additional dynamically-defined skill..."
print(f"Total skills loaded: {len(toolset.skills)}")
```
--------------------------------
### Lazy Initialization of Expensive Resources
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/patterns.md
Defer the initialization of expensive resources until they are actually needed. This improves startup performance by avoiding upfront setup costs.
```python
from pydantic_ai.toolsets.skills import SkillsToolset
from pydantic_ai import RunContext
class MyDeps:
# Assume database, cache, logger, config are defined here or elsewhere
pass
async def initialize_expensive_resource():
# Placeholder for expensive resource initialization
print("Initializing expensive resource...")
await asyncio.sleep(2) # Simulate initialization time
return "Expensive Resource Instance"
skills = SkillsToolset()
@skills.skill()
def expensive_skill() -> str:
return "Use expensive resources"
@expensive_skill.resource
async def get_expensive_resource(ctx: RunContext[MyDeps]) -> str:
"""Lazy-load expensive resource only when needed."""
# First call initializes, subsequent calls reuse
if not hasattr(ctx.deps, '_expensive_resource'):
ctx.deps._expensive_resource = await initialize_expensive_resource()
return str(ctx.deps._expensive_resource)
```
--------------------------------
### Creating a Custom Wrapper Registry
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md
Extend `WrapperRegistry` to create custom composition wrappers. This example defines a `LoggingRegistry` that logs search operations performed on the wrapped registry.
```python
from pydantic_ai_skills.registries import WrapperRegistry
from pydantic_ai_skills.types import Skill
class LoggingRegistry(WrapperRegistry):
"""Registry that logs all operations."""
async def search(self, query: str, limit: int = 10) -> list[Skill]:
print(f'Searching for: {query}')
results = await self.wrapped.search(query, limit)
print(f'Found {len(results)} results')
return results
```
--------------------------------
### Initialize SkillsToolset with Git Registry
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md
Initializes the SkillsToolset by cloning a remote Git repository and loading skills from it.
```python
from pydantic_ai_skills import SkillsToolset
from pydantic_ai_skills.registries import GitSkillsRegistry, GitCloneOptions
# Clone a remote Git repository and load its skills
registry = GitSkillsRegistry(
repo_url='https://github.com/anthropics/skills',
path='skills',
target_dir='./anthropics-skills',
clone_options=GitCloneOptions(depth=1, single_branch=True),
)
toolset = SkillsToolset(registries=[registry])
```
--------------------------------
### Load MCP Servers from Configuration File
Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MCP.md
Load multiple MCP servers from a JSON configuration file. This simplifies the setup when dealing with numerous MCP server integrations.
```python
from pydantic_ai.mcp import load_mcp_servers
servers = load_mcp_servers('mcp_config.json')
agent = Agent('openai:gpt-4o', toolsets=servers)
# Config supports ${VAR} and ${VAR:-default} env var expansion.
```