promptmask
用本地 LLM 在数据发送给云端 AI 前自动脱敏,隐私数据本地处理不上云,零侵入接入现有代码
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
用本地 LLM 在数据发送给云端 AI 前自动脱敏,隐私数据本地处理不上云,零侵入接入现有代码
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象一下这个场景:你正在使用 ChatGPT 帮你写一封取消牙医预约的邮件,输入框里写的是:
"My name is Ho Shih-Chieh and my appointment ID is Y1a2e87. I booked a dental appointment on Oct 26, but I have to cancel for a meeting."
你的姓名、证件号、预约信息,就这样被送到了 OpenAI 的服务器上——即使这只是处理一个简单的日程问题。
这就是 PromptMask 试图解决的核心问题:在享受强大云端 AI 能力的同时,如何确保个人隐私数据永远不离开你的电脑?
PromptMask 由独立开发者 cxumol 创建,诞生于 2025 年 7 月。项目名称本身就是一个精准的隐喻:Mask(遮罩),在数据发送给 AI 之前,先用本地模型给隐私数据打上"马赛克",让 AI 只能看到 [[MASK_001]] 这样的占位符,而看不到真实的姓名、手机号或证件号码。
当前版本 0.1.1(MIT 许可证),GitHub 136 star,Python 3.8+ 兼容。核心技术思路是:用一个可信的本地小模型(如 Ollama 驱动的 qwen2.5:7b)充当你与强大云端 AI 之间的"隐私过滤器"。

