AI Skills - Waza:怎么用
关于环境:Waza 最初是为 Claude Code 设计的技能包,本系列的演示环境是 OpenCode(开源的 AI 编程终端)。Waza 的技能在两个工具中都能正常工作,本章中 Claude Code 特有的概念(如 CLAUDE.md、hooks)会在 OpenCode 的等效机制旁标注。
3.1 想清楚再做:/think
/think 是第一技能,排在设计、审查、调试之前。它的触发时机很简单:在开始建任何新东西之前。
三个模式
Lightweight Mode — 当你要修一个东西而不是建一个东西时激活。问题是确定的,唯一的开放问题是"怎么修"。输出 2-3 句话的推荐方案:改什么、在哪里改(file:line)、为什么改。先给出一种暴力方案,除非用户主动要优雅方案。
Evaluation Mode — 当你要判断某个东西该不该存在、该不该留着、该不该暴露出去时激活。典型触发词是"判断一下"、"有没有必要"、"值不值得"。不列选项,只给一个推荐的结论和理由。如果结论是"删除"或"大改",列出影响范围。
Full Mode — 默认模式。输出一个方案,包含推荐方案 + 备选方案(只在取舍很接近时给)+ 最脆弱假设 + 攻击角度。
最脆弱假设
这是 /think 最有价值的设计。每个方案都有一个最脆弱的假设——如果这个假设不成立,整个方案就坍塌了。要求在方案里明确写出来:
This plan assumes X. If X does not hold, Y happens.
如果这个假设是承重的而且确实脆弱,设计就要在方案层面承受它的失败。
比如你要做一个缓存系统。最脆弱假设可能是"用户的数据访问模式符合 80/20 分布"。如果不符合(比如全量扫描为主),缓存的收益就会大幅下降。方案应该在这个假设不成立时也能正常工作——可能加一个 bypass 开关、或者设置自动降级策略。
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 在 ~/project 操作文件,仓库实际在 ~/www/project | 第一个文件操作前先 pwd |
| 实现到一半才问 API key | 交出方案前列出所有依赖 |
| 方案里有 TBD / TODO / "implement later" | 禁止。占位符等于承诺以后再做计划 |
3.2 做出有观点的 UI:/design
/design 的前提是:如果它看起来像是默认 prompt 生成的,就不够好。
方向锁定五问
开始画任何像素之前,必须回答五个问题。不回答完不动手:
- 谁在用,在什么场景? 分析面板和落地页的差异很大
- 美学方向是什么? 精确命名:dense editorial、raw terminal、ink-on-paper。"Clean and modern" 不算方向
- 留给用户记忆的一件事是什么? 选一个字体的性格、颜色系统、一个不对称布局,做明显
- 硬约束是什么? 框架、包体积、对比度下限、键盘可达性
- 招牌微交互是什么? 按下的缩放、渐次揭示、或者上下文的图标动画
如果用户给的参考是 Linear、Stripe、Claude 这类知名品牌,可以用 npx getdesign@latest add <brand> 拉取 curated preset 作为起点。
截图迭代模式
当用户发来一张截图加一句"这里很丑",进入截图迭代模式。流程很紧凑:
- 读截图,一句话说清楚问题(间距、对比度、对齐、字体、颜色)
- 等用户确认诊断
- 如果诊断结果是已知 UX 问题(分栏同步、无限滚动、虚拟列表、粘性 header),先花一轮看 2-3 个同类产品怎么解决的
- 找到具体代码文件
- 最小改动,一个组件一个问题
- 让用户在浏览器确认
视觉论题三行摘要
写任何代码前,把方向总结成三行:
- 视觉论题:基调、材质、能量的句子(冷色 / 暖色 / 高对比 / 柔和)
- 内容计划:对于营销页面,hero→支撑→细节→CTA;对于应用页面,直接 utility 模式(定位+显示状态+触发动作)
- 交互论题:2-3 种具体动效,说明它们改变页面感受的方式
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 用了 Inter 做展示字体 | 它没有性格。选有辨识度的字体 |
| 轻色模式下白色面板上白色背景 | 相邻嵌套表面必须视觉可区分,背景色阶差 ≥4% 或加阴影 |
| 玻璃拟态忽略移动端限制 | backdrop-filter 在低端设备上很贵。明确说清楚取舍 |
3.3 发版前守住底线:/check
/check 的职责是在合并前找到问题。做完意味着验证在这个 session 里跑过并且通过了。
深度分诊
拿到 diff 后先测量。根据 diff 大小和影响范围决定审查深度:
| 深度 | 标准 | 审查范围 |
|---|---|---|
| 快速 | 100 行以内,1-5 个文件 | 基础审查 |
| 标准 | 100-500 行或 6-10 个文件 | 基础 + 按需专家 |
| 深度 | 500+ 行或 10+ 文件,触及 auth/payments/数据变更 | 基础 + 全专家 + 对抗性审查 |
Autofix 路由
审查发现的问题按类型自动分流:
| 类别 | 定义 | 处理 |
|---|---|---|
| safe_auto | 无歧义无风险:拼写错误、缺少 import、风格不一致 | 自动修复 |
| gated_auto | 大概率正确但改变行为:null 检查、错误处理 | 批量确认一次 |
| manual | 需要判断:架构、行为变更、安全取舍 | 在 sign-off 中陈述 |
| advisory | 仅参考 | 在 sign-off 中标注 |
Document Review 模式
当审查目标是文档(PDF、发版说明、白皮书)时,检查清单不同:
- 隐私扫描:有没有 PII(名字、公司、薪资暗示、位置细节)
- 语气一致:有没有 voice shift、AI 腔
- 双语校验:中英文版本是否一致
- 渲染检查:有没有遗留的 placeholder、Lorem ipsum、TODO
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 给 #249 评论了,实际讨论的是 #255 | 操作前 gh issue view N 确认标题 |
| PR 评论听起来像正式报告 | 1-2 句话,像同事说话,不用结构化格式 |
| 部署后才发现环境变量没设 | 布署前 vercel env ls 对比本地变量 |
3.4 找到根因再修:/hunt
/hunt 的核心纪律是:碰代码之前,必须能用一句话陈述根因。
I believe the root cause is [X] because [evidence].
这句话必须具体到文件和行号。"状态管理问题"不是可验证的假设。"useUser 的 dependencies 数组缺少 userId"才是。
Bisect 模式
bisect 模式在"以前好好的,现在坏了"或"更新后坏了"时激活。流程:
找最后一个已知好的 tag → 定义一个非交互的 pass/fail 测试命令 → 运行 git bisect start → 让 bisect 驱动,不跳步 → 定位 culprit commit 后只读那个 diff
三次假设失败规则
连续三次假设都被证据推翻后,停止。输出 Handoff 格式:
- 原始症状
- 测过的假设(每个假设:假设内容 → 测试方法 → 被排除的原因)
- 已收集的证据
- 已排除的根因
- 未知项
- 建议的下一步方向
Diagnosis Signals
| 状态 | 含义 |
|---|---|
| 日志行和假设匹配 | 好进展,再找一个独立证据再 commit |
| "我先试试" | 没有假设。先写假设 |
| "我确定" | 跑一个工具来证明它 |
| "可能是同一个问题" | 从头重读执行路径 |
| "重启一下" | 读上一次的错误原文。不拿新证据就不重启第三次 |
Gotchas 示例
| 场景 | 规则 |
|---|---|
| Stack trace 指向库深处 | 往回走 3 帧到自己代码里,bug 基本在那里 |
| 能复现但 CI 过不了 | 先对齐环境(版本、env vars、时区)再追代码 |
3.5 写出人话:/write
/write 的目标不是润色词汇,而是去掉 AI 味的表演感。
Pre-flight 三问
动手前先确认三件事:
- 文本存在吗? 如果用户只给了指令没给文本,先让用户给文本
- 读者锁定吗? 新人工程师和架构师的文章读起来应该完全不同
- 语言检测:文本含中文 → 加载
write-zh.md;否则加载write-en.md
去 AI 腔
AI 腔的特征包括:
- filler 短语("值得注意的是"、"你需要考虑"、"换句话说")
- 二元对比("一方面……另一方面……"、"虽然……但是……")
- 戏剧化断句(短句堆叠)
- 过度副词("非常"、"显著地"、"本质上")
硬规则:如果去掉 AI 模式会改变作者的意图,保留原样。不做结构调整,不在原地改组段落。输出改写后的文本,不加改动说明。
双语审查模式
当处理中英混排时的规则:
- 中文和英文之间加空格(CN文字EN → CN 文字 EN)
- 标点符号不混用(中文用、。?!;:)
- 术语全文一致
- 检查英文在中文文档中是否有必要,必要时加翻译或上下文
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 用户只说了"帮我润色"没给文本 | 先问文本内容,不动手 |
| 改掉了作者的原意来消除 AI 腔 | 保留原意优先于消除 AI 腔 |
3.6 系统化学习新领域:/learn
/learn 是 Waza 里最复杂的技能,6 个阶段的全流程研究工具。本系列博客就是用它研究 Waza 后产出的。
六阶段流程
| 阶段 | 做什么 | 关键纪律 |
|---|---|---|
| Phase 1 收集 | 只收一手资料:论文、官方博客、builder 的帖子、官方仓库 | 摘要不算来源 |
| Phase 2 消化 | 通读,砍掉一半不合适的 | 三问测试:是否出现在 2+ 上下文、能否预测新问题、是否专家共识 |
| Phase 3 大纲 | 写提纲,每节标注信源 | 没有信源的节要么砍掉要么去补 |
| Phase 4 填充 | 逐节写 | 卡住就退回到 Phase 2 补那个子主题 |
| Phase 5 精炼 | 去冗余、去 AI 腔、标记漏洞 | /write 可用时交给它 |
| Phase 6 自审 | 人读全文,至少两遍 | 读到顺畅为止 |
Stall 信号
写不下去不是"我懒",而是心智模型在这节不够完整。四个信号:
- 改写开头三遍还没定下来
- 这一节只有单个来源,没法交叉验证
- 需要 Phase 1 没收集到的新来源
- 有一个你没法当面跟人说清楚的主张
任何一个信号出现,退回 Phase 2 补那个子主题,不是补整篇文章。
这篇文章与 /learn 的关系
你现在读的这篇博客系列,就是用 /learn 研究 Waza 本身的产物:/read 抓取 8 个技能的 SKILL.md 和作者博客 → /learn 的 Phase 2 三问筛选核心观点 → Phase 3 产出三章大纲 → Phase 4 逐节填充。每一步用的都是 Waza 自己的技能。
3.7 读取任何内容:/read
/read 的职责很窄:把 URL 或 PDF 转成干净的 Markdown 并保存。不做分析、不做总结、不讨论内容。
平台路由
不同来源走不同通道:
| 输入 | 方法 |
|---|---|
| 飞书 / Lark | 飞书 API 脚本 |
| 微信公众号 | 代理级联优先 |
| PDF(URL 或本地路径) | PDF 提取 |
| GitHub | 优先 raw content 或 gh CLI |
| X / Twitter | 代理级联 |
| 其他 | 代理级联 |
代理级联是核心——它负责处理 paywall、JS 重页面、微信文章的封锁。WebFetch 和 curl 在这些场景下无声失败,所以 /read 被设计为所有 URL 抓取的统一入口。
输出格式
Title: {title}
Author: {author} (if available)
Source: {platform}
URL: {original url}
Content
{full Markdown, truncated at 200 lines if long}
默认保存到 ~/Downloads/{title}.md 并添加 YAML frontmatter。用户可以要求"just preview"跳过保存。
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 抓取 paywall 文章只拿到登录页面 | 检查前 10 行,发现了就停止并警告 |
| 所有方法都失败 | 告诉用户试了什么、哪里失败了 |
| GitHub 页面用 WebFetch 抓 | 优先用 gh 或 raw content |
3.8 审计你的配置:/health
/health 基于作者提出的配置堆栈来审计 AI 编程工具的配置健康度。原作者 tw93 为 Claude Code 定义了六层框架(CLAUDE.md → rules → skills → hooks → subagents → verifiers),/health 将其适配为 OpenCode 的等效栈:AGENTS.md → instructions → skills → permissions/agents → tools → MCP。它评估你的项目复杂度,逐层检查,然后输出分优先级的报告。
项目分级
先判断项目级别,只检查该级别的项目:
| 级别 | 特征 | 期望(Claude Code) | 期望(OpenCode) |
|---|---|---|---|
| Simple | <500 文件,单人,无 CI | CLAUDE.md + 0-1 个技能 | AGENTS.md + 0-1 个技能 |
| Standard | 500-5K 文件,小团队或有 CI | CLAUDE.md + 1-2 条规则 + 2-4 个技能 | AGENTS.md + instructions + 2-4 个技能 |
| Complex | >5K 文件,多人协作,活跃 CI | 完整六层 | AGENTS.md + instructions + skills + agents + tools + MCP |
报告格式
## Health Report: {project} ({tier} tier, {file_count} files)
### [PASS] Passing checks (table, max 5 rows)
### [!] Critical — fix now
### [~] Structural — fix soon
### [-] Incremental — nice to haveNon-goals
- 不自动修复。给出 copy-pasteable 的命令
- 不对简单项目应用复杂级别的检查
- 不猜测。工具缺失就标
(unavailable),不是 flag
Gotchas 示例
| 场景 | 规则 |
|---|---|
| 漏掉了项目级配置覆盖 | OpenCode 的全局配置(~/.config/opencode/opencode.json)和项目配置(opencode.json)是合并的,需要检查两者 |
| 报告语言不对 | 优先用 AGENTS.md 的 Communication rule 或用户最近使用的语言 |
| 自定义 agent 未定义就被标记为异常 | agent 定义可能在 .opencode/agents/ 或 ~/.config/opencode/agents/ 中 |
3.9 连锁调用
技能之间设计为可串联,但串联是手动的。每个技能完成后停下来,等用户决定下一步。
常见的连锁工作流:
设计一个功能: /think → 批准 → 实现 → /check → 合并
修一个 bug: /hunt → 修复 → /check → 发版
调研和写作: /read → /learn → /write
调试和验证: /hunt → 修复 → /check
每个箭头都是用户的手动操作。技能不会自动触发下一个技能。这是有意的——防止模型在未经确认的情况下跑偏。
3.10 用 Waza 写一篇博客:从选题到发布
最后看一个完整的串联实例:用 Waza 自己来写 Waza 的博客。
第一步:/read 收集资料
抓取 Waza README、8 个 SKILL.md、Kaku 和 Kami 的 README、作者的两篇核心博客("You Don't Know Claude Code" 和 "AI 时代如何深入学习")。不走 WebFetch,用 /read 的代理级联处理 GitHub raw content。
第二步:/learn 系统化学习
进入 /learn 的 6 阶段流程:
- Phase 1:收集 10+ 一手资料
- Phase 2:通读后三问筛选——哪些观点出现在两个以上上下文中(保留),哪些是通用智慧(裁剪)
- Phase 3:产出三章大纲(是什么 / 为什么 / 怎么用),每节标注信源
- Phase 4:逐节填充,卡住退回 Phase 2 补子主题
第三步:/think 定结构
在大纲落定前,用 /think 确认最终结构:三章是否覆盖所有关键信息?章节顺序是否合理?最脆弱假设是什么?(假设:读者熟悉 Claude Code 基础概念。如果不熟悉,需要加一段前置说明。)
第四步:写初稿
逐节填充。碰到卡壳——比如写"/design"那一节觉得写得不够好——退回 Phase 2 重新通读 design/SKILL.md 和 references,然后回来再写。
第五步:/write 去 AI 味
把写好的整篇文章交给 /write。去掉 filler 短语("值得注意的是")、二元对比("一方面……另一方面……")、过度副词("非常"、"显著地")。不改变原意,不改结构。
第六步:/check 做终审
走 /check 的 Document Review Mode(在 OpenCode 中路由到 /write 的文档审查模式):
- 隐私扫描:没有泄露出 Waza 项目之外的敏感信息
- 语气一致:三篇文章的语气统一
- 渲染检查:TOML front matter 正确,Markdown 格式无误,链接可访问
- 双语校验:英文术语(如 Lightweight Mode)在中文正文中保持一致的翻译
第七步:发布
按博客平台的要求格式化。这篇博客使用 Zola,所以每一篇都要加 TOML front matter:
+++
title = "文章标题"
date = 2026-05-06T10:00:00+08:00
description = "描述"
[taxonomies]
tags = ["waza", "claude-code"]
[extra]
lang = "zh"
toc = true
comment = true
copy = true
+++为什么这个流程有效
整套流程没有用到任何 Waza 之外的技巧。用的就是 8 个技能本身的定义。每一个技能在需要的时候加载,完成后退出——正如 Waza 设计的那样。
这不是一个精心策划的演示场景。你在读的这些文字,就是在 /learn → /think → /write → /check 这个循环里产出的。如果你也想给自己的知识领域写系列文章,这套流程直接搬到你的项目上就能用。
3.11 如何贡献加新技能
Waza 是开源项目(MIT),贡献新技能走一条明确的路径。
决策表:Skill vs Script vs Rule
加能力之前先确定放哪一层:
| 问题 | 是 | 否 |
|---|---|---|
| 用户需要判断、适配或追问? | Skill | Script 或 Rule |
| 相同输入总产生相同输出? | Script 或 Rule | Skill |
| 是查询、列表、状态检查或不变量检查? | Script 或 Rule | Skill |
| 行为随会话上下文变化? | Skill | Script 或 Rule |
加技能的完整路径
- 创建或更新
skills/<name>/SKILL.md,描述词具体到可触发,包含 "Not for" 排除说明 - 更新
skills/RESOLVER.md和.claude-plugin/marketplace.json,让路由、描述、版本、源路径一致 - 保持 Waza 公共化:项目特定信息通过运行时读取公共 repo 上下文来提取,不要硬编码私有路径
- 确定性执行放
scripts/或rules/,技能 body 只保留需要判断的部分 - 运行
./scripts/verify-skills.sh、make test、make package后提交
提交规范
feat: 新功能
fix: 修复
refactor: 重构
docs: 文档
chore: 杂项
发版标签用小写 v{version}。
系列三篇到此结束。如果你在项目里用上了 Waza 的某个技能,或者发现了新的使用方式,欢迎到 GitHub 讨论或贡献。