Anthropic 在 2026 年 9 月发布的威胁情报报告里记录过一个真实的泄密案例:某家制药公司的员工把日常数据发给 AI 工具,内部资本支出预测顺着请求流向公网,最终进了外部机构用来蒸馏模型的训练集。我在本地开发 agent,让它读取本地代码和工作文档,最担心的就是这种泄密。数据一旦穿过本机网卡离开设备,后续所有访问权限控制就完全失去了意义。端侧芯片这几年虽然性能提升明显,但受限于功耗与内存带宽,本地小模型接不住复杂的全流程推理与多工具编排;而把长任务发往云端的前沿大模型,又伴随着数据出网的泄密风险。
Perplexity 在 Mac 端推出Hybrid Compute时给出了一个折中方案:系统默认由本地小模型负责任务调度和敏感操作,复杂的推理硬任务交给云端模型,但在数据离开设备出网的前一刻,先在本地执行一层脱敏过滤。这道本地网关把拦截到的数据分成了四条处置路径:留在本地处理、替换成占位符后再发往云端、直接拒绝该动作,或者暂停下来等待用户手动批准。事后追查日志解决不了数据外泄的问题,真正的防御要直接前置在数据序列化出网的网卡边界上。Perplexity 随后开源了这道闸门的核心感知部件,也就是与其合作的安全研究机构共同训练的敏感信息检测器。既然本地小模型无法独立承担所有复杂推理,数据又不能随意出网,在出网边界上守住敏感信息,就成了端侧 agent 调用云端算力的必经之路。
想在本地把敏感数据拦下来,第一反应往往是写几行正则表达式,或者拉一张关键词表做字符串匹配。但我在本地拿真实的 API 密钥做测试时,迅速撞上了各种边缘情况。哪怕换上 Perplexity 开源的专用检测器,实测中也接连暴露问题。
一段没有任何上下文修饰的裸密钥输进去,比如一段以 sk- 开头、总长 164 个字符的凭证,检测器容易把它误标成 account_number。更麻烦的是切片位置:它经常只圈出密钥中段的 82 个字符,总长 164 个字符的密钥首尾依然原样留在待发送的文本里。在一段包含代码和配置的混合长文档里,我埋了 4 个真实密钥,模型在文末漏掉了其中 1 个。只要切片偏移或者漏掉几个字符,凭证外泄的漏洞就依然敞开着。
既然规则和专用检测器都有盲区,我试着把输入直接扔给通用大模型,用提示词让它定位文本里的敏感信息,但这条路实测同样走不通。生成式大模型依靠自回归机制工作,核心逻辑是在给定前文后依次预测下一个词元的概率分布。让大模型寻找敏感片段,它输出的是一段新生成的自然语言文本,或者在生成某个词元时的离散概率。这种生成机制无法针对原始输入文本里的连续字符片段,原地给出干净、连续的局部置信度。
这两轮实测把我对检测器的要求逼得越来越明确:它需要在原文里原地圈出起止字符,指认从第几个字符到第几个字符属于哪类实体,并且给每个圈出的片段附带一个置信度分值。外层的调度逻辑是直接拦截、替换成占位符,还是暂停下来等待用户确认,完全依赖这个分值来决定。自由续写的聊天模型给不出这个分值,我需要的是一个能在本地低延迟运行、通读前后两端上下文、而且能对任意片段直接输出概率分布的专用检测器。
我从 HuggingFace 上把 Perplexity 的pplx-pii-masking权重下载到本机。打开权重文件和配置代码,整个模型的 bf16 权重文件只有 1.1GB,稠密参数量约 0.6B。它的底层架构完全没有走生成式大模型的路线,而是一个标准的双向编码器:沿用 Qwen3 架构的注意力层与权重布局,但显式关闭了因果掩码,改成了全双向注意力模式。
通常所说的聊天模型只能向左看历史词元,是因为它的任务是预测下一个词,后面的词生成时还没有出现,因果掩码矩阵把对未来词元的注意力全部遮蔽掉了。但敏感信息检测并不是文本续写任务,待检测的输入文本在送进模型的那一刻就已经完整存在了。
判定一个实体往往需要依赖后文给出的线索。一段 16 位的数字,只有结合后面紧跟的有效期和安全码,才能确认它是支付卡号;一个常见的英文单词,只有读到后面跟着的职位或者问候语,才能确认它是人名。双向注意力抹平了单向因果掩码带来的右侧视野盲区,让模型在单次前向计算中同时看清前后语境。
这个小模型读完一段文本后,核心动作是给序列里的每一个词元贴标签。在模型顶端,它接入了词元分类头与文档敏感度头两个轻量线性输出层。词元分类头把隐藏特征映射到 37 个输出标签上:模型支持的 9 类敏感信息,各自拆分为开始、内部、结束、单字四种边界状态,再加上一个代表非敏感词元的独立状态,正好构成 37 个维度。
得到每个位置的概率后,模型通过维特比算法挑选出一条符合语法规则的最优标注路径。维特比算法的作用是施加状态转移约束,防止出现没有开始状态就直接跳出内部状态的非法标注序列。整个模型把所有算力都集中在字符边界定位与置信度计算上,完全避开了逐字自回归生成的额外开销。
顺着这个架构往下想,自然会冒出一个念头:能不能拿一个现成的因果语言模型,微调时直接把注意力掩码改成双向?这是一个容易踩坑的工程陷阱。因果语言模型在海量语料上预训练时,每个词元的特征表示都是基于只看左侧历史信息的目标训练成型的。如果在微调阶段直接把因果注意力掩码放开成全双向,底层权重无法适应右侧突然涌入的信息流,原本预训练学到的语义表征会出现严重的分布偏移。
Perplexity 采取的演进路径分三步:先完成因果语言模型的常规预训练,再通过双向掩码建模训练出名为 pplx-embed 的双向文本向量底座,最后在底座上挂载分类头,在标注好的敏感数据上完成微调。因果模型单向生成文本,而文本向量底座为了浓缩整句语义天然需要通读全文。借用训练成熟的向量底座作为骨干,模型顺利继承了稳定的双向理解能力,避开了强行打开掩码造成的表征破坏。
这套架构还在解码阶段留出了调节旋钮。检查模型的权重文件,里面内置了两个标量偏置:进入实体开始状态的转移偏置,以及离开实体结束状态的转移偏置。调整这两个标量数值,操作点就能在精确率与召回率之间滑动,不需要重新训练底层参数。在凭证泄露这种宁可多报也不能漏报的场景中,调高偏置就能让拦截策略更加激进。在差不多的时间段里,OpenAI 也开源了结构相近的隐私过滤器。我把这两家团队的开源检测器放在同一个设计坐标系中对照:
| 维度 | Perplexity (pplx-pii-masking) | OpenAI (Privacy Filter) |
|---|---|---|
| 参数量与激活规模 | 约 0.6B 稠密参数 | 1.5B 稀疏架构(约 50M 激活参数) |
| 上下文窗口 | 4096 词元 | 128K 词元(带状注意力,有效窗口仅 257 词元) |
| 底座演进路径 | 因果语言模型 → 双向嵌入底座 → 微调分类头 | 自回归基础模型直接重构为双向分类器 |
| 开源协议 | MIT 协议 | Apache 2.0 协议 |
| 支持敏感类别数 | 9 类 | 8 类 |
我把 OpenAI 的开源权重下载到本地跑通了推理(整个模型仓库约 10GB,含多种量化版本)。它的总参数量为 1.5B,采用 8 层 MoE 架构,包含 128 个专家,每个词元激活其中 4 个,实际激活参数量约 50M,推理用的 bf16 主权重占 2.8GB。它的 tokenizer 采用了与 gpt-oss 系列相同的 o200k_base,底座由自回归模型直接重构为双向分类器。它同样支持维特比解码,在 config 中定义了 33 个标签类,覆盖 8 类敏感信息,并附带了 viterbi_calibration.json 配置文件。
OpenAI 检测器标称的上下文窗口达到了 128K 词元(配置中 max_position_embeddings 为 131072,default_n_ctx 为 128000)。但这个 128K 窗口并不意味着每个词元都能看到全局文本:模型采用了带状注意力,每个词元只看自己左右各 128 个词元的邻域,算上自身,单个词元的实际有效视野只有约 257 个词元。
我在搭载 M3 Ultra 的机器上,使用 MPS 后端对两款模型做了对照测试(OpenAI 模型在无 Triton 环境下走 PyTorch 原生 MoE fallback)。在显存占用上,pplx-pii-masking 占用约 1.2GB 显存,OpenAI 隐私过滤器占用约 3.1GB。
在推理耗时方面,简短文档上 pplx-pii-masking 单次前向扫描约 40 到 80 毫秒,OpenAI 检测器约 55 到 300 毫秒。如果把文档长度推到 2816 词元,pplx-pii-masking 耗时约 0.7 秒,OpenAI 检测器耗时约 5 秒。我接着用一段 21820 词元的超长文档进行测试,OpenAI 检测器耗时约 39 秒。在已经超出 pplx 截断窗口的文本末尾,OpenAI 检测器成功检出了埋在那里的密钥;但带状注意力的局限也随之暴露:一段 16 位的账号数字,因为实体说明标签出现在 550 个词元之前,超出了左右 128 词元的带状视野,模型直接把它误标成了 private_phone。
日常搭 agent 工作流,不少团队习惯了把所有文本分析和提取任务直接扔给大模型,试图靠一段提示词解决所有分类需求。但把这两家机构开源检测器的代码拆开、并在本机跑过一整轮基准测试之后,我对小尺寸双向分类器的工程定位有了更清晰的认识。
如果一项任务符合以下几个特征,双向词元分类器在延迟和准确性上展现出了明显的优势:需要在物理文本中精确定位起止字符偏移量、需要模型给出连续可靠的置信度分值来驱动分支决策、需要输出严格符合语法约束的结构化标签,以及需要在本地端侧设备上维持几十毫秒级的吞吐响应。在 M3 Ultra 上实测,0.6B 的小模型处理 2816 词元只需约 0.7 秒;我在由真实密钥、中文和负样本构成的 14 篇测试文档上跑了一遍,它的 F1 分数达到了约 0.98。
但这套概率检测器也有自己的边界,我在测试里挨个撞到了。商业机密和专有数据属于权限与访问控制的范畴,并不具备固定的语法特征:一份内部资本支出预测或者一段核心算法代码,在文本形式上和公开文档、常规代码并无二致,仅凭文本概率模型划不出安全分界。上下文同样会带来识别漂移:在机械重复的退化语境下,模型即使在有效窗口之内也会漏检;在常规英文句子里,它会把普通动词短语误判成人名。
两款模型对长文档的处理方式也各有取舍与陷阱。pplx-pii-masking 的上下文上限是 4096 词元,输入文本一旦超出限制,模型会直接静默截断而不抛出任何告警,超长部分的内容在无声无息中失去了保护。OpenAI 隐私过滤器虽然给出了 128K 的名义窗口,但带状注意力将每个词元的视野限制在左右各 128 词元(约 257 词元)之内,面对 550 词元之外的上下文线索完全无能为力。两者在本质上都无法做到通读整篇长文档进行全局关联。面对缺乏自然语言修饰的裸密钥和高熵字符串,模型同样容易出现切片偏移或者类别误判。
所以这次拆完,我的结论是端侧防护不可能只靠单一组件:小尺寸双向分类器接住自然语言语境里的多变实体,正则表达式、高熵检测和严格的长度截断负责确定的格式边界,两者各管一段。