Layer 3: Active Skill Context — Full Instructions, Loaded On Demand
~13 min read
Layer 3 loads a skill's full SKILL.md body only once it's been selected as relevant — and supporting files (scripts, templates) go further still, never entering context at all until actually invoked.
Layer 2 (previous subtopic) is the cheap triage step; Layer 3 is what actually happens once triage selects a skill as relevant. Per this course: Layer 3: Active Skill Context — SKILL.md files and associated documentation are loaded as needed. This is the expensive, detailed layer — the actual instructions, examples, and edge-case handling that make a skill useful — but it only enters context for skills Layer 2 already flagged as relevant, never for the whole library.
Zooming into this course's 'Anatomy of a Skill' section fills in what this actually contains: a skill is simply a folder, with a skill.md file holding TWO layers of context within itself — the YAML Front Matter (this is literally Layer 2's content, living inside the same file) and the Skill Body: the detailed instructions, workflows, examples, and guidance used during execution (this is Layer 3's content). So Layers 2 and 3 aren't two separate files — they're two sections of the SAME skill.md file, with the system choosing to load only the top (frontmatter) section during triage, and only pulling in the rest once the skill is actually selected.
There's a further, even cheaper tier beyond Layer 3 worth knowing: optional supporting files such as scripts, templates or reference docs. These aren't loaded into context, they're fetched only when the agent needs them, consuming zero tokens until that moment. This is a real fourth tier of laziness beyond this course's own named three layers — even after a skill's full instructional body is loaded (Layer 3), any accompanying scripts or reference files it points to stay OUTSIDE the context window entirely, fetched directly (like running a script, or reading a template file) rather than being read into the model's context as text. This separation lets Claude stay lightweight until a specific skill is activated — and even then, only as much of that skill as is actually being used at each moment enters context.
Put together across all three subtopics: Layer 1 is always present (universal, cheap per-turn), Layer 2 is always scanned but tiny (cheap triage across everything), and Layer 3 is expensive but rare (loaded fully, only for whatever's actually relevant right now) — with supporting files going a step further and staying out of context entirely until directly used. This architecture supports hundreds of skills without breaching context limits, exactly because each layer's cost scales with a different, carefully chosen thing: Layer 1 with the project (roughly constant), Layer 2 with the total skill count (but tiny per skill), and Layer 3 with only the skills ACTUALLY in use right now (not the total library size at all).
💻 Code example
# Modeling Layer 3 (Active Skill Context) and the further-lazy
# supporting-files tier -- both loaded only ON DEMAND, unlike
# Layer 1 (always) and Layer 2 (always, but tiny).
class Skill:
def __init__(self, name: str, yaml_frontmatter: str, skill_body: str,
supporting_files: dict[str, str]):
self.name = name
self.yaml_frontmatter = yaml_frontmatter # Layer 2 content
self.skill_body = skill_body # Layer 3 content
self.supporting_files = supporting_files # NEVER auto-loaded into context
class SkillLoader:
def __init__(self):
self.context_log: list[str] = []
def scan_metadata(self, skill: Skill):
"""Layer 2: cheap, always happens for relevance triage."""
self.context_log.append(f"[Layer 2] scanned metadata for '{skill.name}'")
def load_active_context(self, skill: Skill):
"""Layer 3: expensive, only for skills SELECTED as relevant."""
self.context_log.append(
f"[Layer 3] loaded full skill body for '{skill.name}' "
f"({len(skill.skill_body)} chars)"
)
def fetch_supporting_file(self, skill: Skill, filename: str):
"""Beyond Layer 3: fetched directly, ZERO tokens spent unless actually used."""
content = skill.supporting_files.get(filename, "")
self.context_log.append(f"[direct fetch, 0 context tokens] used file '{filename}'")
return content
refund_skill = Skill(
name="refund-processing",
yaml_frontmatter="name: refund-processing\ndescription: Use for refund requests.",
skill_body="Step 1: verify order.\nStep 2: check refund eligibility.\n...",
supporting_files={"refund_template.txt": "Dear {name}, your refund of {amount}..."},
)
loader = SkillLoader()
loader.scan_metadata(refund_skill) # happens for every skill, every turn
loader.load_active_context(refund_skill) # happens only for THIS relevant skill
loader.fetch_supporting_file(refund_skill, "refund_template.txt") # never in context at all
for entry in loader.context_log:
print(entry)
💬 Deep Dive with AI
Key points
- •Layer 3, Active Skill Context, loads a skill's full SKILL.md body and associated documentation only once Layer 2 has flagged it as relevant
- •The YAML frontmatter (Layer 2) and Skill Body (Layer 3) are two sections of the SAME skill.md file — not separate files, just loaded at different times
- •Supporting files (scripts, templates, reference docs) go further: they're never loaded into context at all, only fetched directly when actually needed, costing zero tokens
- •Each layer's cost scales differently: Layer 1 with the project (roughly constant), Layer 2 with total skill count (but tiny each), Layer 3 with only currently-active skills
- •This is exactly what lets the whole architecture support hundreds of skills without breaching context limits — cost is proportional to relevance and use, not library size