---
name: skill-creator
description: 创建新技能、修改和改进现有技能，以及衡量技能性能。当用户想要从零创建技能、编辑或优化现有技能、运行评估测试技能、通过方差分析基准测试技能性能，或优化技能描述以获得更好的触发准确度时使用。
---

# Skill Creator（技能创建器）

一个用于创建新技能并迭代改进的技能。

总体而言，创建技能的过程如下：

- 确定技能的目标和大致实现方式
- 编写技能草稿
- 创建一些测试提示，让能访问该技能的 Claude 运行
- 帮助用户定性和定量地评估结果
  - 在后台运行测试的同时，如果没有定量的评估标准，起草一些定量评估（如果有，可以直接使用或根据需要进行修改）。然后向用户解释（或如果已有，解释已有的评估标准）
  - 使用 `eval-viewer/generate_review.py` 脚本向用户展示结果供其查看，同时让他们查看定量指标
- 根据用户的评估反馈重写技能（以及如果定量基准中发现任何明显缺陷）
- 重复直到满意为止
- 扩展测试集并更大规模地再次尝试

在使用本技能时，你的任务是确定用户处于此过程的哪个阶段，然后帮助他们推进这些阶段。例如，用户可能说"我想创建一个做 X 的技能"。你可以帮助他们缩小需求、编写草稿、编写测试用例、确定评估方式、运行所有提示并重复。

另一方面，用户可能已经有一个技能草稿。这种情况下，你可以直接进入评估/迭代部分。

当然，你应该始终保持灵活性。如果用户说"我不需要运行一堆评估，就跟我一起看看就好"，你也可以这样做。

然后在技能完成后（但同样，顺序是灵活的），你还可以运行技能描述优化器（我们有一个单独的脚本用于此）来优化技能的触发效果。

可以吗？好的。

## 与用户沟通

技能创建器的使用者可能对各种编程术语的熟悉程度有很大差异。如果你还没听说（但你怎么可能听说，这最近才开始流行），现在有一个趋势是 Claude 的强大激励着水管工打开他们的终端、父母和祖父母搜索"如何安装 npm"。另一方面，大多数用户可能对电脑相当熟悉。

所以请注意上下文线索来判断如何措辞！在默认情况下，给你一些思路：

- "评估"和"基准测试"算是临界但可以接受
- 对于"JSON"和"断言"这类词，你需要看到用户有明显了解这些概念的情况下才能使用，否则需要解释

如果不确定，可以简要解释术语。如果不确定用户是否能理解，可以加上简短定义说明。

---

## 创建技能

### 捕捉意图

首先理解用户的意图。当前对话可能已经包含了用户想要捕捉的工作流（例如，他们说"把这个变成技能"）。如果是这样，先从对话历史中提取答案——使用的工具、步骤顺序、用户的修正、观察到的输入/输出格式。用户可能需要填补空白，并且应确认后再进行下一步。

1. 这个技能应该让 Claude 能做什么？
2. 这个技能应该在什么情况下触发？（什么用户短语/上下文）
3. 预期的输出格式是什么？
4. 我们是否应该设置测试用例来验证技能是否工作？具有客观可验证输出（文件转换、数据提取、代码生成、固定工作流步骤）的技能适合有测试用例。具有主观输出（写作风格、艺术）的技能通常不需要。根据技能类型建议适当的默认值，但让用户决定。

### 访谈与研究

主动询问边界情况、输入/输出格式、示例文件、成功标准和依赖关系等问题。在这一步完全确定之前，先不要编写测试提示。

检查可用的 MCP——如果对研究有帮助（搜索文档、查找类似技能、查阅最佳实践），如果有子代理可用则并行研究，否则内联研究。带着上下文准备来减少用户的负担。

### 编写 SKILL.md

根据用户访谈，填充以下组成部分：

