news 2026/10/26 10:11:46

Pixie Privy 实战指南:基于 OpenAPI 规范合成带 PII 标注的协议追踪数据集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pixie Privy 实战指南:基于 OpenAPI 规范合成带 PII 标注的协议追踪数据集
  • 可观测性
  • 云原生

【免费下载链接】pixie

Instant Kubernetes-Native Application Observability

项目地址:https://gitcode.com/gh_mirrors/pixie/pixie
点击查看免费下载

Privy 是 Pixie 仓库内置的命令行工具,用于生成与 Pixie 在 Kubernetes 集群中收集的 pod 协议追踪高度相似的合成数据,并自动注入真实感十足的个人身份信息(PII)与对应的标注信息。读完本文,你将掌握如何用bazel run一键生成 JSON / XML / SQL / HTML 等多格式数据集,理解 payloads、templates、spans 三种产出文件的区别与用途,并能基于合成数据训练 PII 检测模型、可视化 PII 分布以及按 Pixie 的真实限制截断协议追踪。

Privy 是什么:为 PII 检测模型合成协议追踪数据

Pixie 是一个面向 Kubernetes 的即时应用可观测性平台,会在运行时抓取集群内 pod 之间的协议流量。这些真实流量中包含大量敏感信息,直接用于训练或评估 PII 识别模型既涉及隐私风险,也难以获得带精确标注的样本。Privy(仓库入口见 src/datagen/pii/privy/README.md)正是为解决这一问题而生的工具:

  • 以OpenAPI 描述符(API 规范文件)为模板来源,描述真实世界中各类 API 请求的字段结构;
  • 以PII 假数据源(姓名、地址、邮箱、银行卡号、SSN、护照号等)填充字段值;
  • 产出完整消息体(full-body messages),支持多种格式:
    • JSON
    • XML
    • SQL(PostgreSQL 与 MySQL 两种方言)
    • HTML
    • Protobuf(文档标注为 in progress,源码中PayloadRoute.conversions也预留了 protobuf 转换位,见 route.py 中的 todo 注释)

该工具同时提供配套的公开合成样本数据集(可在 Hugging Face 检索privy数据集),可用于演示、训练 PII 检测模型以及评估现有 PII 识别系统。社区已有基于 Privy 数据训练的 NLP 模型(如基于 spaCy 的 PII 检测 DistilBERT 模型)以及对应的 PII 匿名化 Demo,并在 Pixie 官方博客发表过关于"在调试数据中检测 PII"的专题文章。此外,源码中还包含一张参考实现图,展示了从 schema 解析到数据产出的完整流程。

工作原理:从 OpenAPI 描述符到带标注的合成数据

Privy 的生成管线可以用"模板 + 运行时填充"概括,理解这条管线有助于你更精准地使用它的各项参数。

1. 拉取 OpenAPI 目录

默认情况下,Privy 会从公开的 OpenAPI 目录(APIs-guru 维护的 openapi-directory 仓库)下载约 4000 份 API 规范作为生成素材。在 generate.py 的main()中,程序会先检查指定目录下是否存在openapi-directory-ea4a924b870ca4f6d687809fa7891cccc0d19085这个固定 commit 的目录,不存在则从 GitHub 下载对应 commit 的 tar.gz 并解压到--api_specs指定的目录下。

2. 遍历描述符并生成请求参数

PayloadGenerator(见 payload.py)会递归遍历 API 规范文件夹,识别openapi.json、swagger.json、openapi.yaml、swagger.yaml等描述符文件,然后用schemathesis与hypothesis这两个基于属性测试的库为每个 HTTP 方法(GET/POST/PUT/DELETE 等,源码中枚举了 9 种方法)生成合法请求参数。每个 OpenAPI 描述符都受--timeout限制,超时即停止,避免超大描述符拖慢整体生成速度并扭曲数据集分布。

3. Schema 分析:把参数名匹配到数据提供者

核心逻辑在 hooks.py 的SchemaAnalyzer中。它通过注册before_generate_casehook 拦截 schemathesis 的默认策略,按照以下优先级为每个参数赋值:

  1. 枚举(enum):若参数或 schema 定义了enum,直接随机取一个枚举值;
  2. PII 关键字:若参数名、schema 值或类型命中 PII 提供者的别名(如user name、email address、credit card),则把参数值替换为{{person}}、{{email}}这类模板占位符,并登记该参数所属的 PII 类型;
  3. 正则模式(pattern):若 schema 带pattern,用st.from_regex生成匹配正则的随机值;
  4. 非 PII 关键字:命中string、integer、boolean等非 PII 提供者,同样以{{...}}占位;
  5. 兜底:以上均未命中时,赋值为{{string}}。

