给自有内容清掉 AI 水印与溯源标记(watermarks-remover)

watermarks-remover 是一套用 Python 写的 AI 水印清理工具:Layer A 清不可见 Unicode,Layer B 处理统计式文本水印,第三层清 C2PA、EXIF、XMP 等文件溯源标记,还能以 Claude Code 插件和 PostToolUse hook 的方式自动跑。这篇讲清它覆盖哪些格式、怎么装、关键参数在哪、有哪些已暴露的坑,以及它和纯中文去痕迹工具的差别。

AI 生成的内容会带上两类痕迹。文本里可能藏着零宽字符、非常规空格、双向文本控制符和标签字符;文件里可能写着 C2PA 声明、EXIF、XMP 或文档属性。这些标记本身是用来标注来源的,当内容归你所有、你要把它交出去或发出去时,它们就变成了隐私层面的负担。

watermarks-remover 是一套用 Python 编写的 AI 水印清理工具与服务,输入文本或文件,清掉不可见 Unicode 与 C2PA、EXIF 等溯源标记,输出干净副本或检查结果。

它的清理分成三层:Layer A 处理不可见 Unicode、异体空格、双向控制符与标签字符,由确定性 Python 脚本执行;Layer B 处理统计式的采样水印,靠模型改写或 rewrite_text.py;第三层处理文件里的 C2PA、EXIF、XMP 与文档属性,覆盖 PNG、JPEG、WebP、AVIF、HEIC、BMP、GIF、TIFF、SVG、PDF、DOCX、XLSX、PPTX、EPUB、ODT、HTML、Markdown、MP4/MOV/M4A/M4V、WAV、MP3、FLAC。针对的来源包括 Claude、Gemini / SynthID-Text、OpenAI 的溯源面,以及开源 LLM 的 Kirchenbauer 绿名单与 keyed-Gumbel / EXP 类水印。

watermarks-remover 项目封面图

仓库地址是 github.com/guillaumemeyer/watermarks-remover,采用 MIT 许可证,主要语言是 Python,占比 97.3%。截至 2026 年 10 月 2 日抓取的数据,它有 23199 个 Star、2656 个 Fork、106 个 Watcher,开放 Issue 18 个,最近一次提交在 2026 年 9 月 29 日。

它不做什么

它无法改写助手即将发出的聊天消息。Claude Code 的 Stop hook 拿到的是只读的 last_assistant_message,工程里没有面向最终回复的发送前过滤器,README 明确写了这一点,Cursor rules 有同样的限制。只存在于聊天记录里的文本仍然依赖 skill 工作流,而 skill 是一段给模型的指令,模型是否调用由模型自己决定,属于尽力而为。确定性的保证只覆盖两处:agent 写出的文件,以及进入 git 之前的那道闸门。

skill 本身不包含任何代码,它通过 HTTP 调用服务。主机上不装 Python 也能用 skill,但服务必须先跑起来,否则 Layer A 这类确定性清理没有东西可调。

像素域的 CtrlRegen 去除依赖外部后端,不是自带能力。C2PA 的读取依赖 c2patool 这类外部工具,仓库的 Issue 里提到过装完它之后 inspect_image.py 的行为。

用之前先准备好什么

安装器要求 Python 3.10 以上,只用标准库、不带依赖。服务端默认监听 http://127.0.0.1:8765,如果换过地址,需要在环境里设 WATERMARKS_SERVICE_URL。

你要确认清理目标落在哪些文件格式里,因为第三层是按格式解析的,PDF、DOCX、MP3 走的是不同分支。要接 hook 的话,宿主得支持 Claude Code 的插件与 hook 机制;只有 Claude Code 和 Cursor 这两类宿主在安装器的目标列表里。

最后是内容权属。这个项目的定位写在 README 第一句里,处理的是你拥有的内容,用它处理别人的内容不在设计目标内。

主要功能

Layer A 的确定性字符清理。 针对不可见 Unicode、异体空格、双向控制符和标签字符,由 Python 脚本直接处理,不经过模型,因此每次跑的结果一致。它同时被 hook、pre-commit 闸门和 CI 的 SARIF 导出复用,判定标准来自 audit_lib 的 scan_file 与 is_actionable。副作用是它也会动到 emoji 的变体选择符与零宽连接符,这一点在 Issue 里被报告过。

Layer B 的统计水印改写。 统计式水印藏在 token 采样分布里,字符层面看不出来。这一层靠 agent 改写,或者调用 rewrite_text.py。rewrite_text.py 的默认 paraphrase 做的是显式的用词加句法攻击,改写从句顺序、连接词、过渡词、句边界和虚词。--strength humanize 提供另一种零样本的「像人写的」通道。v0.7.0 把这一层搬进了 /clean 服务,策略由配置驱动,基准调出来的参数是 [email protected],[email protected]。

文件元数据清理。 覆盖 C2PA、EXIF、XMP 与文档属性,格式清单在上面列过,从图片、办公文档到音频、视频都有对应处理。v0.7.0 加了破坏性的音频清理和逐帧视频清理,v0.4.0 加了通过外部后端实现的 CtrlRegen 像素去除。

