能被 Pi 加载,只说明 Skill 的文件结构合法;高质量还要求它:
- 容易在正确场景触发;
- 不容易在无关场景误触发;
- 步骤可以观察和验证;
- 缺少条件时知道停下;
- 有清楚的安全边界;
- 能与 Tool、其他 Skill 和宿主 Policy 配合;
- 可以独立演进。
本章继续改进 error-log-analysis,从一句说明逐步走到可维护的多阶段工作流。
1. 第一版:简单说明型 Skill
---
name: error-log-analysis
description: Helps analyze logs.
---
# Error Log Analysis
Read the logs and explain the problem.
它虽然可能加载成功,但有四个问题:
- Description 无法区分“分析”“采集”“格式化”“删除”日志;
- 没有输入前置条件;
- 没有可验证步骤;
- “Explain the problem”鼓励模型跳到根因结论。
合法不等于可用。
2. 先优化 Description
可以把 Description 写成:
对象 + 能力 + 产出 + 使用时机 + 排除场景
例如:
description: Analyzes existing application error logs, groups
repeated signatures, reconstructs timelines, and proposes
evidence-backed next checks. Use when the user provides log
files or asks to diagnose runtime failures from logs. Do not
use for configuring log collection or deleting logs.
这不是 Pi 的强制模板,而是根据源码路由机制推导出的写法:模型自动选择前只看到 Name、 Description 和 Location,所以 Description 必须携带足够的正反边界。
3. 怎样减少误触发
Description 应同时回答:
应该何时用?
相邻但不同的任务是什么?
| 用户请求 | 是否匹配 |
|---|---|
| “分析这份 server.log 的超时” | 是 |
| “聚合相同 Error Signature” | 是 |
| “帮我设计日志采集架构” | 否 |
| “清理七天前的日志” | 否 |
| “把 JSON Log 美化一下” | 通常否 |
如果多个 Skill 大量重叠,Pi Core 没有确定性 Router 替你消歧。应拆清 Description,或创建 一个明确编排它们的上层 Skill。
4. 第二版:加入检查清单
## Checklist
- [ ] Confirm readable log paths.
- [ ] Identify timestamp and severity formats.
- [ ] Find the earliest critical event.
- [ ] Group repeated signatures.
- [ ] Correlate by request/service identifiers.
- [ ] Separate observations from hypotheses.
- [ ] Attach evidence to every conclusion.
检查清单的价值不只是“提醒模型”,还为测试提供观察点。
桌面 Agent 可以从 Tool/Event 记录核验:
- 是否读取了路径;
- 是否回读原始证据;
- 是否在输出中区分事实与假设。
Markdown Checkbox 本身不会变成 Pi Runtime State。宿主若要进度条,需要自己从事件推导或让 模型输出结构化状态。
5. 把步骤写成可验证动作
较差:
Thoroughly inspect the logs.
较好:
1. Read no more than a small head/tail sample.
2. State the detected timestamp and severity formats.
3. Produce a first-pass signature count.
4. Read raw ranges around the earliest and most frequent signals.
5. Cite file path plus timestamp or line for each conclusion.
可验证步骤通常具有:
- 明确输入;
- 可观察 Tool Call;
- 可检查输出;
- 完成条件;
- 失败分支。
6. 前置条件要显式
日志分析需要:
- 至少一个可读文件路径;
- 对相关路径的 Read 权限;
- 若要运行脚本,需要 Bash/Process Tool;
- 若跨机器关联,需要时钟或时区信息;
- 若要定位请求,需要相应标识符。
正文可以写:
If no readable log path is available, ask for one.
If the helper script cannot run, continue with bounded manual
sampling and state the limitation.
这比“遇到错误自行处理”更清楚。
7. 第三版:脚本与模板
上一章示例已加入:
scripts/summarize-log.mjs
references/report-format.md
脚本适合机械、确定性的工作:
- 逐行计数;
- 解析固定格式;
- 校验输入;
- 生成机器可读中间结果。
模板适合稳定输出约定:
- 固定标题;
- 必填字段;
- 审核格式;
- 交接文档。
模型负责不确定的关联与解释,脚本负责可重复的计算,两者不要互相冒充。
8. 脚本必须有契约
Skill 应说明:
输入:路径、格式、是否允许多个
输出:stdout 是 JSON 还是文本
stderr:怎样解释
Exit Code:0、2 或其他分别表示什么
副作用:是否写文件或联网
规模边界:是否流式、最大输入
当前示例脚本:
- 接受一个或多个路径;
- 流式逐行读取;
- stdout 输出 JSON;
- 缺参设置 Exit Code 2;
- 不修改源文件;
- 只识别少量启发式签名。
只有把边界写出来,模型才能正确使用结果。
9. 避免把整个 Skill 永久塞进 Context
Pi 的渐进式披露已经把 Metadata 与正文分开。作者还可以继续分层:
SKILL.md:路线、前置、核心安全边界
references/common.md:常用但较长的解释
references/vendor-a.md:特定分支
references/vendor-b.md:另一分支
scripts/:确定性处理
assets/:模板或输入材料
原则:
- 入口文件能独立说明整体路线;
- 只有进入某分支才读取对应 Reference;
- 不在多个文件重复大段内容;
- 不让模型追五六层链接才找到下一步;
- 长期全局规则仍放 System Prompt/Project Context。
10. 第四版:多阶段工作流
把复杂任务分成阶段:
flowchart LR
P["Phase 1\nPreflight"] --> C["Phase 2\nCollect"]
C --> A["Phase 3\nAnalyze"]
A --> V["Phase 4\nVerify"]
V --> R["Phase 5\nReport"]
Phase 1:Preflight
- 确认路径、时间范围和权限;
- 声明不会修改源日志;
- 识别敏感信息风险。
Phase 2:Collect
- 小范围采样;
- 确定格式;
- 运行有界的首轮统计。
Phase 3:Analyze
- 建时间线;
- 按标识符关联;
- 形成多个候选假设。
Phase 4:Verify
- 回到原始行;
- 寻找冲突证据;
- 给每个假设标置信度。
Phase 5:Report
- 使用模板;
- 区分事实、推断和未知;
- 给出最小下一步检查。
阶段结束条件比一长串模糊建议更稳定。
11. 中间产物怎样设计
每个阶段可以定义中间产物:
| 阶段 | 产物 |
|---|---|
| Preflight | Scope / Missing Inputs |
| Collect | Format Profile / Signature Counts |
| Analyze | Timeline / Candidate Hypotheses |
| Verify | Evidence Matrix |
| Report | Final Report |
Skill 可以要求模型在内部维护这些结构,或通过文件/业务 Tool 持久化。
不要把关键业务状态只留在模型记忆里。Session 会压缩,Skill 本身也没有独立 State Store。
12. 第五版:需要用户确认
有些步骤可能:
- 访问生产日志;
- 运行高成本查询;
- 下载大量数据;
- 修改 Issue;
- 触发修复脚本。
Skill 可以写:
Before any production query or side effect:
1. Show the exact target and operation.
2. Explain expected cost and risk.
3. Ask for explicit confirmation.
4. Continue only after the user confirms.
这是给模型的工作流约束,但不是不可绕过的强制 Approval Gate。
真正必须执行的审批应放在:
- Tool 实现;
- Extension
tool_callHook; - 桌面宿主 Policy;
- 服务端权限。
Skill 负责“何时应询问和怎样解释”,执行层负责“未经批准不能做”。
13. 确认要绑定具体动作
不要问:
可以继续吗?
更好的确认:
准备在 production-eu 的 logs-2026.07.27 索引执行
15 分钟范围的只读查询,预计扫描 1.8 GB,不写入数据。
是否执行这个精确查询?
如果目标、参数或副作用变化,应重新确认。确认一次不能无限泛化为后续所有动作。
14. 第六版:组合其他 Skill
假设有:
error-log-analysis;incident-report-writing;ticket-handoff。
可以创建上层 incident-response Skill:
## Workflow
1. If available, load `error-log-analysis` and complete its
evidence collection phases.
2. Then load `incident-report-writing` and create the report.
3. Ask the user before using `ticket-handoff`.
但要准确理解机制:
- Pi 没有
invokeSkill(name)Runtime API; - Skill 正文中的
/skill:other不会被递归命令展开; - 模型需要从 System Prompt 的目录找到另一 Skill Location,再用
read加载; - 被组合 Skill 不可见或
read不可用时,编排会失败; - 多 Skill 指令冲突仍需上层工作流处理。
因此这种组合是模型编排,不是函数调用图。
15. 组合 Skill 要有回退
If `incident-report-writing` is not present in available skills:
- Use the local fallback structure in references/report-fallback.md.
- State that the specialized reporting skill was unavailable.
高质量编排要说明:
- 必需还是可选依赖;
- 不可用时是否停止;
- 谁负责最终输出格式;
- 安全边界冲突时谁优先;
- 每个子流程的完成条件。
16. Skill 怎样与业务 Tool 配合
例如企业桌面 Agent 有:
query_logs
get_deployment
create_incident
Skill 不应重复 Tool Schema,而应说明业务顺序:
1. query_logs 只能先做只读、小时间窗查询;
2. 用 get_deployment 对齐最近发布;
3. 在证据不足时不要 create_incident;
4. create_incident 前展示 Payload 并请求确认。
Tool Definition 提供参数和执行能力,Skill 提供跨 Tool 的流程与决策点。
如果 Tool 不存在,Skill 应说明降级路径或停止条件,不要让模型假装执行。
17. 输出格式要服务于消费方
人类阅读:
## Observations
## Hypotheses
## Evidence gaps
## Next checks
机器消费:
{
"observations": [],
"hypotheses": [],
"nextChecks": []
}
Skill 应明确:
- 必填字段;
- 顺序;
- 证据引用格式;
- 未知值怎样表示;
- 是否允许额外文字;
- 谁会消费结果。
只写“输出 JSON”不够,模型需要 Schema 或 Template;真正严格的机器接口更适合结构化 Tool。
18. 安全边界分三层
flowchart TD
S["Skill 指令层\n识别风险、请求确认"] --> E["Extension/宿主策略层\n拦截与审批"]
E --> T["Tool/服务层\n参数校验、最小权限"]
Skill 至少声明:
- 不可信输入怎样处理;
- 敏感数据怎样脱敏;
- 禁止的副作用;
- 必须确认的动作;
- 允许访问的资源范围;
- 失败时默认停止还是降级。
但强制性不能只依赖自然语言。
19. 版本管理
当前 Pi 的运行时 Skill Metadata 没有标准 version 字段。即使在 Frontmatter 写:
version: 2.1.0
当前 Loader 也只把它当未知字段,不会用于选择、升级或冲突。
不同载体承担不同职责:
- 本地 Skill:用 Git Commit/Tag 固定内容;
- Pi npm Package:在设置中使用精确 Source,例如
npm:@scope/pkg@1.2.3; - Pi Git Package:使用明确 Ref、Tag 或 Commit,例如
git:host/repo@v2.1.0; - Package Version 与 Changelog:表达发布语义和迁移;
- Test Fixture 与期望输出:验证行为;
- SourceInfo 与 Collision Diagnostics:识别当前实际加载来源和 Winner;
- Package Lockfile:只锁 Skill 辅助脚本自身的依赖,不参与 Skill 名称冲突或最新版选择。
Pi 文档说明 Versioned npm Spec 与 Git Ref 都会保持 Pin,更新命令不会自动把它们移动到其他
版本。SourceInfo 只有 Path、Source、Scope、Origin 和可选 BaseDir,没有 Version。
如果需要在正文展示版本,可以写,但不要误以为 Core 会据此解析“最新版本”。
20. 兼容性与迁移
Skill 演进时要关注:
- 重命名会破坏
/skill:old-name; - Description 修改会改变自动触发;
- Script 参数变化会破坏旧指令;
- 输出字段变化会影响下游;
- Reference 移动会造成路径失效;
- 同名新版本可能因 first-wins 根本没有生效。
破坏性变化应:
- 更新 Package Version,并把设置中的 Package Source 固定到期望 npm Version 或 Git Ref;
- 写迁移说明;
- 保留或明确删除旧入口;
- 在测试中同时覆盖旧/新用法;
- 检查 Resource Diagnostics 和 Winner Path。
21. 可验证性矩阵
| 设计点 | 怎样验证 |
|---|---|
| 正确自动触发 | 匹配请求是否 read SKILL.md |
| 不误触发 | 相邻负例是否不读 |
| 前置条件 | 缺路径时是否询问 |
| Tool 顺序 | Event 中的调用序列 |
| 脚本契约 | Fixture、stdout、Exit Code |
| 证据要求 | 输出是否含 Path/Line/Timestamp |
| 用户确认 | 高风险 Tool 前是否等待 |
| 强制审批 | Extension/Tool Test 是否拒绝未授权 |
| 组合 Skill | 子 Skill 缺失与冲突分支 |
| 版本迁移 | 旧命令和输出兼容测试 |
下一章会把这些设计点变成 Faux Provider 和宿主测试。
22. 一份高质量 Skill 的骨架
---
name: capability-name
description: What it does. Use when... Do not use when...
---
# Capability Name
## Preconditions
## Inputs
## Safety boundaries
## Phase 1: Preflight
## Phase 2: Collect
## Phase 3: Analyze
## Phase 4: Verify
## Output contract
## Failure and fallback
## Optional references and scripts
不是每个 Skill 都需要所有标题。简单任务保持简单;复杂任务才增加阶段和资源。
23. 设计检查表
发布前检查:
- Description 是否包含 What/When/Not When?
- Name 是否稳定、兼容标准?
- 缺少输入时是否明确停止?
- 每个步骤是否能从 Tool/Event/输出观察?
- Script 是否有输入、输出、Exit 和副作用契约?
- 入口是否足够短,References 是否按需?
- 相对路径是否从 Skill Directory 解析?
- 是否把不可信内容当数据?
- 是否区分 Skill 提示确认与强制审批?
- 输出是否适合实际消费方?
- 组合依赖是否可见且有回退?
- 是否用 Git/Package/Test 管理版本?
24. 常见误区
“Description 越长越容易触发”
错误。关键信息应具体且可区分,不是堆砌所有关键词。
“Checklist 会自动变成运行时进度”
错误。它仍是模型指令。
“在 Skill 里写确认就有强制审批”
错误。强制 Gate 要在 Extension/Tool/宿主。
“正文里写 /skill:other 会递归执行”
错误。Skill Command Expansion 只处理用户输入预处理,不递归解释模型看到的正文。
“Frontmatter version 会自动选择最新版”
错误。当前 Loader 不提取这个字段。
“输出 JSON 就一定机器可靠”
错误。严格契约应提供 Schema、验证器或结构化 Tool。
25. 本章小结
- 高质量 Skill 从准确 Description、前置条件和可验证步骤开始;
- 正反触发边界能减少模型误选;
- Checklist 是指令,不是 Runtime State;
- Script 处理确定性工作,并需要完整运行契约;
- SKILL.md 保留路线和核心边界,分支资料按需读取;
- 多阶段工作流应定义阶段产物和退出条件;
- Skill 可以提示用户确认,强制审批必须落实到 Extension/Tool/宿主;
- Skill 组合是模型读取其他 Skill 的编排,不是递归命令或 Core invoke API;
- 业务 Tool 提供动作,Skill 提供跨 Tool 的决策流程;
- 当前 Core 不使用 Frontmatter Version,版本应由 Git/Package/Changelog/Test 管理;
- 每个设计点都应能映射到触发、Tool、输出或 Policy 测试。
26. 自测
- Description 怎样同时提高触发率和降低误触发?
- 什么样的步骤算可验证?
- 哪些内容必须留在 SKILL.md,哪些适合拆到 Reference?
- Skill 中的“请求确认”和强制 Approval Gate 有何区别?
- 为什么正文中的
/skill:other不会递归展开? - 组合 Skill 应怎样处理缺失依赖?
- 当前 Pi 是否用 Frontmatter Version 解决同名冲突?
- 如何验证 Skill 与业务 Tool 的调用顺序?