这一步产出的不是最终数据,而是"参数名 → 提供者名"的模板字典,后续再交由具体的数据提供者实例化。

4. 路由转换:模板 → 多格式数据

PayloadRoute(见 route.py)维护了一张格式转换表:JSON 用json.dumps、XML 用dicttoxml、HTML 用json2html、SQL 则交给SQLQueryBuilder(见 sql.py)基于 pypika 随机拼装 SELECT / INSERT / UPDATE 语句,并随机选择 PostgreSQL 或 MySQL 方言。转换后会进行模板去重(is_duplicate),保证 templates 文件中的模板唯一。若开启--fuzz_payloads,PayloadFuzzer还会通过删除花括号、引号、尖括号等字符产出模糊化变体,扩大数据覆盖面。

5. 提供者实例化:从模板到真实感假数据

模板中的{{person}}、{{integer}}等占位符最终由区域化提供者解析。以美式英语提供者 english_us.py 为例,它基于presidio_evaluator的PresidioDataGenerator与 Faker 扩展构建,注册了 60 余个 PII 提供者(分类见下),每个提供者都有模板名、别名集合与值类型。GenericProvider.parse()(见 generic.py)会解析模板字符串并返回带 span 标注的填充结果。德式德语提供者见 german_de.py,两者都继承自区域无关的GenericProvider。

PII 提供者按语义可分为以下类别(以english_us.py中的注册列表为准):

  • 姓名:person、first_name、last_name、name_male/name_female、prefix、organization、nationality、religion 等;
  • 位置:address、street_address、city、state、zipcode、country、坐标(coordinate/latitude/longitude)、机场(airport_iata/airport_icao)等;
  • 金融:bban、aba、iban、credit_card_number、credit_card_expire、swift、currency_code;
  • 时间:age、date、date_of_birth、date_time、year、month、day_of_week;
  • 身份标识:ssn、passport、driver_license、license_plate、itin(美国个人纳税人识别号);
  • 联系方式:email、phone_number;
  • 人口统计:gender、job;
  • 网络/设备:domain_name、url、ip_address、mac_address、imei、password。

值得一提的实现细节:GenericProvider.add_delimited_aliases会为每个别名自动生成空格、连字符、下划线、双下划线及无分隔符等多个变体(见 generic.py),以提高参数名匹配的鲁棒性。

快速开始:一行命令生成 JSON 数据

