跪拜 Guibai
← Back to the summary

AI Skills Are Not Prompts: A Markdown File That Gives Your Coding Agent Permanent Memory

Write Your First AI Skill Step by Step: From Principles to Engineering

Frontend AI Skill System · Introductory Chapter

Vercel's writing-guidelines Skill has been installed 32,500 times. GitHub's official create-agentsmd has been installed 11,800 times. This is not a toy—it is the infrastructure of AI programming in 2026.


Table of Contents


Conclusion First

Skill = A Markdown file that tells the AI "when to use you, how to work, and what not to do."

It is not a Prompt. A Prompt is a one-off conversation. A Skill is a persistent professional SOP—write it once, and it automatically takes effect in every conversation.

Cursor calls it .cursor/rules/*.mdc, Claude Code calls it CLAUDE.md, GitHub calls it AGENTS.md, and skills.sh calls it SKILL.md. Different names, same essence.

This article teaches you to write one from scratch, then engineer it.


I. Principles: 6 Things You Must Know Before Writing

1.1 Trigger Conditions Determine Life or Death

The AI will not "actively discover" your Skill. It relies on keywords in the description to decide whether to load.

# ✅ Precise triggering
description: |
  Load when user says "日报" / "standup" / "今天做了什么".
  Generate structured daily report from git commits.

# ❌ So vague it's useless
description: |
  A helpful skill for various tasks.

Empirical observation: When trigger words cover more than 3 expressions, the hit rate jumps from 40% to 90%+. A user saying "CR", "review", or "帮我看看代码" is the same intent—you must include them all.

1.2 Workflows Must Be Executable

Every step must have: Input → Action → Output.

# ✅ Executable
1. Read `git log --since="today" --oneline`
2. Categorize by feat/fix/refactor/docs
3. Output to `reports/daily/YYYY-MM-DD.md`

# ❌ Not executable
1. Analyze today's code changes
2. Generate a good daily report

"A good daily report" is not an output specification. Format, location, length—all must be nailed down.

1.3 Three Levels of Constraints

Level Meaning Example
MUST Iron law, violation means failure MUST: All components use TypeScript strict
SHOULD Strongly recommended, exceptions allowed SHOULD: Prioritize existing knowledge base patterns
MUST NOT Absolutely forbidden MUST NOT: Do not generate any type

Don't mark every rule as MUST. When 10 MUST rules conflict with each other, the AI will randomly pick one to follow.

1.4 One Skill Does One Thing

Want it to write code, write blogs, and do design reviews? Split it into three.

Judgment criterion: If the word "and" appears in the description, it should be split.

1.5 Examples > Descriptions

The information density of 1 precise example > 10 lines of text description. Examples should cover:

1.6 Writing Is Not the End

A Skill is alive. Review it after every use for the first two weeks, and fix any rules the AI didn't follow. After stabilization, review monthly.

A direct quote from GitHub's official AGENTS.md specification: "This is living documentation - update it as your project evolves."

Six Major Misconceptions (Pitfall Checklist)

Misconception Truth
"Write a longer description, the AI will understand" The description is for trigger matching, not a manual. The more precise, the better
"Mark all rules as MUST" Too many mandatory constraints will cause AI conflicts. Distinguish MUST from SHOULD
"One Skill file handles everything" Split modules when exceeding 200 lines. Context window is a finite resource
"More examples are better" 1-2 precise examples > 10 redundant examples
"Write it and forget it" Skills need iteration. Use for 2 weeks, revise based on actual results
"The AI will automatically know when to use it" It won't. If trigger conditions aren't clearly written, the Skill is a dead file

II. Hands-on: Write a Daily Report Generator in 15 Minutes

2.1 Complete Code

---
name: daily-standup
description: |
  Load when user says "日报" / "standup" / "今天做了什么" / "写日报".
  Generate a structured daily standup report from git commits.
metadata:
  author: your-name
  version: "1.0.0"
  layer: tool
  createdAt: "2026-07-23"
---

# daily-standup — Daily Report Generator

> Automatically generate structured daily reports from git log. No more manually writing "fixed a bug today."

## Trigger Conditions

User input contains: 日报 / standup / 今天做了什么 / 写日报 / daily

## Workflow

1. Execute `git log --since="today 00:00" --oneline --author="$(git config user.name)"`
2. If no commits → Output "No commits today" and ask if manual supplement is needed
3. Categorize by prefix:
   - feat: → ✨ New Feature
   - fix: → 🐛 Bug Fix
   - refactor: → ♻️ Refactor
   - docs: → 📝 Documentation
   - Other → 🔧 Miscellaneous
4. Merge similar items (when exceeding 10 items)
5. Ask for "Tomorrow's Plan" and "Blockers"
6. Output the final daily report

## Output Format

## Daily Report YYYY-MM-DD (DayOfWeek)

### Today's Accomplishments
- ✨ [feat] User registration API integration
- 🐛 [fix] Fixed login page white screen (#1234)

### Tomorrow's Plan
- (User answers)

### Blockers
- (User answers, write "None" if none)

## Constraints

- MUST: Only count today's commits, do not cross days
- MUST: Translate English commit messages to Chinese summaries
- SHOULD: Associate issue numbers (if commit message contains #number)
- MUST NOT: Do not fabricate non-existent commits

2.2 Line-by-Line Breakdown

Section Purpose What Happens If Missing
name Unique identifier Cannot be referenced or managed
description first line Trigger matching AI doesn't know when to load
metadata.version Version tracking Don't know where to rollback if broken
Trigger Conditions section Human-readable trigger explanation Maintainer (future you) won't understand
Workflow step 2 Empty result fallback AI fabricates when there are no commits
Output format Lock structure Different output format each time
MUST NOT Anti-hallucination AI might fabricate commits

30 lines. A usable Skill. Save as daily-standup/SKILL.md, done.


III. Complex Skills: When 30 Lines Are Not Enough

3.1 When to Split

3.2 Real Directory Structure

Taking fe-hub (Frontend Orchestration Hub, 58KB SKILL.md, v1.5) as an example:

fe-hub/
├── SKILL.md              # Entry (architecture positioning + routing table + module index)
├── README.md             # Human instructions (quick start)
├── CHANGELOG.md          # Change log (what + why)
├── INSTALL.md            # Installation guide
├── manifest.json         # Machine-readable metadata
│
├── modules/              # 🔑 Modular sub-processes (11 total, loaded on demand)
│   ├── workflow-recipes.md        # Standard workflows for common tasks
│   ├── input-security.md          # Input security validation
│   ├── error-recovery-log.md      # Error recovery + logging
│   ├── session-tracking.md        # Multi-turn session tracking
│   ├── token-metrics.md           # Token usage metrics
│   ├── usage-stats.md             # Usage statistics
│   ├── knowledge-base.md          # Knowledge base retrieval
│   ├── community-skills-matrix.md # Community Skill evaluation
│   ├── design-inspiration.md      # Design inspiration library
│   ├── extension-guide.md         # Extension development guide
│   └── plugin-packaging-guide.md  # Plugin packaging guide
│
├── config/               # Variable configuration (separated from logic)
│   └── skill-registry.json  # Sub-Skill registry
│
├── templates/            # Output templates
├── tech-stacks/          # Framework-specific rules
├── bin/                  # Helper scripts
├── stats/                # Runtime statistics
├── logs/                 # Runtime logs
├── sessions/             # Session persistence
├── reviews/              # Code review archives
└── docs/                 # Output documents

3.3 5 Rules for Complex Skills

# Rule Why
1 SKILL.md ≤ 300 lines, only index and routing AI context window is limited, stuffing everything dilutes focus
2 modules/ one file per sub-process Load on demand, unused ones don't consume tokens
3 config/ separated from logic Changing registry doesn't require touching SKILL.md
4 manifest.json is mandatory Supports automated version detection and dependency management
5 CHANGELOG.md must be maintained In three months you'll forget why you changed that line

3.4 How to Write the Entry File (Complex Version)

---
name: fe-hub
description: |
  Load when user starts any frontend development task.
  Orchestration hub: routes to the right fe-* Skill.
metadata:
  author: mjd
  version: "1.5.0"
  layer: orchestration
---

# fe-hub — Frontend Orchestration Hub

> Unified entry point for all frontend tasks. Doesn't do the work, only dispatches.

## Routing Table

| User Intent | Trigger Words | Dispatch Target |
|----------|--------|----------|
| Write component/page | "组件/component/页面" | → fe-engineer-pack S3 |
| Write tests | "测试/test/单测/e2e" | → fe-test-pack |
| Fix bugs | "bug/报错/修复/fix" | → fe-engineer-pack S2 |
| Code review | "review/CR/审查" | → fe-engineer-pack S5 |
| Performance optimization | "性能/优化/lighthouse" | → fe-engineer-pack S7 |
| Initialize project | "初始化/init/新项目" | → fe-agent-init |
| Health check | "检查/健康/状态" | → fe-skill-inspector |

## Module Index

| Module | Description | File |
|------|------|------|
| Workflow Recipes | Standard workflows for common tasks | modules/workflow-recipes.md |
| Input Security | Anti-injection/authorization validation | modules/input-security.md |
| Error Recovery | Failure retry + degradation strategy | modules/error-recovery-log.md |
| Session Tracking | Multi-turn context management | modules/session-tracking.md |

## Global Constraints

- MUST: Write to stats/usage-log before route dispatch
- MUST NOT: Do not skip the 5-step detection of fe-base-skill
- SHOULD: Prioritize existing patterns in tech-stacks/

3.5 Module File Example (Route Dispatch)

Excerpt from modules/workflow-recipes.md:

# Route Dispatch Module

## Matching Rules

By priority from high to low:

1. **Exact Match**: User input contains a Skill's triggerKeywords from the registry
2. **Semantic Match**: User intent description has high semantic similarity with Skill's description
3. **Fallback**: Cannot match → Ask the user

## Route Record

Each route SHALL be written to stats/usage-log.md:

| Field | Description |
|------|------|
| timestamp | ISO 8601 |
| skill | Target Skill name |
| trigger | Trigger keyword |
| routedDomain | Hit domain |
| routeCorrected | Whether corrected by user (default false) |

## Conflict Resolution

When multiple Skills match simultaneously:
- Priority: Deeper layer takes precedence (base > capability > orchestration)
- Same layer: triggerKeywords exact match > semantic match

IV. Universal Standards: Rules Every Skill Should Follow

4.1 Minimum Directory Structure

my-skill/
├── SKILL.md              # [Required] The only file automatically loaded by AI
├── README.md             # [Recommended] Instructions for humans
├── CHANGELOG.md          # [Recommended] Change log
├── manifest.json         # [Recommended] Machine-readable metadata
├── modules/              # [Optional] Split when SKILL.md > 200 lines
├── knowledge/            # [Optional] Persistent memory (experience/patterns/cases)
├── config/               # [Optional] Variable configuration
├── templates/            # [Optional] Output templates
└── bin/                  # [Optional] Helper scripts

4.2 Frontmatter Specification

---
name: skill-name              # Unique identifier, kebab-case
description: |                # First line must be trigger condition
  Load when user [specific scenario].
  [One-line core value].
metadata:
  author: your-name
  version: "1.0.0"           # Semantic versioning
  layer: tool                # meta/orchestration/capability/base/tool/agent
  createdAt: "2026-07-23"
  updatedAt: "2026-07-23"
---

4.3 Body Structure (Recommended Order)

# skill-name — One-line positioning

> Supplementary note

## Trigger Conditions          ← When to load (keyword list)
## Workflow                    ← Core process (numbered steps, each with Input→Action→Output)
## Output Specification        ← Format, location, template
## Constraints                 ← MUST / SHOULD / MUST NOT
## Examples                    ← 1 normal + 1 edge case
## Known Limitations           ← Honest disclosure (optional)

4.4 Rule Checklist

# Rule Level
1 Frontmatter includes name + description + version MUST
2 Description first line is "Load when..." MUST
3 Body has explicit "Trigger Conditions" section MUST
4 Each workflow step has Input→Action→Output MUST
5 Constraints use MUST / SHOULD / MUST NOT three levels SHOULD
6 Split to modules/ when exceeding 200 lines SHOULD
7 Knowledge base has _index.md index SHOULD
8 Update CHANGELOG on every modification SHOULD
9 Examples cover normal + edge case SHOULD
10 Do not hardcode variable configuration MUST NOT

4.5 Complete Example: code-reviewer

---
name: code-reviewer
description: |
  Load when user says "review" / "代码审查" / "帮我看看这段代码" / "CR".
  Structured code review with severity levels and actionable suggestions.
metadata:
  author: mjd
  version: "1.0.0"
  layer: tool
  createdAt: "2026-07-23"
---

# code-reviewer — Structured Code Review

> Not "looks good", but "Line 42 has a null pointer risk, suggest using optional chaining".

## Trigger Conditions

User input contains: review / CR / 代码审查 / 帮我看看 / 这段代码有问题吗

## Workflow

1. **Locate Code**: Code snippet provided by user / specified file / recently modified file
2. **Multi-dimensional Review**:
   - 🔴 Correctness (logic errors, missing edge cases, null pointers)
   - 🟡 Robustness (error handling, exception paths, resource leaks)
   - 🟢 Maintainability (naming, duplication, complexity)
   - 🔵 Performance (unnecessary loops, memory allocation, N+1)
3. **Output Review Report**

## Output Format

| Severity | Location | Issue | Suggestion |
|--------|------|------|------|
| 🔴 Critical | L42 | Unhandled null | Use optional chaining |
| 🟡 Warning | L78 | Empty catch block | At least console.error |

## Constraints

- MUST: Every issue must provide **specific modification suggestions**, not just "this is bad"
- MUST: Sort by severity, Critical first
- SHOULD: If overall code quality is good, acknowledge first then raise issues
- MUST NOT: Do not argue about style preferences (tab vs space, etc.)

## Examples

Input: User pastes a 20-line fetch function
Output:
| 🔴 | L5 | fetch has no error handling, network exception will cause unhandled rejection | Wrap with try-catch + timeout control |
| 🟡 | L12 | response.json() doesn't check status | Check res.ok first |
| 🟢 | L3 | Variable name `d` is unclear | Change to `responseData` |

V. Q&A

Q1: What's the difference between Skill and System Prompt?

System Prompt is the employee handbook, Skill is the job SOP.

An AI can simultaneously have 1 System Prompt + 30 Skills.

Q2: What's the relationship between Skill and RAG knowledge base?

A Skill's knowledge/ directory is its "working memory". Reference existing patterns when writing code, rather than reasoning from scratch each time.

Q3: What's the appropriate file size?

Type Limit What to Do If Exceeded
Single-file Skill 200 lines Split into modules/
SKILL.md entry 300 lines Keep only index, point details to modules/
Single module 150 lines Continue splitting into sub-modules
Total No limit Load on demand, don't stuff everything at once

Q4: How to test if a Skill works well?

Three metrics:

  1. Trigger Accuracy: Does it load when trigger words are spoken? Does it not falsely trigger on unrelated content?
  2. Output Consistency: Run the same input 3 times, is the structure stable?
  3. Constraint Compliance Rate: Are MUST rules followed every time?

Q5: I wrote it but the AI doesn't use it?

99% of the time it's a description problem:

Q6: What if multiple Skills conflict?

Priority:

Q7: Are there ready-made ones from the community?

Yes. skills.sh is the npm for Agent Skills:

# Search
npx skills find "react typescript"

# Install
npx skills add vercel-labs/agent-skills@writing-guidelines

# Popular leaderboard (as of 2026-07-23)
# convex-create-component: 89K installs
# writing-guidelines: 32.5K installs
# create-agentsmd: 11.8K installs

Vercel, GitHub, Sentry, and LaunchDarkly have all published official Skills. Install others' first, understand the structure, then write your own.


VI. Mainstream Platform Adaptation: One Skill Runs on All IDEs

6.1 Platform Comparison Table

Platform Carrier Location Trigger Method Multi-file
Cursor .cursor/rules/*.mdc Project .cursor/rules/ Activates on glob file match
Claude Code CLAUDE.md + .claude/rules/ Project root/subdirectory/~/.claude/ Load on startup + subdirectory on-demand
GitHub Copilot copilot-instructions.md + instructions/ .github/ Auto-load + path-specific
Windsurf .windsurfrules Project root Auto-load
Cline .clinerules Project root/global Auto-load
Aone Copilot .aone_copilot/rules/*.md Project root Auto-load
Universal AGENTS.md Project root/subdirectory Natively compatible with 22+ tools

6.2 Cursor Adaptation (.mdc Format)

Cursor uses .mdc files, supporting glob triggering—activates only when editing matching files:

.cursor/rules/
├── general.mdc          # alwaysApply: true, globally effective
├── react.mdc            # globs: "src/**/*.tsx"
├── testing.mdc          # globs: "**/*.test.*"
└── security.mdc         # globs: "src/api/**"

