☰
Semantic Router PII 信号实战指南:把个人数据检测变成可复用、可审计的路由输入
2026/10/14 18:13:57 网站建设 项目流程
  • 后端
  • API网关
  • 模型推理服务
  • AI Agent

【免费下载链接】semantic-router

An open, programmable decision layer for models and compute.

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

导读:本文围绕 Semantic Router 的pii信号族展开,讲解如何将请求中的敏感个人数据(PII)检测转换为标准化的路由输入,从而在流量到达后端模型与插件栈之前完成拦截、降级或隔离。读完本文,你将掌握routing.signals.pii规则配置、global.model_catalog.system.pii_classifier学习型分类器的完整参数体系,以及 fail-closed(失败闭合)等安全语义在源码中的实现原理,可直接在真实网关配置中落地隐私敏感路由策略。

概览:什么是 PII 信号

pii是 Semantic Router 内置的信号(signal)族之一,用于检测请求中携带的敏感个人数据(如电子邮件、电话号码、身份证号、住址等实体类型)。它在配置层面映射到config/fragments/signal/pii/,并统一声明在routing.signals.pii之下。

与基于关键词或启发式的简单过滤不同,该信号族属于学习型信号:它通过global.model_catalog.system.pii_classifier配置的 PII 检测路径完成实体识别。也就是说,检测能力来自一个专门训练的 PII 分类模型(默认为pii_classifier),而不是一堆写死的正则规则。这使得它能够泛化到未见过的表述方式,并输出结构化的实体类型、位置与置信度,供路由决策消费。

从默认配置可以看到,PII 分类器的默认阈值为0.01(极低,几乎任何置信度的检出都会命中),默认use_cpu: true,模型引用名为pii_classifier。

主要优势

根据 PII 信号文档 的阐述,pii信号为网关带来四点核心价值:

  • 隐私敏感路由显式化:是否携带敏感数据不再是散落在各插件里的隐式判断,而是routing.signals中一个可命名、可文档化、可观测的信号。
  • 决策前置:路由决策可以在流量到达后端之前完成,对含 PII 的请求执行拦截、降级(路由到更安全/更便宜的模型)或隔离(走独立插件栈),而无需后端先"看一眼"再拒绝。
  • 低风险标识允许列表:通过pii_types_allowed声明哪些实体类型是低风险的(例如仅允许EMAIL_ADDRESS),允许列表之外的任何检出都触发信号匹配。
  • 策略复用:隐私策略可以同时被路由规则与插件(如脱敏插件)引用,避免同一份策略在多处重复定义、漂移失配。

解决什么问题

没有专用 PII 信号时,隐私敏感流量可能在检测完成前就到达了错误的模型或插件栈——例如一个含身份证号的提示被送到无脱敏能力的通用模型;而临时的过滤脚本、散落的正则又让策略难以审计和演进。

pii把个人数据检测变成可复用的路由输入:一次检测结果可以同时驱动多个决策(模型选择、插件链、降级策略),并且作为信号参与信号级审计与回放,让"这个请求为什么被拦"有据可查。

何时使用 pii 信号

在以下场景应启用pii信号:

  • 提示可能包含受监管或敏感的个人数据(金融、医疗、法律等场景尤为典型);
  • 部分 PII 类型可以接受(如仅收集邮箱做订阅),而其他类型(如证件号)必须触发更安全的路由;
  • 隐私敏感流量需要走不同的插件或后端(例如先脱敏再转发,或路由到本地私有模型);
  • 路由策略依赖早期 PII 检测(在模型选择阶段就需要知道请求是否含隐私数据)。

配置指南:信号规则

源片段族位于config/fragments/signal/pii/,仓库自带的 strict.yaml 是开箱即用的严格模式示例:

routing: signals: pii: - name: restricted_pii threshold: 0.01 include_history: true pii_types_allowed: - EMAIL_ADDRESS description: Sensitive prompts where only low-risk identifiers may pass through.

而完整参考配置config/config.yaml中给出的规则与之对应,仅多了一个显式的source: ""字段:

pii: - name: restricted_pii source: "" threshold: 0.01 include_history: true pii_types_allowed: - EMAIL_ADDRESS description: Sensitive prompts where only low-risk identifiers may pass through.

规则参数说明

PIIRule结构体定义在 src/semantic-router/pkg/config/signal_config.go,各字段语义如下:

参数YAML 键类型含义与取值
namenamestring规则名,供路由决策引用、日志与回放标识
thresholdthresholdfloat32实体置信度阈值,检出实体置信度 ≥ 该值才计入命中;默认分类器阈值为0.01
pii_types_allowedpii_types_allowed[]string允许通过的实体类型白名单;为空时任意检出的 PII 都可能使信号匹配
include_historyinclude_historybool是否将对话历史一并纳入检测
sourcesourcestring检测内容来源,可选tool_result或省略(省略保留传统的用户输入/历史行为),见下文"tool_result 源"
descriptiondescriptionstring规则语义描述,供审计与文档生成