- **name**：技能标识符
- **description**：何时触发、做什么。这是主要的触发机制——包括技能做什么以及何时使用的具体上下文。所有"何时使用"的信息都放在这里，而不是正文中。注意：当前 Claude 有"触发不足"的倾向——在有用的时候不使用技能。为解决这个问题，请让技能描述稍微"强势"一些。例如，与其写"如何构建一个快速仪表盘来展示内部 Anthropic 数据"，不如写"如何构建一个快速仪表盘来展示内部 Anthropic 数据。确保在用户提到仪表盘、数据可视化、内部指标或想要展示任何公司数据时使用本技能，即使他们没有明确要求'仪表盘'。"
- **compatibility**：所需的工具、依赖项（可选，很少需要）
- **技能的其余内容 :)**

### 技能编写指南

#### 技能结构

```
skill-name/
├── SKILL.md（必需）
│   ├── YAML frontmatter（name、description 必需）
│   └── Markdown 说明
└── 捆绑资源（可选）
    ├── scripts/    - 用于确定性/重复性任务的可执行代码
    ├── references/ - 按需加载到上下文的文档
    └── assets/     - 输出中使用的文件（模板、图标、字体）
```

#### 渐进式披露

技能使用三级加载系统：
1. **元数据**（name + description）——始终在上下文中（约 100 字）
2. **SKILL.md 正文**——技能触发时在上下文中（理想情况下 < 500 行）
3. **捆绑资源**——按需加载（无限制，脚本可在不加载的情况下执行）

这些字数是大致参考，如果需要可以更长。

**关键模式：**
- 保持 SKILL.md 在 500 行以下；如果接近这个限制，添加一个额外的层级结构，并给出清晰的指引，说明使用该技能的模型下一步该去哪里。
- 从 SKILL.md 中清晰地引用文件，并说明何时阅读它们
- 对于大文件（> 300 行），包含目录

**领域组织**：当技能支持多个领域/框架时，按变体组织：
```
cloud-deploy/
├── SKILL.md（工作流 + 选择）
└── references/
    ├── aws.md
    ├── gcp.md
    └── azure.md
```
Claude 只读取相关的参考文件。

#### 无意外原则

这不用说，技能不得包含恶意软件、利用代码或任何可能危及系统安全的内容。技能的内容不应令用户对其意图感到意外。不要配合创建误导性技能或旨在促进未经授权访问、数据窃取或其他恶意活动的请求。像"角色扮演为 XYZ"之类的内容是可以的。

#### 编写模式

在说明中优先使用祈使句。

**定义输出格式**——可以这样做：
```markdown
## 报告结构
始终使用这个精确模板：
# [标题]
## 执行摘要
## 主要发现
## 建议
```

**示例模式**——包含示例很有用。可以按如下格式（但如果示例中有"输入"和"输出"，可能需要稍作调整）：
```markdown
## 提交信息格式
**示例 1：**
输入：使用 JWT 令牌添加用户认证
输出：feat(auth)：implement JWT-based authentication
```

### 写作风格

尽量向模型解释为什么某些内容重要，而不是生硬地使用全大写的"必须"。使用心理理论，尝试让技能变得通用而不仅仅局限于特定示例。先写草稿，然后以全新的视角审视并改进。

### 测试用例

编写技能草稿后，提出 2-3 个真实的测试提示——真实用户会实际说的那种话。与用户分享："这里有几个我想尝试的测试用例。看起来对吗？还是想添加更多？"然后运行它们。

将测试用例保存到 `evals/evals.json`。先不要编写断言——只写提示。在运行过程中起草断言。

```json
{
  "skill_name": "example-skill",
  "evals": [
    {
      "id": 1,
      "prompt": "用户的任务提示",
      "expected_output": "预期结果的描述",
      "files": []
    }
  ]
}
```

完整模式见 `references/schemas.md`（包括 `assertions` 字段，稍后会添加）。

## 运行和评估测试用例

这一节是一个连续的流程——不要中途停止。不要使用 `/skill-test` 或其他测试技能。

将结果放在 `<skill-name>-workspace/` 中，作为技能目录的同级。在工作区内，按迭代组织结果（`iteration-1/`、`iteration-2/` 等），每个测试用例在其中有目录（`eval-0/`、`eval-1/` 等）。不要一次性全部创建——按需创建目录。

