技能系统设计:SKILL.md 结构、关键词检测与意图门控
技能系统设计:SKILL.md 结构、关键词检测与意图门控
学习目标
- 理解 OMX 如何通过 SKILL.md 文件定义可复用工作流
- 掌握关键词检测引擎的四层流水线
- 了解意图门控防止危险技能误触发的实现
- 理解任务规模过滤器和 Ralplan 门控的防御性设计
前置知识
本章涉及技能系统设计的通用原理,建议先阅读:
下文假设你已理解上述概念,直接聚焦 Oh-My-Codex 的具体实现。
项目实践
SKILL.md 结构
OMX 的每个技能都是一个目录,至少包含一个 SKILL.md 文件:
skills/├── deep-interview/│ └── SKILL.md├── ralplan/│ └── SKILL.md├── ultragoal/│ └── SKILL.md├── ralph/│ └── SKILL.md├── team/│ └── SKILL.md├── autopilot/│ └── SKILL.md├── prometheus-strict/│ ├── SKILL.md│ └── README.md└── ... (共 46 个技能)SKILL.md 的前置元数据(YAML frontmatter):
---name: deep-interviewdescription: 通过面试式提问澄清需求、边界和非目标triggers: ["$deep-interview", "interview me", "don't assume"]argument-hint: "describe the change or problem"---正文使用标准化的章节结构:Purpose、Use_When、Do_Not_Use_When、Steps、Tool_Usage、Examples。
技能分类
OMX 的 46 个技能分为以下类别:
| 类别 | 数量 | 典型技能 |
|---|---|---|
| 核心执行工作流 | 9 | autopilot、ralph、ultragoal、team、pipeline |
| 规划/面试 | 4 | deep-interview、ralplan、prometheus-strict、best-practice-research |
| 分析/审查 | 5 | analyze、code-review、security-review、visual-verdict |
| 设计/视觉 | 3 | design、frontend-ui-ux、visual-ralph |
| 实用工具 | 10 | cancel、note、doctor、trace、hud、wiki |
| 领域特定 | 6 | git-master、build-fix、tdd、deepsearch |
| 询问/沟通 | 3 | ask、ask-claude、ask-gemini |
| 协调 | 2 | worker、ralph-init |
关键词检测引擎的具体实现
OMX 的关键词检测引擎(src/hooks/keyword-detector.ts,~1800 行)运行在 Codex 的 UserPromptSubmit Hook 中。
四层检测流水线:
关键词注册表(src/hooks/keyword-registry.ts):
伪代码:const KEYWORD_TRIGGER_DEFINITIONS = [ { keywords: ["$autopilot", "autopilot", "build me"], skill: "autopilot", priority: 10 }, { keywords: ["$ralph", "don't stop", "keep going"], skill: "ralph", priority: 9 }, { keywords: ["$deep-interview", "interview me", "don't assume", "ouroboros"], skill: "deep-interview", priority: 8 }, { keywords: ["$cancel", "stop", "abort"], skill: "cancel", priority: 5 }, // ... 更多定义]意图门控的危险关键词列表:
伪代码:KEYWORDS_REQUIRING_INTENT = [ "ralph", "team", "stop", "abort", "parallel", "autoresearch", "ultragoal", "autopilot"]这些关键词即使用户在输入中提到,也需要显式的调用上下文(如 $ralph、use ralph、ralph mode)才能触发。
技能激活与状态持久化
关键词匹配后,recordSkillActivation() 执行:
伪代码:function recordSkillActivation(skill, prompt, sessionId): // 1. 持久化技能激活状态 state = read(".omx/state/skill-active-state.json") state.activeSkill = skill state.activatedAt = now() write(state)
// 2. 初始化技能模式状态 if skill == "autopilot": write(".omx/state/autopilot-state.json", { phase: "deep-interview", iteration: 0 }) if skill == "deep-interview": write(".omx/state/deep-interview-state.json", { inputLocked: true })
// 3. 管理深度面试的输入锁(防止 "yes"/"ok" 等自动通过) if skill == "deep-interview": setInterviewInputLock(sessionId, true)任务规模过滤器
伪代码(src/hooks/task-size-detector.ts):function classifyTaskSize(text): wordCount = countWords(text)
hasSmallSignals = text.contains([ "typo", "spelling", "rename", "one-liner", "single file", "minor fix" ]) hasLargeSignals = text.contains([ "architecture", "refactor", "redesign", "cross-cutting", "migration", "full-stack" ])
if wordCount < 50 && hasSmallSignals: return "small" if wordCount > 200 || hasLargeSignals: return "large" return "medium"小型任务会抑制重型模式(ralph、autopilot、team、ultrawork、ultragoal、swarm、ralplan)的触发。逃生舱前缀:quick:、simple:、tiny:、minor:、small:、just:、only:。
Ralplan 门控
伪代码(keyword-detector.ts 中的 applyRalplanGate):function applyRalplanGate(keyword, text): if keyword not in ["ralph", "autopilot", "team", "ultrawork"]: return keyword
effectiveWords = countEffectiveWords(text) hasFileRefs = regexMatchFilePatterns(text) hasCodeBlocks = text.contains("```") hasStructured = regexMatchStructuredPatterns(text)
if effectiveWords < 15 && !hasFileRefs && !hasCodeBlocks && !hasStructured: return "ralplan" // 输入太模糊,先规划
return keywordPrompt 引导合约(不变量验证)
OMX 维护一套 Prompt 引导合约(src/hooks/prompt-guidance-contract.ts),验证模板文件中的关键模式是否存在:
伪代码:const ROOT_TEMPLATE_CONTRACTS = [ { file: "templates/AGENTS.md", patterns: [ /outcome.first framing/i, /auto-continue rule/i, /permission handoff/i, /role routing guidance/i ] }]
const SKILL_CONTRACTS = [ { file: "skills/ultraqa/SKILL.md", patterns: [ /adversarial e2e/i, /scenario matrix/i, /hostile user modeling/i, /prompt injection testing/i ]}]这确保重构提示词时不会遗漏关键指令。
问题与规避
| 问题 | 后果 | OMX 的规避策略 |
|---|---|---|
| 危险技能误触发 | 意外执行破坏性操作 | 意图门控要求显式调用上下文 |
| 小任务触发重型编排 | 资源浪费、延迟高 | 任务规模过滤器 + 逃生舱前缀 |
| 模糊输入直接执行 | 产出方向错误 | Ralplan 门控自动重定向到规划 |
| 提示词重构遗漏关键指令 | Agent 行为异常 | Prompt 引导合约验证 |
| 过期技能残留 | 旧工作流被误触发 | omx setup 清理 deprecated 技能 |
设计取舍
为什么选择关键词检测而非纯 Agent 判断?
OMX 选择了基于关键词的显式路由,而非让 Agent 自主判断使用哪个技能。
优势:
- 确定性:匹配结果是确定的,不受模型输出波动影响
- 低延迟:关键词匹配比额外一轮 Agent 推理快得多
- 用户可控:用户通过
$skill语法精确控制触发哪个技能
代价:
- 用户需要学习技能名称和触发短语
- 关键词注册表需要维护,避免膨胀和冲突
替代方案:
- 纯 Agent 判断:让 Agent 根据输入自主选择技能(更灵活但不可控)
- 混合模式:关键词优先,无匹配时 Agent 自主判断(OMX 的 triage heuristic 就是这种模式)
参考来源
- Oh-My-Codex v0.18.9 源码 —
src/hooks/keyword-detector.ts(检测引擎) - Oh-My-Codex v0.18.9 源码 —
src/hooks/keyword-registry.ts(关键词注册表) - Oh-My-Codex v0.18.9 源码 —
src/hooks/task-size-detector.ts(任务规模分类) - Oh-My-Codex v0.18.9 源码 —
src/hooks/prompt-guidance-contract.ts(引导合约验证) - Oh-My-Codex v0.18.9 源码 —
skills/目录(46 个 SKILL.md 文件)