基准测试 LLM 上下文感知而不发送原始 PII
Source: Dev.to
TL;DR: 我测量了在 原始标识符从不进入提示 的情况下,LLM 是否仍能理解关系和上下文。结果——简单的删减效果不佳,但稍作调整后几乎可以匹配完整上下文!
我比较了三种方法
- Full Context (baseline) → 完整上下文(基线)
- Standard Redaction (everything becomes
) → **标准删减**(所有内容都变成) - Semantic Masking (my own simple package built on top of spaCy that generates context‑aware placeholders with IDs to keep relations, e.g.
{Person_A}) → 语义掩码(我基于 spaCy 构建的简单包,生成带有 ID 的上下文感知占位符以保持关系,例如{Person_A})
结果出人意料:在关系推理的压力测试中,标准删减的准确率下降到 27 %。语义掩码达到了 91 % 的准确率——几乎完美匹配未掩码的基线,同时保持直接标识符本地化。
Scope note: This is not anonymisation. The goal is narrower but practical: keep direct identifiers (names, emails, IDs) local, while giving the model enough structure to reason intelligently.
范围说明: 这 不是 匿名化。目标更为狭窄且实用:将 直接标识符(姓名、电子邮件、ID)保持本地,同时为模型提供足够的 结构 以进行智能推理。
All source code is linked at the end.
所有源代码链接在文末。
为什么这很重要(不仅仅是 RAG)
人们喜欢使用 AI 界面,但我们常常忘记,LLM 是一个 通用引擎,而不是安全金库。无论你在构建 聊天机器人、代理或 RAG 流水线,传递原始数据都存在风险:
- 提示日志记录与追踪
- 向量数据库存储(嵌入原始个人身份信息)
- 调试截图
- “回退” 调用外部提供商
作为欧盟的开发者,我想探索一种 先掩码的方法:在本地转换数据,对掩码文本进行提示,并(可选)在本地重新填充响应。
问题:上下文崩溃
标准脱敏工具的问题不在于它们本身不好——而是它们会破坏模型理解 谁在做什么 所需的信息。
“Anna & Emma” 场景
原文: “Anna calls Emma.”
标准脱敏 → calls .
- 问题: 模型完全无法区分是谁打给谁。推理崩溃。
语义掩码 → {Person_A} calls {Person_B}.
- 优势: 模型知道 A 与 B 是不同的人,保留了关系。当答案返回(
{Person_A} initiated the call)时,我们可以在本地把真实姓名换回去。
我想要测量:通过脱敏我们到底失去了多少推理能力,能否通过加入一些语义信息来修复它?
基准测试
我进行了两个实验来检验该假设。
| # | 基准测试 | 描述 |
|---|---|---|
| 1 | “Who is Who” Stress Test (N = 11) | 小型合成数据集,旨在使用不同的 PII‑removal 工具测试 LLM 的上下文感知能力。包含多个角色在同一故事中的互动以及关系推理(例如,“谁是经理?”)。 |
| 2 | RAG QA Benchmark | 检索流水线的模拟: 1. 获取一份私有文档。 2. 对其进行遮蔽。 3. 基于遮蔽后的文本向 LLM 提问,仅使用遮蔽文本进行回答。 |
设置
- 模型:
gpt‑4o‑mini(temperature = 0) - 评估者:
gpt‑4o‑mini用作 LLM 法官,在单独的评估提示中运行 (temperature = 0) - 指标: 关系抽取问题的准确率
注意: Small‑N 基准旨在揭示失效模式,而非声称统计上的完美。它们是对逻辑的“氛围检查”。
比较方法
-
完整上下文(基线) – 原始文本(隐私风险高,完美上下文)。
-
标准编辑 – 用通用标签替换实体(“)。
-
语义遮蔽 – 我的方案,区别于前两者的三点:
- 一致性: “Anna” 变为
{Person_hxg3};随后出现的每一次都使用相同的占位符。 - 实体链接: “Anna Smith” 与 “Anna” 被识别为同一实体,并获得 相同 的占位符。
- 语义提示: 日期不仅是 “,而是
{Date_October_2000},在不泄露具体日期的前提下保留时间线信息。
- 一致性: “Anna” 变为
结果
基准测试 1 – 共指压力测试 (N = 11)
| 策略 | 准确率 | 为什么? |
|---|---|---|
| 完整上下文 | 90.9 % (10/11) | 基线(因模型幻觉导致一次错误)。 |
| 标准编辑 | 27.3 % (3/11) | 完全崩溃——模型盲目猜测,因为所有人都是 “。 |
| 语义遮蔽 | 90.9 % (10/11) | 上下文已恢复——性能与原始数据相匹配。 |
基准测试 2 – RAG 问答
| 策略 | 上下文保留 |
|---|---|
| 原始(基线) | 100 % |
| 标准编辑 | ≈ 10 % |
| 语义遮蔽 | 92–100 % |
要点: 你不需要真实姓名来推理。只需要结构。
我学到的
- 结构 > 内容: 对于大多数 AI 任务,模型并不在乎谁是某个人;它在乎的是关系图(例如,人物 A → 上司 → 人物 B)。
- 实体链接至关重要: 朴素的查找替换在“Anna”与“Anna Smith”之间会失效。你需要逻辑将它们链接到同一 ID,否则模型会认为它们是两个不同的人。
- 隐私启用: 这打开了以前认为“因为不能发送数据而无法使用 LLM”的用例(HR、详细客户支持、法律等)。
可重复性 vs. 隐私
- 在生产环境中: 使用 临时 ID(每个会话随机)。“Anna”今天是
{Person_X},明天是{Person_Y},从而防止跨会话画像。 - 用于基准测试: 我使用了固定种子,以便使运行结果可比。
资源与代码
如果您想自行复现或对我的语义掩码方法进行压力测试,请查看以下库:
# 克隆仓库
git clone https://github.com/Privalyse/privalyse-research.git
cd privalyse-research
# 安装依赖
pip install -r requirements.txt
# 运行指代消解压力测试
python benchmarks/coreference_stress_test.py
# 运行 RAG QA 基准测试
python benchmarks/rag_qa.py
指代消解基准测试 (context_research/01_coreference_benchmark.py)
# (your coreference benchmark code here)
RAG QA 基准测试 (context_research/02_rag_qa_benchmark.py)
# (your RAG QA benchmark code here)
语义掩码库
pip install privalyse-mask
限制 / 威胁模型
- ✅ 直接标识符已消除: 名称、电子邮件、电话号码在本地被遮蔽。
- ❌ 可能重新识别: 如果上下文(除PII外)足够独特(例如,“2010年苹果公司的CEO”),模型可能推断出真实人物。
- ❌ 没有差分隐私: 这是一种以实用性为先的方法,而非数学保证。
这种方法旨在最小化数据暴露同时最大化模型智能,而不是实现完美匿名。
讨论
- 是否有其他工具在掩码过程中处理实体链接?
- 您是否了解用于“隐私保护推理”的标准数据集?
- 是否有针对这种上下文感知的通用基准?(我只找到了针对长上下文的)
让我们在评论中聊聊吧!👇