### 第 1 步：在同一轮中启动所有运行（带技能 AND 基准测试）

对每个测试用例，在同一轮中启动两个子代理——一个带技能，一个不带。这很重要：不要先运行带技能的测试，然后再回来做基准测试。一次性全部启动，这样它们大约同时完成。

**带技能运行：**

```
执行此任务：
- 技能路径：<path-to-skill>
- 任务：<eval prompt>
- 输入文件：<eval files if any, or "none">
- 保存输出到：<workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- 要保存的输出：<用户关心的内容——例如".docx 文件"、"最终 CSV">
```

**基准测试运行**（相同提示，但基准测试取决于上下文）：
- **创建新技能**：完全没有技能。相同提示，无技能路径，保存到 `without_skill/outputs/`。
- **改进现有技能**：旧版本。编辑前，快照技能（`cp -r <skill-path> <workspace>/skill-snapshot/`），然后将基准子代理指向快照。保存到 `old_skill/outputs/`。

为每个测试用例编写一个 `eval_metadata.json`（断言暂时可以为空）。根据测试内容给每个评估一个描述性名称——不仅仅是"eval-0"。目录也使用这个名称。如果本轮使用新的或修改过的评估提示，为每个新评估目录创建这些文件——不要假设它们从之前的迭代继承。

```json
{
  "eval_id": 0,
  "eval_name": "descriptive-name-here",
  "prompt": "用户的任务提示",
  "assertions": []
}
```

### 第 2 步：在运行过程中起草断言

不要只是等待运行完成——你可以利用这段时间高效工作。为每个测试用例起草定量断言并向用户解释。如果 `evals/evals.json` 中已有断言，审查它们并解释它们检查什么。

好的断言是客观可验证的，并有描述性名称——它们在基准查看器中应该清晰可读，以便浏览结果的人立即理解每条断言检查什么。主观技能（写作风格、设计质量）更适合定性评估——不要强行将断言用于需要人类判断的内容。

更新 `eval_metadata.json` 文件和 `evals/evals.json`，并在草稿完成后加入断言。同时向用户解释他们将在查看器中看到什么——包括定性输出和定量基准。

### 第 3 步：运行完成后捕获计时数据

每个子代理任务完成时，你会收到包含 `total_tokens` 和 `duration_ms` 的通知。立即将数据保存到运行目录中的 `timing.json`：

```json
{
  "total_tokens": 84852,
  "duration_ms": 23332,
  "total_duration_seconds": 23.3
}
```

这是捕获该数据的唯一机会——它通过任务通知传递，不会被持久化到其他地方。每次收到通知时处理它，而不是尝试批量处理。

### 第 4 步：评分、汇总并启动查看器

所有运行完成后：

1. **对每次运行评分**——启动评分子代理（或内联评分），读取 `agents/grader.md`，根据输出评估每个断言。将结果保存到每个运行目录的 `grading.json` 中。grading.json 的 expectations 数组必须使用字段 `text`、`passed` 和 `evidence`（而不是 `name`/`met`/`details` 或其他变体）——查看器依赖于这些精确的字段名。对于可以通过编程检查的断言，编写并运行脚本而不是目测——脚本更快、更可靠，并且可以跨迭代重用。

2. **汇总为基准**——从 skill-creator 目录运行汇总脚本：
   ```bash
   python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>
   ```
   这会生成 `benchmark.json` 和 `benchmark.md`，包含每种配置的通过率、时间和 tokens，带有均值 ± 标准差和差值。如果手动生成 benchmark.json，请查看 `references/schemas.md` 以了解查看器期望的确切模式。每个 with_skill 版本放在其基准对应版本之前。

3. **进行分析师检查**——读取基准数据，找出汇总统计可能隐藏的模式。查看 `agents/analyzer.md` 中的"分析基准结果"部分，了解需要关注什么——比如无论是否有技能始终通过的断言（非区分性）、高方差评估（可能不稳定）以及时间/令牌的权衡。