其中pii_types_allowed是决定信号是否命中的关键开关:findDeniedEntities会从检出实体集合中剔除白名单内的类型,只要存在白名单之外的"被拒绝实体"(denied entities),该规则即匹配,results.PIIDetected被置为 true,规则名被追加到MatchedPIIRules(见 classifier_signal_pii.go)。

source 字段与校验

source字段由 src/semantic-router/pkg/config/validator_pii.go 校验,合法值仅为tool_result或省略(空串)。该字段用于控制哪些请求内容进入共享缓存:tool_result表示检测工具调用返回的结果文本(按请求预算扫描),省略则保留传统的"用户提示 + 历史"行为。传入未知值会在配置校验阶段直接报错。

配置指南:PII 分类器(全局学习型路径)

PII 信号是学习型信号,规则本身不含检测逻辑,真正的实体识别能力来自全局分类器配置。完整示例见config/config.yaml的global.model_catalog.modules.classifier.pii:

pii: # Omit to keep the historical behaviour of running whenever a model is # configured; false disables the classifier outright. enabled: true model_ref: pii_classifier # Vela 2.0 0.3B finds spans with its router span head and reads the # whole text up to its scan budget, so it sets no window; a token # classifier such as Vela 1.0 PII takes a document budget (32768), # token windows (window: {size: 512, overlap: 255}) and its # pii_mapping.json. max_sequence_length: 0 use_cpu: true pii_mapping_path: "" # allow (default) keeps a classify error as a non-match for that # content; block treats it as a match on classification_error, so # unverified text cannot pass as clean. on_error: allow # block (default) matches content the model did not read in full # (over its input or cap, a provider-declared truncation, or not # scanned by the signal deadline) as unscanned, so a long request # routes as private; allow leaves such content to on_error. on_unscanned: block

PIIModel的底层结构定义在 src/semantic-router/pkg/config/model_config_types.go,参数要点:

  • enabled:显式开关;省略时保留历史行为(配置了模型即运行),false则彻底关闭分类器。
  • model_ref:指向模型目录中注册的 PII 模型,默认值为pii_classifier。
  • threshold:模型级置信度阈值(默认0.01),低于该置信度的检出不产生实体。
  • max_sequence_length/window:长文本处理预算。无window且值为 0 时,本地 Vela 模型按 32K 文档预算、512-token 前向滑窗扫描全文;也可以显式配置window: {size: 512, overlap: 255}进行分窗。
  • use_cpu:是否以 CPU 推理(默认 true,适合网关侧小模型)。
  • pii_mapping_path:实体标签映射文件(如pii_mapping.json),远程 token_spans 后端要求标签必须出现在该映射中。
  • on_error/on_unscanned:两个安全语义开关,见下文"失败闭合"。
  • backend:可选,挂载一个说token_spans.v1契约的远程分类器;缺省时保留本地 PII 推理行为(pii_remote_backend.go)。

model_ref与部署的绑定关系由global.model_catalog.bindings指定,例如 vela2-labels-spans.yaml 中:

bindings: pii_classifier: deployment: vela2 contract: token_spans.v1

这意味着 PII 信号与 decision 信号可以共用同一个部署实例(同一次调用内回答 PII 问题),节省推理开销。

远程后端与契约

按照config/README.md的说明,PII 后端挂载在global.model_catalog.modules.classifier.pii.backend,读取单一契约token_spans.v1(因此contract可以省略):远程模型以码点偏移(code-point offsets)返回实体 span,且其标签必须出现在配置的pii_mapping_path中。后端与本地选择器(use_mmbert_32k)互斥。远程返回不完整时(ErrTokenSpansTruncated),已返回的 span 仍计入检测,未被覆盖的剩余部分交给on_error决定是否阻断。

工作原理:从请求文本到路由决策

PII 信号的核心求值入口是 classifier_signal_pii.go 的evaluatePIISignal,整体流程可概括为:

  1. 收集内容:遍历所有 PII 规则,汇总每条规则选中的内容片段(用户提示、历史、可选 tool_result),以piiCacheKey{source, content}去重建立共享缓存——同一段字节只推理一次。
  2. 并发推理:通过modelservice.Fan对去重后的文本片段并发调用classifyPIITokens,得到 Token 级分类结果;工具结果内容受maxPIIToolResultInferenceCalls = 1024的请求级推理预算约束,超出后剩余内容标记为incomplete。
  3. 逐规则判定:对每条规则收集实体类型集合,剔除白名单后计算被拒绝实体;存在被拒绝实体则记录信号匹配。
  4. 证据与指标:为每个内容片段生成隐私证据(NewPrivacyEvidence),汇总PIIContentVerified(内容是否完整且干净)、PIIEntities、MatchedPIIRules,并记录Metrics.PII.ExecutionTimeMs与信号提取指标。

