☰
semantic-router Keyword Routing 实战指南:用显式关键词与正则规则构建可审计的确定性路由
2026/10/13 1:58:18 网站建设 项目流程
  • 后端
  • API网关
  • 模型推理服务
  • AI Agent

【免费下载链接】semantic-router

An open, programmable decision layer for models and compute.

项目地址:https://gitcode.com/gh_mirrors/sem/semantic-router
点击查看免费下载

本指南围绕 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 支持的全部字段:

字段类型含义默认值
namestring规则唯一标识,同时用作匹配到的 category 名必填
operatorstring逻辑运算符AND/OR/NOR必填
keywordsstring[]待匹配的关键词列表必填
case_sensitivebool是否大小写敏感false
methodstring匹配方法:regex(默认)/bm25/ngramregex
fuzzy_matchbool是否启用近似匹配(Levenshtein 编辑距离)false
fuzzy_thresholdint近似匹配允许的最大编辑距离2
bm25_thresholdfloat32BM25 方法命中阈值0.1
ngram_thresholdfloat32n-gram 方法命中阈值0.4
ngram_arityintn-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_request0.625
OR 命中 2 个关键词(2/4)"This urgent emergency needs your help now"urgent_request0.75
OR 命中 3 个关键词(3/4)"This is urgent and needs immediate response asap"urgent_request0.875
OR 命中全部 4 个关键词(4/4)"This urgent emergency requires immediate attention asap please"urgent_request1.0
AND 两个关键词都命中(2/2)"My SSN and credit card info were stolen"sensitive_data1.0
REGEX 命中 email 模式(1/2)"Please send the report to user.name@domain.com today"regex_pattern_match0.75
大小写不敏感(URGENT / Emergency)"This is URGENT please help"urgent_request0.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.

项目地址:https://gitcode.com/gh_mirrors/sem/semantic-router
点击查看免费下载

相关推荐

上一篇:告别重复废话:BullshitGenerator语料库清洗完全指南
下一篇:React Native Geolocation常见问题与解决方案:从入门到精通

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询