4. **启动查看器**，同时呈现定性输出和定量数据：
   ```bash
   nohup python <skill-creator-path>/eval-viewer/generate_review.py \
     <workspace>/iteration-N \
     --skill-name "my-skill" \
     --benchmark <workspace>/iteration-N/benchmark.json \
     > /dev/null 2>&1 &
   VIEWER_PID=$!
   ```
   对于第 2+ 轮迭代，还要传入 `--previous-workspace <workspace>/iteration-<N-1>`。

   **Cowork / 无头环境：** 如果 `webbrowser.open()` 不可用或环境没有显示器，使用 `--static <output_path>` 写入独立的 HTML 文件而不是启动服务器。用户点击"提交所有审阅"时，反馈将作为 `feedback.json` 文件下载。下载后，将 `feedback.json` 复制到工作区目录中供下一轮迭代使用。

注意：请使用 generate_review.py 创建查看器；不需要编写自定义 HTML。

5. **告诉用户**类似："我已将结果在浏览器中打开。有两个标签页——'Outputs' 让你逐一点击每个测试用例并留下反馈，'Benchmark' 显示定量比较。完成后，回到这里告诉我。"

### 用户在查看器中看到的内容

"Outputs"标签页一次显示一个测试用例：
- **Prompt**：给出的任务
- **Output**：技能产生的文件，尽可能内联渲染
- **Previous Output**（第 2+ 轮迭代）：折叠区域，显示上一轮的输出
- **Formal Grades**（如果运行了评分）：折叠区域，显示断言通过/失败
- **Feedback**：文本框，输入时自动保存
- **Previous Feedback**（第 2+ 轮迭代）：他们上次的评论，显示在文本框下方

"Benchmark"标签页显示统计摘要：每种配置的通过率、时间和令牌使用情况，附带每个评估的细分和分析师观察。

可通过上一页/下一页按钮或箭头键导航。完成后，他们点击"提交所有审阅"将所有反馈保存到 `feedback.json`。

### 第 5 步：读取反馈

当用户告诉你完成后，读取 `feedback.json`：

```json
{
  "reviews": [
    {"run_id": "eval-0-with_skill", "feedback": "图表缺少轴标签", "timestamp": "..."},
    {"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
    {"run_id": "eval-2-with_skill", "feedback": "完美，我很喜欢", "timestamp": "..."}
  ],
  "status": "complete"
}
```

空的 feedback 意味着用户认为没问题。将改进重点放在用户有具体抱怨的测试用例上。

完成后关闭查看器服务器：

```bash
kill $VIEWER_PID 2>/dev/null
```

---

## 改进技能

这是循环的核心。你已经运行了测试用例，用户审阅了结果，现在你需要根据他们的反馈让技能变得更好。

### 如何思考改进

1. **从反馈中归纳。** 整体思路是我们在创建可以跨许多不同提示使用一百万次（可能真的，甚至更多谁知道呢）的技能。你和用户只在几个示例上迭代，因为这样能更快推进。用户对这些示例了如指掌，评估新输出对他们来说很快。但如果你们共同开发的技能只适用于这些示例，那就没用了。与其做那些过拟合的小改动或压迫性的 MUST，如果有一些顽固的问题，你可以尝试扩展思路，使用不同的比喻，或推荐不同的工作模式。尝试的成本很低，也许会有很棒的结果。

2. **保持提示简洁。** 移除没有贡献的内容。确保阅读转录文本，而不仅仅是最终输出——如果看起来技能让模型浪费了大量时间做不产生效果的事情，可以尝试删除导致这种行为的技能部分，看看会发生什么。

3. **解释原因。** 尽力解释你要求模型做的每件事背后的**原因**。当今的 LLM 很**聪明**。它们有很好的心理理论，在好的框架下可以超越机械指令真正实现目标。即使用户的反馈简洁或沮丧，也要尝试真正理解任务和用户写的内容以及他们的真实意图，然后将这种理解传递到指令中。如果你发现自己在大写 ALWAYS 或 NEVER，或使用超级僵化的结构，那是一个黄旗——如果可能，重新框架并解释推理，让模型理解你为什么要求做这件事。这是一种更人性化、更强大、更有效的方法。

