Skip to content

How DeerFlow Skills System Extends AI Agent Capabilities

Purpose

I’ve been frustrated with how most AI agent frameworks handle capabilities. Every time I need a new feature, I have to:

  1. Modify the agent code
  2. Understand the codebase architecture
  3. Risk breaking existing functionality
  4. Deploy a new version

When I explored DeerFlow, I found a different approach: the skills system. Instead of hardcoding capabilities, DeerFlow uses declarative Markdown files that inject workflows at runtime.

This post explains how the skills system works, why it matters, and how to create custom skills.

The Problem: Hardcoded Agent Capabilities

Traditional AI agents have capabilities baked into their code. Here’s what happens when you want to add a new feature:

Traditional Agent Workflow
Developer Request: "Add web research capability"
|
v
1. Fork the agent codebase
2. Find where tools are defined
3. Write new tool function
4. Register the tool
5. Update documentation
6. Submit PR or redeploy
|
v
User gets the feature (maybe)

This works for developers but fails for end users. If you’re using an agent platform and need a custom workflow, you’re stuck unless you can modify the source.

What DeerFlow Skills Are

DeerFlow skills are Markdown files (SKILL.md) that define:

  1. Metadata: Name, description, license, allowed tools
  2. Workflow: Step-by-step instructions for the agent
  3. Examples: How to use the skill in practice

The key insight: skills are loaded progressively, not all at once. The agent sees skill descriptions in its system prompt, then loads full skill content only when needed.

Exploring the Built-in Skills

I started by examining the skills directory structure:

Terminal
cd deer-flow
ls -la skills/public/
Output
drwxr-xr-x deep-research/
drwxr-xr-x ppt-generation/
drwxr-xr-x image-generation/
drwxr-xr-x video-generation/
drwxr-xr-x podcast-generation/
drwxr-xr-x data-analysis/
drwxr-xr-x frontend-design/
drwxr-xr-x github-deep-research/
drwxr-xr-x skill-creator/
drwxr-xr-x claude-to-deerflow/
... (17 total)

Each skill has a SKILL.md file. I examined the deep-research skill:

Terminal
cat skills/public/deep-research/SKILL.md | head -50
deep-research/SKILL.md (excerpt)
---
name: deep-research
description: Use this skill for ANY question requiring web research...
license: MIT
allowed-tools:
- web_search
- web_fetch
- bash
---
# Deep Research Skill
## Overview
This skill provides a systematic methodology for conducting thorough web research.
## Workflow
### Phase 1: Broad Exploration
Start with general queries to understand the landscape...
### Phase 2: Deep Dive
Focus on specific aspects based on Phase 1 findings...
### Phase 3: Synthesis
Combine findings into a coherent response...

The YAML frontmatter defines what the skill is and what tools it can use. The body contains the workflow instructions.

How Skills Get Loaded

I wanted to understand the loading mechanism. Here’s what I found:

Step 1: Skill Discovery

DeerFlow recursively scans the skills directory:

Skill Discovery Flow
skills/
├── public/ # Built-in skills
│ ├── deep-research/SKILL.md
│ ├── ppt-generation/SKILL.md
│ └── ...
└── custom/ # User-defined skills
└── my-skill/SKILL.md

The system parses each SKILL.md file and extracts metadata.

Step 2: System Prompt Injection

Enabled skills are listed in the agent’s system prompt:

System Prompt (simplified)
## Available Skills
1. **deep-research**: Use for systematic web research...
Path: /mnt/skills/public/deep-research/SKILL.md
2. **ppt-generation**: Create professional presentations...
Path: /mnt/skills/public/ppt-generation/SKILL.md
3. **image-generation**: AI image creation...
Path: /mnt/skills/public/image-generation/SKILL.md

Only the descriptions are loaded initially. The full skill content loads when the agent decides to use it.

Step 3: Progressive Loading

When the agent encounters a task matching a skill:

