Skip to main content

Skills Discovery

Agent Skills provides three ways to load skills into a toolset, plus a search API for runtime discovery. The three mechanisms can be combined freely.

Loading Skills into a Toolset​

1. Path-based loading​

Point AgentSkillsToolset at one or more local directories. Every sub-directory containing a SKILL.md file is discovered automatically when the toolset is first used.

When to use: skills checked into the same repository, or mounted at a well-known path at runtime (e.g. a Kubernetes shared volume).

from agent_skills import AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

toolset = AgentSkillsToolset(
directories=["./skills"], # scanned recursively for SKILL.md
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

Expected directory layout:

skills/
├── pdf-extractor/
│ ├── SKILL.md
│ └── scripts/
│ └── extract.py
└── data-analyzer/
├── SKILL.md
└── scripts/
└── analyze.py

2. Module-based loading​

Use AgentSkill.from_module() to load skills that are packaged inside an installed Python library. Works for both regular packages (with __init__.py) and namespace packages (directories without __init__.py, where __file__ is None).

When to use: skills distributed as part of a pip-installable package, such as the built-in skills in agent-skills itself.

from agent_skills import AgentSkill, AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

toolset = AgentSkillsToolset(
skills=[
AgentSkill.from_module("agent_skills.skills.crawl"),
AgentSkill.from_module("agent_skills.skills.github"),
AgentSkill.from_module("agent_skills.skills.pdf"),
AgentSkill.from_module("agent_skills.skills.events"),
],
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

from_module() imports the module, resolves its directory, and delegates to AgentSkill.from_skill_md() — no extra configuration needed.

3. Entrypoint-based loading (automatic)​

Installed Python packages that declare entrypoints in the agent_skills.skills group are discovered automatically when the toolset initialises. No explicit configuration is required — just install the package and the skills appear.

When to use: distributing skills as standalone pip-installable packages that consumers can install independently. This is the recommended approach for sharing skills across teams or publishing them on PyPI.

from agent_skills import AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

# Entrypoint skills are found automatically — no skills= or directories= needed
toolset = AgentSkillsToolset(
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

The package registers its skills in pyproject.toml:

[project.entry-points."agent_skills.skills"]
whoami = "datalayer_skills.skills.whoami"

Each key is a skill name and each value is a dotted Python module path that contains a SKILL.md file (the same layout used by AgentSkill.from_module()).

To disable entrypoint scanning (e.g. for testing), set discover_entrypoints=False:

toolset = AgentSkillsToolset(
discover_entrypoints=False,
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

You can also call the discovery function directly:

from agent_skills import discover_entrypoint_skills

for skill in discover_entrypoint_skills():
print(f"{skill.name}: {skill.description}")

Combining all three​

The three approaches stack freely. Skills loaded via skills= are merged with any skills discovered from directories= and from entrypoints:

toolset = AgentSkillsToolset(
directories=["./skills"], # local / custom skills
skills=[
AgentSkill.from_module("agent_skills.skills.crawl"),
],
# discover_entrypoints=True (default) — finds installed packages too
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

In a Kubernetes / SaaS pod​

In the Datalayer SaaS deployment the agent-runtimes container runs alongside a Jupyter container in the same pod. The two loading patterns map to the two-container architecture as follows:

┌─────────────────────────────── Pod ────────────────────────────────────┐
│ │
│ agent-runtimes :8765 jupyter :2300 │
│ ┌──────────────────────────┐ ┌────────────────────────────┐ │
│ │ AgentSkillsToolset │ │ Jupyter Kernel │ │
│ │ │ │ ┌──────────────────────┐ │ │
│ │ Module-based ──────────►│──reads────► │ skill script code │ │ │
│ │ (agent_skills pip pkg) │ script │ │ (sent as string via │ │ │
│ │ │ content │ │ SandboxExecutor) │ │ │
│ │ Path-based ────────────►│──reads────► └──────────────────────┘ │ │
│ │ (/mnt/shared-agent/ │ SKILL.md │ │ │
│ │ skills/) │ │ Shared Volume: │ │
│ └──────────────────────────┘ │ /mnt/shared-agent/ │ │
│ │ └── skills/ ◄── also │ │
│ │ accessible here │ │
│ └────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
  • Module-based — agent-skills is pip-installed in the image → the agent uses AgentSkill.from_module() to get skill metadata. Script code is read from the installed package and sent as a string to the Jupyter kernel via SandboxExecutor.

  • Path-based — the container entrypoint copies /opt/datalayer/skills/ → /mnt/shared-agent/skills/ (a Kubernetes emptyDir shared by both containers). Set AGENT_RUNTIMES_SKILLS_FOLDER=/mnt/shared-agent/skills so agent-runtimes scans the shared volume for any additional or custom skills.

Regardless of how a skill is loaded, script execution always happens inside the Jupyter kernel — the SandboxExecutor reads the script file content from the agent-runtimes side and sends it as Python source code to the kernel over the Jupyter HTTP API.


Runtime Discovery via the Agent​

When AgentSkillsToolset is attached to an agent, the agent can discover skills dynamically through two built-in tools.

list_skills​

Lists all available skills with summaries:

# Agent calls: list_skills()
# Returns:
[
{
"name": "data-analyzer",
"description": "Analyzes datasets and provides insights",
"tags": ["data", "analysis"],
"scripts": ["analyze", "summarize"],
"resources": ["reference"]
},
{
"name": "file-processor",
"description": "Process files in batches",
"tags": ["files", "batch"],
"scripts": ["process", "validate"],
"resources": []
}
]

load_skill​

Get full details for a specific skill:

# Agent calls: load_skill(skill_name="data-analyzer")
# Returns:
{
"name": "data-analyzer",
"description": "Analyzes datasets and provides insights",
"content": "# Data Analyzer\n\nUse this skill to analyze...",
"scripts": [
{"name": "analyze", "description": "Analyze a data file"},
{"name": "summarize", "description": "Summarize analysis results"}
],
"resources": [
{"name": "reference", "description": "Reference documentation"}
],
"tags": ["data", "analysis"],
"allowed_tools": ["filesystem__read_file"],
"version": "1.0.0"
}

The agent calls list_skills to browse what is available, then load_skill to get the full instructions before executing a skill script.