.mdc File Structure:

---
description: "Next.js + React + TypeScript Development Standards"
globs: "src/**/*.tsx"
alwaysApply: false
---

You are an expert in TypeScript, Next.js 14 App Router, React, Tailwind CSS.

Key Principles
- Use functional, declarative programming. Avoid classes.
- Use descriptive variable names with auxiliary verbs (isLoading, hasError).
- Favor named exports for components.

Error Handling
- Handle errors at the beginning of functions.
- Use early returns for error conditions.
- Use guard clauses for preconditions.

React/Next.js
- Use function, not const, for components.
- Minimize 'use client', 'useEffect', 'setState'. Favor RSC.
- Use Zod for form validation.
- Wrap client components in Suspense with fallback.

Key Difference: The globs field enables "trigger by file type"—load React rules when editing .tsx, load testing rules when editing .test.ts. This is Cursor's unique fine-grained control.

6.3 Claude Code Adaptation (Hierarchical + On-demand)

Claude Code uses CLAUDE.md, with two loading mechanisms:

Load on Startup (globally effective):

~/.claude/CLAUDE.md              # User-level: personal preferences
project/CLAUDE.md                # Project-level: team-shared standards
project/CLAUDE.local.md          # Local-level: personal project preferences (gitignore)

Load on Demand (effective only when reading files in that directory):

project/src/CLAUDE.md            # Subdirectory-level: module-specific rules
project/src/components/CLAUDE.md # Deeper level: component standards

⚠️ Note: Official documentation explicitly states "if two rules contradict, Claude may pick one arbitrarily". There is no guarantee that "deeper level always overrides shallower level"—avoiding contradictory rules is more important than relying on priority.

Also supports .claude/rules/ directory for path-specific rules, and @path/to/file syntax to import external files.

AGENTS.md Compatibility: Claude Code doesn't natively read AGENTS.md, but you can write @AGENTS.md in CLAUDE.md to import it.

6.4 GitHub Copilot Adaptation (Repository-level + Path-specific)

GitHub Copilot supports two layers of instructions:

.github/
├── copilot-instructions.md          # Repository-level (globally effective)
└── instructions/
    ├── react.instructions.md        # Path-specific (matches specific paths)
    └── testing.instructions.md

6.5 AGENTS.md Universal Solution

60,000+ open-source projects are using it, natively compatible with 22 AI programming tools:

Codex (OpenAI) · Jules (Google) · Cursor · Windsurf · Devin · Gemini CLI · Aider · goose · opencode · Zed · Warp · VS Code · Junie (JetBrains) · Amp · RooCode · Kilo Code · Phoenix · Semgrep · GitHub Copilot · Ona · Augment Code · Factory ...

# AGENTS.md

## Project Overview
React 18 + TypeScript + Vite single-page application...

## Setup Commands
pnpm install
pnpm dev

## Testing Instructions
pnpm test              # Full suite
pnpm vitest run -t "login"  # Single test case

## Code Style
- Functional components, no classes
- Naming: camelCase variables, PascalCase components
- Import order: react → third-party → local modules → styles

## Build and Deployment
pnpm build → dist/
CI: GitHub Actions, PR must pass lint + test

Monorepo Rule: One in root directory + one per sub-project, the closest one takes precedence.

6.6 Single-file Platform Adaptation (Windsurf / Cline)

Core strategy: Compress to within 100 lines, keep only workflow + constraints.

# .windsurfrules

## Role
Frontend development assistant. TypeScript strict, functional components.

## Workflow
Write code: Detect tech stack → Match standards → Generate → Self-check → Output
Fix bugs: Reproduce → Locate → Fix → Verify

## Constraints
- MUST: TypeScript strict, no `any`
- MUST: Components declared with function, not const arrow
- MUST: Error handling with early return + guard clause
- MUST NOT: Do not skip type checking
- SHOULD: Prioritize existing project components

Cut modular references, knowledge bases, examples—single-file platforms can't fit them, keep the most core 20%.

6.7 Cross-platform Migration Checklist

6.8 One Sentence

The essence of Skill is platform-agnostic. What changes is the carrier (.mdc / CLAUDE.md / AGENTS.md / .windsurfrules), what remains constant are four things: trigger conditions + workflow + constraints + examples. Write one good SKILL.md, adaptation is just format conversion.


Conclusion

In 2026, the competitiveness of AI programming lies not in "which IDE you can use", but in how much professional memory you've loaded into the AI.

Vercel did it, GitHub did it, Sentry did it. 32,500 people installed writing-guidelines.

Now it's your turn. Open your editor, start with that scenario you have to explain 3 times every day.

Your AI shouldn't have amnesia every day.


Next: "Write Your First AI Agent Step by Step" — When a Skill has memory, has a role, has initiative, it's no longer a tool, but a colleague.