可自托管的 HTTP 服务。 v0.5.0 起它是一个可以自己架的服务:标准库写的 HTTP API,GHCR 上的 Docker 镜像,一条命令的 compose 栈,仓库根目录里有 compose.yaml、compose-check.sh 与 Makefile。

Claude Code 插件与 skill 安装。 安装器 install_skill.py 覆盖四种宿主目标,仓库同时是一个单插件市场,两条命令就能装好并原地更新。附带的 skill 有两个:remove-ai-marks 是完整版、依赖服务,clean-user-facing-text 只处理文本、自包含。

PostToolUse hook。 插件在 Write|Edit|MultiEdit|NotebookEdit 上注册 hook,对 agent 刚写的文件跑 service/scripts/hook_written_file.py。模式分 check(默认,只报告,把发现交给模型,退出码 2)和 clean(原地清理,然后告诉模型磁盘上的文件变了)。clean 模式先写同目录临时文件,只有真有差异才替换,已经干净的文件保持 mtime,不会反复触发文件监听。

水印窃取与研究验证。 v0.7.0 加了一个黑盒的水印窃取模块,目录是 stealer/。另有两个可选的研究用 harness:图像侧的 MarkDiffusion,文本侧的 MarkLLM,用来验证你的流水线是否真的清干净了。v0.4.0 还引入了 finding-confidence 分级与聚合审计。

安装与最短示例

最快的一条路是走插件市场,不用克隆仓库:

/plugin marketplace add guillaumemeyer/watermarks-remover
/plugin install watermarks-remover@watermarks-remover

装好之后 skill 带命名空间加载,/watermarks-remover:remove-ai-marks 和 /watermarks-remover:clean-user-facing-text 都可以用,裸写的 /remove-ai-marks 在没有重名时也有效。/plugin marketplace update watermarks-remover 拉取后续版本。

不用插件的话,用安装器把 skill 铺到宿主目录:

python3 install_skill.py --skill remove-ai-marks --target claude-code

Windows 上把 python3 换成 py。macOS 和 Linux 也可以用 install-skill.sh 这个包装脚本。项目安装的写法是加 --target claude-project --project-dir /path/to/project,装进项目目录后可以提交到仓库里共享。

最短的一次使用,是装完 skill 后直接在 Claude Code 里调用 /remove-ai-marks,或者用自然语言要求「strip AI watermarks / C2PA / Claude marks / SynthID-class text」。剩下的事由服务端和 agent 的改写流程完成。

关键参数

安装器 install_skill.py 的选项:--skill 指定要装的 skill,--target 指定宿主,--project-dir PATH 配合 --target claude-project 使用,--force 覆盖已有安装,--link 改成符号链接、本仓库的修改会即时生效,--list 打印可安装的 skill 列表。不加 --force 时已有安装会被保留,替换走暂存,旧版本留成带唯一名字的备份。

安装器在写任何东西之前会按 Agent Skills 的打包规则校验 skill:frontmatter 只允许 name、description、license、compatibility、metadata、allowed-tools;name 要小写连字符且不超过 64 字符、与目录名一致;description 非空且不超过 1024 字符。Cowork 的打包额外受 30 MB 上传上限约束。

环境变量方面,WATERMARKS_SERVICE_URL 指定服务地址,WATERMARKS_HOOK_MODE 指定 hook 模式。hook 也可以用插件设置里的 Hook mode 控制,对应 CLAUDE_PLUGIN_OPTION_HOOK_MODE。仓库的注释里提到,hook 命令故意不插值 ${user_config.hook_mode},因为 Claude Code 拒绝运行引用了用户从未在 /plugin manage 里打开过的选项的 hook,声明默认值不算数,插值会导致全新安装上 hook 静默不跑。

改写侧的参数,rewrite_text.py 支持 --candidates N 生成多个改写候选,--strength humanize 走人类风格通道。

结果在哪里看

hook 跑在 check 模式时,发现会送到模型那里,退出码是 2,模型可以据此提议清理。跑在 clean 模式时文件在磁盘上就地改掉,文件已经干净的情况下不写盘、不更新时间戳。

进入 git 的路径由 pre-commit 闸门把守,检测环节与 hook 共用 audit_lib 的判定,CI 那边则导出 SARIF。clean_file.py 是清理逻辑的唯一出口,hook 也 shell out 到它,不重复实现。

想单独检查而不清理,用 inspect_file.py、inspect_image.py 这类脚本;想验证流水线是否真的清干净,用 MarkDiffusion 和 MarkLLM 这两个 harness。

实际使用中的坑

第三方检测器不认账。 有用户拿两张图跑过 skill,把它们送进 thehive.ai 检测,返回的仍是 99.9% 的 gemini 3.0 结果,因此怀疑工具是否真的有效。这条 Issue 已有 10 条评论,当前标记为已解决。它说明清理效果与第三方检测器的判定之间未必同步,检测器结论不能直接当验收标准。

