ARTICLE · 1308905
脱敏控件的大小飞轮:一次 32MB 的 token 爆炸,逼出可商用的底座
事情是从一个"简单事故"开始的。脱敏控件跑完一次跨使用循环之后,把运行轨迹写进 out/ 目录给人翻看,这本是再正常不过的一步,可那次落盘出来的 agent_run.json 有 10.78MB,bigloop_run.json 有 21.65MB,archived_actions.json 也有 0.77MB,三份文件加起来约 32MB。它们本来只是"最近一次运行"的快照,搁在磁盘上无人问津,可只要被人随手读进对话上下文,就是千万级 token 直冲进来,会话当场被压缩崩溃。一个本该悄无声息的落盘动作,变成了压垮会话的那根稻草,后来被称为"崩溃式事项"。
脱敏控件真正难的,从来不是把规则写对,而是让规则系统在长期运行里既不饱和为死水,也不因为一次手滑就炸穿上下文。大小飞轮解决的就是这件事。

一、两套循环,各管一摊
脱敏控件里跑着两套循环,名字叫大循环和小循环,文件分别在 agents/bigloop.py 和 agents/loop.py,它们不能互相替代,报表里"学到了什么"和"改到了哪"两本账得分开记。
大循环管的是跨使用。它消化使用痕迹,交给 adjudicator 做三裁判投票判定,单条上下文只给 MAX_CONTEXT=120 字,然后写进 Memory,Memory 只追加不删改,再驱动小循环去施工,最后把已经治好的案例关掉。它的活儿是"换掉那批案例",每一次施工都带进来一批新案例,所以它不会饱和,这是刻在机制里的性质。
小循环管的是单次运行内。它走诊断、生成、裁判、归档,裁判不调 LLM,走 judge.py 的确定性评测,measure、probe、gate 一套下来给出结论。它的活儿是"在已有语料上把规则榨干",这是会饱和的,而饱和恰恰是正常结局,也是该停的时候。小循环榨干了当前这批语料,大循环就换一批新的进来,飞轮因此一直转,不靠某一方独自扛到底。
两套循环咬合的地方,是规则表。小循环改的是规则表,规则表作用在语料上,语料沉淀出新的使用痕迹喂给大循环,大循环又把判定结果写进 Memory,Memory 只追加,从不回删。五个部件首尾相连,形成一个只往前推的环。
二、只进不退的闸门
这个环上有一道闸门,叫 gate_real,写在 agents/judge.py 里,性质是"只进不退"。真实召回必须涨,bench 一条都不许变差,否则这个动作直接被拒,规则表原地不动。它保证飞轮每转一圈,质量只可能往上走,不可能因为某次激进修改而把之前治好的东西弄丢。
这道闸门管得住规则表的质量,却管不住轨迹文件的体积,而那次事故,恰恰出在体积上。
三、爆炸是怎么发生的
根子在 judge.recall_on() 的返回值里有个 covered 字段。这个字段把每一条 gold 对应的整篇文档全文都嵌了进去,单次就是大约 2MB。轨迹文件又把这个完整结果嵌了不止一份:agent_run.json 里一份,bigloop_run.json 里一份,archived_actions.json 的归档动作里,text 字段又存了一份整篇文档全文。三份文件合计约 32MB,全是从同一个 covered 全文派生出来的冗余。
问题不在于文件大。文件大,搁在磁盘上也就是占点空间。问题在它会被读进对话上下文。review 时习惯把"最近一次运行"的快照丢进会话里看,一旦这几个 MB 级文件被读进来,千万级 token 直接灌进上下文窗口,会话当场被压缩、崩溃。一个本该给人慢慢翻的快照,变成了会话的定时炸弹,而且它平时一声不响,只在你打开它的那一刻炸。
轨迹文件的设计初衷是给人 review,不是给模型当输入,可当它被读进上下文,两种用途的边界就塌了。

