关键词检测引擎与意图门控:技能激活的安全模式
关键词检测引擎与意图门控:技能激活的安全模式
学习目标
读完本章后,你将能够:
- 设计多层次的关键词检测引擎(显式解析 → 意图门控 → 隐式匹配 → 延续检测)
- 实现意图门控防止危险技能被意外触发
- 构建任务规模过滤器防止重型编排器被小任务误触发
- 设计启发式三路分类器实现无关键词时的自动路由
前置知识
核心概念
1. 为什么需要关键词检测引擎
在 Agent 系统中,技能(Skill)是预定义的工作流模板。问题在于:何时触发哪个技能?
有两种基本策略:
| 策略 | 优点 | 缺点 |
|---|---|---|
用户显式调用(如 $skill) | 意图明确,不误触 | 用户需要记住所有技能名 |
| Agent 自动判断 | 用户无需学习 | Agent 可能误判或忽略重要技能 |
关键词检测引擎结合两者优势:显式 $skill 语法保证精确调用,关键词匹配降低学习成本,意图门控防止误触发。
2. 多层次检测流水线
第一层:显式 $skill 解析
从左到右扫描输入中的 $token,识别连续的 $skill 调用链:
伪代码:function parseExplicitSkills(text): tokens = [] for word in tokenize(text): if word.startsWith("$"): normalized = normalizeAlias(word) // "ulw" → "ultrawork" tokens.push(normalized) return tokens别名规范化:常用技能有缩写别名(如 ulw → ultrawork),解析时统一规范化为规范名。
第二层:意图门控(Intent Gating)
对于危险技能(如 $ralph、$team、$stop),即使用户提到了关键词,也需要显式调用上下文才能触发:
伪代码:INTENT_KEYWORDS = ["ralph", "team", "stop", "abort", "parallel", "autoresearch", "ultragoal", "autopilot"]
function checkIntentGate(keyword, text): if keyword not in INTENT_KEYWORDS: return true // 普通关键词,直接通过
// 危险关键词需要显式上下文 return hasExplicitInvocation(text, keyword)
function hasExplicitInvocation(text, keyword): // 匹配: "$keyword", "/prompts:keyword", "use keyword", // "keyword mode", "enter keyword" patterns = [ /\$\w*{keyword}/, /\/prompts:{keyword}/, /use {keyword}/, /{keyword} mode/, /enter {keyword}/ ] return patterns.any(p => p.test(text))意图门控的效果:
| 用户输入 | 关键词 | 意图门控 | 结果 |
|---|---|---|---|
$ralph fix the bug | ralph | ✅ 显式 $ 前缀 | 触发 ralph |
I don't want ralph mode | ralph | ❌ 否定上下文 | 不触发 |
let's use ralph for this | ralph | ✅ “use ralph” 模式 | 触发 ralph |
the ralph project mentioned in docs | ralph | ❌ 引用上下文 | 不触发 |
第三层:隐式模式匹配
当没有显式 $skill 时,回退到正则表达式模式匹配:
伪代码:function matchImplicitKeywords(text): for trigger in KEYWORD_REGISTRY: if trigger.regex.test(text): return trigger.skill return null关键词注册表(KEYWORD_TRIGGER_DEFINITIONS)定义了每个关键词/触发短语的映射:
伪代码:[ { keywords: ["$ralph", "don't stop", "keep going"], skill: "ralph", priority: 9 }, { keywords: ["$autopilot", "autopilot", "build me"], skill: "autopilot", priority: 10 }, { keywords: ["$deep-interview", "interview me", "don't assume"], skill: "deep-interview", priority: 8 }, { keywords: ["$cancel", "stop", "abort"], skill: "cancel", priority: 5 },]优先级用于解决多个关键词同时命中的冲突,优先级高的胜出。
第四层:延续检测
当用户输入既不匹配显式也不匹配隐式关键词时,检测是否为”继续”意图:
伪代码:CONTINUATION_PHRASES = ["keep going", "continue", "resume", "go on", "next"]
function checkContinuation(text, previousSkill): if CONTINUATION_PHRASES.any(p => text.includes(p)): if previousSkill && isContinuationAllowed(previousSkill): return previousSkill return null3. 任务规模过滤器
即使关键词匹配,对于小型任务也不应该触发重型编排器:
伪代码:function applyTaskSizeFilter(keyword, text): size = classifyTaskSize(text)
if size == "small" and keyword in HEAVY_MODES: return false // 小任务不触发重型模式
return true
HEAVY_MODES = ["ralph", "autopilot", "team", "ultrawork", "ultragoal", "swarm", "ralplan"]
function classifyTaskSize(text): wordCount = countWords(text) hasLargeSignals = text.contains(["architecture", "refactor", "migration", "full-stack"]) hasSmallSignals = text.contains(["typo", "spelling", "rename", "one-liner"])
if wordCount < 50 && hasSmallSignals: return "small" if wordCount > 200 || hasLargeSignals: return "large" return "medium"逃生舱前缀:用户可以通过 quick:、simple:、tiny:、minor:、small:、just:、only: 前缀显式声明任务为小型,强制绕过重型模式。
4. Ralplan 门控(规划优先门)
当检测到执行类关键词(ralph、autopilot、team、ultrawork),但用户的输入过于模糊时,自动重定向到规划阶段:
伪代码:function applyRalplanGate(keyword, text): if keyword not in EXECUTION_KEYWORDS: return keyword // 非执行关键词,不做门控
effectiveWords = countEffectiveWords(text) hasFileReferences = text.contains(filePatterns) hasCodeBlocks = text.contains("```") hasStructuredSignals = text.contains(listPatterns)
if effectiveWords < 15 && !hasFileReferences && !hasCodeBlocks && !hasStructuredSignals: return "ralplan" // 输入太模糊,先规划
return keyword
EXECUTION_KEYWORDS = ["ralph", "autopilot", "team", "ultrawork"]门控的边界条件:用户可以通过 force: 前缀或 ! 前缀强制跳过 Ralplan 门控。
5. 启发式三路分类器(Triage Heuristic)
当没有关键词匹配时,使用启发式分类器决定路由:
三 lane 分类规则:
| Lane | 条件 | 目的地 |
|---|---|---|
| PASS | 简单确认(“hi”、“thanks”)、显式退出(“just chat”)、模糊短提示 | 不使用技能 |
| LIGHT | 问题/解释 → explore;定位修改 → executor;视觉/样式 → designer;外部文档 → researcher | 单 Agent 技能 |
| HEAVY | 6+ 词的命令式输入(以 “implement”、“build”、“refactor” 开头) | autopilot |
状态抑制:当上一次的路由决策为 suppress_followup 时,对简短的后续回复(“yes”、“no”、“the…”)抑制重新路由。
陷阱与对策
| 陷阱 | 后果 | 对策 |
|---|---|---|
| 意图门控过于严格 | 用户需要反复尝试才能触发技能 | 提供清晰的触发短语列表(如 /skills 命令) |
| 意图门控过于宽松 | 技能被意外触发 | 定期审计误触发率,调整意图模式 |
| 任务规模阈值不当 | 小任务被重型编排器处理 | 允许用户通过 quick: 前缀覆盖 |
| 延续检测误判 | 将无关的 “continue” 误判为技能延续 | 检查前一个技能的状态(是否可延续) |
| Ralplan 门控误杀 | 明确的执行请求被重定向到规划 | 提供 force: 和 ! 前缀逃生舱 |
| 关键词注册表膨胀 | 过多关键词导致匹配性能下降 | 按优先级分层,高优先级先匹配 |
参考来源
- OpenAI Codex CLI —
UserPromptSubmithook and keyword detection module - Intent classification patterns — NLP intent recognition best practices