Skip to content
BAEM1N.DEV — AI, RAG, LLMOps 개발 블로그
Go back

DeepCoWork #9: Skills System -- SKILL.md, Progressive Disclosure, Runtime Injection

TL;DR: A single ~/.cowork/skills/{name}/SKILL.md file extends agent capabilities as a plugin, with UI-based CRUD and instant propagation to all agents.

Table of contents

Open Table of contents

What is a Skill

A skill is a plugin that extends agent capabilities. Adding a “django-expert” skill makes the agent specialize in Django projects. The design was inspired by the Agent Skills Specification community standard.

SKILL.md Format

---
name: django-expert
description: Django project specialist
allowed-tools: read_file write_file execute
---

# django-expert

## When to Use
- Working with Django models, views, URLs, serializers
- Designing Django REST Framework APIs

## Instructions
- Always read current settings before changing settings.py
- Run migrations in order: makemigrations -> migrate
- Use pytest-django for tests

Frontmatter Parsing

A simple YAML parser with no external dependencies extracts name, description, and allowed_tools from the --- delimited frontmatter block.

Skill Resolution and Injection

At agent build time, _resolve_skills() scans skill directories:

def _resolve_skills(workspace_dir: Path) -> list[str]:
    sources: list[str] = []
    global_skills = config.WORKSPACE_ROOT / "skills"
    if global_skills.is_dir():
        sources.append("skills/")
    ws_skills = workspace_dir / "skills"
    if ws_skills.is_dir():
        sources.append("skills/")
    return sources

Priority: global (~/.cowork/skills/) < workspace ({workspace}/skills/).

REST API

Skills are managed through three endpoints:

Skill name validation prevents path traversal attacks:

def _validate_skill_name(name: str) -> str:
    if not re.match(r'^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$', name):
        raise HTTPException(400, "Skill name: lowercase letters, numbers, hyphens only")
    if ".." in name or "/" in name:
        raise HTTPException(400, "Invalid skill name")
    return name

UI: SkillsPanel

The panel provides a list view of all skills with inline editing. Users can create skills from a template, edit SKILL.md content directly, and delete skills with confirmation. Allowed tools are displayed as badges.

Progressive Disclosure

Skills follow a “load only when needed” pattern:

  1. At agent build time, only check if skill directories exist
  2. The Deep Agents SDK’s SkillsMiddleware activates only relevant skills for the task context
  3. Deleting a skill deactivates it immediately

This prevents unnecessary skills from consuming LLM context.

Benchmark

MetricValue
Skill loading time (SKILL.md parsing)~2ms/file
System prompt increase with 10 skills~1,500 tokens (metadata only)
Skill name max length64 chars (a-z, 0-9, hyphens)
Skill change to agent rebuild~150ms
API response time (GET /settings/skills)~8ms (5 skills)

Lessons Learned

Placing the skills folder at ~/.cowork/skills/ caused _resolve_skills() to return a relative path (skills/), which made the SDK look for a skills/ directory relative to the current working directory. Skills showed up as 0. The fix was resolving paths relative to config.WORKSPACE_ROOT. Since it was a silent path mismatch with no error message, debugging took considerable time.

The second issue was skill name validation. Initially we allowed / in names, which opened a path traversal attack via PUT /settings/skills/../../etc/passwd. We locked it down to a regex allowing only lowercase letters, numbers, and hyphens, plus an additional is_safe_path() double-check.

Third, we considered using pyyaml for frontmatter parsing but decided against adding the dependency. A simple 20-line parser handling key: value pairs was sufficient — there was no need to support nested YAML structures like metadata.category.

FAQ

Do I need to restart the agent after adding a skill?

No. rebuild_all_agents_safe() rebuilds all active agents immediately on skill changes. Applied from the next message in ongoing conversations.

What does allowed-tools do?

Declares which tools the skill can use. Currently metadata-only; planned for tool access control in a future release.


Series

  1. DeepCoWork: I Built an AI Agent Desktop App
  2. Tauri 2 + Python Sidecar
  3. DeepAgents SDK Internals
  4. System Prompt Design per Mode
  5. SSE Streaming Pipeline
  6. HITL Approval Flow
  7. Multi-Agent ACP Mode
  8. Agent Memory 4 Layers
  9. [This post] Skills System
  10. LLM Provider Integration
  11. Security Checklist
  12. GitHub Actions Cross-Platform Build

AI-assisted content
Share this post on:

Previous Post
DeepCoWork #10: LLM Provider Integration -- 5 Backends, Model Auto-Detection, Build Variants
Next Post
DeepCoWork #8: Agent Memory 4 Layers -- SOUL.md, USER.md, AGENTS.md, MEMORY.md