In Chapter 2: Lead Agent & Orchestration, we built the "Brain" of our system. We created a Lead Agent capable of thinking, planning, and maintaining context.
However, a brain without hands cannot interact with the world. If you ask the Lead Agent to "Analyze this spreadsheet" or "Scrape this website," it can describe how to do it, but it cannot actually execute the code to do it.
In this chapter, we give our Agent its "Hands." We call them Skills.
In traditional software, adding a new feature usually means rewriting the core code of the bot. In deer-flow, we want a system that is modular and extensible.
Think of Skills like the learning pods in the movie The Matrix.
If you want to add a new capability (like sending emails or resizing images), you don't touch the Lead Agent's code. You simply drop a new Skill Folder into the project.
Let's imagine the user uploads a file named sales_2024.csv and asks:
User: "What is the average revenue per region in this file?"
To solve this, the Lead Agent needs a Data Analysis Skill. It needs to know:
In deer-flow, a Skill is not just a Python script. It is a package consisting of two parts:
SKILL.md): Instructions for the AI.scripts/): Executable code for the computer.Let's look at the folder structure:
skills/public/data-analysis/
โโโ SKILL.md <-- The Manual for the AI
โโโ scripts/
โโโ analyze.py <-- The Python script that does the work
SKILL.md)This is the interface. It tells the Lead Agent what this skill does. It uses Markdown because LLMs (Large Language Models) are very good at reading documentation.
Simplified SKILL.md:
---
name: data-analysis
description: Use this skill when the user uploads Excel or CSV files and wants to generate statistics or SQL queries.
---
# Data Analysis Manual
## Workflow
1. Inspect the file structure first.
2. Run an SQL query to get the answer.
## Usage
Run the script with: `python analyze.py --files <path> --sql <query>`
Explanation: When the system starts, it reads this file. It injects this "knowledge" into the Lead Agent. Now, when you ask about CSVs, the Agent thinks: "Aha! I have a manual for that."
scripts/)This is the engine. The Lead Agent cannot run the analysis itself (it's just a text generator). It delegates the heavy lifting to a script.
Simplified scripts/analyze.py:
import pandas as pd
import duckdb
# 1. Load the file the AI told us to load
df = pd.read_csv("sales_2024.csv")
# 2. Run the SQL query the AI wrote
result = duckdb.query("SELECT region, AVG(revenue) FROM df").df()
# 3. Print the result so the AI can read it
print(result.to_markdown())
Explanation: This script doesn't know about the User or the Chat. It just takes a file, runs a query, and outputs text.
How do we connect the Brain (Chapter 2) to the Hands (Chapter 3)?
When the User asks "Analyze sales.csv", the following sequence happens:
data-analysis.SKILL.md, the Agent figures out it needs to write an SQL query.How does the backend find these skills? We use a Dynamic Loader.
Instead of hard-coding imports like import data_analysis, we scan the directory. This is why you can add skills without rebooting the core logic in some advanced setups (though usually, a restart is required to load new definitions).
We look for every folder that contains a SKILL.md.
# src/skills/loader.py (Simplified)
def load_skills(directory: str):
skills = []
# 1. Loop through every folder in skills/public
for folder in os.listdir(directory):
skill_path = os.path.join(directory, folder)
# 2. Check if SKILL.md exists
if os.path.exists(f"{skill_path}/SKILL.md"):
# 3. Parse the file and add to list
skills.append(parse_skill_markdown(skill_path))
return skills
Explanation: This function acts like a librarian walking through the aisles, noting down every book (Skill) available on the shelf.
Once we have the Skill definition, we need to convert it into a format the LLM (like DeepSeek or GPT) understands. We use the LangChain tool definition format.
# src/skills/converter.py (Simplified)
def create_tool_from_skill(skill):
return StructuredTool.from_function(
# The name the AI sees (e.g., "data_analysis")
name=skill.name,
# The description from the YAML top matter
description=skill.description,
# The function to call when the AI chooses this
func=lambda **args: run_script(skill.script_path, args)
)
Explanation: We wrap the raw script execution in a standardized "Tool" object. The LLM sees this object as a function it can call, complete with a description of what it does.
init_skill.py)To make it easy for developers to add new capabilities, deer-flow includes a helper script. You don't need to manually create folders and files.
Command:
python skills/public/skill-creator/scripts/init_skill.py my-new-skill --path skills/public
What it does:
skills/public/my-new-skill.SKILL.md (The Manual).scripts/ folder with a dummy Python script.This standardization ensures every skill looks the same, making the system cleaner.
Separating the Definition (Markdown) from the Execution (Code) has massive benefits:
chart-visualization skill), or Bash. The Lead Agent doesn't care; it just reads the Markdown and runs the command.In this chapter, we equipped our Lead Agent with Skills.
SKILL.md) for the AI to read.scripts/) for the system to execute.Now our Agent knows how to analyze data, but running complex scripts (like scraping 100 websites or processing big data) can take time. If the Lead Agent runs this script directly, the chat interface will freeze until the script finishes.
To solve this, we need to execute these skills in the background.
Next Chapter: Sub-Agent Execution System
Generated by Code IQ