实体检测数据结构

检测结果由 classifier_pii_init.go 的PIIDetection承载:

type PIIDetection struct { EntityType string `json:"entity_type"` // 实体类型,如 PERSON、EMAIL、PHONE Start int `json:"start"` // 在原始文本中的起始字符位置 End int `json:"end"` // 结束字符位置 Text string `json:"text"` // 实际实体文本 Confidence float32 `json:"confidence"` // 置信度 0.0-1.0 }

实体类型与置信度共同决定了信号是否命中:只有置信度达到规则threshold且不在白名单中的实体才会触发匹配。

失败闭合:on_error 与 on_unscanned 的源码语义

PII 信号对"没查完"和"查失败"采取显式策略(与 jailbreak 分类器同构的 fail-closed 行为):

  • on_error: block:当内容无法完整分类(后端错误,或 provider 声明了截断)时,规则以classification_error(即常量PIIClassificationErrorType)匹配,而不是被当作干净内容放过;allow(默认)则视为不匹配。
  • on_unscanned: block(默认):模型未完整读取的内容(超过输入上限、provider 声明截断、或信号截止时间未扫完)以unscanned实体类型匹配,因此超长请求会被当作隐私流量路由;allow则留给on_error处理。

在 evaluatePIIRule 中,扫描状态被建模为piiScanClean/piiScanIncomplete/piiScanFailed三态:非 clean 状态且on_error: block或存在未扫描内容时,规则向被拒绝实体列表追加哨兵类型并记录到SignalErrors(错误码如pii_evaluation_incomplete)与SignalErrorMatches,实现"未经验证的内容不能以干净身份通过"。

decision 后端:面向判定模型的替代路径

当pii_classifier绑定的是说decision.v1契约的判定模型时,走 decision_pii.go 的evaluateDecisionPIISignal路径:不产出 token 位置,而是同时询问"PII 是否存在"(presence,0-1 概率)与"PII 类别"(categories 概率分布)两个问题,规则阈值同时作用于两个答案。该路径不虚构 token 位置,需要精确位置的调用方会收到能力错误(ErrCapability)。

端到端示例:隐私敏感流量的隔离路由

结合 agent 配方 与内置配方的用法,一个典型的隐私隔离方案如下:先声明严格 PII 规则,再在决策中引用它:

routing: signals: pii: - name: pii_strict threshold: 0.01 pii_types_allowed: - EMAIL_ADDRESS description: Block any entity beyond low-risk email addresses.

然后在路由决策的 plugin 链或 model 选择中引用signal: pii / name: pii_strict(规则按信号族 + 名称组合寻址),实现"命中即切换到私有插件栈 / 降级模型"。这一层约束同时服务于回放审计:信号命中与未命中均以结构化证据记录,可在 router-replay 场景中复现。

测试与验证

仓库为 PII 信号提供了完整测试覆盖,可在阅读源码时对照印证:

  • classifier_pii_test.go:实体类型翻译、长文本、部分扫描、on_error 语义等基础行为;
  • history_aware_pii_e2e_test.go:include_history: true的历史感知端到端验证;
  • pii_remote_backend_test.go:远程token_spans.v1后端的契约与截断处理;
  • pii_backend_parity_test.go:本地与远程后端行为一致性校验;
  • validator_pii_test.go:source字段合法值校验。

配置层的语义校验可运行go test ./pkg/config/...(config/README.md 中给出的聚焦校验命令)确认片段、配方与公开配置字段保持同步。

最佳实践小结

  1. 白名单优先,而非正则黑名单:利用pii_types_allowed精确声明"什么可以过",其余一律视为拒绝,策略意图一目了然且可审计。
  2. 保持 fail-closed:除非明确需要容忍漏检,否则将on_unscanned保持为block,超长输入永远按隐私流量处理;on_error: block可进一步保证后端异常时也不放行。
  3. 共享检测路径:让pii_classifier与 decision 信号绑定同一部署、同一次调用完成多个问题,降低隐私检测的附加时延。
  4. 结合历史与工具结果:include_history覆盖多轮会话中的隐私数据累积;source: tool_result将工具返回内容纳入检测时,注意其受 1024 次推理预算约束,超出部分按不完整处理。
  5. 用证据链支撑审计:信号求值生成PIIEvidence与PIIContentVerified,配合回放机制验证每一次隐私拦截的依据,满足合规审计要求。
  • 后端
  • API网关
  • 模型推理服务
  • AI Agent

【免费下载链接】semantic-router

An open, programmable decision layer for models and compute.

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

相关推荐

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

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

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

立即咨询