@netpilot/skills 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/AGENTS.md +1 -1
  5. package/CHANGELOG.md +17 -0
  6. package/README.md +6 -1
  7. package/docs/skill-evolution.md +43 -0
  8. package/docs/skill-localization.md +60 -0
  9. package/package.json +1 -1
  10. package/skills/ask/SKILL.md +19 -13
  11. package/skills/ask/references/phase-boundaries.md +70 -0
  12. package/skills/code-review/SKILL.md +14 -14
  13. package/skills/codebase-design/SKILL.md +2 -2
  14. package/skills/diagnosing-bugs/SKILL.md +8 -2
  15. package/skills/diagnosing-bugs/scripts/hitl-loop.template.mjs +3 -1
  16. package/skills/domain-modeling/SKILL.md +1 -1
  17. package/skills/grill-me/SKILL.md +2 -2
  18. package/skills/grill-me/agents/openai.yaml +2 -2
  19. package/skills/grill-with-docs/SKILL.md +5 -5
  20. package/skills/grill-with-docs/agents/openai.yaml +1 -1
  21. package/skills/grilling/SKILL.md +27 -11
  22. package/skills/grilling/agents/openai.yaml +2 -2
  23. package/skills/handoff/SKILL.md +1 -1
  24. package/skills/implement/SKILL.md +2 -2
  25. package/skills/implement/references/verification.md +32 -0
  26. package/skills/improve-codebase-architecture/SKILL.md +7 -5
  27. package/skills/prototype/SKILL.md +3 -3
  28. package/skills/prototype/references/logic.md +38 -58
  29. package/skills/prototype/references/ui.md +51 -43
  30. package/skills/research/SKILL.md +4 -2
  31. package/skills/resolving-merge-conflicts/SKILL.md +1 -1
  32. package/skills/tdd/SKILL.md +9 -7
  33. package/skills/teach/SKILL.md +13 -13
  34. package/skills/to-questionnaire/SKILL.md +57 -0
  35. package/skills/to-questionnaire/agents/openai.yaml +6 -0
  36. package/skills/to-spec/SKILL.md +12 -10
  37. package/skills/to-tickets/SKILL.md +2 -2
  38. package/skills/triage/SKILL.md +9 -9
  39. package/skills/wait-what/SKILL.md +7 -0
  40. package/skills/wait-what/agents/openai.yaml +6 -0
  41. package/skills/wayfinder/SKILL.md +16 -16
  42. package/skills/wizard/SKILL.md +51 -0
  43. package/skills/wizard/agents/openai.yaml +6 -0
  44. package/skills/wizard/template.sh +272 -0
  45. package/skills/writing-for-agents/SKILL-MECHANICS.md +70 -0
  46. package/skills/writing-for-agents/SKILL.md +93 -0
  47. package/skills/writing-for-agents/agents/openai.yaml +6 -0
  48. package/skills/writing-for-agents/references/behavioral-evaluation.md +29 -0
  49. package/skills/writing-great-skills/SKILL.md +0 -125
  50. package/skills/writing-great-skills/agents/openai.yaml +0 -6
  51. package/skills/writing-great-skills/references/glossary.md +0 -279
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Wizard 分阶段引导用户完成必须人工操作的流程。
4
+ # 由 wizard skill 生成;用户执行,agent 只做静态检查。
5
+ #
6
+ # STAGES 标记以上是统一 library,生成向导时保持不变。
7
+ # 只编写标记以下的具体阶段。
8
+
9
+ set -euo pipefail
10
+
11
+ # ──────────────────────────────────────────────────────────────────────────
12
+ # Wizard library:每份向导复用相同的进度、输入、保存和确认行为。
13
+ # ──────────────────────────────────────────────────────────────────────────
14
+
15
+ if [[ -t 1 ]] && command -v tput >/dev/null 2>&1 && [[ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]]; then
16
+ BOLD=$(tput bold); DIM=$(tput dim); RESET=$(tput sgr0)
17
+ BLUE=$(tput setaf 4); GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3); RED=$(tput setaf 1)
18
+ else
19
+ BOLD=""; DIM=""; RESET=""; BLUE=""; GREEN=""; YELLOW=""; RED=""
20
+ fi
21
+
22
+ # Author sets this at the top of the stages section.
23
+ TOTAL_STAGES=0
24
+
25
+ _STAGE_INDEX=0
26
+ ENV_FILE="${ENV_FILE:-.env}"
27
+ GH_REPO="${GH_REPO:-}" # 由阶段作者设置明确的 [host/]owner/repo,不从 cwd 推断。
28
+ WRITTEN_ENV=() # KEYs written to ENV_FILE this run
29
+ WRITTEN_SECRET=() # secret NAMEs set this run
30
+ SKIPPED=() # things we couldn't do (e.g. gh missing)
31
+
32
+ # _clear wipes the terminal so only the current step is on screen. No-op when
33
+ # output isn't a terminal, so piped logs stay readable.
34
+ _clear() {
35
+ [[ -t 1 ]] || return 0
36
+ if command -v tput >/dev/null 2>&1; then tput clear; else printf '\033[2J\033[3J\033[H'; fi
37
+ }
38
+
39
+ # banner "Title" shows the opening frame: what this wizard does.
40
+ banner() {
41
+ _clear
42
+ printf '\n%s%s %s%s\n' "$BOLD" "$BLUE" "$1" "$RESET"
43
+ printf '%s 共 %s 个阶段%s\n\n' "$DIM" "$TOTAL_STAGES" "$RESET"
44
+ printf '%s 你操作浏览器,向导说明步骤并接收你复制回来的值。\n' "$DIM"
45
+ printf ' 可随时按 Ctrl-C 停止;再次运行可保留已经保存的值。\n'
46
+ printf ' 迁移等非幂等步骤仍须先检查当前状态,再决定是否执行。%s\n' "$RESET"
47
+ pause "准备开始?"
48
+ }
49
+
50
+ # stage "Name" clears the screen, then announces a stage and shows progress.
51
+ # Clearing keeps only the current step on screen.
52
+ stage() {
53
+ _clear
54
+ _STAGE_INDEX=$((_STAGE_INDEX + 1))
55
+ printf '\n%s%s▸ 阶段 %s/%s · %s%s\n' \
56
+ "$BOLD" "$BLUE" "$_STAGE_INDEX" "$TOTAL_STAGES" "$1" "$RESET"
57
+ }
58
+
59
+ # say "..." prints a plain instruction line.
60
+ say() { printf ' %s\n' "$1"; }
61
+ # step "..." is a numbered-feeling action the human takes in the browser.
62
+ step() { printf ' %s•%s %s\n' "$BLUE" "$RESET" "$1"; }
63
+ note() { printf ' %s%s%s\n' "$DIM" "$1" "$RESET"; }
64
+ warn() { printf ' %s⚠ %s%s\n' "$YELLOW" "$1" "$RESET"; }
65
+
66
+ # open_url URL opens it in the human's browser, cross-platform incl. WSL.
67
+ open_url() {
68
+ local url="$1"
69
+ [[ "$url" == https://* || "$url" == http://* ]] || { warn "只支持 HTTP/HTTPS 地址"; return 1; }
70
+ printf ' %s↗ 打开%s %s\n' "$GREEN" "$RESET" "$url"
71
+ { if command -v wslview >/dev/null 2>&1; then wslview "$url"
72
+ elif command -v explorer.exe >/dev/null 2>&1; then explorer.exe "$url"
73
+ elif command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"
74
+ elif command -v open >/dev/null 2>&1; then open "$url"
75
+ else false; fi
76
+ } >/dev/null 2>&1 || warn "无法打开浏览器,请手动访问:$url"
77
+ }
78
+
79
+ # pause "msg" waits for the human to confirm they've done the manual part.
80
+ pause() {
81
+ printf ' %s%s%s ' "$DIM" "${1:-按 Enter 继续}" "$RESET"
82
+ read -r _ || { warn "输入中断,已停止"; return 1; }
83
+ }
84
+
85
+ # confirm "question" is a y/N gate; returns success on yes.
86
+ confirm() {
87
+ local reply=""
88
+ printf ' %s? %s [y/N] ' "$YELLOW" "$1"
89
+ read -r reply || return 1
90
+ [[ "$reply" =~ ^[Yy] ]]
91
+ }
92
+
93
+ _check_key() {
94
+ [[ "$1" =~ ^[A-Z_][A-Z0-9_]*$ ]] || { warn "键名须为大写字母、数字和下划线,且不以数字开头" >&2; return 1; }
95
+ case "$1" in
96
+ HOME|PATH|IFS|ENV|BASH_ENV|SHELLOPTS|BASHOPTS|CODEX_HOME|ENV_FILE|GH_REPO|TOTAL_STAGES|_STAGE_INDEX|WRITTEN_ENV|WRITTEN_SECRET|SKIPPED|BOLD|DIM|RESET|BLUE|GREEN|YELLOW|RED)
97
+ warn "该名称属于宿主或向导控制变量" >&2; return 1 ;;
98
+ esac
99
+ }
100
+
101
+ # 只接受单行 dotenv 值;不 source 文件或执行其中的 shell 表达式。
102
+ _decode_env_value() {
103
+ local value="$1"
104
+ value="${value%$'\r'}"
105
+ if [[ "$value" == \'*\' && ${#value} -ge 2 ]]; then
106
+ value="${value:1:${#value}-2}"
107
+ [[ "$value" != *\'* ]] || return 1
108
+ elif [[ "$value" == \"*\" && ${#value} -ge 2 ]]; then
109
+ value="${value:1:${#value}-2}"
110
+ [[ "$value" != *\"* && "$value" != *\\* ]] || return 1
111
+ else
112
+ [[ "$value" =~ ^[a-zA-Z0-9_./:@+=,-]*$ ]] || return 1
113
+ fi
114
+ printf '%s' "$value"
115
+ }
116
+
117
+ _check_env_file() {
118
+ [[ ! -L "$ENV_FILE" ]] || { warn "不写入符号链接 env 文件" >&2; return 1; }
119
+ [[ ! -e "$ENV_FILE" || -f "$ENV_FILE" ]] || { warn "env 目标不是普通文件" >&2; return 1; }
120
+ [[ -f "$ENV_FILE" ]] || return 0
121
+ local line value
122
+ while IFS= read -r line || [[ -n "$line" ]]; do
123
+ line="${line%$'\r'}"
124
+ [[ "$line" =~ ^[[:space:]]*(#.*)?$ ]] && continue
125
+ [[ "$line" =~ ^[a-zA-Z_][a-zA-Z0-9_]*= ]] || { warn "env 格式超出单行模板能力;请使用项目认可的配置工具" >&2; return 1; }
126
+ value="${line#*=}"
127
+ _decode_env_value "$value" >/dev/null || { warn "env 含复杂引号、注释或多行值;请使用项目认可的配置工具" >&2; return 1; }
128
+ done < "$ENV_FILE"
129
+ }
130
+
131
+ # _existing KEY: current value of KEY in ENV_FILE, if any.
132
+ _existing() {
133
+ [[ -f "$ENV_FILE" ]] || return 1
134
+ local line; line=$(grep -E "^${1}=" "$ENV_FILE" | tail -n1) || return 1
135
+ _decode_env_value "${line#*=}"
136
+ }
137
+
138
+ # ask KEY "Prompt" reads a value into $KEY. Offers the existing .env value as
139
+ # a default on re-runs (Enter keeps it). Visible input (non-secret).
140
+ ask() {
141
+ local key="$1" prompt="$2" current input
142
+ _check_key "$key" || return 1
143
+ _check_env_file || return 1
144
+ current=$(_existing "$key" || true)
145
+ if [[ -n "$current" ]]; then
146
+ printf ' %s%s%s %s[Enter 保留当前值]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
147
+ else
148
+ printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
149
+ fi
150
+ read -r input || { warn "输入中断,未保存"; return 1; }
151
+ [[ -z "$input" && -n "$current" ]] && input="$current"
152
+ printf -v "$key" '%s' "$input"
153
+ }
154
+
155
+ # ask_secret KEY "Prompt" is like ask, but input is hidden.
156
+ ask_secret() {
157
+ local key="$1" prompt="$2" current input
158
+ _check_key "$key" || return 1
159
+ _check_env_file || return 1
160
+ current=$(_existing "$key" || true)
161
+ if [[ -n "$current" ]]; then
162
+ printf ' %s%s%s %s[Enter 保留当前值]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
163
+ else
164
+ printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
165
+ fi
166
+ read -rs input || { printf '\n'; warn "输入中断,未保存"; return 1; }
167
+ printf '\n'
168
+ [[ -z "$input" && -n "$current" ]] && input="$current"
169
+ [[ -n "$input" ]] || { warn "秘密值不能为空,未保存"; return 1; }
170
+ printf -v "$key" '%s' "$input"
171
+ }
172
+
173
+ # write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces
174
+ # any existing line). Idempotent.
175
+ write_env() {
176
+ local key="$1" value="$2" tmp encoded
177
+ _check_key "$key" || return 1
178
+ _check_env_file || return 1
179
+ [[ "$value" != *$'\n'* && "$value" != *$'\r'* ]] || { warn "模板不支持多行 env 值,未写入"; return 1; }
180
+ if [[ "$value" != *\'* ]]; then
181
+ encoded="'$value'"
182
+ elif [[ "$value" != *\"* && "$value" != *\\* ]]; then
183
+ encoded="\"$value\""
184
+ else
185
+ warn "值包含无法可靠往返的引号组合,请使用项目认可的配置工具"; return 1
186
+ fi
187
+ tmp=$(mktemp "${ENV_FILE}.tmp.XXXXXX") || return 1
188
+ if [[ -f "$ENV_FILE" ]]; then
189
+ # grep 的 1 表示没有保留行;其他状态是读取失败,不能当成空文件。
190
+ local filtered=0
191
+ grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || filtered=$?
192
+ if [[ $filtered -gt 1 ]]; then rm -f -- "$tmp"; return 1; fi
193
+ fi
194
+ if ! printf '%s=%s\n' "$key" "$encoded" >> "$tmp" || ! mv -- "$tmp" "$ENV_FILE"; then
195
+ rm -f -- "$tmp"; return 1
196
+ fi
197
+ WRITTEN_ENV+=("$key")
198
+ printf ' %s✓ 已写入%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"
199
+ }
200
+
201
+ _confirm_repo_write() {
202
+ [[ "$GH_REPO" =~ ^([a-zA-Z0-9.-]+/)?[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$ ]] || return 1
203
+ confirm "写入 GitHub 仓库 $GH_REPO 的 $1 $2?"
204
+ }
205
+
206
+ # set_secret NAME VALUE sets a GitHub Actions repo secret via gh. Falls back
207
+ # to a warning (and records it) if gh is unavailable or unauthenticated.
208
+ set_secret() {
209
+ local name="$1" value="$2"
210
+ _check_key "$name" || return 1
211
+ [[ -n "$value" ]] || { warn "秘密值不能为空"; return 1; }
212
+ if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1 && _confirm_repo_write secret "$name"; then
213
+ if printf '%s' "$value" | gh secret set "$name" --repo "$GH_REPO" >/dev/null 2>&1; then
214
+ WRITTEN_SECRET+=("$name")
215
+ printf ' %s✓ 已设置%s GitHub secret %s\n' "$GREEN" "$RESET" "$name"
216
+ return
217
+ fi
218
+ fi
219
+ SKIPPED+=("GitHub secret $name:未确认写入成功;先核查目标仓库状态,再决定下一步")
220
+ warn "未确认 GitHub secret $name 写入成功:目标、授权或 gh 不可用,或写入失败;请核查"
221
+ }
222
+
223
+ # set_var NAME VALUE sets a GitHub Actions repo variable (non-secret).
224
+ set_var() {
225
+ local name="$1" value="$2"
226
+ _check_key "$name" || return 1
227
+ if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1 && _confirm_repo_write variable "$name"; then
228
+ if gh variable set "$name" --body "$value" --repo "$GH_REPO" >/dev/null 2>&1; then
229
+ printf ' %s✓ 已设置%s GitHub variable %s\n' "$GREEN" "$RESET" "$name"
230
+ return
231
+ fi
232
+ fi
233
+ SKIPPED+=("GitHub variable $name")
234
+ warn "未确认 GitHub variable $name 写入成功,请核查目标仓库状态"
235
+ }
236
+
237
+ # finish clears, then shows a closing summary of everything configured.
238
+ finish() {
239
+ _clear
240
+ printf '\n%s%s 向导执行结束%s\n' "$BOLD" "$GREEN" "$RESET"
241
+ (( ${#WRITTEN_ENV[@]} )) && note "已写入 $ENV_FILE:${WRITTEN_ENV[*]}"
242
+ (( ${#WRITTEN_SECRET[@]} )) && note "已设置 GitHub secrets:${WRITTEN_SECRET[*]}"
243
+ if (( ${#SKIPPED[@]} )); then
244
+ printf '\n'; warn "仍需人工核查或完成:"
245
+ for s in "${SKIPPED[@]}"; do note " - $s"; done
246
+ fi
247
+ printf '\n'
248
+ }
249
+
250
+ # ──────────────────────────────────────────────────────────────────────────
251
+ # STAGES: 只编写此部分;每个人工步骤对应一个 stage。
252
+ # 替换以下示例,使 TOTAL_STAGES 与阶段数量一致。
253
+ # ──────────────────────────────────────────────────────────────────────────
254
+
255
+ TOTAL_STAGES=1
256
+
257
+ banner "Stripe 配置"
258
+
259
+ # ── Example stage: replace with your real steps ───────────────────────────
260
+ stage "Stripe:API keys"
261
+ say "获取 Stripe 测试密钥,用于本地开发与 CI;CI 写入需要明确 GH_REPO 并由你确认。"
262
+ open_url "https://dashboard.stripe.com/test/apikeys"
263
+ step "在 API keys 页面复制 Publishable key(以 pk_test_ 开头)。"
264
+ ask STRIPE_PUBLISHABLE_KEY "粘贴公开密钥:"
265
+ step "在 Secret key 行点击 'Reveal test key',然后复制。"
266
+ ask_secret STRIPE_SECRET_KEY "粘贴秘密密钥:"
267
+ write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"
268
+ write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"
269
+ set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY" # CI needs this one
270
+ # ──────────────────────────────────────────────────────────────────────────
271
+
272
+ finish
@@ -0,0 +1,70 @@
1
+ # Skill Mechanics(技能调用机制)
2
+
3
+ 这是 [`writing-for-agents`](SKILL.md) 的 skill-specific branch:当 agent-consumed document 是 skill 时,frontmatter、Invocation 选择与 Router Skills 会带来额外机制。其余写作规则都以 `SKILL.md` 的通用 reference 为唯一来源。
4
+
5
+ ## Invocation(调用方式)
6
+
7
+ Skill 有两种选择,用两种负载互换:
8
+
9
+ - **model-invoked** skill 保留面向模型的 `description`,因此 agent 可以自主触发它,其他 skills 也能到达它。用户仍然可以显式输入名称:model invocation 始终 _包含_ user reach;description 只增加 agent discovery,从不移除人的入口。Description 是 skill 顶层的 Context Pointer,被迫始终加载;它用永久 Context Load 换取 discoverability。全是 Reference 的 model-invoked skill 还可以成为共享 Reference 的唯一归属:多个 skills 都能调用它,所以共同材料只保存一份。Claude source 省略 `disable-model-invocation`;Codex metadata 显式设置 `policy.allow_implicit_invocation: true`;description 按 `SKILL.md` 的 pointer rules 写入真实 trigger branches。
10
+ - **user-invoked** skill 把 description 从模型可见集合中移除:只有人显式输入名称才能启动,其他 skills 也不能调用。它不支付常驻 Context Load,却支付 Cognitive Load——人是必须记住它存在的 index。Claude source 设置 `disable-model-invocation: true`;Codex metadata 设置 `policy.allow_implicit_invocation: false`;description 变成人类可读的一行摘要,移除模型 trigger list。
11
+
12
+ 只有 agent 必须自行到达该 skill,或另一个 skill 必须调用它时,才选择 model invocation。如果永远只应由人手动启动,就保持 user-invoked,不支付 Context Load。
13
+
14
+ 两个 user-invoked skills 共同需要的 Reference 不能住在其中任何一个:没有模型可见 description,二者都无法调用对方。把它移到 skill system 之外的普通文件,作为任何 skill 都能指向的 External Reference。
15
+
16
+ Invocation classification 只决定如何到达 skill,不授予文件、Git、tracker 或远程写入权限;动作授权必须由该 skill 的正文和当前用户请求另行确定。
17
+
18
+ ## 按 Invocation 拆分
19
+
20
+ Sequence cut 在 `SKILL.md`;Invocation cut 是 skill 特有的切法。只有出现一个应该独立触发的 Leading Word——而且用户 prompts 中真实使用这个词——或另一个 skill 必须到达该能力时,才拆成 model-invoked skill。新的 description 会永久支付 Context Load,因此 independent reach 必须值得这笔成本。
21
+
22
+ ## Router Skills(路由技能)
23
+
24
+ 当 user-invoked skills 多到人难以记住时,累积的 Cognitive Load 由 **Router Skill** 处理:只需记住一个入口,Router 点名其他入口以及何时选择每一个。
25
+
26
+ Router 只能提示,不能替用户启动 user-invoked skill。User-invoked skill 对模型没有可达的 description,因此只有人能到达它。Router 应给出 canonical 名称和精确显式调用形式,把选择权交还用户;显式调用 Router 本身也不自动授权下游动作。
27
+
28
+ ## 上游本地化
29
+
30
+ 本地化成熟上游 skill 时使用 **Conservation First(保留优先)**。它不是拒绝 Pruning,而是改变举证责任:在证明某段内容属于允许适配、真正 Duplication,或经场景验证的 No-Op 之前,先保留其限定词、判断规则、Failure Modes、例子作用和在 Information Hierarchy 中的位置。
31
+
32
+ 按下面顺序处理:
33
+
34
+ 1. 锁定来源版本,完整读取 `SKILL.md`、references、scripts、assets 与 metadata。完成条件是候选的全部运行时文件都有唯一、可复核的来源。
35
+ 2. 保留 Steps 顺序、Leading Words、Completion Criteria 的原位置、例子作用和 Progressive Disclosure 关系。完成条件是每个上游行为约束在本地都有唯一去向。
36
+ 3. 只做有证据的适配:去除个人角色与作者口吻、删除不存在的 setup 或命令、翻译普通说明、映射真实宿主路径与工具、加入必要权限门禁,以及修复有一手资料或可运行证据支持的矛盾。
37
+ 4. 保持上游方法自身的形状:短 orchestration skill 仍然短,reference-only skill 不被改成主动 workflow,不强加统一章节。
38
+ 5. 上游 skill 被移除但附件仍有独立方法价值时,把附件迁移到职责最接近的 canonical skill,并更新 Context Pointer。完成条件是有价值的 Reference 可达,同时没有同职责双入口。
39
+
40
+ 特别保留 `where possible`、`each claim`、`before` / `after`、`only` 等会改变适用范围、时机或证据强度的词。对是否可删存在疑问时,保留。
41
+
42
+ 上游例子是规则的一部分:诊断例子、反例和 branch 选择例子不能只剩抽象总结。需要适配个人语境或失效工具时,替换表面内容,但保留例子原本帮助 agent 区分的相邻情况。例如,一个用于区分 Logic 与 UI prototype 的具体问题,不能被概括成“根据情况选择分支”。
43
+
44
+ 只有满足以下至少一项,才能合并、删除或替换上游内容:
45
+
46
+ - 属于个人角色、作者口吻或不存在的命令;
47
+ - 与真实宿主、平台 API 或本地权限边界冲突,并有一手资料或可运行证据;
48
+ - 与同一权威位置完全 Duplication,删除后所有 predicates、例子作用和 Completion Criterion 仍有唯一去向;
49
+ - 独立前向测试确认它是 No-Op,删除后 trigger、execution、stop 或 failure boundary 没有回退。
50
+
51
+ AI 提出的“优化”必须说明它解决的真实问题,并通过场景或结构验证;更整齐、更短或更长都不是优先于上游的依据。
52
+
53
+ ### 中文与英文的选择
54
+
55
+ 中文承载完整指令,英文保留行为锚点。普通动作、解释、问题和导航标题译成自然中文;Leading Word、跨文件共享领域词首次出现时用英文加中文定义,之后复用同一主名称。命令、路径、代码标识符、协议字段、状态 label 与被其他文档引用的固定章节名保持原值;固定章节名需要解释时,在原值后加中文,不静默改名。
56
+
57
+ 逐句保持约束强度:`only` 是“仅当/只有”,`each / every` 是“每项/每个”,`before / after` 保留先后,`where possible / if available` 保留“尽可能/可用时”。不能把条件性要求译成绝对要求,也不能把强制要求译成建议。英文例句若以措辞本身演示行为锚定,保留原句并解释;若只是演示业务情境,翻译情境但保留角色、动作、结果和反例作用。
58
+
59
+ 不复制整份英文正文形成双语并排版本。文本契约和结构检查只能证明对应规则仍存在;声称中英文效果接近前,需要在相同模型、宿主、任务与权限下反复对照运行,分别检查触发、执行、停止和失败边界。未运行时明确标注“行为等效未验证”。
60
+
61
+ ## NetPilot 宿主适配
62
+
63
+ - Skill 目录与 frontmatter `name` 使用唯一的英文 kebab-case;`display_name` 由 canonical name 派生。普通说明、`description`、`short_description` 与 `default_prompt` 默认使用中文,稳定 Leading Words、协议字段、代码、路径和命令保留英文。
64
+ - 每个 skill 提供 `agents/openai.yaml`。`default_prompt` 显式包含 `$<skill-name>`;Claude 与 Codex 的 invocation 分类必须成对一致。
65
+ - 仓库保留双宿主单源;Codex 安装时生成确定性投影,移除 Claude-only frontmatter,但保留 Codex metadata 行为。
66
+ - 大段条件性 Reference 放在 `references/`,确定性重复操作放在 `scripts/`,供产物使用而非加载进 context 的模板放在 `assets/`。Context Pointer 只深入一层,并明确说明何时读取。
67
+ - 普通过程标题使用中文;具有行为锚定作用的 Leading Word、领域词、协议字段、label 与代码术语保留英文,并在首次出现时解释。
68
+ - 不统一追加“完成标准”或“反模式”。真实 Steps 在原位置保留 Completion Criterion;上游方法本身有诊断价值时才保留 Failure Modes。
69
+ - Git、issue tracker、外部消息或其他可见写入可以成为 skill 能力,但正文必须说明明确目标、用户授权、完成证据与 Failure Boundary。Push、PR、merge、deploy 和 publish 不从相邻动作或 Invocation classification 隐式获得授权。
70
+ - 去除个人角色、作者口吻、私有暗语和不存在的命令;实质改编受许可约束的内容,只在仓库级 `THIRD_PARTY_NOTICES.md` 保存必要声明。
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: writing-for-agents
3
+ description: 为 agent 编写文档。当创建或编辑 skills、修改 AGENTS.md 或 CLAUDE.md,或维护由 Context Pointer 到达的 agent 文档时使用;纯面向人的普通文档不使用。
4
+ ---
5
+
6
+ # Writing for Agents
7
+
8
+ 这是为 agent 编写任何文档的参考:skills、`AGENTS.md` / `CLAUDE.md`,以及由 Context Pointer 到达的文档。包装形式不同,写作方法相同:相同的杠杆让 agent 每次采用相同的过程,而不是每次产生相同的输出,从而获得 **Predictability(可预测性)**。
9
+
10
+ 当正在编写的文档是 skill 时,必须读取 [SKILL-MECHANICS.md](SKILL-MECHANICS.md),了解 frontmatter、Invocation 选择与 Router Skills。
11
+
12
+ 当要比较中英文效果、修改触发与停止条件,或验证一项优化是否真的改变行为时,读取 [行为验证](references/behavioral-evaluation.md)。它提供独立场景运行与证据判断方法;检查结束后返回当前文档编辑,不把每次文字修订都变成完整评测。
13
+
14
+ ## Context Pointers(上下文指针)
15
+
16
+ **Context Pointer** 是保留在 agent context 中的一条引用:它命名 context 之外的材料,同时编码到达该材料的条件。Skill 的 description 是 Context Pointer;`AGENTS.md` 中点名另一份文档的一行也是同一种对象。决定 agent 何时、以及多可靠地到达材料的是 pointer 的 _措辞_,不是目标文件本身。必须读取的材料如果藏在措辞薄弱的 pointer 后面,就是 variance bug:先收紧 pointer 的措辞;只有收紧后仍失败时才把材料直接放进正文。
17
+
18
+ 一个 pointer 同时完成两件事:说明材料是什么,并列出应该触发它的 **branches(分支)**。Branch 是文档处理的一种独立情形,因此不同运行会经过不同路径。始终加载的 pointer 中,每个词都会在每一轮支付成本,所以它比正文更需要 Pruning:
19
+
20
+ - **Front-load the Leading Word(把行为锚点放在前面)**:pointer 正是在这里完成触发。
21
+ - **One trigger per branch(每个分支保留一个触发条件)**:仅仅用同义词重命名同一个 branch,等于把同一 branch 写了两次;合并它们,只保留真正不同的 branches。
22
+ - **删除正文已经承担的身份说明**。
23
+
24
+ ## 两种负载
25
+
26
+ 每增加一份文档或 pointer,都会花费下面两种预算之一:
27
+
28
+ - **Context Load(上下文负载)**:始终加载的材料占用 agent context window 的成本。`AGENTS.md` 中的一行、skill description,以及每轮都位于 context 中的内容,无论是否触发都消耗 tokens 与注意力。
29
+ - **Cognitive Load(认知负载)**:由人承担的成本——记住有哪些文档,以及何时使用每一份。人是索引。它不是应该机械最小化的成本,而是人保有自主决定权的代价;在人类判断重要时支付,在不重要时移除。
30
+
31
+ 只通过 pointer 到达的材料可以避开正文的 Context Load,但要支付 pointer 自身一行的成本;完全没有 pointer 的材料则完全依赖 Cognitive Load。
32
+
33
+ ## Information Hierarchy(信息层级)
34
+
35
+ 文档由两种内容自由组合:
36
+
37
+ - **Steps(步骤)**:agent 按顺序执行的动作;
38
+ - **Reference(参考资料)**:按需查阅的定义、规则和事实。
39
+
40
+ 文档可以全是 Steps(操作步骤)、全是 Reference(审查规则或本 skill),也可以二者兼有。核心判断是把每项内容放在 **Information Hierarchy** 的哪一级;这个阶梯按 agent 多快需要材料排序:
41
+
42
+ 1. **In-file Step(文件内步骤)**:主要层,agent 按顺序执行的动作。
43
+ 2. **In-file Reference(文件内参考)**:按需查阅。它可以是合法的同层规则集合,例如 review 的每条规则都在同一层;这不是结构缺陷。
44
+ 3. **Disclosed Reference(按需展开的外部参考)**:移到独立文件中,由 Context Pointer 到达,只在 pointer 触发时加载。它可以是同一目录下的文件,也可以是任何文档都能指向的 External Reference。
45
+
46
+ 下推得太少会让顶部膨胀;下推得太多会藏起 agent 真正需要的材料。这股张力就是全部判断。
47
+
48
+ **Progressive Disclosure(渐进披露)** 是沿阶梯向下移动:把内容从主文件移到 pointer 后面,使顶部保持可辨认。它首先保护 Information Hierarchy,而不只是节省 tokens。按分支判断是最清楚的披露检验:每个 branch 都需要的内容直接放在正文中;只有部分 branches 到达的内容放到 pointer 后面。文档存在 Steps 时,本应按需展开的 Reference 会埋住 Steps,使 agent 是否关注它近似抛硬币;这是影响运行差异的因素,不只是可读性问题。
49
+
50
+ **Co-location(相关内容相邻放置)** 是同一文件内的配套判断:阶梯决定内容放多深,Co-location 决定到达该层后哪些内容彼此相邻。把一个概念的定义、规则和注意事项放在同一标题下,而不是散落各处,使 agent 读到一部分时也同时获得它的邻居。测试方式是:文档应像专门写给 agent 的文档;相关材料集中时通常如此。Co-location 不同于 Duplication:Duplication 重复同一含义,散落则把一个含义的不同部分拆到多处。
51
+
52
+ **Sprawl(无节制膨胀)** 是这里的 Failure Mode:即使每一行仍然有效且唯一,文档也可能只是太长。过量内容会分散注意力,每增加一行也多一行需要持续保持相关。处理方式是 Information Hierarchy:把 Reference 移到 pointer 后面按需展开,并按 branch 或 sequence 拆分,使每条路径只携带它所需的内容。
53
+
54
+ ## Steps 与 Completion Criteria(步骤与完成条件)
55
+
56
+ 每个 Step 都结束于 **Completion Criterion**:告诉 agent 这项工作何时完成的条件。两个属性让它成为行为杠杆:
57
+
58
+ - **Clarity(清晰度)**:agent 能否区分完成与未完成?模糊边界(例如“已经形成理解”)会邀请 **Premature Completion(过早结束)**:当前 Step 尚未真正完成,注意力已经滑向“赶快结束”。仍然可见的后续 Steps——**Post-Completion Steps(当前步骤之后的步骤)**——提供向前的拉力,Criterion 的 Clarity 提供阻力。按顺序防守:**先把完成边界写明确**,因为它局部且便宜;只有边界不可避免地模糊,且真实运行已经观察到仓促跳步,才通过步骤序列拆分隐藏后续 Steps。隐藏只有跨越真实上下文边界才生效,例如 handoff 或 subagent dispatch;在当前上下文内调用仍让后续 Steps 留在 context 中,什么也没有清除。
59
+ - **Demand(工作要求的强度)**:Criterion 要求多少工作。“每个修改过的 model 都已核对”会驱动比“生成改动列表”更充分的工作。Demand 驱动 **Legwork(深入调查)**——agent 在工作单元内部完成的挖掘;它潜伏在措辞里,不应另写成机械步骤。Demand 也不依赖 Steps:“每条规则都已应用”同样能约束一份同层规则组成的 Reference,因此全 Reference 文档仍然可以拥有穷尽门槛。
60
+
61
+ 最强的 Completion Criteria 同时可检查且穷尽。
62
+
63
+ ## 何时拆分
64
+
65
+ 把一份文档拆成两份会花费两种负载之一,因此只在切分确实值得时进行:
66
+
67
+ - **按步骤序列拆分**:当 Post-Completion Steps 诱使 agent 仓促结束当前 Step 时切分。把后续内容移出视野,可以驱动当前任务内更多 Legwork。反方向也要小心:合并 sequences 会让每个 Step 看到更多后续 Steps,从而邀请 Premature Completion。
68
+ - **按 Invocation 拆分**:这是 skill 特有的切法;读取 [SKILL-MECHANICS.md](SKILL-MECHANICS.md)。
69
+
70
+ ## Leading Words(行为锚点)
71
+
72
+ **Leading Word** 是模型预训练中已经存在、agent 运行文档时用来思考的紧凑概念,例如 _lesson_、_fog of war_、_tracer bullets_。它以 token 重复,而不是以句子重复;由此积累分布式定义,并用最少 tokens 调用已有的行为先验,锚定一整片行为。自造词只要定义清楚也能工作,但它没有预训练先验:已有词免费提供的东西,自造词要用定义所需的 tokens 来偿还,因此先寻找已有词。
73
+
74
+ Leading Word 有两次锚定作用:
75
+
76
+ - 在正文中锚定 _execution(执行)_:agent 每次看到它都到达相同类型的行为;在同层规则组成的 Reference 中,它把注意力聚焦到要寻找的一类对象。
77
+ - 在 pointer 中锚定 _invocation(调用)_:当同一个词也存在于提示词、文档与代码库中时,agent 会把共享语言连接到相应材料,并更可靠地到达它。
78
+
79
+ 主动寻找可以用 Leading Words 改写的表达:三处都展开的三元组、用整句含糊指向一个想法的 pointer,都应该收拢为一个 token。
80
+
81
+ - “快速、确定、低开销” → _tight_,形成 _tight feedback loop_。
82
+ - “一个你相信的循环” → _red_:模糊门禁变为二元可观察状态——loop 能在 bug 上变 _red_,或不能。
83
+
84
+ 收益有两次:tokens 更少,同时为 agent 的思考提供更锋利的挂钩。默认假设每份文档都携带着可由 Leading Words 退役的复述,并主动寻找它们。
85
+
86
+ **Negation(否定表达)** 是这个杠杆旁边的 Failure Mode:通过禁止来引导,会把被禁止的行为拖进 context,反而提高它的可用性。_Don't think of an elephant_(不要想大象),此时 context 中只剩大象;negation 是弱修饰语,可能被刚刚强烈激活的概念压过,使禁令被半读成行动提示。使用 **positive(正向目标)**来提示:直接描述目标行为,例如“注释保持单行”,让被禁止对象不进入提示的关注范围。只有无法用正向目标表达的硬性防护边界才值得保留禁令;即使如此,也要配对写出正向目标,使注意力落到应该做什么。
87
+
88
+ ## Pruning(删减)
89
+
90
+ - 让每个含义只有一个 **Single Source of Truth(单一事实来源)**:一个权威位置,使行为变化只需修改一处。**Duplication(语义重复)** 是同一含义出现在多处;它增加维护与 tokens,并把该含义在 Information Hierarchy 中的显著程度抬得高于真实层级。它是 Leading Word 的意外反面:Leading Word 有意重复一个 token,从不重复完整含义。
91
+ - **environment(运行环境)** 也是事实来源:`package.json` scripts、配置文件、目录布局与 `--help` 输出都可以被 agent 直接查看。文档复述这些内容就是 **cache(缓存)**,只有查找本身昂贵时才值得支付负载。缓存 agent 无法通过查看得到的内容:未写下的约定、选择背后的原因、配置中看不出的陷阱。把一文件或一命令即可得到的事实留在 environment 中,那里不会因复制而过时。
92
+ - 逐行检查 **Relevance(相关性)**:这行是否仍直接影响文档所做的事?一行可能从未与任务相关,例如纯背景讲解或本应按需展开的 branch;也可能随着行为或世界变化而过时。更短的文档更容易保持相关。没有 Pruning 纪律时,默认结局是 **Sediment(失效内容沉积)**:旧层因为添加令人安心、删除令人不安而不断沉积,直到维护者必须向下取芯才能找到仍然有效的内容。
93
+ - 逐句寻找 **No-Op(相对模型默认行为不起作用的指令)**:模型默认已经会遵守的指令,只支付负载却没有改变行为。测试问题是“相对默认值,它是否改变了行为?”这取决于具体模型,而不是读者个人感受;两个人对 No-Op 有分歧,实质是在争论模型默认值,应通过运行文档解决,而不是辩论。句子失败时删除整句,不要靠删几个词保留它。Leading Word 也接受同一测试:如果 _be thorough_ 无法超过模型本来就有的“有点 thorough”,它就是 No-Op;修复方式是更有力的词,例如 _relentless_,而不是另造技巧。
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "Writing For Agents"
3
+ short_description: "编写或维护供 Agent 使用的 Skills、项目规则与指针文档"
4
+ default_prompt: "请使用 $writing-for-agents 创建或改写这份 Agent 文档,并核对触发、信息层级与行为约束。"
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,29 @@
1
+ # 技能行为验证
2
+
3
+ 静态校验可以发现损坏的 metadata、引用和附件;固定关键词可以保护特定文本契约。它们都不能证明 agent 会在真实任务中作出正确决定。只有需要验证触发、执行、停止、失败边界或语言效果时才使用本参考。
4
+
5
+ ## 选择能区分行为的场景
6
+
7
+ 从真实请求、已观察到的失败或此次修改的假设出发,写下用户输入、必要原始材料、可用工具及权限。验收条件描述外部可观察行为,不抄 skill 的标题作为答案。
8
+
9
+ 根据本次变化选择正常、相邻不触发、边界或失败场景。例如:测试 `grilling` 时,提供两个已就绪决定和一个依赖问题,观察实际轮次;测试脱敏时,在假日志中放入虚构认证值,观察展示内容;测试工具不可用时,明确工具集,观察是否虚构执行。不要拿真实凭证或生产数据作样本。
10
+
11
+ 完成条件:每个场景都能说明要观察哪个决定或结果,以及什么证据能够推翻“修改有效”的假设。
12
+
13
+ ## 独立前向运行
14
+
15
+ 有可用且已获授权的子代理时,使用新上下文运行,每个评估者只看到:实际用户请求、待测 skill 及其必要附件、最低限度的原始材料、工具与写入边界。**不提供预期答案、怀疑的问题、修改理由、作者结论或其他运行结果。** 评判标准由调用方保留,不能在给执行者的提示中泄露答案。
16
+
17
+ 使用隔离临时工作区或纯只读场景;有外部副作用时使用受控工具桩。不要加载两个竞争版本,也不要让第二轮继承第一轮的推理。没有独立执行环境时,说明只完成静态分析,不把作者自己的复述当成前向运行。
18
+
19
+ 比较版本时保持任务、原始材料、模型、推理设置、宿主、工具和权限一致。中英文比较要区分“原始上游与本地适配”的综合差异和“仅改变语言”的差异;需要隔离语言因素时,两份材料的宿主及权限适配也必须相同。
20
+
21
+ 完成条件:每次运行都有可复核的输入与真实输出/工具轨迹,且执行者未收到答案提示;不能把一次只读推演描述成实际工具执行。
22
+
23
+ ## 判断结果并回到编辑
24
+
25
+ 调用方逐条对照事先定义的验收条件,记录结果、支持证据与未能观察的部分。区分规则缺失、调用不可达、宿主限制和模型运行差异。修正只针对有证据的问题;不要把单次场景的偶然细节扩成所有任务都必须遵守的规则。
26
+
27
+ 一次运行适合发现具体反例,不能证明总体等效。要比较可靠性,交错运行顺序并重复场景,报告实际次数与结果分布;高方差时增加样本,证据不足时保留不确定性。结构检查、盲测和人工判断分别报告。
28
+
29
+ 完成条件:结论对应实际证据,未执行与无法判定项明确;有回退则修订并重跑受影响场景,再返回当前编辑任务。没有行为运行证据时,不声称效果已提升或中英文等效。
@@ -1,125 +0,0 @@
1
- ---
2
- name: writing-great-skills
3
- description: 创建和编辑高质量 skills 的词汇与原则,核心目标是让 agent 的执行过程可预测。
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Writing Great Skills
8
-
9
- Skill 的作用,是从 stochastic system 中约束出足够的 determinism。根本美德是 **Predictability**:每次采用相同的过程,而不是每次产生相同的输出。下面所有杠杆都服务于它。
10
-
11
- 正文中的**粗体术语**均在 [glossary.md](references/glossary.md) 中有完整定义。第一次使用某个术语判断设计时,读取对应定义,不靠近义词猜测。
12
-
13
- ## 调用方式(Invocation)
14
-
15
- 有两种调用方式,它们支付不同成本:
16
-
17
- - **Model-Invoked** skill 对模型暴露一条 **Description**,因此 agent 可以自主选择它,其他 skills 也可以到达它,用户仍然可以显式输入名称。它在每轮支付 **Context Load**。机制:`SKILL.md` 省略 disable-model-invocation 字段,`agents/openai.yaml` 设置 `policy.allow_implicit_invocation: true`,并编写包含真实触发分支的模型侧 description。
18
- - **User-Invoked** skill 只由用户显式输入名称启动;模型和其他 skills 都不能启动它。它没有常驻 Context Load,但把“有哪些入口、何时使用”变成用户承担的 **Cognitive Load**。机制:`SKILL.md` 设置 disable-model-invocation 为 true,`agents/openai.yaml` 设置 `policy.allow_implicit_invocation: false`;仍保留一行面向用户和目录展示的 description,但不要把它写成模型触发词清单。
19
-
20
- 只有当 agent 必须自行到达某项能力,或另一个 skill 必须调用它时,才选择 Model-Invoked。如果它只应由人手动启动,让它保持 User-Invoked。
21
-
22
- User-Invoked skills 多到用户难以记住时,用一个 **Router Skill** 降低 Cognitive Load。Router 只说明每个入口及其适用时机;它不能替用户启动另一个 User-Invoked skill,应给出精确命令让用户显式选择。
23
-
24
- ## 编写 Description
25
-
26
- Model-Invoked skill 的 **Description** 同时完成两件事:说明它是什么,并列出应该触发它的真实 **Branches**。每个词都会增加 Context Load,因此 description 比正文更需要裁剪:
27
-
28
- - 把 skill 的 **Leading Word** 放在前面,让模型尽早进入正确概念区域。
29
- - 每个 branch 只保留一个触发条件。仅仅换同义词重复同一 branch 属于 **Duplication**;“用 TDD 构建功能”和“用户要求 test-first”若指同一路径,就不应写两遍。
30
- - 删除正文已经承担的身份说明。Description 只保留触发分支,以及必要的“当另一 skill 需要……”到达条款。
31
- - 写出相邻 skill 的关键不适用边界,但不要把整份路由表塞进 description。
32
-
33
- User-Invoked skill 的 description 是面向人的一句摘要,不承担模型触发任务。
34
-
35
- ## 信息层级(Information Hierarchy)
36
-
37
- Skill 由两类内容构成:**Steps** 与 **Reference**。二者可以任意组合:全是步骤、全是参考资料,或同时存在。关键是每项内容在 **Information Hierarchy** 中应处于哪一层:
38
-
39
- 1. **In-skill Step**:`SKILL.md` 中按顺序执行的动作,是主要层。每个真正的 step 都在原位置结束于 **Completion Criterion**,让 agent 能判断该步是否完成。标准应可检查,并在重要处穷尽,例如“每个修改过的 model 都已核对”,而不是“生成改动列表”;它属于步骤边界,不是每个 skill 都要追加的统一尾部章节。
40
- 2. **In-skill Reference**:`SKILL.md` 中按需查阅的定义、规则与事实。它可以是合法的扁平同级集合;全是 reference 的 skill 并不是结构缺陷。
41
- 3. **Disclosed / External Reference**:从 `SKILL.md` 移到独立文件、只在 **Context Pointer** 触发时加载的资料。它可以是 skill 内的 `references/*.md`,也可以是 skill 系统之外由多个 skills 指向的普通文件。
42
-
43
- 高要求的 Completion Criterion 会驱动充分 **Legwork**。这一点既适用于 steps,也适用于 flat reference:“应用每条规则”同样可以约束全 reference skill 的覆盖度。
44
-
45
- 顶部保留过多内容会造成 **Sprawl**;向下推得太多会藏起每条 branch 都需要的材料。**Progressive Disclosure** 就是在这股张力中把 reference 下移:每条 branch 都需要的内容内联,只有部分 branch 需要的内容放到清楚命名的文件后面。Context Pointer 的措辞,而不是目标文件本身,决定 agent 何时、是否可靠地读取它。
46
-
47
- Information Hierarchy 决定材料放多深,**Co-location** 决定放在同一层的哪些材料应相邻。一个概念的定义、规则和 caveats 应聚在同一标题下,让 agent 读到一部分时同时获得其邻居。
48
-
49
- ## 何时拆分
50
-
51
- **Granularity** 是 skills 被切分得多细。每次切分都会增加 Context Load 或 Cognitive Load,因此只有切分带来明确收益时才做。两种有效切法:
52
-
53
- - **By Invocation**:某项能力拥有独立 Leading Word,应该自主触发,或必须被另一 skill 调用时,把它拆成 Model-Invoked skill。新增的常驻 description 必须值得它支付的 Context Load。
54
- - **By Sequence**:当前 step 后面可见的 **Post-Completion Steps** 让 agent 急于向前、产生 Premature Completion 时,把后续步骤隐藏到真实上下文边界之后。先尝试把当前 step 的 Completion Criterion 写清;只有标准不可避免地模糊、且真实测试观察到抢跑时才切分。
55
-
56
- 仅仅把后续内容写在同一文件的另一个标题下不会形成上下文边界。有效边界来自用户显式交接或独立 subagent dispatch。
57
-
58
- ## 修剪(Pruning)
59
-
60
- 让每个 meaning 只有一个 **Single Source of Truth**,这样行为变化只需修改一处。
61
-
62
- 逐行检查 **Relevance**:它现在是否仍直接影响 skill 的行为?再逐句进行 **No-Op** 测试:与模型默认行为相比,这句话是否真的改变执行?一句失败时删除整句,不要靠换词保留没有行为价值的 prose。
63
-
64
- 主动寻找 **Sediment**、**Duplication** 与 Sprawl。添加通常让人感觉安全,删除让人感觉冒险,因此没有裁剪纪律的 skill 会自然积累失效层。
65
-
66
- ## Leading Words(引导词)
67
-
68
- **Leading Word** 是模型预训练中已经存在、运行 skill 时会用来思考的紧凑概念,例如 _lesson_、_Zone of Proximal Development_、_fog of war_、_tracer bullets_。它用很少 tokens 调用已有 priors,并在 skill 各处形成分布式定义。
69
-
70
- Leading Word 对 Predictability 有两次作用:
71
-
72
- - 在正文中锚定 execution:每次出现都把 agent 拉回同一种行为;
73
- - 在 description 中锚定 invocation:当用户 prompts、项目 docs 与代码也使用同一词时,agent 更可靠地把请求连到 skill。
74
-
75
- 寻找可被 Leading Word 折叠的重复表达。三个位置都写一遍的三元组、用整句含糊指向一个概念的 description,通常都可以 collapse:
76
-
77
- - “快速、确定、低开销”可折叠为 _tight_,形成 tight feedback loop;
78
- - “一个你相信的循环”可折叠为 _red_,把模糊门禁变成二元可观察状态:loop 能在 bug 上变 red,或不能。
79
-
80
- 优先使用已有词。自造词没有预训练 priors,需要用额外定义 tokens 偿还成本。
81
-
82
- ## 上游本地化
83
-
84
- 本地化不是摘要竞赛。处理已有优秀上游 skill 时:
85
-
86
- 1. 锁定来源版本,完整读取 `SKILL.md`、references、scripts 与 metadata。
87
- 2. 保留步骤顺序、Leading Words、Completion Criterion 的原位置、示例作用和 Progressive Disclosure 关系。
88
- 3. 只做有证据的适配:去个人化、删除不存在的命令、翻译普通说明、映射真实宿主路径与工具、加入必要权限边界、修复可证实矛盾。
89
- 4. 不强加统一章节,不把短 orchestration skill 扩成第二套方法,不把 reference-first skill 改成主动工作流。
90
- 5. 上游 skill 被移除但附件仍有独立方法价值时,把它迁移到职责最接近的现有 skill,并更新 Context Pointer。
91
-
92
- 采用 **Conservation First(保留优先)**:默认认为上游的限定词、判断规则、失败边界、例子和刻意重复都可能承担行为约束。逐句翻译时特别保留 `where possible`、`each claim`、`before`/`after`、`only` 等会改变适用范围、时机或证据强度的词。
93
-
94
- 只有满足以下至少一项,才合并、删除或替换上游内容:
95
-
96
- - 属于个人化角色、作者口吻或不存在的命令;
97
- - 与真实宿主、平台 API 或本地权限边界冲突,并有一手资料或可运行证据;
98
- - 与同一权威位置完全重复,删除后所有谓词、例子作用和 completion criterion 仍有唯一去向;
99
- - 独立前向测试确认它是 No-Op,删除后没有触发、执行、停止或失败边界回退。
100
-
101
- 上游例子是规则的一部分:诊断例子、反例和 branch 选择例子不得只剩抽象总结。需要适配例子时,替换个人语境或失效工具,但保留它原来帮助 agent 区分的情况。
102
-
103
- AI 提出的“优化”只有在能说明解决了什么真实问题,并通过场景或结构验证时才优先于上游;更整齐、更短或更长都不是改写依据。对是否可删存在疑问时,保留。
104
-
105
- ## NetPilot 宿主适配
106
-
107
- - 目录名与 frontmatter `name` 使用唯一的英文 kebab-case;`display_name` 从 canonical name 派生。中文用户可见的 description、`short_description`、`default_prompt` 和正文使用中文,代码、路径、命令与标准术语保留英文。
108
- - 每个 skill 提供 `agents/openai.yaml`。`default_prompt` 必须显式包含对应的 `$<skill-name>`;Claude Code 的调用形式由 README 说明,不在正文复制三套工作流。
109
- - 大段 reference 放在 `references/`,确定性重复操作放在 `scripts/`,静态模板和可复用产物放在 `assets/`。Context Pointer 只深入一层,并清楚说明何时读取。
110
- - 创建或修改前收集正向、反向和压力场景。完成后运行结构校验、真实触发测试和权限门禁测试;根据观察到的失败修改最小必要内容。
111
- - Git、issue tracker、外部消息和其他可见写入可以成为 skill 能力,但必须有明确目标与用户授权,并在正文说明触发条件、完成证据与失败边界。Invocation classification 不等于动作权限。
112
- - 去除个人角色、作者口吻、私有暗语和不存在的命令。实质改编受许可约束的内容时,在仓库级 `THIRD_PARTY_NOTICES.md` 保留必要法律声明。
113
- - 普通过程标题和说明使用中文;稳定 Leading Words、领域术语、协议字段、label、代码和路径保留英文,并在首次出现时解释。
114
- - 不强制统一“完成标准”或“反模式”。上游或该方法自身需要时保留,否则用真实步骤内的 Completion Criterion 和 Failure Modes。
115
-
116
- ## 失败模式(Failure Modes)
117
-
118
- 用这些模式诊断 skill:
119
-
120
- - **Premature Completion**:step 在真正完成前结束。先 sharpen Completion Criterion;只有标准无法更清楚且测试确实观察到抢跑时,才隐藏 Post-Completion Steps。
121
- - **Duplication**:同一 meaning 有多个来源,增加维护和 tokens,并把它在层级中的权重抬得过高。
122
- - **Sediment**:旧内容因为只加不删而沉积。
123
- - **Sprawl**:即使每行仍有效且唯一,`SKILL.md` 也可能长到削弱注意与可维护性。用 Information Hierarchy、branches 和 sequence cuts 处理。
124
- - **No-Op**:模型默认就会做的指令。弱 Leading Word 也可能是 No-Op;换成足以改变行为的词,或删除。
125
- - **Negation**:用禁止语激活了被禁止行为。优先描述正向目标;只有无法正向表达的硬 guardrail 才保留禁止,并同时说明应采取的替代行为。
@@ -1,6 +0,0 @@
1
- interface:
2
- display_name: "Writing Great Skills"
3
- short_description: "用可预测性、信息层级和裁剪原则创建或改写高质量 skills"
4
- default_prompt: "请使用 $writing-great-skills 创建或改写这个 skill,并验证其调用、过程与权限边界。"
5
- policy:
6
- allow_implicit_invocation: false