四、落盘守卫:把"不能再膨胀"钉进机制
事故之后没有去手写几行清理脚本了事,而是新建了一个 agents/trace_guard.py,让所有 out/ 轨迹落盘强制走 safe_dump。思路很简单:落盘这一刻,就把会膨胀的东西拦下来。
第一道是递归摘要。recall_on 的完整结果,包括那个藏着全文的 covered,全部压成一组标量摘要:recall、gold、hit、publishable、pub_rate、covered_count,全文丢弃,只留数字。原本 2MB 的全文,落盘后变成几个字段。
第二道是超长 text 截断。归档动作里的来源文档等超长 text,按 TEXT_TRUNCATE=200 截断到前缀加标注,不再整篇塞进去。
第三道是体积上限告警。MAX_TRACE_BYTES=500KB,落盘之后若超限就打印告警,不打断流程,但让问题可见。告警不拦你,只是盯着你。
第四道是收口落盘点。loop.py、bigloop.py、archive.py 的落盘全部收口到 safe_dump,同时保留现有的 recall_summary 包裹作双保险,确保无论从哪条路径落盘,都过同一道关。
第五道是把规矩钉进测试。tests/test_trace_guard.py 写了 7 个用例,核心断言就是轨迹文件不能再膨胀,任何让体积回弹的改动,测试先挂。
第六道是离线护栏。scripts/guard_trace.py 扫描 out/ 下超限的 JSON,退出码 1,可以接质量闸门、CI 或者定时巡检,让膨胀在没人盯着的时候也被发现。
第七道是豁免名单。像 evolve_cache.json 这种预测缓存,存的是 span 列表不含全文、可重建、稳态体积,就放进豁免名单,不被误伤。
机制的意义,是从"靠人记住别把大文件读进来",变成"文件本身就不会大到能被读炸"。
五、实测:32MB 压到 130KB
收口之后的数字很直接。agent_run.json 从 10.78MB 降到 0.034MB,bigloop_run.json 从 21.65MB 降到 0.095MB,三份合计约 32MB 压到 130KB 上下,差不多是原来的 1/250。又顺手删掉了现存那几个 MB 级的旧文件,把现患也清了。
换算成 token 视角,那次崩溃的千万级来源,被拦在了落盘这一刻。会话不会再因为任何一份"最近运行"快照而被挤爆,review 的人照样能拿到召回、命中、可发布率这些关键标量,只是拿不到那几 MB 的全文噪音。
六、从"容易炸"到"可控可审计":商用化底座
这次事故的处置,把脱敏控件从"容易炸、靠人盯"推到了"可控、可审计、可解释"。这几条不是修饰词,是机制给的底:
规则表驱动,动作可撤回,改错了能回退;可逆还原配分级授权,谁能看到还原后的明文,按级别定;质量闸门只进不退,真实召回涨、bench 不降才放行;落盘体积有硬上限,轨迹文件不可能再膨胀到威胁上下文。把这四条摆在一起,脱敏能力才从一套内部工具,变成一件能交付的产品,因为它每一个会出事的地方,都被机制预先兜住了。
七、参数对比
把这次处置前后的关键参数摊开,比单下结论更有说服力。
个人域:召回从 0.8248 涨到 0.9665,可发布整篇从 26% 提到 76.9%,人名召回 0.983,地址召回 0.950,benign 误伤 2 处保持不变。
企业域:严格 gold 493/730 即 0.675,公共平台被脱 0/180,项目名 0/12,产出质量问题 0,AMOUNT_MONEY 从 0.787 提到 0.885。
工程侧:测试从 678 通过涨到 728 通过,性能 908 字/秒,实体类型 19 种,DICOM 已支持。
行业隐私算法对照 7/12:已具备规则表驱动、可逆还原分级授权、质量闸门、中文专精、确定性评测、审计追踪、spanned 覆盖;暂缺 FPE、k-匿名、l-多样性、差分隐私、日期偏移。
八、和 Presidio、Skyflow、Protegrity 们比,我们站在哪
下面这张表是 10 分制,评分基于公开能力对比、非官方基准,分值只反映公开资料能看出来的能力覆盖,不代表任何厂商的官方评测结果。维度口径与脱敏控件的既有竞品研究保持一致;表内「竞品分值」一列按 Presidio、Skyflow、Protegrity、国内同类 的顺序排列。
本脱敏插件在中文/混合实体专精、规则表驱动可解释、可逆还原分级授权、质量闸门只进不退、908 字/秒性能、国产化部署这几项上相对领先,短板集中在高级隐私算法:FPE、k-匿名、l-多样性、差分隐私、日期偏移都还缺。性能这一项被 Protegrity 的模型派实现压过一头,这是如实写进表里的。
Microsoft Presidio 是开源标尺,英文为主,规则加 ML,没有原生中文优化,也没有可逆还原分级和质量闸门,胜在生态和免费。Skyflow 是商业 SaaS,令牌化强、合规强,但中文和国产化弱、闭源、按量计费。Protegrity 是商业方案,FPE 和格式保留强、金融级合规,但价格高、国产化弱、闭源。国内同类大多是规则库,缺可逆还原分级与质量闸门机制。
我们的领先项,恰好是脱敏这件事最难被替代的那几项:中文实体、可解释、可撤回、质量只进不退。那几个暂缺的高级隐私算法,是明确的补强方向,不是遮掩的短板。

九、回环
32MB 的轨迹文件,并不是 bug,而是设计里漏算的那一环:快照给人看,和快照被读进上下文,是两种用途,可落盘时它们被当成同一回事。落盘守卫把这条边界重新划清,飞轮因此多了一道齿,转得更稳。
大循环换案例,小循环榨语料,Memory 只追加,规则表被改又只进不退,闸门守着质量,守卫守着体积。脱敏控件从一个会炸的内部工具,变成一件能解释、能审计、能交付的产品,靠的不是某次灵光,是这套机制自己转出来的。















































