Progressive Loading Flow
User: "Research the latest React 19 features"
|
v
Agent sees: deep-research skill description matches
|
v
Agent loads: Full SKILL.md content
|
v
Agent follows: Workflow defined in skill

This approach keeps the context window lean. With 17 skills, loading everything would waste tokens. Progressive loading means only relevant skills consume context.

Testing a Skill in Practice

I tested the deep-research skill with a real request:

test_skill.py
from deerflow.client import DeerFlowClient
client = DeerFlowClient()
response = client.chat(
"Research the current state of server-sent events (SSE) "
"in web frameworks. What are the alternatives?",
thread_id="research-test"
)
print(response)

The agent recognized this as a research task and loaded the deep-research skill. I watched the logs:

Agent Logs
[lead-agent] Analyzing request...
[lead-agent] Matched skill: deep-research
[lead-agent] Loading skill from: /mnt/skills/public/deep-research/SKILL.md
[lead-agent] Executing workflow:
- Phase 1: Broad exploration (3 queries)
- Phase 2: Deep dive (2 focused queries)
- Phase 3: Synthesis
[lead-agent] Skill execution complete

The result was a structured research report with sources.

Creating a Custom Skill

I wanted to test custom skill creation. Here’s what I did:

Step 1: Create the Directory Structure

Terminal
mkdir -p skills/custom/code-reviewer

Step 2: Write the Skill Definition

skills/custom/code-reviewer/SKILL.md
---
name: code-reviewer
description: "Use this skill when reviewing code for security, performance, and best practices"
license: MIT
allowed-tools:
- bash
- read_file
- write_file
---
# Code Reviewer Skill
## Overview
This skill provides a systematic methodology for conducting thorough code reviews.
## Workflow
### Phase 1: Security Analysis
1. Check for hardcoded secrets (API keys, passwords, tokens)
2. Identify SQL injection risks
3. Look for XSS vulnerabilities
4. Verify CSRF protection
5. Check authentication/authorization
### Phase 2: Performance Review
1. Identify N+1 queries
2. Check for memory leaks
3. Look for unnecessary loops
4. Verify caching is used appropriately
### Phase 3: Code Quality
1. Check function length (<50 lines recommended)
2. Verify proper error handling
3. Look for code duplication
4. Check naming conventions
## Output Format
```markdown
## Code Review Report
### Security Issues
- [CRITICAL] Description...
- [HIGH] Description...
### Performance Issues
- [MEDIUM] Description...
### Quality Issues
- [LOW] Description...
### Recommendations
1. ...

Examples

User: “Review the code in /mnt/data/auth.py” Agent: [Loads skill, follows workflow, outputs report]

### Step 3: Enable the Skill
I updated the extensions config:
```json title="extensions_config.json"
{
"skills": {
"deep-research": {"enabled": true},
"ppt-generation": {"enabled": true},
"code-reviewer": {"enabled": true}
}
}

Step 4: Test the Custom Skill

test_custom_skill.py
from deerflow.client import DeerFlowClient
client = DeerFlowClient()
# Write some code to review
client.chat(
"Create a file called test_auth.py with a simple login function",
thread_id="review-test"
)
# Request a code review
response = client.chat(
"Review the code in test_auth.py for security issues",
thread_id="review-test"
)
print(response)

The agent loaded my custom skill and followed the workflow I defined:

Output
## Code Review Report
### Security Issues
- [CRITICAL] Password stored in plain text
- [HIGH] No input validation on username
### Performance Issues
- [LOW] Database connection not pooled
### Recommendations
1. Use bcrypt for password hashing
2. Add input sanitization
3. Implement connection pooling

Programmatic Skill Management

DeerFlow provides APIs for managing skills programmatically.

Using the Python Client

skill_management.py
from deerflow.client import DeerFlowClient
client = DeerFlowClient()
# List all skills
skills = client.list_skills()
print(skills)
# {"skills": [
# {"name": "deep-research", "enabled": true, ...},
# {"name": "ppt-generation", "enabled": false, ...},
# ...
# ]}
# Enable a skill
client.update_skill("ppt-generation", enabled=True)
# Disable a skill
client.update_skill("deep-research", enabled=False)
# Install a skill from archive
client.install_skill("/path/to/skill.archive.skill")

