K3.2.2 Task 3.2

三个字段把 Prompt 变成安全的工作流

SKILL.md 文件支持 YAML frontmatter,有三个 commands 没有的配置字段:context: forkallowed-toolsargument-hint。每个解决一个特定问题。用对它们——包括知道什么时候不用——是一个配置得当的 skill 和一个要么危险要么白白慢的 skill 之间的区别。

context: fork — 隔离,不是沙箱

Fork 在隔离的子代理中运行 skill。主会话在 skill 完成时只收到一个摘要。Skill 的所有冗长输出——文件列表、分析细节、探索结果——留在 fork 中,永远不进入主对话上下文。

这对冗长的 skill 至关重要。一个不带 fork 的代码库分析 skill 产出 20,000+ token 会填满 40% 的主上下文。后续命令因为对话被陈旧的分析数据塞满而降级。带 fork,主会话保持干净。

Fork 隔离什么: 对话上下文。模型对 skill 详细输出的记忆不会转移到主会话。

Fork 不隔离什么: 文件系统。一个有 Write 权限的 fork skill 创建的真实文件在 fork 结束后持久存在。Fork 是上下文隔离,不是文件系统沙箱。一个既生成冗长分析又写结果文件的 skill 可以 fork,不会丢文件输出——文件留下,冗长推理不留。

Fork 什么时候是错的

Fork 增加开销且只返回摘要。这让它不适合:

  • 快速操作 — 2 秒 lint 检查不需要 fork。开销和工作量不成比例。
  • 用户需要看到的直接编辑 — 带 fork 的 /quick-fix skill 在子代理中应用修复。主会话看不到什么变了,逼开发者手动验证。用户需要看到确切变化的就留在主上下文。
  • 建立会话上下文的 skill — 如果 skill 的输出是后续问题或后续命令需要的,fork 会丢弃它。短小但建立重要上下文的 skill 即使输出少也不该 fork。

一个团队审计的数据:

Skill上下文占用已 fork?动作
代码分析40%加 fork
测试生成5%保持
PR 审查35%加 fork
快速 lint2%去掉 fork
文件搜索8%不动

Fork 占 35%+ 上下文的 skill。从快速低输出 skill 去掉 fork,开销不值得。影响只有 8% 的不动。

allowed-tools — 确定性安全

没有 allowed-tools,skill 继承包括 Bash 在内的所有工具。一个指令说”只生成迁移文件,不要执行”的迁移 skill 仍然可能在模型认为执行有帮助时执行 DROP TABLE。

这不是 bug。Prompt 指令是概率性的。模型在指令和自己的判断之间权衡。allowed-tools 是确定性的——如果 Bash 不在列表里,它在 skill 的环境中不存在。模型无法调用不存在的工具。

---
allowed-tools:
  - Read
  - Grep
  - Glob
---

这个 skill 在物理上不能写文件、编辑文件或执行命令。模型再怎么巧妙推理也无法覆盖。

最小权限原则: 只列出 skill 实际需要的工具。只读分析 skill 拿 Read, Grep, Glob。文件生成 skill 拿 Read, Write。完全省略 allowed-tools——即使对一个”只需要 Read”的 skill——是反模式,因为它给了包括 Bash 在内的不受限访问。

更强的 prompt 措辞(“绝对永远不要执行”)不改变根本限制。它仍然是和模型判断竞争的概率性指令。allowed-tools 是唯一的保证。

argument-hint — 提示参数

当 skill 需要输入(文件路径、模块名、目录)时,开发者经常不带参数就调用。一个团队发现 40% 的调用缺少必需的模块路径,导致分析错误目录或不清楚的错误。

---
argument-hint: "Provide the module path (e.g., src/auth or src/payments)"
---

开发者不带参数调用 skill 时,Claude Code 在 skill 开始前显示这个提示。这是配置级的 UX 改进——不需要和模型交互,不会有可能错误的静默默认值。

替代方案——prompt 指令让 skill “如果没有路径就问用户”——能用但多一个来回。参数提示在执行开始前就提供引导。

三个一起用

一个安全漏洞扫描器需要:冗长的探索输出(fork)、只读访问(allowed-tools)、和目录路径输入(argument-hint)。

---
context: fork
allowed-tools:
  - Read
  - Grep
  - Glob
argument-hint: "Provide the directory path to scan (e.g., src/api)"
---

三个需求,三个字段。每个确定性地解决一个特定关注点:

  1. Fork 防止 20,000+ token 的扫描输出填满主会话。
  2. Allowed-tools 保证没有文件修改或命令执行。
  3. Argument-hint 确保开发者在扫描开始前提供目标。

CLAUDE.md 做不了的事

CLAUDE.md 是始终加载的标准。Skills 是按需的工作流。把安全审计工作流放在 CLAUDE.md 意味着它的指令在每次交互时加载——开发者只是在写代码时浪费上下文。

反过来,把编码标准放在 skill 里意味着它们只在显式调用时才适用。标准必须是持续的;工作流必须是按需的。给每个用对的机制。

不存在的 frontmatter 字段

这些经常被提出但不是有效的 SKILL.md frontmatter:

  • max-tokens — 不存在。用 fork 做输出隔离。
  • safe-mode — 不存在。用 allowed-tools 做安全。
  • verbose: false — 不存在。
  • timeout — 不存在。
  • output-limit — 不存在。
  • context: main — 不存在。默认(没有 context 字段)就在主会话中运行。

一句话总结: context: fork 隔离冗长输出(不是文件),allowed-tools 提供确定性安全(不是概率性指令),argument-hint 提示必需输入——按各自用途使用,不是作为全面默认。