- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
本指南围绕 semantic-router 的 keyword-based routing 展开,讲解如何通过显式 keyword rule 与 regex 模式将请求路由到不同模型与决策路径。该能力适用于合规、安全与可解释 AI 场景——例如金融、医疗、政务等对审计追溯有硬性要求的系统,可据此在亚毫秒级延迟内实现完全确定性的路由决策。读完本文,你将掌握 signals/decisions 配置、AND/OR/NOR 运算符语义、regex/BM25/n-gram 三种匹配方法、置信度计算规则,以及如何通过响应头验证路由结果。
为什么需要关键词路由:ML 黑箱之外的确定路径
基于 ML 的 classification 通常是难以审计和解释的黑箱:模型为什么把这条查询路由到某个 category,外部审计人员无法从模型权重中获得答案。Keyword routing 提供了另一条路线:
- 可解释的 decision:确切知道为什么一个查询被路由到特定 category(因为命中了哪几个关键词);
- 监管 compliance:审计人员可以逐条验证路由逻辑是否符合 GDPR、HIPAA、SOC2 等要求;
- 确定性行为:相同的 input 始终产生相同的 output,无随机性;
- 零 latency:无需 model 推理,瞬时完成 classification;
- 精确控制:针对 security、compliance 和业务逻辑编写显式 rule。
从源码结构看,这一能力由 keyword_classifier.go 中的KeywordClassifier实现:每个配置的规则使用 regex(默认)、BM25 或 n-gram 匹配,并按配置顺序依次评估。它不依赖任何 embedding 模型或 GPU,因此延迟与吞吐量都可预测。
何时使用 Keyword Routing
- 需要 audit trail 的受监管行业(金融、医疗、法律);
- 需要确定性 PII 检测的security/compliance场景;
- 亚毫秒级 latency 至关重要的高吞吐量系统;
- 具有清晰 keyword 指示的紧急/优先级路由;
- 匹配 regex 模式的结构化数据(email、ID、文件路径)。
配置:在 config.yaml 中定义 keyword signal 与 decision
在您的config.yaml中添加 keyword signal,并用它组合出 decision。以下为 v0.1 参考配置(主分支已不再保留旧的完整示例文件,可直接使用本页代码片段):
# 定义 keyword signal signals: keywords: - name: "urgent_keywords" operator: "OR" # 匹配任意关键词 keywords: ["urgent", "immediate", "asap", "emergency", "紧急"] case_sensitive: false - name: "sensitive_data_keywords" operator: "OR" keywords: ["SSN", "social security", "credit card", "password", "身份证"] case_sensitive: false - name: "spam_keywords" operator: "OR" keywords: ["buy now", "free money", "click here", "免费领取"] case_sensitive: false # 使用 keyword signal 定义 decision decisions: - name: urgent_request description: "路由紧急请求" priority: 100 # 高优先级 rules: operator: "OR" conditions: - type: "keyword" name: "urgent_keywords" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: false plugins: - type: "system_prompt" configuration: system_prompt: "你是一位响应迅速的助手,专门处理紧急请求。" - name: sensitive_data description: "路由敏感数据查询" priority: 90 rules: operator: "OR" conditions: - type: "keyword" name: "sensitive_data_keywords" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: false plugins: - type: "system_prompt" configuration: system_prompt: "你是一位具有安全意识的助手,专门处理敏感数据。" - name: filter_spam description: "拦截垃圾查询" priority: 95 rules: operator: "OR" conditions: - type: "keyword" name: "spam_keywords" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: false plugins: - type: "system_prompt" configuration: system_prompt: "此查询似乎是垃圾信息。请提供礼貌的回复。"配置项的完整字段说明
从 signal_config.go 中的KeywordRule结构体可以确认 keyword rule 支持的全部字段:
| 字段 | 类型 | 含义 | 默认值 |
|---|---|---|---|
name | string | 规则唯一标识,同时用作匹配到的 category 名 | 必填 |
operator | string | 逻辑运算符AND/OR/NOR | 必填 |
keywords | string[] | 待匹配的关键词列表 | 必填 |
case_sensitive | bool | 是否大小写敏感 | false |
method | string | 匹配方法:regex(默认)/bm25/ngram | regex |
fuzzy_match | bool | 是否启用近似匹配(Levenshtein 编辑距离) | false |
fuzzy_threshold | int | 近似匹配允许的最大编辑距离 | 2 |
bm25_threshold | float32 | BM25 方法命中阈值 | 0.1 |
ngram_threshold | float32 | n-gram 方法命中阈值 | 0.4 |
ngram_arity | int | n-gram 的 n 值 | 3 |
其中case_sensitive在 types_route.go 的 CRD 定义(KeywordSignal)中默认值为false;decision 的priority取值范围为 0~1000,默认 0,数值越高优先级越高。需要说明的是,CRD 层面的KeywordSignal.Operator枚举目前为AND;OR,而路由内部实现的KeywordClassifier与 lexical 层同时支持NOR(见下文运算符小节)。
method为regex时,关键词会被regexp.QuoteMeta转义后作为字面量匹配;为bm25或ngram时,则会走 lexical/rule.go 与 lexical/bm25.go、lexical/ngram.go 中的打分逻辑。仓库自带的两个 fragment 文件给出了这三种方法的现成示例:
- config/fragments/signal/keyword/regex.yaml:
urgent_keywords、sensitive_data_keywords两个 OR 规则,均为默认 regex 方法; - config/fragments/signal/keyword/nlp.yaml:
code_keywords使用method: bm25与bm25_threshold: 0.1,urgent_keywords使用method: ngram、ngram_threshold: 0.4、ngram_arity: 3。
decision 还支持把 keyword signal 与其它类型 signal 组合。例如 config/fragments/decision/and/urgent-business.yaml 演示了operator: AND下同时要求domain: business与keyword: urgent_keywords两个条件同时成立才算命中:
routing: decisions: - name: urgent_business_route description: Match only when business intent and urgent language appear together. priority: 140 rules: operator: AND conditions: - type: domain name: business - type: keyword name: urgent_keywords modelRefs: - model: qwen2.5:3b use_reasoning: false运算符语义:OR / AND / NOR
- OR:如果找到任意一个 keyword 则匹配;
- AND:仅当找到所有keyword 时才匹配;
- NOR:仅当未找到任何keyword 时才匹配(排除)。
这三个运算符在 lexical 层的Rule.decide中严格实现(lexical/rule.go):
case "OR": matched = len(keywords) > 0 case "AND": matched = len(keywords) == len(r.Keywords) case "NOR": return Match{TotalKeywords: len(r.Keywords)}, len(keywords) == 0其中 AND 要求所有关键词都命中(命中数等于规则关键词总数),NOR 在没有任何关键词命中时匹配,因此Match.Keywords为空——日志中会以 "matched rule with a NOR rule" 的形式记录(见 keyword_classifier_dispatch.go 的logRuleMatch)。同时KeywordClassifier构造时会校验 operator,不支持的运算符(如"unsupported keyword rule operator")会直接返回错误,避免配置静默失效。
值得注意的是,keyword 规则按配置文件中定义的顺序依次评估,采用 first-match 语义:ClassifyWithKeywordsAndCount遇到第一个命中的规则即返回,因此urgent_request(priority 100)与filter_spam(priority 95)同时命中时会先落入配置更靠前的规则;若需要多信号组合参与 decision 的 AND/OR/NOT 表达式,则使用MatchAll评估全部规则(源码注释对此有明确说明)。
三种匹配方法:regex / BM25 / n-gram
KeywordClassifier通过method字段选择引擎(keyword_classifier.go):
- regex(默认):每个关键词预编译为正则表达式。字面量关键词经
QuoteMeta转义后再编译,避免特殊字符被误解析为正则语法;显式编写 regex 模式的关键词则原样编译(keyword_classifier_regex.go 中的regexPatterns)。对于含字母、数字或下划线的字面量关键词,还会施加相邻字符边界检查(LiteralBoundaries),防止 "urgent" 误匹配 "not-urgent" 之类的子串;连续 CJK 文本则保留子串匹配语义,这也解释了配置中紧急、免费领取等中文关键词无需额外转义。 - bm25:基于 BM25 打分,命中阈值由
bm25_threshold控制(默认 0.1),适合对关键词做了轻微改写、仍保有一定词法相关度的文本。 - ngram:基于 n-gram 打分(默认 arity=3、阈值 0.4),通过字符级重叠容忍拼写差异,适合处理带噪音的短文本。
从源码注释可知,lexical 包是纯 Go 实现,等价替代了此前 nlp-binding 提供的 bm25 2.3.2 与 ngrammatic 0.7.0 两个 Rust crate 的行为——同样的分词器、同样的 float32 打分运算、同样的 AND/OR/NOR 语义,因此历史配置中的阈值含义保持一致。
另外,regex 方法还支持fuzzy_match近似匹配:启用后基于 Levenshtein 编辑距离进行容错(默认fuzzy_threshold=2),并预计算关键词的小写形式用于比较。
置信度:由命中比例动态计算
Keyword 路由虽然是确定性匹配,但依然会输出一个 0~1 的置信度,供上层决策与可观测性使用。核心公式位于 keyword_classifier.go 的Classify:
ratio := float64(matchCount) / float64(totalKeywords) confidence := 0.5 + (ratio * 0.5)即:命中 1/4 个关键词时置信度为 0.625,2/4 为 0.75,3/4 为 0.875,全部命中为 1.0。这与 E2E 测试数据 e2e/testcases/testdata/keyword_routing_cases.json 中记录的期望值完全吻合:
| 用例 | 查询 | 期望 category | 期望置信度 |
|---|---|---|---|
| OR 命中 1 个关键词(1/4) | "I need urgent help with my account" | urgent_request | 0.625 |
| OR 命中 2 个关键词(2/4) | "This urgent emergency needs your help now" | urgent_request | 0.75 |
| OR 命中 3 个关键词(3/4) | "This is urgent and needs immediate response asap" | urgent_request | 0.875 |
| OR 命中全部 4 个关键词(4/4) | "This urgent emergency requires immediate attention asap please" | urgent_request | 1.0 |
| AND 两个关键词都命中(2/2) | "My SSN and credit card info were stolen" | sensitive_data | 1.0 |
| REGEX 命中 email 模式(1/2) | "Please send the report to user.name@domain.com today" | regex_pattern_match | 0.75 |
| 大小写不敏感(URGENT / Emergency) | "This is URGENT please help" | urgent_request | 0.625 |
同时,在信号求值层(classifier_signal_rule_evaluators.go 的evaluateKeywordSignal),keyword 信号作为基于规则的信号其置信度固定记录为 1.0(results.Metrics.Keyword.Confidence = 1.0),并输出匹配的规则名与关键词列表,供 decision 组合引擎消费。
请求示例与结果可观测性
# 紧急请求(匹配 "urgent") curl -X POST http://localhost:8801/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "MoM", "messages": [{"role": "user", "content": "I need urgent help with my account"}] }' # 敏感数据(匹配所有关键词) curl -X POST http://localhost:8801/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "MoM", "messages": [{"role": "user", "content": "My SSN and credit card were stolen"}] }'路由结果通过响应头对外暴露,便于调试与审计。E2E 测试 keyword_routing.go 直接读取以下头部进行断言:
x-vsr-selected-decision/x-vsr-selected-category:命中的 decision / category 名称;x-vsr-matched-keywords:实际匹配到的关键词列表(逗号分隔),其常量定义在 headers.go 中(VSRMatchedKeywords = "x-vsr-matched-keywords");x-vsr-selected-confidence:本次路由的置信度。
该 E2E 用例将查询发送到本地服务(测试中使用的模型名为vllm-sr/auto),随后校验 category、关键词列表(顺序无关地比较)与置信度三项是否全部符合预期,并以accuracy_rate、keyword_accuracy汇总上报——这正是本文配置在真实集群环境下可被自动验证的落点。在开发与调试阶段,这些响应头可以让运维人员直接看到"这条请求因为命中了哪些关键词而被路由到哪个决策",与 keyword routing 的可解释目标完全一致。
真实世界用例
1. 金融服务(透明合规)
问题:监管机构要求为 audit trail 提供可解释的路由 decision。解决方案:Keyword rule 为每个路由 decision 提供清晰的 "原因"(例如,"SSN" keyword → 安全处理器)。影响:通过了 SOC2 审计,实现了 decision 的完全透明。
2. 医疗平台(合规的 PII 检测)
问题:HIPAA 要求确定性的、可审计的 PII 检测。解决方案:AND operator 通过记录的 rule 检测多个 PII 指示符。影响:100% 确定性,提供符合 compliance 要求的完整 audit trail。
3. 高频交易(亚毫秒级路由)
问题:实时市场数据路由需要 <1ms 的 classification latency。解决方案:Keyword matching 提供即时 classification,无 ML 开销。影响:0.1ms latency,可处理 100K+ 次请求/秒。
4. 政府服务(可解释的规则)
问题:公民需要了解为什么请求被路由或拒绝。解决方案:清晰的 keyword rule 可以用通俗易懂的语言进行解释。影响:减少了投诉,实现了 decision 制定的透明化。
5. 企业安全(透明的威胁检测)
问题:Security team 需要了解为什么查询被 flag。解决方案:针对威胁模式使用显式的 keyword/regex rule,并附带清晰的文档。影响:Security team 可以自信地验证和更新 rule。
性能优势
- 亚毫秒级 latency:无 ML 推理开销;
- 高吞吐量:单核可处理 100K+ 次请求/秒;
- 成本可预测:无需 GPU 或 embedding model;
- 零冷启动:第一个请求即可实现即时 classification。
从实现角度,这些优势来源于两点:其一,regex 关键词在配置加载阶段即完成预编译(preppedKeywordRule持有CompiledRegexpsCS/CompiledRegexpsCI),运行时只做匹配不做编译;其二,lexical 层对同一文本的 token 化与 n-gram 计算按文本与 arity 缓存(lexical/rule.go 中的Text结构),一个请求即使被多个规则检查也只分词一次,进一步压低了单请求 CPU 成本。
参考与版本说明
- 本文配置片段可直接作为v0.1参考配置使用;主分支已经不再保留旧的完整示例文件。
- 若需进一步验证路由行为,可运行 e2e/testcases/keyword_routing.go 对应的
keyword-routingE2E 用例(测试数据见 e2e/testcases/testdata/keyword_routing_cases.json),或参考单元测试 keyword_accuracy_test.go 中覆盖的 jailbreak、creative、deep thinking 等真实场景规则。 - 生产环境建议将 keyword 路由与 embedding 等语义信号结合使用:确定性规则负责合规边界与硬性拦截,语义信号负责模糊意图识别,两者通过 decision 组合(AND/OR)互补。
- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
相关推荐
semantic-router 关键词路由(Keyword Routing)实战指南:用显式规则实现可解释、可审计、亚毫秒级的智能路由
semantic router 关键词路由(Keyword Routing)实战指南:用显式规则实现可解释、可审计、亚毫秒级的智能路由 本指南基于 semant
后端API网关模型推理服务AI Agentsemantic-router Keyword Signal 完全指南:用关键词规则构建确定性的低延迟路由
semantic router Keyword Signal 完全指南:用关键词规则构建确定性的低延迟路由 导读 Keyword Signal 是 semant
后端API网关模型推理服务AI Agentsemantic-router 关键词信号(keyword signal):从 YAML 配置到 BM25、n-gram 与正则匹配的实现详解
semantic router 关键词信号(keyword signal):从 YAML 配置到 BM25、n gram 与正则匹配的实现详解 本文基于 sem
后端API网关模型推理服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考