An open-source Agent Skill framework implementing progressive disclosure architecture
Project description
OpenSkills SDK
An open-source Agent Skill framework implementing the progressive disclosure architecture for AI agent skills.
Features
-
Three-layer progressive disclosure architecture
- Layer 1 (Metadata): Always loaded for skill discovery
- Layer 2 (Instruction): Loaded on demand when skill is selected
- Layer 3 (Resources): Conditionally loaded References and Scripts
-
SKILL.md file format - Simple markdown-based skill definition
-
Smart Reference loading - Three modes (explicit/implicit/always) with LLM-based selection
-
Auto-discovery - Automatically discover references from
references/directory -
Script execution - Run scripts triggered by LLM via
[INVOKE:name] -
Multiple LLM providers - OpenAI, Azure OpenAI, Ollama, Together, Groq, DeepSeek
-
Auto skill invocation - Automatically match and invoke skills based on user queries
-
Multimodal support - Handle images via URL, base64, or file path
-
Sandbox execution - Secure script execution in isolated AIO Sandbox environment
-
Automatic file sync - Upload input files and download outputs automatically
Installation
pip install openskills-sdk
Quick Start
Using SkillAgent (Recommended)
import asyncio
from openskills import create_agent
async def main():
# Create agent with infographic-skills
agent = await create_agent(
skill_paths=["./infographic-skills"],
api_key="your-api-key",
model="gpt-4",
)
# Chat with automatic skill invocation
response = await agent.chat("帮我总结会议")
print(response.content)
print(f"Used skill: {response.skill_used}")
asyncio.run(main())
Using Sandbox Mode (Recommended for Script Execution)
import asyncio
from openskills import create_agent
async def main():
# Create agent with sandbox enabled
agent = await create_agent(
skill_paths=["./skills"],
api_key="your-api-key",
model="gpt-4",
use_sandbox=True, # Enable sandbox execution
sandbox_base_url="http://localhost:8080",
auto_execute_scripts=True,
)
# Local file paths are automatically uploaded to sandbox
response = await agent.chat("请处理这个文件: /path/to/file.pdf")
print(response.content)
# Output files are automatically downloaded to skill_dir/output/
asyncio.run(main())
Using SkillManager (Low-level API)
from pathlib import Path
from openskills import SkillManager
manager = SkillManager([Path("./infographic-skills")])
# Discover infographic-skills (Layer 1 - Metadata)
await manager.discover()
# Match user query
skills = manager.match("summarize meeting")
# Load instruction (Layer 2)
if skills:
instruction = await manager.load_instruction(skills[0].name)
print(instruction.content)
Sandbox Environment
OpenSkills supports executing scripts in an isolated sandbox environment using AIO Sandbox. This provides:
- Security: Scripts run in isolated containers
- Dependency management: Auto-install Python packages defined in SKILL.md
- File synchronization: Automatic upload/download of files
Installing AIO Sandbox
Option 1: Docker (Recommended)
# Pull and run the sandbox container
docker run -d --name aio-sandbox \
-p 8080:8080 \
ghcr.io/agent-infra/aio-sandbox:latest
# Verify it's running
curl http://localhost:8080/health
Option 2: Docker Compose
# docker-compose.yml
version: '3.8'
services:
sandbox:
image: ghcr.io/agent-infra/aio-sandbox:latest
ports:
- "8080:8080"
volumes:
- sandbox-data:/home/gem
restart: unless-stopped
volumes:
sandbox-data:
docker-compose up -d
Sandbox Features
Automatic Dependency Installation
Define dependencies in SKILL.md frontmatter:
dependency:
python:
- PyMuPDF==1.23.8
- pandas>=2.0.0
system:
- mkdir -p output/images
Dependencies are installed automatically when the skill is initialized.
Automatic File Synchronization
- Upload: Local file paths in script input are auto-uploaded to
/home/gem/uploads/ - Download: Specify output directories in script config to auto-download results
scripts:
- name: process_file
path: scripts/process.py
description: Process uploaded files
timeout: 120
outputs:
- /home/gem/output # Auto-sync to local skill_dir/output/
Sandbox Client API
For advanced use cases, use the SandboxClient directly:
from openskills.sandbox import SandboxClient
async with SandboxClient("http://localhost:8080") as client:
# Execute commands
result = await client.exec_command("python --version")
print(result.output)
# File operations
await client.write_file("/home/gem/test.txt", "Hello World")
content = await client.read_file("/home/gem/test.txt")
# Upload/download files
await client.upload_file(local_bytes, "/home/gem/uploads/file.pdf")
data = await client.download_file("/home/gem/output/result.txt")
# List files
files = await client.list_files("/home/gem/output")
for f in files:
print(f"{f.name} (dir={f.is_dir})")
Skill Structure
my-skill/
├── SKILL.md # Skill definition (required)
├── references/ # Reference documents
│ └── handbook.md
└── scripts/ # Executable scripts
└── upload.py
SKILL.md Format
---
name: meeting-summary
description: Summarize meetings in structured format
version: 1.0.0
triggers:
- "summarize meeting"
- "会议总结"
references:
- path: references/finance-handbook.md
condition: "When content involves finance or budget"
description: Financial guidelines
mode: explicit # LLM evaluates condition
- path: references/frameworks/
mode: implicit # LLM decides if useful (default)
- path: references/safety-policy.md
mode: always # Always loaded
scripts:
- name: upload
path: scripts/upload.py
description: Upload summary to cloud storage
---
# Meeting Summary Skill
You are a professional meeting assistant...
## Output Format
...
Architecture
┌─────────────────────────────────────────────────────────────┐
│ OpenSkills SDK │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: Metadata (Always loaded) │
│ ├── name, description, triggers, tags │
│ └── Used for skill discovery and matching │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: Instruction (On-demand) │
│ ├── SKILL.md body content │
│ └── Loaded when skill is selected │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: Resources (Conditional) │
│ ├── Reference: Documents loaded based on conditions │
│ └── Script: Executed when LLM outputs [INVOKE:name] │
└─────────────────────────────────────────────────────────────┘
Reference Loading Modes
References support three loading modes:
| Mode | Behavior |
|---|---|
explicit |
Has condition, LLM evaluates whether condition is met |
implicit |
No condition, LLM decides if useful for current query (default) |
always |
Always loaded (e.g., safety guidelines, specs) |
Auto-Discovery
References are automatically discovered from the references/ directory. You don't need to declare every file in frontmatter:
my-skill/
├── SKILL.md
└── references/
├── guide.md # Auto-discovered (implicit mode)
├── api-docs.md # Auto-discovered (implicit mode)
└── frameworks/
└── react.md # Auto-discovered (implicit mode)
You can still declare specific references in frontmatter to customize their behavior:
references:
# Override mode for specific file
- path: references/guide.md
mode: always # Now always loaded instead of implicit
# Add condition for another file
- path: references/api-docs.md
condition: "When user asks about API"
mode: explicit
Auto-discovered files that aren't declared in frontmatter default to implicit mode, letting the LLM decide whether to load them based on the user's query.
Environment Variables
OpenAI
export OPENAI_API_KEY=your-api-key
export OPENAI_BASE_URL=https://api.openai.com/v1 # Optional
export OPENAI_MODEL=gpt-4 # Optional
Azure OpenAI
export AZURE_OPENAI_API_KEY=your-azure-api-key
export AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
export AZURE_OPENAI_DEPLOYMENT=your-deployment-name
export AZURE_OPENAI_API_VERSION=2024-02-15-preview # Optional
Using Azure OpenAI
from openskills import AzureOpenAIClient, SkillAgent
# Method 1: Using environment variables
client = AzureOpenAIClient()
# Method 2: Explicit configuration
client = AzureOpenAIClient(
api_key="your-api-key",
endpoint="https://your-resource.openai.azure.com",
deployment="gpt-4",
)
# Method 3: Using create_client helper
from openskills import create_client
client = create_client("azure", deployment="gpt-4")
# Use with SkillAgent
agent = SkillAgent(
skill_paths=["./infographic-skills"],
llm_client=client,
)
Examples
See the examples directory for complete examples:
demo.py- Main demo showing reference auto-discovery and LLM selectionprompt-optimizer/- Prompt engineering skill with 57 frameworks (auto-discovered)meeting-summary/- Meeting summarization skill with finance referenceoffice-skills/- Word and Excel processing skillsfile-to-article-generator/- PDF/Word parsing with sandbox executionweekly-report-to-annual/- Weekly report aggregation skill
Running Examples
Basic Demo (Local Execution)
cd examples
export OPENAI_API_KEY=your-api-key
python demo.py
Sandbox Demo (Recommended)
# 1. Start sandbox first
docker run -d -p 8080:8080 ghcr.io/agent-infra/aio-sandbox:latest
# 2. Run demo with sandbox
cd examples/file-to-article-generator
export OPENAI_API_KEY=your-api-key
python demo.py /path/to/your/file.pdf
The sandbox demo will:
- Initialize sandbox environment and install dependencies
- Upload your file to sandbox automatically
- Execute parsing script in isolated environment
- Download generated images to local
output/directory - Generate article with proper image references
CLI Commands
# List all infographic-skills
openskills list
# Show skill details
openskills show meeting-summary
# Validate a skill
openskills validate ./my-skill/
# Match query to infographic-skills
openskills match "summarize meeting"
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openskills_sdk-0.0.8.tar.gz.
File metadata
- Download URL: openskills_sdk-0.0.8.tar.gz
- Upload date:
- Size: 55.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dfc6c96b12c74d0fa7949b47afdf0bbf3326a598229bf72992a3f8c8e7d5bed
|
|
| MD5 |
ce9ef76da147c4d6fbef28aff27e54de
|
|
| BLAKE2b-256 |
da3dcf929c933631e1736802b3a27edab773a6107844b3a9d90c5807d04face3
|
File details
Details for the file openskills_sdk-0.0.8-py3-none-any.whl.
File metadata
- Download URL: openskills_sdk-0.0.8-py3-none-any.whl
- Upload date:
- Size: 68.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75d9e1e3060156fb871f9341198be090a11c40d978ad78e593f17c2db99c789f
|
|
| MD5 |
cefeba098d214cfea4e2e57ac03b77d1
|
|
| BLAKE2b-256 |
ad7cb3d35c340607a27910269a12ede8a8bee8ef2344157d8158460d56738674
|