4. **寻找测试用例间的重复工作。** 阅读测试运行的转录，注意子代理是否都独立编写了类似的辅助脚本或采用了相同的多步骤方法。如果所有 3 个测试用例都导致子代理编写了 `create_docx.py` 或 `build_chart.py`，这是一个强烈信号，说明技能应该捆绑该脚本。编写一次，放在 `scripts/` 中，并指示技能使用它。这能节省每个未来调用重新发明轮子的时间。

这个任务相当重要（我们正在尝试创造数十亿的年经济价值！），你的思考时间不是瓶颈；慢慢来，真正深入思考。我建议写一版修订草稿，然后用新的眼光审视并改进。真正尝试进入用户的大脑，理解他们想要和需要什么。

### 迭代循环

改进技能后：

1. 将改进应用到技能
2. 将所有测试用例重新运行到新的 `iteration-<N+1>/` 目录中，包括基准测试运行。如果你在创建新技能，基准测试始终为 `without_skill`（无技能）——这在各迭代间保持不变。如果你在改进现有技能，根据你的判断哪种基准测试有意义：用户最初带来的原始版本，还是上一次迭代。
3. 启动查看器，使用 `--previous-workspace` 指向上一轮迭代
4. 等待用户审阅并告诉你完成
5. 读取新的反馈，再次改进，重复

继续进行直到：
- 用户说满意
- 所有反馈都是空的（一切看起来很好）
- 你不再取得有意义的进展

---

## 高级：盲测对比

对于需要更严格比较两个技能版本的情况（例如，用户问"新版本真的更好吗？"），有一个盲测对比系统。阅读 `agents/comparator.md` 和 `agents/analyzer.md` 了解详情。基本思路是：给一个独立代理两个输出，不告诉它哪个是哪个，让它判断质量。然后分析胜者为何胜出。

这是可选的，需要子代理，大多数用户不需要。人工审阅循环通常就足够了。

---

## 描述优化

SKILL.md frontmatter 中的 description 字段是决定 Claude 是否调用技能的主要机制。创建或改进技能后，主动提供优化描述以提高触发准确性。

### 第 1 步：生成触发评估查询

创建 20 个评估查询——混合应该触发和不应该触发的。保存为 JSON：

```json
[
  {"query": "用户的提示", "should_trigger": true},
  {"query": "另一个提示", "should_trigger": false}
]
```

查询必须真实，是 Claude Code 或 Claude.ai 用户实际会输入的内容。不是抽象请求，而是具体且有相当多细节的请求。例如文件路径、关于用户工作或情况的个人背景、列名和值、公司名称、URL。有一点背景故事。有些可能是小写或包含缩写、拼写错误或口语。使用不同长度的混合，重点关注边界情况而不是让它们一目了然（用户将有机会确认）。

糟糕：`"格式化这些数据"`、`"从 PDF 中提取文字"`、`"创建图表"`

好：`"ok 我的老板刚给我发了一个 xlsx 文件（在我的下载文件夹里，叫类似'Q4 sales final FINAL v2.xlsx'），她想让我添加一列显示利润率百分比。收入在 C 列，成本在 D 列我想"`

对于**应该触发**的查询（8-10），考虑覆盖率。需要同一意图的不同措辞——一些正式，一些随意。包括用户没有显式命名技能或文件类型但明显需要它的情况。加入一些不常见的用例，以及本技能与其他技能竞争但应胜出的情况。

对于**不应该触发**的查询（8-10），最有价值的是接近命中但失之交臂的查询——与本技能共享关键词或概念但实际上需要不同内容。考虑相邻领域、模糊措辞（朴素的关键词匹配会触发但不应该触发），以及查询涉及技能做某事但在另一个工具更合适的上下文中的情况。

关键要避免：不要让不应该触发的查询明显不相关。"写一个斐波那契函数"作为 PDF 技能的负例测试太容易了——它什么都测试不了。负面案例应该真正有难度。

### 第 2 步：与用户一起审查

使用 HTML 模板向用户展示评估集供审查：

