How to Extend LLM Capabilities with an Agent Skill System: A Three-Layer Progressive Disclosure Pattern
The AI Agent Book repository implements a progressive disclosure pattern where skills expose metadata to the system prompt, load full workflows on demand, and execute bundled scripts only when needed, keeping context minimal while maximizing extensibility.
To extend LLM capabilities with an agent skill system, you need a modular architecture that prevents context window overflow while allowing the model to access complex tools. The bojieli/ai-agent-book repository demonstrates this through a self-contained Agent Skills framework that treats capabilities as plugins the LLM can discover and load dynamically.
The Three-Layer Progressive Disclosure Architecture
The system uses a progressive disclosure mechanism divided into three distinct layers. Each layer controls when specific information enters the LLM's context, ensuring the model only receives heavy payloads when absolutely necessary.
Layer 1: Metadata Catalog
At startup, the agent injects only a thin catalog into the system prompt. This contains just the name and description of each available skill—typically a few hundred tokens total.
In chapter2/agent-skills-ppt/demo.py, the scan_skill_catalog() function (lines 72-82) reads the front-matter of every SKILL.md file across the skills/ directory. For example, skills/pptx/SKILL.md exposes its purpose without revealing implementation details, allowing the LLM to understand what tools exist without carrying their full weight.
Layer 2: Core Workflow
When the LLM decides a specific skill is required, it invokes the read_skill tool. This returns the complete SKILL.md document containing the high-level workflow, required parameters, and constraints.
The tool_read_skill() implementation (lines 8-15 in demo.py) handles this request by locating the skill directory and returning the markdown file content. This layer provides the LLM with procedural knowledge—how to use the skill—without yet loading executable code or large reference documents.
Layer 3: Implementation Details
For complex tasks requiring detailed specifications or actual code execution, the system exposes two additional tools:
read_skill_file: Loads auxiliary documents likereference.mdcontaining detailed style guides or technical specifications. Implemented intool_read_skill_file()(lines 17-31).run_skill_script: Executes bundled Python scripts from thescripts/subdirectory. Implemented intool_run_skill_script()(lines 33-61).
This separation ensures that large codebases and detailed documentation remain outside the context window until the LLM explicitly requests them.
Safety and Extensibility Mechanisms
The architecture enforces strict boundaries to maintain security while enabling rapid feature development.
Directory Traversal Protection: Both tool_read_skill_file() and tool_run_skill_script() validate paths using an is_relative_to guard. The system rejects any request attempting to access files outside the declared skill directory, preventing malicious prompts from reading sensitive system files.
Plug-and-Play Extensibility: Adding new capabilities requires no code changes to the agent core. Create a new folder under skills/ containing:
- A
SKILL.mdwith front-matter metadata - Optional
reference.mdfor detailed specs - A
scripts/folder with executable Python files exposing functions likebuild_presentation
The catalog scanner automatically discovers new skills at startup, and the LLM can immediately begin using them through the standard tool interface.
Provider Resolution
The skill system abstracts LLM backend specifics through the agentbook.providers registry. The resolve_backend() function in agentbook/providers/registry.py maps model names to concrete API endpoints (OpenAI, OpenRouter, etc.) and handles API key and base URL resolution. This allows the same skill infrastructure to work with any LLM supporting function calling, from GPT-4 to open-source alternatives.
Practical Implementation Guide
Adding a New Skill
Create a directory structure like skills/summary/ with three components:
---
name: summary
description: Summarize a long document into a concise bullet-point list
---
You are a summarizer. Follow these steps:
1. Read the full document (provided in the payload).
2. Produce a JSON with `summary` (list of bullet points).
3. Return the JSON as the tool result.
Save the above as SKILL.md, then add the implementation script at scripts/generate_summary.py:
import json
from pathlib import Path
def build_presentation(data: dict, out_path: str) -> dict:
# `data` contains the full document text
text = data["text"]
# Simple summarizer (replace with LLM call if desired)
bullets = [line.strip() for line in text.splitlines() if line.strip()][:5]
summary = {"summary": bullets, "path": out_path}
Path(out_path).write_text("\n".join(bullets), encoding="utf-8")
return summary
Invoking Skills from the Agent Loop
The agent loop dispatches tool calls based on LLM requests:
# Load the skill workflow into context
dispatch(
catalog,
"read_skill",
{"name": "summary"},
Path("output/summary.txt")
)
# Execute the skill script
dispatch(
catalog,
"run_skill_script",
{
"name": "summary",
"script": "generate_summary.py",
"payload": json.dumps({"text": long_document_text})
},
Path("output/summary.txt")
)
The LLM receives the JSON result containing the output path, which it can reference in subsequent reasoning or present to the user.
Running in Offline Mode
Test the skill system without API costs using the offline flag:
python chapter2/agent-skills-ppt/demo.py --offline \
--output output/summary_demo.pptx
This mode uses a fixed outline from papers/sample_outline.json but executes the complete three-layer tool chain, enabling deterministic regression testing of new skills.
Summary
- Progressive disclosure minimizes context usage by exposing only skill metadata at startup, loading workflows on demand, and executing code only when necessary.
- Safety guards in
tool_read_skill_file()andtool_run_skill_script()prevent directory traversal attacks usingis_relative_tochecks. - Zero-code extensibility allows adding capabilities by dropping new folders into
skills/; thescan_skill_catalog()function discovers them automatically. - Provider abstraction via
resolve_backend()enables switching between OpenAI, OpenRouter, and other backends without modifying skill implementations. - Offline testing via the
--offlineflag ensures skills work correctly before incurring API costs.
Frequently Asked Questions
What is the progressive disclosure pattern in AI agents?
Progressive disclosure is an architectural pattern where information enters the LLM's context window in stages. The AI Agent Book implementation exposes only skill names and descriptions initially, then loads full workflows when the LLM calls read_skill, and finally pulls in executable scripts or detailed references only when explicitly requested via run_skill_script or read_skill_file. This prevents token overflow while maintaining access to complex capabilities.
How does the skill system prevent security vulnerabilities?
The system implements path validation in tool_read_skill_file() and tool_run_skill_script() using is_relative_to checks to ensure all requested files reside within the specific skill's directory. This blocks directory traversal attacks where a malicious prompt might attempt to read /etc/passwd or other sensitive files. Additionally, skills are sandboxed to their own folders, preventing cross-skill contamination.
Can I use this skill system with any LLM provider?
Yes. The agentbook.providers registry abstracts provider-specific details. The resolve_backend() function in agentbook/providers/registry.py handles API keys, base URLs, and model routing for any backend supporting function calling—including OpenAI, OpenRouter, or self-hosted models. Skills remain provider-agnostic because they interact only with the standardized tool interface.
How do I add a new capability without modifying existing code?
Create a new subdirectory under skills/ containing a SKILL.md file with YAML front-matter (name and description), optionally a reference.md for detailed specs, and a scripts/ folder with Python files. The scan_skill_catalog() function automatically detects new skills at startup by scanning the skills/ directory, requiring no changes to demo.py or other core files.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →