Loading Skills

Load skills into agents using LocalSkills and the Skills orchestrator.

Skills are loaded using the Skills class with one or more SkillLoader instances set as loaders.

Currently, LocalSkills is available for loading skills from the filesystem.

Setup

In an activated virtual environment, install Agno and the model client:

uv pip install -U agno openai
export OPENAI_API_KEY="your_openai_api_key"

Save this as create_skill.py and run python create_skill.py. It creates a small skill beside the script:

create_skill.py
from pathlib import Path

skill_dir = Path(__file__).parent / "skills" / "code-review"
skill_dir.mkdir(parents=True, exist_ok=True)
skill_file = skill_dir / "SKILL.md"
if not skill_file.exists():
    skill_file.write_text(
        "---\n"
        "name: code-review\n"
        "description: Review small Python functions for clear names and correct behavior.\n"
        "---\n\n"
        "# Code review\n\n"
        "Read the supplied code. Identify concrete correctness issues, explain them, "
        "and propose a minimal improvement. State when additional context is needed.\n"
    )
print(skill_file)

Save the agent or team script in the same directory. Its skills/code-review/SKILL.md now exists before LocalSkills loads it.

Basic Usage

from pathlib import Path

from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.skills import Skills, LocalSkills

# Load skills from a directory
agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    skills=Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills"))])
)

LocalSkills Loader

The LocalSkills loader reads skills from the local filesystem.

Loading from a Directory of Skills

If you have multiple skills in subdirectories:

skills/
├── code-review/
│   └── SKILL.md
├── git-workflow/
│   └── SKILL.md
└── testing/
    └── SKILL.md
from pathlib import Path
from agno.skills import Skills, LocalSkills

# Load all skills from the directory
skills = Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills"))])

Loading a Single Skill

If you want to load just one skill:

from pathlib import Path
from agno.skills import Skills, LocalSkills

# Load a single skill directory
skills = Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills" / "code-review"))])

Multiple Loaders

Configuration fragment: replace these paths with existing skill directories to combine multiple loaders:

from pathlib import Path
from agno.skills import Skills, LocalSkills

skills = Skills(loaders=[
    LocalSkills("/path/to/shared-skills"),
    LocalSkills("/path/to/project-skills"),
])

If skills from different loaders have the same name, the later loader's skill will overwrite the earlier one.

Agent Tools

When you add skills to an agent, it automatically gets access to these tools:

ToolDescription
get_skill_instructions(skill_name)Load full instructions for a skill
get_skill_reference(skill_name, reference_path)Load a reference document
get_skill_script(skill_name, script_path, execute, args, timeout)Read or execute a script

Example: Using Skill Tools

from pathlib import Path

from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.skills import Skills, LocalSkills

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    skills=Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills"))]),
    instructions=[
        "You have access to specialized skills.",
        "Use get_skill_instructions to load full guidance when needed.",
    ],
)

# The model decides whether to call the skill tools.
agent.print_response("Review this code for best practices: def foo(): pass")

System Prompt Integration

Skills metadata is automatically added to the agent's system prompt. The agent sees:

  • Skill names and descriptions
  • Available scripts and references
  • Instructions on how to load full skill details

This exposes metadata first and detailed content through tool calls. The local loader has already read and parsed skill files.

Reloading Skills

If your skills change at runtime, you can reload them:

from pathlib import Path
from agno.skills import Skills, LocalSkills

skills = Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills"))])

# ... skills are modified on disk ...

# Reload to pick up changes
skills.reload()

Error Handling

Skills are validated when loaded. If validation fails, a SkillValidationError is raised:

from agno.skills import Skills, LocalSkills, SkillValidationError

try:
    skills = Skills(loaders=[LocalSkills(str(Path(__file__).parent / "skills"))])
except SkillValidationError as e:
    print(f"Skill validation failed: {e}")
    print(f"Errors: {e.errors}")

Pass validate=False to LocalSkills to skip spec validation. Invalid skills then load on a best-effort basis; unreadable files and other parsing/loading failures can be skipped with a warning. Skills also catches non-validation loader errors, such as a missing directory, and can return an empty skill set. Verify loading explicitly:

print(skills.get_skill_names())
if "code-review" not in skills.get_skill_names():
    raise RuntimeError("The code-review skill did not load")

Complete Example

from pathlib import Path

from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.skills import Skills, LocalSkills

# Get skills directory relative to this file
skills_dir = Path(__file__).parent / "skills"

# Create agent with skills
agent = Agent(
    name="Code Assistant",
    model=OpenAIResponses(id="gpt-5.2"),
    skills=Skills(loaders=[LocalSkills(str(skills_dir))]),
    instructions=[
        "You are a helpful coding assistant with access to specialized skills."
    ],
    markdown=True,
)

if __name__ == "__main__":
    agent.print_response(
        "Review this Python function:\n\n"
        "def calc(x,y): return x+y"
    )