图1:PromptMask 核心工作流——本地 LLM 负责脱敏,云端 LLM 负责推理
PromptMask 的工作流程分为三个精密的环节:
第一步(Mask):本地 LLM 识别并替换隐私信息
用户输入的原始文本(如"我的预约号是 Y1a2e87")被发送给本地运行的 LLM(如 Ollama),由本地模型根据内置的 prompt template 识别出隐私实体(如姓名、ID、日期),并用统一的占位符格式 [[MASK_001]]、[[MASK_002]] 等替换。识别哪些类型的信息是"敏感的",可以通过配置文件灵活定制——包括电话号码、证件号、医疗记录、邮件地址等。
第二步(Send):脱敏后的文本发送给云端 AI
被替换后的文本("我的预约号是 [[MASK_002]]")通过网络发送给 ChatGPT、Claude 或其他云端 AI 服务。由于隐私数据已被替换,AI 处理的是完全安全的内容。
第三步(Unmask):响应中的占位符还原为原始数据
AI 返回的内容中,所有 [[MASK_002]] 占位符会被实时替换回对应的原始值——即使 AI 在回复中提到了"您的预约号",用户最终看到的依然是完整的真实信息。
PromptMask 提供了两种使用路径,适应不同技术背景的用户:
路径一:Python SDK 替换(开发者友好)
# 只需改一行 import
from promptmask import OpenAIMasked as OpenAI
client = OpenAI() # 自动继承 openai.OpenAI 的所有能力
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "我的手机号是 13800138000,帮我预约明天的会议室"}]
)
这意味着现有所有基于 OpenAI SDK 的代码只需修改一个 import 语句,即可获得隐私保护能力。项目对流式输出(streaming)也有完整支持。
路径二:本地 API 网关(零代码,适合所有工具)
pip install "promptmask[web]"
promptmask-web # 启动在 http://localhost:8000
启动后,PromptMask 在本地暴露一个 OpenAI 兼容的网关端点 /gateway/v1/chat/completions,你可以在任何工具(如 Cursor、Claude Desktop、Open Interpreter)中配置使用这个本地地址作为 API endpoint,无需修改任何代码。
# promptmask.config.user.toml
[llm_api]
model = "qwen2.5:7b" # 指定本地隐私过滤模型
base = "http://localhost:11434/v1" # Ollama 默认地址
src/promptmask/
├── core.py # 核心逻辑:Mask/Unmask、Prompt 构建
├── config.py # 配置管理:优先级加载、合并、env 注入
├── utils.py # 工具函数:日志、配置合并、字符串处理
├── adapter/
│ └── openai.py # OpenAIMasked:SDK 替换适配器
└── web/
├── main.py # FastAPI 应用主入口
├── gateway.py # OpenAI 兼容网关路由
├── models.py # Pydantic 请求/响应模型
└── static/ # Web UI 静态文件
core.py:隐私处理的引擎
PromptMask 类是整个项目的核心。其 _build_mask_prompt() 方法负责构建给本地 LLM 的 prompt——包含 system prompt(告诉模型哪些信息是敏感的)、few-shot 示例(帮助模型理解 mask/unmask 的格式),以及用户输入。_parse_mask_response() 负责从本地 LLM 的响应中提取 JSON 格式的 mask map(原始值 → 占位符的映射关系)。
unmask_str() 和 unmask_stream() 方法则负责将 AI 响应中的占位符还原为原始数据。流式输出的 unmask 实现尤为精妙——通过 SSE 缓冲区逐块解析,在每个 chunk 中查找 [[ 和 ]] 标记,实时还原后再 yield 给客户端。
adapter/openai.py:零侵入的 SDK 劫持
OpenAIMasked 继承自官方 openai.OpenAI,通过 _hijack_chat_completions() 方法将 chat.completions.create 替换为包装函数,在调用真实 API 前插入 mask 逻辑、调用后再执行 unmask。这种 monkey patch 的方式实现了真正的零侵入——用户的代码只需要改一个 import,不需要学习任何新 API。
web/main.py:FastAPI 驱动的 Web 服务
使用 FastAPI + Uvicorn 构建 Web 服务,提供了完整的 REST API(/v1/mask、/v1/unmask 等)和 Web UI(HTTPServer served static/index.html)。支持热更新配置(创建/更新 promptmask.config.user.toml 后无需重启),通过 FastAPI 的 lifespan 机制管理异步客户端(httpx)和 PromptMask 实例的生命周期。
web/gateway.py:透明代理
OpenAI 兼容网关的核心。当用户将 PromptMask 的网关地址配置为目标 AI 服务的 endpoint 时,所有请求被转发到真实的上游服务(如 OpenAI API),响应通过 SSE 实时 unmask 后返回给客户端。
PromptMask 的配置采用 TOML 格式,支持四层优先级:直接传入的 dict 参数 > 指定路径的配置文件 > 用户目录的 promptmask.config.user.toml > 包内默认配置。这套系统还支持环境变量注入(LOCALAI_API_BASE、LOCALAI_API_KEY),便于容器化部署。
项目包含 tests/ 目录,支持 pytest + pytest-asyncio,测试异步 mask/unmask 流程。虽然当前代码覆盖度未达到企业级标准,但对于一个 0.1.1 版本的项目来说,基础测试框架已就位。
PromptMask 的部署异常简单。开发者提供了三种启动路径:
路径 A:pip 直接安装(推荐)
pip install "promptmask[web]"
# 需要一个本地 LLM API 服务(Ollama 默认监听 localhost:11434)
promptmask-web # 启动 Web UI + 网关
路径 B:Docker 一键启动
# docker-compose.yml
services:
promptmask:
build: .
ports:
- "8000:8000"
volumes:
- ./promptmask.config.user.toml:/app/promptmask.config.user.toml
docker-compose up
路径 C:CPU 模式 llama.cpp 脚本
start-cpu-llamacpp.sh 提供了一个完整的本地运行方案:启动 llama.cpp server(可配置 GPU 加速或纯 CPU),然后启动 promptmask-web,全程不依赖任何外部服务。
PromptMask 本身是轻量级的 Python 库(仅需 ~200MB 磁盘),核心隐私过滤功能不需要 GPU。但若要完全本地化运行(用本地 LLM 替代云端 AI),则需要根据模型大小配备相应硬件——qwen2.5:7b 建议至少 8GB 显存,纯 CPU 推理需要 16GB+ 内存。
mask 准确率依赖本地模型能力
PromptMask 的隐私保护质量完全取决于本地 LLM 的实体识别能力。如果模型将"会议室"误识别为隐私信息并 mask 掉,AI 就会收到错误的信息,影响处理结果。项目提供了 benchmark 工具帮助用户选择合适的本地模型,但对于非技术用户来说,模型选型仍然是一个门槛。
配置门槛不低
虽然使用路径简单(一个 pip install + 一行代码),但深度定制(如调整敏感信息类型、修改 mask 格式、对接 Gemini 等非 OpenAI 平台)需要用户理解 TOML 配置格式和 prompt engineering 的基本概念。
v0.1.1 版本的成熟度
作为一个相对年轻的项目(2025年7月才创建),PromptMask 在错误处理边界(如本地 LLM 完全不可用时的降级策略)、大规模并发场景下的性能等方面,还有待生产环境检验。
在 AI 隐私保护领域,主流方案通常有两个极端:完全本地化(Ollama、LM Studio)牺牲了模型能力,或完全信任云端(直接使用 ChatGPT API)牺牲了隐私。PromptMask 提供了第三条路——用小模型保隐私,大模型保能力,两者的结合让用户不再需要在便利性和安全性之间二选一。
随着 GDPR、医疗隐私法等监管趋严,以及企业数据泄露事件的频繁发生,类似 PromptMask 这样的"隐私中间层"工具正在成为 AI 时代的基础设施组件。它代表了一种务实的隐私保护思路:与其要求用户改变行为习惯,不如在技术层面自动消除风险。
分析基于 GitHub 仓库 master 分支 v0.1.1 版本,项目持续活跃中(最近更新:2026-07-25)