Skills Patterns
Skill design patterns summarized through extensive practice can help you make reasonable decisions quickly when facing new requirements.
This article summarizes the 7 most commonly used design patterns and their applicable scenarios.
* * *
## Pattern 1: Single Responsibility Skill
Each Skill does one thing and does it well.
The more focused the functionality, the more precise the description, the higher the trigger accuracy, and the easier maintenance becomes.
| Approach | Example |
| --- | --- |
| Correct: Single responsibility | pdf-to-text (only responsible for extracting text) |
| Wrong: Mixed responsibilities | pdf-tools (reading, converting, merging, watermarking... all together) |
> If you find that a Skill's description needs to be very long to explain what it "doesn't do", it usually means it takes on too many responsibilities and should be split.
* * *
## Pattern 2: Defensive Input Check
Centralize all input validation at the Skill script entry point, and only proceed to business logic after validation passes.
## Example
# File path: scripts/defensive_entry.py
# Pattern: Defensive Input Check - Centralized validation at entry, proceed after passing
import sys
import os
import json
def validate(args) ->list:
"""Centralized validation of all inputs, returns error list (empty list means all passed)"""
errors =[]
if not args.file:
errors.append("Missing parameter --file")
elif not os.path.exists(args.file):
errors.append(f"File does not exist: {args.file}")
elif os.path.getsize(args.file)==0:
errors.append("File content is empty")
if args.limit<1:
errors.append("--limit must be greater than 0")
return errors
def run(args):
"""Business logic entry, only called after validation passes"""
# Execute actual processing...
return{"status": "success","file": args.file}
if __name__ =="__main__":
import argparse
parser= argparse.ArgumentParser()
parser.add_argument("--file",required=False, default="")
parser.add_argument("--limit",type=int, default=100)
args =parser.parse_args()
# 1. Centralized validation
errors = validate(args)
if errors:
result ={"status": "input_error","errors": errors}
print(json.dumps(result, ensure_ascii=False))
sys.exit(1)
# 2. Execute business logic after validation passes
result = run(args)
print(json.dumps(result, ensure_ascii=False))
* * *
## Pattern 3: Progressive Output
For Skills that take more than 5 seconds, you should output progress in stages instead of leaving users facing silent waiting.
## Execution Flow (Progressive Output Example)### Step 1: Read FileAfter running the read script, immediately inform the user:> File read: tutorial_data.csv (1,024 rows, 8 columns)Data cleaning in progress...### Step 2: Data CleaningAfter cleaning is complete, inform the user:> Data cleaning complete: 3 duplicate rows removed, 12 empty values filled.Generating report...### Step 3: Generate ReportAfter report is generated, display the download link and explain the content:> Report generated, containing statistical summary and data quality assessment.
* * *
## Pattern 4: Idempotent Operations
The execution result of a Skill should be idempotent: the same input, regardless of how many times it is executed, should produce the same output.
Non-idempotent operations (such as appending content each time) will cause confusion when users retry.
## Example
# File path: scripts/idempotent_output.py
import os
from datetime import datetime
OUTPUT_DIR ="/mnt/user-data/outputs"
def get_output_path(base_name: str, suffix: str=".xlsx") ->str:
"""
Generate deterministic output path
Idempotent approach: overwrite same name file each time (instead of appending or generating new files)
Ensure same input always corresponds to same output file
"""
# Approach A: Fixed file name (always overwrite for same input)
return os.path.join(OUTPUT_DIR,
YouTip