Using the Gateway API

Terminal
# List skills
curl http://localhost:2026/api/skills
# Enable/disable a skill
curl -X PUT http://localhost:2026/api/skills/deep-research \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
# Install from archive
curl -X POST http://localhost:2026/api/skills/install \
-F "archive=@./my-skill.skill"

Why This Approach Matters

After testing, I identified several advantages of the skills approach:

1. User Customization Without Code Changes

End users can add capabilities by creating a SKILL.md file. No Python knowledge required, no codebase modifications.

2. Domain-Specific Workflows

Teams can inject domain expertise:

Domain Skills Examples
legal-team/
└── contract-reviewer/SKILL.md # Legal review workflow
medical-team/
└── patient-summary/SKILL.md # Medical note summarization
finance-team/
└── expense-analyzer/SKILL.md # Expense report workflow

3. Efficiency Through Progressive Loading

With 17+ skills, loading all content would consume ~10,000+ tokens. Progressive loading means the agent only loads what it needs.

4. Sharing and Distribution

Skills can be packaged as .skill archives:

Terminal
# Export a skill
deerflow skill export code-reviewer --output code-reviewer.skill
# Share with team
# Import on another machine
deerflow skill install code-reviewer.skill

Issues I Encountered

Not everything was smooth:

  1. Skill debugging: When a skill fails, the error messages are cryptic. I had to check container logs to understand what went wrong.

  2. Tool restrictions: The allowed-tools field doesn’t enforce restrictions. It’s more of a documentation hint. The agent can still use any available tool.

  3. Skill conflicts: When multiple skills match a task, the agent sometimes picks the wrong one. There’s no priority system.

  4. Documentation: The skill format documentation was sparse. I learned mostly by reading the built-in skills.

Comparison: Skills vs Other Approaches

I’ve used other extensibility patterns. Here’s how skills compare:

ApproachUser CustomizableCode RequiredContext Efficient
Hardcoded toolsNoYesYes
Plugin systemYesYes (usually)Depends
MCP serversYesYesYes
DeerFlow SkillsYesNo (Markdown)Yes

The Markdown-based approach is unique. It trades some flexibility (no arbitrary code execution) for accessibility (anyone can write Markdown).

When to Create Custom Skills

Based on my testing, custom skills make sense when:

  1. You have a repeatable workflow: A multi-step process you use regularly
  2. Domain expertise matters: You want to inject specialized knowledge
  3. Consistency is important: You want the agent to follow the same steps each time
  4. You’re not a developer: You can express your workflow in natural language

Skip custom skills if:

  1. Simple tool access: You just need the agent to call an API
  2. One-off tasks: The workflow doesn’t repeat
  3. Code is easier: Your workflow is complex enough to need actual code

My Recommendation

The skills system is one of DeerFlow’s most thoughtful features. It solves the real problem of agent extensibility without requiring users to modify code.

Use custom skills when:

  • You have domain-specific workflows
  • You want to share capabilities across a team
  • You prefer Markdown over code

Stick with tools/MCP when:

  • You need to call external APIs
  • Your workflow requires arbitrary computation
  • You’re building something for developers

For teams using DeerFlow, I recommend starting with the built-in skills, then creating custom skills for your most common workflows. The investment pays off quickly when the agent consistently follows your team’s best practices.

Summary

DeerFlow’s skills system provides a Markdown-based way to extend AI agent capabilities. Skills are loaded progressively (only when needed), keeping context windows efficient. The system includes 17 built-in skills and supports custom skill creation.

I tested custom skill creation and found it straightforward: create a directory, write a SKILL.md file, enable in config. The main limitation is that skills are workflow definitions, not executable code—they guide the agent rather than run independently.

For developers building on DeerFlow, the skills system offers a practical path to domain-specific customization that doesn’t require modifying the codebase.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments