create-skill
指导创建有效的 Agent Skills;创建前默认先做参照调研(本仓同族 skill + 管理源 + 社区搜索),借鉴现有设计而非从零起草。触发:"创建技能/skill"、"SKILL.md 怎么写"。
SKILL.mdskills/create-skill/SKILL.md
GitHub创建 Agent Skills
概述
目的:指导用户创建有效的 Agent Skills,提供从需求收集到技能验证的完整工作流
功能:提供技能创建的最佳实践、文件结构规范、描述编写指南、实用脚本模板,以及创建前的参照调研(同族 skill / 管理源 / 社区)
使用场景:
- 当用户想要创建、编写新技能,或想先看看有没有可借鉴的现有 skill 时
- 当用户询问技能结构、最佳实践、SKILL.md 格式时
- 当用户需要将现有工作流转化为可复用的技能时
前置守门:沉淀路由检查
在进入任何创建流程之前,先检查 loop-discovery skill 是否可用:
- 如果可用且本次创建未经过路由:先用它完成三步检查(证据门 → 覆盖阶梯 → 载体选择):
- 路由结论为"复用现有 / 修触发 / 扩展现有 / 换轻载体"时,不继续本流程
- 路由结论为"新建 skill"时,继续后续步骤
- 如果 loop-discovery 已输出"新建 skill"结论:直接继续,不重复路由
- 如果不可用:至少自检一次:现有 skills/ 中是否已有功能重叠的技能?内容是否薄到用 memory/rule 更合适?
边界:本守门只判定「建不建」(有否决权)。「怎么建得更好」——找可借鉴的现有/社区 skill——由「阶段 1.5 参照调研」负责(无否决权)。两者互不越界。
前置步骤:需求分析
在开始创建技能之前,首先检查 requirement-mining skill 是否可用:
- 检查 skill 可用性:尝试加载
requirement-miningskill - 如果可用:
- 使用该 skill 进行需求分析
- 分析完成后不需要落盘(无需保存分析结果文件)
- 基于分析结果继续后续的技能创建流程
- 如果不可用:跳过此步骤,直接进入后续流程
注意:此步骤仅用于获取需求上下文,不生成持久化文档。分析结果仅在当前对话中有效。
本技能指导你创建有效的 Agent Skills。技能是 Markdown 文件,教会智能体如何执行特定任务:按团队标准审查 PR、生成首选格式的提交消息、查询数据库模式,或任何专业工作流。
开始之前:收集需求
创建技能前,向用户收集以下关键信息:
- 目的与范围:该技能应帮助完成什么具体任务或工作流?
- 存储位置:应作为个人技能还是项目技能?
- 触发场景:智能体何时应自动应用此技能?
- 关键领域知识:智能体需要哪些它尚不了解的专业信息?
- 输出格式偏好:是否有特定模板、格式或风格要求?
- 现有模式:是否有可参考的现有示例或约定?(用户随口提到的线索先记下;系统的同类查找交由「阶段 1.5 参照调研」完成)
从上下文推断
如有之前的对话上下文,可从中推断技能需求。你可以基于对话中出现的工作流、模式或领域知识来创建技能。
获取更多信息
如需澄清,在可用时使用 AskQuestion 工具:
AskQuestion 使用示例:
- "此技能应存储在何处?" 选项如 ["个人 (~/.cursor/skills/)", "项目 (.cursor/skills/)"]
- "此技能是否应包含可执行脚本?" 选项如 ["是", "否"]
如 AskQuestion 工具不可用,以对话方式询问。
技能文件结构
目录布局
技能以目录形式存储,包含 SKILL.md 文件:
skill-name/
├── SKILL.md # 必需 - 主要指令
├── reference.md # 可选 - 详细文档
├── examples.md # 可选 - 使用示例
└── scripts/ # 可选 - 实用脚本
├── validate.py
└── helper.sh
SKILL.md 结构
每个技能需要一个 SKILL.md 文件,包含 YAML 前置元数据、AI 说明层和 Markdown 正文:
---
name: your-skill-name
description: <做什么、产出什么>。触发:"<触发词1>"、"<触发词2>"。
---
# 你的技能名称
## 概述
**目的**:[说明这个技能要解决什么问题或完成什么任务]
**功能**:[说明这个技能能做什么,提供哪些能力]
**使用场景**:[说明何时应该使用此技能,列出具体的触发场景]
## 指令
清晰、分步的智能体指导。
## 示例
使用此技能的具体示例。
description 只写 1-2 句、建议 ≤120 字符:句 1 说清「做什么 + 产出」,句 2 用
触发:起头带 3-5 个高信号触发词。工作流、模式枚举、落盘路径、边界声明、触发词枚举全集一律下沉正文(见「编写有效的描述」)。
AI 说明层规范
为什么需要 AI 说明层:
- AI 需要在众多技能中快速判断"这个技能是否适用于当前场景"
- description 只承担"选不选它",且会被截断展示——触发词全集、边界声明、降级策略由本层承载
- 正文可能直接进入具体指令,缺少概述
- AI 说明层让 AI 无需阅读全文即可理解技能用途
必须包含的三个维度:
| 维度 | 说明 | 示例 |
|---|---|---|
| 目的 | 这个技能要解决什么问题或完成什么任务 | "帮助用户快速生成符合团队规范的代码审查报告" |
| 功能 | 这个技能能做什么,提供哪些能力 | "支持多语言代码审查、安全漏洞检测、性能分析" |
| 使用场景 | 何时应该使用此技能,列出具体触发场景 | "当用户请求代码审查、提交 PR、或询问代码质量时" |
编写要求:
- 使用简洁明了的语言
- 每个维度 1-2 句话即可
- 使用场景应列出 2-3 个具体触发条件
- 使用场景是 description 的卸载区:描述里放不下的触发词全集、边界("XX 交给别的 skill")、降级策略写在这里
- 避免重复 description 字段的内容
- 使用中文编写
必需的元数据字段
| 字段 | 要求 | 用途 |
|---|---|---|
name |
最多 64 字符,仅小写字母/数字/连字符 | 技能的唯一标识符 |
description |
非空;1-2 句、建议 ≤120 字符(YAML 上限 1024 字符只是天花板,不是目标) | 帮助智能体判断何时应用此技能(触发依据) |
编写有效的描述
描述对于技能发现至关重要——但它只承担一件事:让智能体判断"用不用它"。默认 1-2 句,说清楚即可。
为什么必须短:描述在技能清单中是截断展示的,越靠后越可能不被读到——触发词堆在末尾等于没写(实测
performance-analysis的 579 字符描述,末尾 13 个触发短语与 3 条边界声明全部不可见)。把 description 当 mini-README 写,代价是可见性反而更差。
长度硬约束
| 项 | 要求 |
|---|---|
| 句数 / 长度 | 1-2 句(以 。?!; 断句,字符数为硬闸门);建议 ≤120 字符,>200 字符视为不合格(先删到 1-2 句再放行);英文按 2 句 / ≤200 字符把握 |
| 结构 | 句 1「做什么 + 产出」;句 2 以 触发: 起头带触发词(本仓库既有约定,61 个 skill 中 57 个如此) |
| 触发词 | ≤5 个,取高信号、口语化的说法;两类不可下沉——用户最可能脱口而出的说法、与相邻 skill 的关键区分词;其余变体与枚举全集移到正文「使用场景」 |
| 位置 | 最关键的 2-3 个触发词必须落在前 120 字符内 |
阈值性质:120 / 200 是约定的安全区(由"超长描述尾部会被截断"的观测得出),不是实测截断点;个别 skill 确需突破时须在正文写明理由,默认不放宽。
其余一律不进 description:工作流步骤、模式枚举(M1/M2/M3)、落盘路径、边界声明("XX 属别的 skill")、降级策略、触发词全集 —— 归位表与真实改写对照见 reference.md「description 精简细则」。
描述最佳实践
使用第三人称编写(描述会被注入系统提示):
- ✅ 正确:"处理 Excel 文件并生成报告"
- ❌ 避免:"我可以帮你处理 Excel 文件"
- ❌ 避免:"你可以用这个来处理 Excel 文件"
具体且包含触发术语:
- ✅ 正确(69 字符):从 PDF 文件中提取文本和表格、填写表单、合并文档。触发:"处理 PDF"、"表单填写"、"文档合并"。
- ❌ 模糊:"帮助处理文档"
写完逐句自问:删掉这句,智能体还能不能正确选中这个技能?不能 → 留;能 → 删(多半是工作流与边界)。
描述示例
# PDF 处理
description: 从 PDF 文件中提取文本和表格、填写表单、合并文档。触发:"处理 PDF"、"表单填写"、"文档合并"。
# Excel 分析
description: 分析 Excel 电子表格,创建数据透视表与图表。触发:"分析 Excel"、"数据透视表"、"表格数据"。
# Git 提交助手
description: 通过 git diff 生成描述性提交消息。触发:"写提交消息"、"审查暂存更改"、"commit message"。
# 代码审查
description: 按团队标准审查代码质量、安全性与可维护性。触发:"review 这个提交"、"检查这段代码"、"code review"。
核心编写原则
1. 简洁是关键
上下文窗口与对话历史、其他技能和请求共享。每个标记都在争夺空间。
默认假设:智能体已经非常聪明。只添加它尚不具备的上下文。
审视每条信息:
- "智能体真的需要这个解释吗?"
- "我能假设智能体知道这些吗?"
- "这段内容值得占用标记空间吗?"
好的(简洁):
## 提取 PDF 文本
使用 pdfplumber 进行文本提取:
\`\`\`python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
\`\`\`
差的(冗长):
## 提取 PDF 文本
PDF(便携式文档格式)文件是一种常见的文件格式,包含文本、图像和其他内容。要从 PDF 中提取文本,你需要使用一个库。有很多 PDF 处理库可用,但我们推荐 pdfplumber,因为它易于使用且在大多数情况下表现良好...
2. 保持 SKILL.md 在 500 行以内
为获得最佳性能,主 SKILL.md 文件应简洁。使用渐进式展开处理详细内容。
3. 渐进式展开
将核心信息放在 SKILL.md 中;将详细参考资料放在单独的文件中,智能体仅在需要时读取。
# PDF 处理
## 快速开始
[此处为核心指令]
## 更多资源
- 完整 API 详情,参见 [reference.md](reference.md)
- 使用示例,参见 [examples.md](examples.md)
保持引用层级为一层 - 从 SKILL.md 直接链接到参考文件。深层嵌套引用可能导致部分读取。
只适用于同 skill 内:引用其他 skill 时不要写相对路径(skill 可被单独安装,兄弟目录不保证存在),改用
use_skill("<skill>")形式——见「应避免的反模式 6」。
4. 设置适当的自由度
根据任务的脆弱性匹配具体程度:
| 自由度 | 使用时机 | 示例 |
|---|---|---|
| 高(文本指令) | 多种有效方法,依赖上下文 | 代码审查指南 |
| 中(伪代码/模板) | 首选模式,可接受变化 | 报告生成 |
| 低(具体脚本) | 脆弱操作,一致性关键 | 数据库迁移 |
常见模式
模板模式
提供输出格式模板:
## 报告结构
使用此模板:
\`\`\`markdown
# [分析标题]
## 执行摘要
[关键发现的单段概述]
## 关键发现
- 发现 1 及支持数据
- 发现 2 及支持数据
## 建议
1. 具体可操作的建议
2. 具体可操作的建议
\`\`\`
示例模式
对于输出质量依赖于示例的技能:
## 提交消息格式
**示例 1:**
输入:添加了基于 JWT 的用户认证
输出:
\`\`\`
feat(auth): 实现基于 JWT 的认证
添加登录端点和令牌验证中间件
\`\`\`
**示例 2:**
输入:修复了日期显示不正确的 bug
输出:
\`\`\`
fix(reports): 修正时区转换中的日期格式
在报告生成中统一使用 UTC 时间戳
\`\`\`
工作流模式
将复杂操作分解为带清单的清晰步骤:
## 表单填写工作流
复制此清单并跟踪进度:
\`\`\`
任务进度:
- [ ] 步骤 1:分析表单
- [ ] 步骤 2:创建字段映射
- [ ] 步骤 3:验证映射
- [ ] 步骤 4:填写表单
- [ ] 步骤 5:验证输出
\`\`\`
**步骤 1:分析表单**
运行:\`python scripts/analyze_form.py input.pdf\`
...
条件工作流模式
引导决策点:
## 文档修改工作流
1. 确定修改类型:
**创建新内容?** → 按下方"创建工作流"执行
**编辑现有内容?** → 按下方"编辑工作流"执行
2. 创建工作流:
- 使用 docx-js 库
- 从头构建文档
...
反馈循环模式
对于质量关键的任务,实现验证循环:
## 文档编辑流程
1. 进行编辑
2. **立即验证**:\`python scripts/validate.py output/\`
3. 如验证失败:
- 查看错误信息
- 修复问题
- 再次运行验证
4. **仅在验证通过后继续**
实用脚本
预制脚本相比生成代码有以下优势:
- 比生成代码更可靠
- 节省标记(上下文中无代码)
- 节省时间(无需生成代码)
- 确保使用间的一致性
## 实用脚本
**analyze_form.py**:从 PDF 提取所有表单字段
\`\`\`bash
python scripts/analyze_form.py input.pdf > fields.json
\`\`\`
**validate.py**:检查错误
\`\`\`bash
python scripts/validate.py fields.json
# 返回:"OK" 或列出冲突
\`\`\`
明确智能体应执行脚本(最常见)还是读取脚本作为参考。
应避免的反模式
1. Windows 风格路径
- ✅ 使用:
scripts/helper.py - ❌ 避免:
scripts\helper.py
2. 选项过多
# 差 - 令人困惑
"你可以使用 pypdf,或 pdfplumber,或 PyMuPDF,或..."
# 好 - 提供默认选项及备选方案
"使用 pdfplumber 进行文本提取。
对于需要 OCR 的扫描 PDF,改用 pdf2image 配合 pytesseract。"
3. 时间敏感信息
# 差 - 会过时
"如果你在 2025 年 8 月之前执行此操作,使用旧 API。"
# 好 - 使用"旧模式"部分
## 当前方法
使用 v2 API 端点。
## 旧模式(已弃用)
<details>
<summary>旧版 v1 API</summary>
...
</details>
4. 术语不一致
选择一个术语并贯穿使用:
- ✅ 始终使用"API 端点"(不混用"URL"、"路由"、"路径")
- ✅ 始终使用"字段"(不混用"框"、"元素"、"控件")
5. 模糊的技能名称
- ✅ 正确:
processing-pdfs、analyzing-spreadsheets - ❌ 避免:
helper、utils、tools
6. 跨 skill / 跨 agent 引用写成相对路径
skill 与 agent 都是可被单独安装 / 加载的单元,兄弟目录不保证存在——相对路径在运行时可能指向虚空。
- ❌ 避免:
[web-index SKILL.md](../web-index/SKILL.md)「规模判断」、按 agents/course-reviewer/agent.md 的维度评审 - ✅ 使用:
use_skill("web-index")的「规模判断」、use_agent(course-reviewer)的维度
分界线(关键):
| 引用方向 | 写法 | 原因 |
|---|---|---|
同 skill 内(SKILL.md ↔ reference.md / examples.md / assets/) |
相对路径 ✅ | 它们随 skill 一起分发,永远同级 |
| 跨 skill | use_skill("<skill>") ✅ |
对方目录不保证存在 |
| 跨 agent(引用某个子 agent 的能力 / 维度定义) | use_agent(<agent-name>) ✅ |
不写文件路径、不重复 agent 内容 |
目标不是对方 SKILL.md 时(而是其 reference.md、templates/ 等):写成 use_skill("<skill>") → 其 reference.md ——use_skill 只加载对方 SKILL.md,再由它导向细则文件。
约定 SSOT:skill 侧见本条;agent 侧见
use_skill("create-sub-agent")的「其他 skill 如何引用本 agent」(use_agent(<agent-name>)且不带引号),本条不重复其细节。
7. description 写成 mini-README
把工作流、模式枚举、落盘路径、边界声明连同十几个触发词全塞进描述——越写越看不到:描述在技能清单中是截断展示的,被截掉的往往正是排在末尾的触发词。
- ❌ 避免:
performance-analysis现状 237 字符、12 个触发词枚举,能力段还塞了盘点 / 量化 / 两条路建议 - ✅ 使用:1-2 句、建议 ≤120 字符,句 1「做什么 + 产出」+ 句 2
触发:带 3-5 个区分词;余下内容下沉正文(细则见 reference.md「description 精简细则」)
技能创建工作流
帮助用户创建技能时,遵循以下流程:
阶段 1:发现
收集以下信息:
- 技能的目的和主要用例
- 存储位置(个人 vs 项目)
- 触发场景
- 任何具体需求或约束
- 可参考的现有示例或模式
如有 AskQuestion 工具可用,使用它进行高效结构化收集。否则以对话方式询问。
阶段 1.5:参照调研(Prior Art)
本阶段只回答「怎么建得更好」,不回答「该不该建」——后者由「前置守门」的 loop-discovery 决定。
为什么需要:从零起草的 skill 容易漏掉别人已经验证过的结构、触发词写法和坑。先查一圈再动手,成本远低于事后返工。
三条纪律(先立规矩,防跑偏):
- 借鉴 ≠ 替代:找到相似 skill(哪怕高度相似)都不改变 loop-discovery 的路由结论。本阶段没有否决权——它的产出是"可借鉴点",不是"不建了"。
- 本仓库规范优先:外部样本与本仓库约定冲突时(无 AI 说明层、超 500 行、跨 skill 用相对路径、description 写成 mini-README 等),一律以本仓库为准。借鉴点是翻译过来,不是搬过来。
- 只取骨架与约定,不取正文:抄结构、抄避坑清单、抄措辞模式;禁止复制正文内容——否则几十个 skill 互相复制膨胀,正是 ecosystem-review 判定的「层级重复(有害)」。
无否决权 ≠ 无上报义务:L0 若扫到高度重复的现有 skill,且本次创建未经 loop-discovery 路由(守门走的是第 3 条自检路径),必须先提示用户"已存在:<skill>"并建议先走一次 loop-discovery 裁定。提示后是否继续由用户决定——本阶段既不自行中止,也不自行裁决。
来源三层(由近及远,性价比递减):
| 层 | 来源 | 怎么做 | 默认 |
|---|---|---|---|
| L0 本仓库同族 skill | skills/ 下已有技能 |
按形态找 2-3 个标杆(对照表见 reference.md「形态 → 标杆 skill 对照表」),读它们的 SKILL.md 骨架与约定。若本次创建已由 loop-discovery 路由而来(其 Step 2 已扫过本地覆盖),L0 只做这一件事,不重复判断"是否重复" | 必做 |
| L1 管理源其他仓库 | ~/.hackwu-skills/(skill-install 的多仓库池) |
grep 同名/近义 skill 的 SKILL.md | 建议做 |
| L2 社区 / 远端 | web_search、GitHub(若 npx skills 已提供 search 子命令,优先用它) |
搜 <主题> agent skill SKILL.md、<主题> Claude skill best practice 一类 |
默认开启 |
降级与跳过(不阻塞是底线):
- 网络/搜索工具不可用 → 打印「L2 跳过(原因)」后继续,绝不阻塞、绝不编造命中结果
- 用户明确说"不用搜 / 直接写",或只是微调现有 skill → 可整体跳过本阶段
- L0/L1 无命中 → 如实写"无同类",同样继续
也适用于"改造现有 skill"(不只服务新建):重构 / 升级某个 skill 时,L0 要再读一遍待改 skill 自身,做"现状 vs 标杆"对照——这一步往往比新建时更值钱。
外部样本筛选(防把坏模式带进来):优先一手样本(知名仓库的 SKILL.md 原文);博客 / 二手解读只取清单类内容;样本若连 frontmatter 或触发描述都没有,说明它遵循的是别的规范——只取结构,不取规范(纪律 2)。
提取五个维度(固定清单,避免"看了一圈啥也没带走"):
| # | 维度 | 具体看什么 |
|---|---|---|
| 1 | 触发词覆盖 | description 怎么写?口语化触发词是否落在前 120 字符内、有无被工作流/边界挤到末尾?(既有长描述只作反例,硬约束见「编写有效的描述」) |
| 2 | 结构切分 | 是否拆 reference.md / examples.md / scripts/?按什么粒度拆? |
| 3 | 工作流阶段 | 几阶段、每阶段产出是什么、有无清单? |
| 4 | 反模式 / 已知坑 | 性价比最高——别人踩过的坑直接抄进自己的反模式表 |
| 5 | 生态咬合 | 有无「与相关 skill 的关系」表、SSOT 声明、use_skill 交接? |
输出(3-5 条,作为阶段 2 的设计输入,默认不落盘;下方为节选示意,完整模板见 reference.md):
🔍 参照调研(Prior Art)
- L0 同族标杆:<skill> / <skill>(形态:<形态>)
- L1 管理源:<命中项 / 无>
- L2 社区:<命中项 / 无 / 跳过(原因)>
可借鉴点:
1. [触发词] <具体写法> ← <来源>
2. [结构] <怎么拆文件> ← <来源>
3. [反模式] <坑> ← <来源>
不适用点:<外部样本与本仓库规范冲突、已丢弃的部分>
阶段 2:设计
输入 = 阶段 1 的需求 + 阶段 1.5 的可借鉴点。
- 起草技能名称(小写、连字符、最多 64 字符)
- 写 description:1-2 句、建议 ≤120 字符的第三人称描述——句 1「做什么 + 产出」,句 2
触发:带 ≤5 个触发词 - 概述所需的主要部分
- 确定是否需要支持文件或脚本
阶段 3:实现
- 创建目录结构
- 编写带前置元数据的 SKILL.md 文件
- 创建任何支持参考文件
- 需要时创建实用脚本
阶段 4:验证
- 验证 SKILL.md 在 500 行以内
- 检查 description:是否 1-2 句、建议 ≤120 字符(>200 字符即不合格——先删工作流与边界,再放行)
- 确保全文术语一致
- 验证所有文件引用层级为一层
- 测试技能可被发现和应用
完整示例
这是一个结构良好的技能示例:
目录结构:
code-review/
├── SKILL.md
├── STANDARDS.md
└── examples.md
SKILL.md:
---
name: code-review
description: 根据团队标准审查代码质量、安全性和可维护性。当审查拉取请求、检查代码变更或用户请求代码审查时使用。
---
# 代码审查
## 概述
**目的**:帮助开发者快速识别代码中的问题,确保代码质量符合团队标准
**功能**:支持多语言代码审查,覆盖安全性、Bug 风险、代码规范、架构设计、性能、测试覆盖等维度
**使用场景**:
- 当用户请求代码审查时
- 当用户提交 PR 或询问代码质量时
- 当用户说"review 这个提交"、"检查这段代码"时
## 快速开始
审查代码时:
1. 检查正确性和潜在 bug
2. 验证安全最佳实践
3. 评估代码可读性和可维护性
4. 确保测试充分
## 审查清单
- [ ] 逻辑正确且处理边界情况
- [ ] 无安全漏洞(SQL 注入、XSS 等)
- [ ] 代码遵循项目风格约定
- [ ] 函数大小适当且职责单一
- [ ] 错误处理全面
- [ ] 测试覆盖变更内容
## 提供反馈
反馈格式:
- 🔴 **严重**:合并前必须修复
- 🟡 **建议**:考虑改进
- 🟢 **锦上添花**:可选增强
## 更多资源
- 详细编码标准,参见 [STANDARDS.md](STANDARDS.md)
- 审查示例,参见 [examples.md](examples.md)
更多资源
- 形态 → 标杆 skill 对照表、参照调研输出模板与示例,参见 reference.md
总结清单
最终确定技能前,验证:
参照调研(阶段 1.5)
- L0 同族标杆已找(2-3 个),L2 社区搜索已执行或已注明跳过原因
- 借鉴点落在结构 / 触发词 / 避坑上,未复制正文
- 与本仓库同族 skill 风格一致(AI 说明层 / 反模式 / 与相关 skill 关系)
- 参照调研输出未越界给出"已有类似 skill、建议不建"类结论(若出现,回交 loop-discovery 裁定)
核心质量
- 描述 1-2 句、建议 ≤120 字符(>200 字符即不合格)
- 描述只写"做什么 + 何时用",未塞入工作流 / 模式枚举 / 落盘路径 / 边界声明
- 句 2 用
触发:带 ≤5 个触发词,核心触发词落在前 120 字符内 - 描述使用第三人称、具体且含关键术语
- SKILL.md 正文在 500 行以内
- 全文术语一致
- 示例具体而非抽象
- 包含 AI 说明层(目的、功能、使用场景)
结构
- 文件引用层级为一层
- 适当使用渐进式展开
- 工作流步骤清晰
- 无时间敏感信息
如包含脚本
- 脚本解决问题而非回避问题
- 已记录所需包
- 错误处理明确且有帮助
- 无 Windows 风格路径