Layer A 会动到正常 emoji。 emoji 的变体选择符 U+FE0F 和序列内部的零宽连接符,在 Layer A 眼里和隐藏字符属于同一类,会被一并清掉,导致表情显示发生变化。这条已解决。

正文里的字面词被当成元数据。 有 docx 文件没有任何 AI 生成标签,却因为正文里出现了字面的 Claude 一词,被 inspect_file.py 报成 AI metadata: True。属于误报,已解决。

C2PA 检查一度全为真。 装上 c2patool 之后,inspect_image.py 对每个文件都报 C2PA: True,原因是「No claim found」这句话里含有 claim 这个词,优先级判断让守卫条件失效,已解决。

pre-commit 永远过不了。 每一次非文本的 clean_file 运行都报 changed,因为每个 strip_* / clean_* 函数都会追加一条「什么都没删掉」的动作记录,而不是返回相应状态,结果是 pre-commit hook 永远无法通过。这条已解决。

横向对照

项目适合谁部署方式主要限制什么情况下选它更合适项目地址
watermarks-remover要在 Claude Code 或 Cursor 里成批处理自有文本与文件溯源标记的开发者Python 3.10+ 安装 skill,服务端是标准库 HTTP API,仓库提供 compose.yaml 与 GHCR 镜像聊天消息里的文本得不到确定性清理,像素域去除依赖外部后端需要同时覆盖文本统计水印和 C2PA、EXIF 等文件元数据的多格式批量场景watermarks-remover
swaylq/humanize-chinese只处理中文文本、希望纯本地跑的写作者纯 Python 本地运行只覆盖文本层,SynthID 采样水印只量残留、不声称能删目标只有中文文本、不需要碰文件元数据时swaylq/humanize-chinese
aloshdenny/claude-awm只针对 Claude 单一来源做处理的用户未逐一核实仓库描述只有一句 claude anti-watermarking,能力边界未逐一核实只想针对 Claude 这一个来源做轻量处理aloshdenny/claude-awm

这两个都是同类项目,差别在覆盖面和使用门槛上。humanize-chinese 是纯 Python 本地跑,不需要先起一个 HTTP 服务、也不需要把 skill 装到宿主目录里,中文文本场景下开箱更直接;watermarks-remover 要先让 service 跑起来,Layer B 才有得调用。反过来说,只要你的目标里包含 C2PA、EXIF 这类文件元数据,或者你需要在 agent 写文件的那一刻自动介入,humanize-chinese 覆盖不到,此时该用 watermarks-remover。

合规与授权边界

这个项目会读取并改写内容里的溯源标记,涉及对生成来源信息的移除,使用时必须限定在你自己拥有版权的内容,或者已经拿到明确授权的素材上。把它用在别人的作品、平台上他人的发布内容,或者用来规避平台对 AI 生成内容的标注要求,可能触碰著作权、平台规则以及不同司法辖区对 AI 生成内容标识的规定,Issue 列表里就有用户以欧盟 AI 法案的角度提出过质疑。第三方检测器给出的结论也不能当成合法性的依据。

适合谁

适合已经在用 Claude Code 或 Cursor、需要在文件落盘那一刻自动清掉溯源标记的开发者,也适合要把 DOCX、PDF、图片、音视频成批交出去、不希望里面残留 C2PA 与文档属性的团队。愿意自己架一个本地 HTTP 服务、并且在意判定标准在 hook、pre-commit 和 CI 之间保持一致的人,会用到它比较深的部分。

只想处理中文文本、不想引入服务依赖的人,用纯本地的同类工具更省事。只需要检查而不需要清理的人,inspect_file.py 这类脚本够用,不必把整套服务跑起来。要求清理结果为确定性、可复现的人也要留意,Layer B 依赖模型改写,属于启发式,拿不到逐字节稳定的输出。

焚评:这个项目的量化评分

本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 9.9 分(满分 10)。下表是各维度的得分:

评分维度得分
热度动量(权重 25%)10.0 / 10
开发活跃(权重 25%)9.9 / 10
社区响应(权重 15%)10.0 / 10
文档质量(权重 15%)10.0 / 10
发布节奏(权重 10%)8.8 / 10
风险控制(权重 10%)10.0 / 10

评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。

内容核验说明

收录价值在于它把水印清理拆成可核对的层次:不可见 Unicode、统计式改写、文件元数据,并说明哪些环节是确定性的、哪些只是尽力而为。装法、参数、hook 模式与已知误报都标了具体位置,适合已在 Claude Code 或 Cursor 里成批处理自有素材的开发者。

文中 Star、Fork、Issue 数等 GitHub 指标与焚.com 评分均引自公开数据,诀.com 未独立验证;Issue 的已解决/待解决状态取自仓库标记,未逐条复核代码;无任何实测证据。

项目来源与说明

开源项目:guillaumemeyer(guillaumemeyer)

本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。

查看项目仓库