1. 从 `assets/eval_review.html` 读取模板
2. 替换占位符：
   - `__EVAL_DATA_PLACEHOLDER__` → JSON 格式的评估项数组（不带引号——它是 JS 变量赋值）
   - `__SKILL_NAME_PLACEHOLDER__` → 技能名称
   - `__SKILL_DESCRIPTION_PLACEHOLDER__` → 技能的当前描述
3. 写入临时文件（如 `/tmp/eval_review_<skill-name>.html`）并打开：`open /tmp/eval_review_<skill-name>.html`
4. 用户可以编辑查询、切换 should_trigger、添加/删除条目，然后点击"导出评估集"
5. 文件下载到 `~/Downloads/eval_set.json`——在 Downloads 文件夹中检查最新版本，以防有多个（如 `eval_set (1).json`）

这一步很重要——糟糕的评估查询会导致糟糕的描述。

### 第 3 步：运行优化循环

告诉用户："这需要一些时间——我将在后台运行优化循环，并定期检查。"

将评估集保存到工作区，然后在后台运行：

```bash
python -m scripts.run_loop \
  --eval-set <path-to-trigger-eval.json> \
  --skill-path <path-to-skill> \
  --model <model-id-powering-this-session> \
  --max-iterations 5 \
  --verbose
```

使用系统提示中的模型 ID（驱动当前会话的那个），以便触发测试与用户实际体验匹配。

运行时，定期查看输出尾部，向用户更新当前进行的轮次和分数情况。

这会自动处理完整的优化循环。它将评估集拆分为 60% 训练和 40% 保留测试，评估当前描述（每个查询运行 3 次以获得可靠的触发率），然后调用 Claude 基于失败内容提出改进。它在训练和测试上重新评估每个新描述，最多迭代 5 次。完成后，在浏览器中打开一个 HTML 报告，显示每轮的结果，并返回包含 `best_description` 的 JSON——通过测试分数而非训练分数选择以避免过拟合。

### 技能触发的工作原理

了解触发机制有助于设计更好的评估查询。技能出现在 Claude 的 `available_skills` 列表中，带有名称 + 描述，Claude 根据该描述决定是否查阅技能。重要的是要知道，Claude 只查阅那些它自己不容易处理的任务的技能——简单、单步骤的查询如"读取这个 PDF"即使描述完美匹配也可能不会触发技能，因为 Claude 可以直接用基本工具处理它们。复杂、多步骤或专业化的查询在描述匹配时能可靠地触发技能。

这意味着你的评估查询应该足够实质性，让 Claude 会从查阅技能中获益。像"读取文件 X"这样的简单查询是糟糕的测试用例——无论描述质量如何，它们都不会触发技能。

### 第 4 步：应用结果

从 JSON 输出中取出 `best_description` 并更新技能的 SKILL.md frontmatter。向用户展示前后对比并报告分数。

---

### 打包并呈现（仅当 `present_files` 工具可用时）

检查你是否能访问 `present_files` 工具。如果不能，跳过此步。如果能，打包技能并向用户展示 .skill 文件：

```bash
python -m scripts.package_skill <path/to/skill-folder>
```

打包后，指导用户到生成的 `.skill` 文件路径，以便他们安装。

---

## Claude.ai 专用说明

在 Claude.ai 中，核心工作流相同（草稿 → 测试 → 审阅 → 改进 → 重复），但由于 Claude.ai 没有子代理，一些机制会变化。以下是需要调整的地方：

**运行测试用例**：没有子代理意味着无法并行执行。对每个测试用例，读取技能的 SKILL.md，然后按照其说明自己完成测试提示。一次做一个。这不如独立子代理严谨（你编写了技能，也运行它，所以你有完整的上下文），但这是一个有用的合理性检查——而且人工审阅步骤可以弥补。跳过基准测试运行——只需按请求使用技能完成任务。

**审阅结果**：如果你无法打开浏览器（如 Claude.ai 的 VM 没有显示器，或你在远程服务器上），完全跳过浏览器查看器。直接在对话中呈现结果。对每个测试用例，显示提示和输出。如果输出是用户需要看到的文件（如 .docx 或 .xlsx），保存到文件系统并告诉他们位置，以便他们下载和检查。内联询问反馈："看起来怎么样？有什么要改的吗？"