在仓库根目录(使用 Bazel 构建,入口 target 为//privy/generate:privy_generate)执行:

bazel run //privy/generate:privy_generate

默认行为:

  • 首次运行会下载约 4000 份 OpenAPI 规范(若本地已有缓存则直接使用);
  • 数据默认输出到 Bazel 沙箱运行时目录;
  • 默认只生成json类型数据集。

如需自定义输出位置、数据类型与日志级别,可追加参数(支持长选项,也支持首字母短选项):

bazel run //privy/generate:privy_generate -- --out_folder=/path/to/output/directory --generate json sql --logging=debug
  • --out_folder指定输出目录的绝对路径;
  • --generate json sql同时生成 JSON 与 SQL 两类数据集;
  • --logging=debug输出调试级日志,便于观察参数匹配过程(如某参数命中了哪个 PII 提供者)。

三种数据集文件格式详解

对每种协议类型(如 json),Privy 会在输出目录的data/子目录下生成三个配套文件,它们对应不同的模型训练任务。文件名模式为{protocol_type}-{suffix},例如json-payloads.csv、json-templates.txt、json-spans.json。

payloads-{protocol_type}.csv:文本 + 标签

每行包含一个文本样本、二进制has_pii标签(1 表示含 PII)以及该样本中包含的pii_types(多个类型用逗号分隔):

# JSON payload, has_pii, pii_types {"first_name": "Moustafa", "sale_id": "235234"}|,1,first_name

该文件可直接用于训练二分类或多标签 PII 分类模型,判断一段文本是否包含 PII。

templates-{protocol_type}.txt:唯一模板

每行是数据集中的一个唯一字符串模板,{{}}内的值会在运行时与对应数据提供者匹配:

# Values enclosed in {{}} are matched with an appropriate data provider at runtime {"first_name": "{{person}}", "sale_id": "{{integer}}"}

模板是"生成器"而非"样本":你可以用同一批模板配合不同的数据提供者,生成贴合自己业务场景的新数据集。

spans-{protocol_type}.json:带偏移的 NER 标注

每行是一个 (非)PII 样本,包含文本内容、每个 PII 实体的字符串区间(start/end 偏移)、实体类型、生成该 span 所用的模板及模板唯一 ID:

# text sample, span for each PII entity along with its location in the string and type, the template used this span, a unique ID for the template used to generate this span {"fake": "{\"first_name\": \"Moustafa\", \"sale_id\": \"235234\"}", "spans": "[{\"value\": \"Moustafa\", \"start\": 15, \"end\": 24, \"type\": \"person\"}]", "template": "{\"first_name\": \"{{person}}\", \"sale_id\": \"235234\"}", "template_id": 0}

该文件专为命名实体识别(NER)模型设计,可支撑 token 级 PII 分类与脱敏任务的训练。从源码看,每个模板默认生成 10 条 span(由--spans_per_template控制,见 route.py 中write_payload_to_csv的循环逻辑)。

合成数据的三类典型用途

文档给出"数据能用来做什么"的对应关系,这也是选择数据集格式的决策依据:

数据文件典型用途
payloads训练二分类或多标签 PII 模型,判断文本样本是否含 PII
templates用唯一字符串模板自建数据集:可替换数据提供者,生成贴合特定场景的数据;也可参考 presidio 评估框架中的数据生成器思路;更直接的做法是向 providers 目录 中新增你自己的数据提供者
spans训练 NER 模型,实现 token 级 PII 分类与脱敏(redaction)

配套工具链:训练、可视化与截断

Privy 不止于数据生成,还提供三个围绕数据集的实用工具与测试入口。

用 FlairNLP 训练序列标注(NER)模型

基于 FlairNLP 框架训练 token 级序列标注模型,输入为 spans JSON 文件:

bazel run //privy/train:privy_flair_ner -- --input=/path/to/input/spans.json

训练脚本位于 train/flair_ner.py。

可视化合成数据中的 PII 分布

输入 payloads CSV,输出各 PII 类型的数量分布、含 PII 的 payload 百分比、平均每个含 PII payload 的 PII 类型数,并绘制柱状图(实现见 visualize.py,基于 plotly):

bazel run //privy/generate:privy_visualize -- --input=path/to/input/data-payloads.csv

按 Pixie 的真实限制截断协议追踪

Pixie 在采集协议追踪时会限制每行最大字符数,为了让合成数据与真实采集行为对齐,Privy 提供截断工具:

bazel run //prive/generate:privy_truncate -- --input=path/to/input/data-payloads.csv

注意:上例中的 target 名以仓库实际定义为准(文档中的//privy/generate:privy_truncate)。截断逻辑位于 truncate.py:对超过长度上限的行保留前--max_chars_per_line个字符并追加... [TRUNCATED]标记,同时保留has_pii与pii_types两列。除--input外还支持:

  • --max_chars_per_line:每行保留的最大字符数,默认 500;
  • --replace:就地截断,直接覆盖输入文件;
  • --out:截断结果的输出路径。

运行测试

仓库为 Privy 提供了 JSON、SQL、数据提供者三组单元测试(测试目录见 tests),可在仓库根目录统一执行:

bazel test ...

命令行选项全解析

privy_generate的全部可用选项如下(默认值与校验规则已结合 generate.py 与 utils.py 的源码核对):

options: -h, --help show this help message and exit --generate_types {json,sql,proto,xml,html} [{json,sql,proto,xml,html} ...], -g {json,sql,proto,xml,html} [{json,sql,proto,xml,html} ...] Which dataset to generate. Can select multiple e.g. json sql proto xml (default: ['json']) --region {english_us,german_de}, -r {english_us,german_de} Which language/region specific providers to use for PII generation. (default: english_us) --logging {debug,info,warning,error}, -l {debug,info,warning,error} logging level: debug, info, warning, error (default: info) --out_folder OUT_FOLDER, -o OUT_FOLDER Absolute path to output folder. By default, saves to bazel cache for this runtime. --api_specs API_SPECS, -a API_SPECS Absolute path to folder download openapi specs into. Privy checks if this folder already exists. --fake_persons_file_path FAKE_PERSONS_FILE_PATH, -fp FAKE_PERSONS_FILE_PATH Absolute path to file containing fake person data downloaded from fakenamegenerator.com. (default: ) --multi_threaded, -m Generate data multithreaded (default: False) --num_additional_pii_types NUM_ADDITIONAL_PII_TYPES, -n NUM_ADDITIONAL_PII_TYPES Upper bound for the number of PII types to generate when inserting additional PII into sensitive payloads. E.g. 6 (default: 6) --equalize_pii_distribution_to_percentage EQUALIZE_PII_DISTRIBUTION_TO_PERCENTAGE, -e EQUALIZE_PII_DISTRIBUTION_TO_PERCENTAGE Equalize distribution of PII in the dataset to the given percentage by generating additional PII payloads for pii types with the lowest count. To disable, set to 0. (default: 50) --timeout TIMEOUT, -t TIMEOUT Timeout (in seconds) after which data generation for the current openAPI descriptor will be halted. Very large descriptors tend to slow down data generation and skew the output dataset, so we apply a uniform timeout to each. (default: 400) --pii_types PII_TYPES [PII_TYPES ...], -p PII_TYPES [PII_TYPES ...] PII types to match and generate. If not specified, all available PII types will be matched. (default: None) --fuzz_payloads, -f Fuzz payloads by removing characters. (default: False) --spans_per_template SPANS_PER_TEMPLATE, -s SPANS_PER_TEMPLATE Number of (non-)PII spans (NER-compatible, token-wise labeled samples) to generate per unique payload template. (default: 10) --ignore_spec IGNORE_SPEC [IGNORE_SPEC ...], -ig IGNORE_SPEC [IGNORE_SPEC ...] OpenAPI specs to ignore. If not specified, all specs will be matched. (default: ['stripe.com'])

几个值得结合源码理解的关键选项:

  • --equalize_pii_distribution_to_percentage(默认 50):真实 API 请求中,含敏感字段的参数往往不会在字段名里显式带 PII 关键字,导致天然分布中 PII 样本偏少。Privy 会在已知含 PII 的请求中额外随机注入 PII 字段,直到含 PII 的 payload 占比达到目标百分比;若某类 PII 数量偏少,则优先为计数最低的 PII 类型补样本。相关逻辑见 payload.py 的generate_pii_case()与equalize_pii_distribution()。设为 0 可关闭该均衡机制。注意该参数是百分比校验,合法范围为 0–99(见 utils.py 的check_percentage)。
  • --num_additional_pii_types(默认 6):配合上面的均衡机制,控制单次注入时最多追加的 PII 类型数量(1 到该值之间随机)。校验要求为正整数(check_positive)。
  • --timeout(默认 400 秒):每个 OpenAPI 描述符的生成超时。超大描述符会拖慢生成并扭曲数据分布,故对每个描述符施加统一超时;超时后跳过当前 HTTP 方法并继续(见parse_http_methods中的时间检查)。
  • --pii_types:指定后只匹配并生成所列 PII 类型;不指定则匹配所有可用类型。--region决定使用哪套区域化提供者(english_us/german_de),两者的Provider注册表可在 english_us.py 与 german_de.py 中查看。
  • --ignore_spec(默认['stripe.com']):按子串匹配要跳过的 OpenAPI 规范(如某些超大体量的规范),可传多个值。
  • --multi_threaded:开启后用 joblib 以 10 线程并行处理描述符(见 payload.py 中Parallel(n_jobs=10, prefer='threads'))。
  • --fake_persons_file_path:指定从 fakenamegenerator.com 下载的假人数据 CSV,english_us.py会读取并构造RecordsFaker,从同一条人物记录中采样姓名、地址等,以提升数据的内部一致性;不指定则使用 presidio 自带的 1000 条美国假名数据。
  • --fuzz_payloads:开启后PayloadFuzzer会删除 JSON 的花括号/引号、XML 的尖括号/斜杠等字符,产出模糊化变体,扩大覆盖度(见 route.py)。

深入阅读

  • Privy 官方说明:src/datagen/pii/privy/README.md
  • 生成入口与参数解析:privy/generate/generate.py
  • 核心生成管线(schemathesis 集成、PII 均衡注入):privy/payload.py
  • Schema 分析与关键字匹配:privy/hooks.py
  • 多格式转换与模糊化:privy/route.py
  • SQL 语句构建(PostgreSQL/MySQL):privy/sql.py
  • 数据集统计与分布均衡:privy/analyze.py
  • 区域化数据提供者:privy/providers/english_us.py、privy/providers/german_de.py、privy/providers/generic.py
  • 单元测试:privy/tests
  • 可观测性
  • 云原生

【免费下载链接】pixie

Instant Kubernetes-Native Application Observability

项目地址:https://gitcode.com/gh_mirrors/pixie/pixie
点击查看免费下载

相关推荐

上一篇:终极Windows安装媒体创建工具:一键支持1507到23H2全版本,轻松绕过硬件限制
下一篇:终极指南:如何使用Python高效读取通达信本地数据

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 0:03:10

基于agency-agents的多智能体协作架构与工程实践

看到“agency-agents”这个词,我第一反应不是某个具体开源仓库,而是一种正在被反复验证的多智能体协作模式:把几个擅长不同事情的 AI Agent,像一家小型公司那样组织起来,让它们各自认领角色、互相传递中间结果、最后拼…

作者头像 李华