【免费下载链接】Waza
🥷 Engineering habits you already know, turned into skills Claude can run.
Waza 是一个把工程师既有习惯沉淀为 AI Agent 可执行技能的开源项目,而 rules/waza-routing.md 正是这套技能体系的路由总纲:它用一张 8 行路由表,把"用户说了什么"映射到"该调用哪个技能",并规定了歧义出现时的消解纪律。本文以该路由文档为主体,结合仓库内的 skills/RESOLVER.md(完整路由索引)、scripts/verify_skills.py(路由一致性校验)、scripts/setup-rule.sh(路由规则安装器)等源码,从触发词设计、匹配机制、防漂移校验、歧义消解到安装落地,给你一套可复制、可验证的技能路由实战方案。
读完本文,你将掌握:Waza 八大技能的触发词边界与设计意图、路由表与 SKILL.md 元数据之间的绑定校验原理、多技能同时命中时的 11 条消解规则、技能串联的工作流编排方式,以及如何在自己的 Agent 环境中安装并验证这条路由规则。
为什么需要一张"技能路由表"
Waza 定位为"工程习惯"而非"编码脚手架"——它交付的是/think、/ui、/check、/hunt、/write、/learn、/read、/health八个技能。问题在于:用户并不会每次都说"请调用 /think 技能",他们说的是"帮我看看这个方案值不值得做"。
路由表要解决的正是这个语义鸿沟:把自然语言请求(尤其是中英混合的日常表达)映射到唯一且正确的技能。路由文档开宗明义地给出了两条铁律:
- 命中即优先:当请求匹配某个触发词时,优先使用对应技能,而不是用一个"通用实现"从头重写工作流("Do not reimplement the workflow from scratch");
- 禁止静默二选一:两个技能都匹配时,先读两个
SKILL.md的 "Not for" 段来消解歧义;仍然模糊就询问用户,绝不悄悄选一个("Never silently pick one")。
这两条纪律保证了路由不是"概率猜谜",而是一套有明确退出路径的决策流程。
八大技能路由表:触发词、适用场景与设计意图
路由文档的核心是下面这张表。每个技能一行,use when列混合了英文场景描述与中文用户原话(引号内短语即用户可能逐字输入的触发词):
| skill | use when |
|---|---|
| think | new feature / architecture / "怎么设计" / "有没有必要" / "值不值得" / product judgment |
| ui | UI / page / component / frontend / typography / screenshot says "丑/不清晰/不和谐" |
| check | review / "看看代码" / pre-merge / release / push / close issue / project audit |
| hunt | error / crash / regression / test failure / "以前是好的" / screenshot proves regression |
| write | draft / rewrite / proofread / "去 AI 味" / tweet / launch copy / document review |
| learn | deep dive into an unfamiliar domain / compile a batch of sources into one article |
| read | message contains an http(s) URL or PDF path / "看这个链接" / "读一下" |
| health | Claude/Codex/Pi ignores instructions / hook misfire / config drift / agent config audit / rot |
从触发词可以读出每个技能的设计意图,这与各 SKILL.md 的 frontmatter 元数据一一对应:
think(动手前):new feature、architecture、product judgment属于"要不要做、怎么做"的判断类请求。对应 skills/think/SKILL.md 的when_to_use("怎么设计, 用什么方案, 有没有必要, 值不值得, what's the best approach, plan this...")与dispatch_intent("New feature, architecture, how should I design this, value judgment, executable plan, handoff")。ui(动手前):页面、组件、前端、排版,以及"截图说丑/不清晰/不和谐"这类审美校准请求。注意它与hunt的分工:截图审美问题归ui,截图证明"以前好的现在坏了"的回归归hunt。check(交付前):review、合并前检查、release、push、关闭 issue、项目审计——一切"交付把关"动作。hunt(出问题):error、crash、regression、测试失败、"以前是好的"。对应 skills/hunt/SKILL.md 的when_to_use("排查, 报错, 崩溃, 回归, 截图回归, debug, regression, used to work, why broken..."),其核心纪律是"定位根因之前不许动代码"。write(内容输出):草稿、改写、校对、"去 AI 味"、推文、launch copy、文档审阅。learn(内容输入):深入陌生领域研究、把一批资料编译成一篇文章。read(内容输入):消息中含 http(s) URL 或 PDF 路径、"看这个链接"、"读一下"。health(元层):Agent 自身出问题——Claude/Codex/Pi 忽略指令、hook 失灵、配置漂移、Agent 配置审计、AI coding 腐化(rot)。它与hunt的关键区别:agent 配置/维护性问题归health,用户代码抛异常归hunt。
这张表本身是"给人看"的浓缩版。更完整的分阶段路由表(Pre-build / Post-build / Diagnostic / Content 四类场景,含release、triage、audit等子模式)位于 skills/RESOLVER.md,并明确说明:Claude Code 实际是通过每个 SKILL.md 的description自动匹配技能,RESOLVER.md 是集中索引与校验依据——"改 SKILL.md 的适用范围时,同步改这里"。
路由的底层机制:SKILL.md 元数据契约
路由表不是凭空维护的文字,它由每个 SKILL.md 的 YAML frontmatter 驱动。以 scripts/skill_frontmatter.py 的parse_frontmatter实现为准,Waza 的 frontmatter 刻意保持精简,只允许四个顶层标量:
name:必须与技能目录名一致(如think),否则校验直接失败(NAME MISMATCH);description:Agent 解析器首先看到的字段,要求以动词/动作短语开头、长度在 40~500 字符之间、必须包含 "Use when" 与 "Not for" 两段(check_description_conformance强制,因为"部分 Agent 运行时在读到 when_to_use 之前先看 description")、且公开元数据必须纯英文(CJK 内容放在when_to_use);when_to_use:逗号分隔的中英触发词清单,路由表的引号短语必须在这里"落地生根";dispatch_intent:供 scripts/build_metadata.py 生成 dispatcher 路由表使用。
为什么 description 里强制要求 "Not for"?从 scripts/checks_content.py 的注释可以读出设计意图:消歧不只在路由表层面发生,description 本身就要教会解析器"什么时候不该触发"。这让check与hunt(都是"帮我看看")、ui与hunt(都涉及截图)这类高危重叠对,在元数据层面就有了第一道排除机制。
触发词"接地"校验:引号短语必须有技能认领
路由表里最容易被忽略的细节是:use when列中所有带引号的短语,都被视为"用户会逐字输入的断言"。为此 scripts/checks_routing.py 实现了check_waza_routing_triggers,其逻辑是:
- 用
QUOTED_PHRASE_RE提取表格中的引号内容——这个正则同时覆盖直引号(")、弯引号(U+201C/D)以及中文书名号(「」『』),保证中文短语被同等对待; - 将引号短语按
/切分、去除空白后,逐一检查是否出现在对应技能的when_to_use中; - 只要有一个短语缺失,就报
WAZA ROUTING UNGROUNDED TRIGGER,提示"只能引用用户真正会输入的短语,要么对齐 when_to_use,要么把它加进 when_to_use"。
这就是为什么路由文档中"怎么设计""有没有必要"这类短语,能在 skills/think/SKILL.md 的when_to_use里逐字找到——路由表永远不会宣传一个技能并未声明的触发词。而未加引号的英文场景词(如architecture、review)属于自由措辞,有意不做此项校验,保持路由表可读性。
结构漂移校验:路由表必须与技能集精确对齐
触发词之外,路由表还受到两层"结构一致性"保护:
第一层:路由表 vs 技能目录。check_waza_routing_skills逐行解析rules/waza-routing.md的 Markdown 表格,提取合法的技能名(匹配[a-z][a-z0-9_-]*),然后与skills/*/SKILL.md目录做集合差:
- 技能存在但路由表缺失 →
WAZA ROUTING MISSING SKILLS; - 路由表列出了不存在的技能 →
WAZA ROUTING STALE SKILLS。
也就是说,新增或删除任何一个技能,路由表必须同步增删行,否则 scripts/verify_skills.py 会在python3 scripts/verify_skills.py时直接以非零码退出。这保证了"人看的索引"与"模型看到的 SKILL.md"永远锁步。
第二层:dispatcher 与 RESOLVER 对齐。scripts/check_routing_drift.py 额外要求 scripts/dispatcher.md 与 skills/RESOLVER.md 引用完全相同的技能名集合。dispatcher 是 Waza 以宿主插件方式安装时的统一入口,其路由表由build_metadata.py从各技能的dispatch_intent自动生成(<!-- routing-table:start -->与<!-- routing-table:end -->之间的表格即生成产物),因此这个脚本被定位为"生成逻辑旁边的廉价绊线(sanity tripwire)"。
值得一提的是:verify_skills.py是纯驱动入口,校验逻辑全部拆分到可导入的兄弟模块(checks_content.py、checks_distribution.py、checks_routing.py),从而可以被 tests/python/ 下的单元测试直接 import 测试。这是路由这种"易腐化"文档能长期保持可信的制度保障。
歧义消解:从二元冲突到 11 条决策规则
路由文档给出了消解的第一原则:两个技能都匹配时,先读两个 SKILL.md 的 "Not for" 段;仍模糊就问用户,绝不静默二选一。而 skills/RESOLVER.md 在此基础上把常见冲突固化为 11 条可执行的消解规则,按冲突类型可归纳为六组:
- 最具体优先:
/ui比/think更具体(仅限 UI 决策),"帮我设计登录页"优先/ui; - URL 二次分流:消息含 URL → 先走
/read取回 Markdown;要总结/分析就继续,是长文研究素材再接/learn; - 改错 vs review:代码已交付/走到 PR →
/check;代码跑不通/行为错了 →/hunt。两者都可能命中"帮我看看",按"有没有具体错误现象"判断; - Agent 配置异常 vs 代码错误:Claude/Codex 不听话、hook 不触发、MCP 掉链子、AGENTS/CLAUDE/config.toml 漂移、
/health消耗 token、AI coding 腐化 →/health;用户代码抛异常 →/hunt; - 发布动作 vs 发布文案:写 release notes/changelog →
/write;提交、打 tag、publish、push、补 release reactions、回复/关闭 issue →/check; - 截图审美 vs 截图回归:说"丑/不好看/不清晰"且是审美校准 →
/ui;截图证明以前好的现在坏了、渲染错、状态错、生成物错 →/hunt; - 从零成稿 vs 润色:从零到成稿 →
/learn;已有稿子要改 →/write; - 判断 vs 调试:报错/异常/不工作 →
/hunt;"有没有必要/该不该保留/值不值得" →/think的 Evaluation Mode; - 质量改善 vs 调试:有可审 diff、要改善质量且无报错 →
/check;有具体报错或回归 →/hunt; - 需求包 vs issue 队列:对象是未实施的一批诉求/截图(判断接受与否)→
/thinkTriage Mode;对象是仓库里已存在的 issue/PR(处置、回复、关闭)→/checkTriage Mode; - 兜底:两者都模糊时读两个 SKILL.md 的 "Not for" 段用排除法;仍模糊就问用户。
这些规则的共同特征是把"表面相似的请求"拆成可判断的维度(有没有错误现象、是动作还是文案、是审美还是回归、是从零还是改稿),每一维都有明确的归属。verify_skills.py里还有一道自动化防线check_trigger_overlap:当两个技能的when_to_use关键词集合 Jaccard 相似度 ≥ 0.5 时直接失败——从源头阻止触发词大面积重叠,把人工消解的工作量压到最低。
技能串联:路由之后的编排纪律
路由决定"用哪个技能",而 skills/RESOLVER.md 的 Chaining 一节决定了"多个技能如何接力"。核心原则是:技能边界用于分工,不缩小用户已授权的任务——单项请求不自动扩大;同一请求明确包含多个技能的工作时,按对应技能继续完成、共用完成清单,不在内部交接点再次索要授权;但提交、发布等动作仍需其对应授权。
最常见的四条工作流(与 scripts/dispatcher.md 的 Chaining 一节完全一致):
- 规划功能:
/think出方案 → 用户说"实现" → 实施 → 用户说/check→ 把关合并; - 修复发布:
/hunt定位根因 → 用户说"修" → 修复 → 用户说/check→ 发布前检查与收尾(push / 关闭 issue); - 研究与写作:
/read(取回多篇 URL)→ 用户说/learn(综合成文)→ 用户说/write(去 AI 味); - 调试与验证:
/hunt(定位根因)→ 修复 →/check(确认无副作用);/health发现配置问题 → 修复 → 再跑一次/health复验。
每个技能只在自己的"请求结果"处停止:/think交付决策完备的计划,/hunt交付根因句 + 验证结果,接力必须由用户显式授权触发,而不是技能自行推断后续动作。
把路由规则安装进你的 Agent
rules/waza-routing.md有两个落地形态:
形态一:随技能安装(八技能之一)。通过 README 中的安装命令npx skills add tw93/Waza -a claude-code codex cursor -g -y安装后,八大技能以/check、/think等斜杠命令形式出现;宿主插件形态(/plugin marketplace add tw93/Waza)则按命名空间waza:check调用。
形态二:作为常驻规则安装(可选)。路由提示需要写进 Agent 的持久指令才生效,由 scripts/setup-rule.sh 完成:
bash "$WAZA_RULE_SCRIPT" waza-routing claude-codesetup-rule.sh的第二个参数支持三个目标,落点各不相同:
| 目标 | 落点 | 形式 |
|---|---|---|
claude-code | ~/.claude/rules/waza-routing.md | 独立规则文件 |
codex | ~/.codex/AGENTS.md | 标记块(<!-- Waza Routing: start -->…<!-- Waza Routing: end -->) |
antigravity-cli | ~/.gemini/antigravity-cli/rules/waza-routing.md | 独立规则文件 |
从源码看,这个安装器有几个值得注意的工程细节:
- 标记块幂等:Codex 目标用
<!-- Waza Routing: start -->/<!-- Waza Routing: end -->包裹内容,重复运行会替换旧块而不是叠加;MARKER_LABEL对waza-routing有显式覆盖为Routing,避免生成"Waza Waza Routing"这种重复标记; - 原子下载:先下载到临时文件,完整后才
mv覆盖,中途失败(含 Ctrl-C / kill)绝不触碰已安装的规则;下载失败时明确提示"Existing Waza files were left untouched"; - 版本钉扎:
WAZA_REF默认钉在发布标签(如v3.39.0),可用WAZA_REF=main切换到主线脚本,且会校验格式必须是main或vX.Y.Z。
这个安装行为有专门的集成测试覆盖:tests/test_routing-installer.sh 用桩 curl 验证了三条路径——Claude Code 目标把规则落进~/.claude/rules/waza-routing.md、Codex 目标用标记注入且重复执行后<!-- Waza Routing: start -->仍只有一处(幂等性断言)、内容正确写入AGENTS.md。
卸载时,按 README 删除对应规则文件即可:rm -f ~/.claude/rules/waza-routing.md,Codex 则移除~/.codex/AGENTS.md中的 Waza 标记块,删除后需开启新会话生效。
从源码结构看路由体系的设计取向
综合 skills/RESOLVER.md 的 Latent vs Deterministic 一节与上述校验脚本,可以提炼出 Waza 路由设计的两个取向:
路由判断是"fat skill"而非硬编码:触发词匹配、场景判断、追问用户都属于需要模型语义理解的"潜变量"(latent),因此放在 Markdown 技能文档与路由表中人工调优;而同入同出、纯校验列举的约束(如"引号短语必须接地""路由表必须与技能集对齐")则下沉为脚本与规则(
verify_skills.py、checks_routing.py、rules/*.md),用确定性代码兜底。新加能力时的决策问题是:需要判断/适应场景/追问用户 → 做成 skill;只是校验和列举 → 做成 script 或 rule。"不要把 lint 检查写成 skill,也不要把'怎么研究一个陌生领域'塞进脚本。"路由表是被"防漂移机制"保护的可信文档:
rules/waza-routing.md浓缩版、skills/RESOLVER.md完整版、scripts/dispatcher.md自动生成版三份路由索引,各自通过check_waza_routing_skills、check_waza_routing_triggers、check_resolver、check_routing_drift.py四道校验互锁;插件分发形态下plugins/waza/rules/waza-routing.md是build_metadata.py从根目录规则生成的镜像,同样纳入校验范围。这种"文档即代码、变更必验证"的做法,正是 Waza 想通过rules/waza-routing.md示范的工程习惯——连 Agent 技能的路由规则本身,也要像生产代码一样接受漂移检测。
小结
rules/waza-routing.md虽是一张 8 行的表格,背后却是一套完整的技能路由工程:frontmatter 元数据定义触发能力、引号短语接地校验保证路由表不撒谎、结构漂移检查保证三份路由索引与技能集锁步、11 条消解规则处理重叠、串联纪律约束接力授权,最后通过setup-rule.sh以幂等、原子的方式落地到你的 Agent 常驻指令中。无论是为 Waza 扩展新技能,还是在自己的 Agent 项目里建立类似的路由体系,这张表与其配套校验脚本都值得直接借鉴。
【免费下载链接】Waza
🥷 Engineering habits you already know, turned into skills Claude can run.
相关推荐
Waza Skill Resolver 路由机制全解析:触发词路由表、歧义消解与技能串联实战指南
Waza Skill Resolver 路由机制全解析:触发词路由表、歧义消解与技能串联实战指南 Waza 是一个把工程师日常习惯沉淀为 Claude 可运行技
Waza 技能路由指南:八项工程技能的正确分发、歧义消解与串联执行
Waza 技能路由指南:八项工程技能的正确分发、歧义消解与串联执行 Waza 是一套把开发者早已熟悉的工程习惯固化为 Claude 等 Agent 可运行技能(
ANTLR4 C 语法中 `type_` 规则的语义谓词消歧:从符号表到解析树的完整实战解析
ANTLR4 C 语法中 type_ 规则的语义谓词消歧:从符号表到解析树的完整实战解析 本篇文章以 grammars v4 仓库中 C v8 语法( csha
编程语言编译器开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考