**基准测试**：跳过定量基准测试——它依赖于基准比较，没有子代理就没有意义。专注于来自用户的定性反馈。

**迭代循环**：和以前一样——改进技能，重新运行测试用例，询问反馈——只是中间没有浏览器查看器。如果有文件系统，你仍然可以将结果组织到迭代目录中。

**描述优化**：此部分需要 `claude` CLI 工具（具体是 `claude -p`），仅在 Claude Code 中可用。在 Claude.ai 上跳过。

**盲测对比**：需要子代理。跳过。

**打包**：`package_skill.py` 在安装了 Python 和文件系统的任何地方都可以工作。在 Claude.ai 上，你可以运行它，用户可以下载生成的 `.skill` 文件。

**更新现有技能**：用户可能要求你更新现有技能，而非创建新的。在这种情况下：
- **保留原始名称。** 注意技能的目录名和 `name` frontmatter 字段——原样使用。例如，如果已安装的技能是 `research-helper`，输出 `research-helper.skill`（而不是 `research-helper-v2`）。
- **编辑前复制到可写位置。** 已安装的技能路径可能是只读的。复制到 `/tmp/skill-name/`，在那里编辑，然后从副本打包。
- **如果手动打包，先在 `/tmp/` 中暂存**，然后复制到输出目录——直接写入可能因权限而失败。

---

## Cowork 专用说明

如果你在 Cowork 中，主要需要知道：

- 你有子代理，所以主要工作流（并行生成测试用例、运行基准测试、评分等）都有效。（但如果你遇到严重的超时问题，也可以串行运行测试提示。）
- 你没有浏览器或显示器，所以在生成评估查看器时，使用 `--static <output_path>` 写入独立的 HTML 文件而不是启动服务器。然后提供一个用户可点击的链接，在浏览器中打开该 HTML。
- 由于某种原因，Cowork 设置似乎使 Claude 在运行测试后倾向于不生成评估查看器，所以重申一下：无论你在 Cowork 还是在 Claude Code 中，运行测试后，你始终应该生成评估查看器供人类查看示例，然后再自己修正技能，使用 `generate_review.py`（而不是编写自己的定制 HTML 代码）。提前道歉但我要全大写：在你自己评估输入之前，先生成评估查看器！你要尽快把它们呈现在用户面前！
- 反馈机制不同：由于没有运行中的服务器，查看器的"提交所有审阅"按钮会下载 `feedback.json` 文件。然后你可以从那里读取（可能需要先请求访问权限）。
- 打包可行——`package_skill.py` 只需要 Python 和文件系统。
- 描述优化（`run_loop.py` / `run_eval.py`）在 Cowork 中应该没问题，因为它通过子进程使用 `claude -p`，不需要浏览器，但请先完全完成技能创建并获得用户确认后再进行。

---

## 参考文件

agents/ 目录包含专用子代理的说明。在需要启动相关子代理时阅读它们。

- `agents/grader.md` — 如何根据输出评估断言
- `agents/comparator.md` — 如何在两个输出之间进行盲测 A/B 对比
- `agents/analyzer.md` — 如何分析为什么一个版本胜过另一个

references/ 目录有额外文档：
- `references/schemas.md` — evals.json、grading.json 等的 JSON 结构

---

再次强调核心循环：

- 确定技能的目标
- 起草或编辑技能
- 在测试提示上运行能访问该技能的 Claude
- 与用户一起评估输出：
  - 创建 benchmark.json 并运行 `eval-viewer/generate_review.py` 以帮助用户审阅
  - 运行定量评估
- 重复直到你和用户满意
- 打包最终技能并返回给用户。

请在你可能有的待办列表中添加步骤，确保不会忘记。如果你在 Cowork 中，请特别将"创建 evals JSON 并运行 `eval-viewer/generate_review.py` 以便人类审阅测试用例"添加到待办列表中，确保它发生。

祝你好运！
