Skip to content

3.2. Skills

What is an Agent Skill?

An Agent Skill is a directory rooted at SKILL.md with metadata and instructions for one task class. The model first sees a compact name/description and loads the body only when relevant. This progressive disclosure reduces routine context size and avoids exposing every procedure to every turn.

What does the course skill contain?

agents/data/skills/incident-triage/SKILL.md declares:

---
name: incident-triage
description: How to prioritize and triage open incidents for the Ops Copilot.
---

Its body defines a deterministic triage procedure: exclude resolved incidents, sort SEV1 before SEV2 before SEV3, break ties by oldest opened_at, check service status, and never invent data. The source file remains the canonical complete instruction.

How are skills loaded safely?

def skills_dir() -> Path:
    return settings.data_dir / "skills"


def skill_toolset() -> SkillToolset:
    base = skills_dir()
    skills = [load_skill_from_dir(base / name) for name in list_skills_in_dir(base)]
    return SkillToolset(skills=skills, tool_filter=["list_skills", "load_skill"])

The tool filter is intentional. The agent may discover and load instructions, but it cannot invoke broader skill-resource or script execution capabilities. Files come only from the configured immutable dataset directory.

When should you use a skill instead of a tool?

  • Use a tool for a typed observation or action.
  • Use a skill for a reusable decision procedure that composes existing tools.
  • Use the system instruction for rules that apply to every task.
  • Use code or policy for invariants the model must not bypass.

A triage ranking procedure is a skill. Fetching incidents is a tool. Requiring approval for writes is runtime policy.

What are the security risks?

Skill text enters model context and must be treated as executable influence. Review its provenance, restrict directories and allowed tools, avoid secret material, reject path traversal/symlinks where relevant, and test malformed metadata. Loading a repository skill is not equivalent to trusting arbitrary user-supplied Markdown.

How do you add a skill?

  1. Create one kebab-case directory under agents/data/skills.
  2. Add valid name/description front matter and focused instructions.
  3. Refer only to tools the agent actually owns.
  4. Add discovery, load, missing, and malformed tests.
  5. Add an evaluation case proving the skill changes the intended trajectory.

Keep a skill small enough that loading it is cheaper and safer than adding its content to every system prompt.

What is the skill checkpoint?

cd agents/python
uv run pytest tests/test_skills.py

Confirm only list_skills and load_skill are exposed, the triage skill is discoverable, an unknown/path-traversal name fails safely, and root-agent instructions tell the model when to load it.

How would you author a new Agent Skill?

Exercise: add a second skill and wire its progressive disclosure.

  • Goal: create a new skill (e.g. postmortem-writer) that is discoverable via list_skills, loadable by name via load_skill, and only pulled in for its task — never injected into every prompt.
  • Files to touch: a new SKILL.md (plus any resources) under agents/data/skills/<your-skill>/, the root-agent instruction so the model knows when to load it, and cases in agents/python/tests/test_skills.py.
  • Gate that proves completion: cd agents/python && uv run pytest tests/test_skills.py passes, showing the new skill lists, loads by exact name, and rejects an unknown/path-traversal name safely — while the allowlist still exposes only list_skills and load_skill.