关于 remove-ai-marks
remove-ai-marks 是用于清理文本和文件中 AI 标记的技能,面向因隐私、清洁或研究需求处理自有内容的用户。确定性处理由独立 HTTP 服务执行,并会先检查可用后端,再建议使用检测或像素处理功能。
主要功能
- 01检查文本和文件中的标记
- 02清理文本与文件元数据
- 03检测受支持的文本和图像水印
- 04使用可选的像素移除后端
- 05处理前检查服务能力
适用场景
- 01检查文档中的可疑标记
- 02移除受支持文件的元数据
- 03比较清理前后的水印检测结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ guillaumemeyer/ watermarks-remover --skill remove-ai-marks安装后在 Claude Code 中输入/remove-ai-marks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ethics.mdhow-claude-marks.mdmark-classes.mdmarkdiffusion.mdremoval-matrix.mdvendor-notes.md详细介绍
移除 AI 标记
针对文本(Unicode + 统计改写)和文件(常见容器中的 C2PA / AI 元数据)的多厂商防检测处理。
如有需要,请阅读:
references/mark-classes.md— Unicode / 采样 / C2PA / 容器references/vendor-notes.md— Claude、Gemini/SynthID、OpenAI、开放 LLMreferences/removal-matrix.md— 不同情况下使用哪一层references/ethics.md— 预期用途references/how-claude-marks.md— Anthropic 专属详情references/markdiffusion.md— 可选的 MarkDiffusion 图像测试框架(方案、诚实性注意事项)
此技能是一个轻量客户端。所有确定性清理操作都在独立的 HTTP 服务(本仓库的 service/)中运行,因此 Agent 主机不需要 Python、虚拟环境或清理工具。使用 curl 调用服务;切勿直接运行清理脚本。
服务访问
基础 URL 来自 WATERMARKS_SERVICE_URL,默认值为 http://127.0.0.1:8765:
WM="${WATERMARKS_SERVICE_URL:-http://127.0.0.1:8765}"
服务由运维人员启动(使用 docker compose up -d 或已发布的 GHCR 镜像),也可以在本地启动(使用 make serve)。务必先检查服务;如果无法访问,请停止并给出明确提示,绝不要回退到本地清理:
AUTH_HEADER=()
if [ -n "$WATERMARKS_SERVER_API_KEY" ]; then
AUTH_HEADER=(-H "Authorization: Bearer $WATERMARKS_SERVER_API_KEY")
fi
curl -sf "${AUTH_HEADER[@]}" "$WM/health"
# {"ok": true, "version": "..."}
如果服务端设置了 WATERMARKS_SERVER_API_KEY,每个请求(包括健康检查和功能检查)都需要添加 -H "Authorization: Bearer $WATERMARKS_SERVER_API_KEY"。默认 URL 指向回环地址;如果服务运行在其他主机上,请将 WATERMARKS_SERVICE_URL 设为 https:// URL,以免令牌以明文形式发送,并且不要添加 -L(重定向可能会将令牌转发到其他主机)。
功能
curl -s "${AUTH_HEADER[@]}" "$WM/capabilities"
报告服务端可用的可选工具(c2patool、exiftool、qpdf、ghostscript)、已提供的评分器(scorers.stylometry、scorers.synthid、scorers.synthid_http)、文本水印检测器(text_detectors.markllm、text_detectors.claude-text),以及已配置的重型后端(pixel_backends.ctrlregen、pixel_backends.diffusion、harnesses.markllm)。请据此提供建议:只有在服务报告相应后端可用时,才建议进行像素标记移除、SynthID 评分或厂商检测。
HTTP API(curl)
载荷为 JSON,文件内容采用 base64 编码。Agent 会解码 cleaned
字段,并自行将其写入输出路径。
| 方法 | 路径 | 请求体 | 返回值 |
|---|---|---|---|
| GET | /health | — | {"ok": true, "version": ...} |
| GET | /capabilities | — | 当前可用的可选工具 / 后端 |
| GET | /openapi.json | — | 动态生成的 OpenAPI 3.0.3 规范 |
| POST | /inspect | {"file": "<base64>", "name": "notes.md"} | {"ok", "kind", "suspicious", "report"} |
| POST | /detect | {"file": "<base64>", "name": "notes.txt"} | {"ok", "kind", "detections": [...]} |
| POST | /clean | {"file": "<base64>", "name": "notes.md", "options": {...}} | {"ok", "kind", "cleaned": "<base64>", "report"} |
/clean 和 /inspect 会根据上传文件的 name 扩展名和字节内容进行路由;
无法识别的格式会返回 kind: "unknown"(/inspect)或 400(/clean)。
为粘贴的文本创建临时文件时,请确保发送的 name 中包含已知扩展名(.txt /
.md)。
机器可读的接口规范位于 $WM/openapi.json — 可将其接入任何
OpenAPI 工具(客户端生成器、Swagger UI、编辑器),而无需手动编写
客户端。
/clean 接受的 options:nfkc、aggressive_homoglyphs(文本)、
keep_non_ai_metadata、strip_all_metadata、remove_pixel(ctrlregen |
diffusion)(图像和视频)、also_layer_a_text(容器)、deep_images
(auto | always | lossless | never,PDF:追查嵌入图像中所含元数据的力度;
不接受其他值)、clean_attachments
(auto | always | never,PDF:追查嵌入文件附件(回形针文件)中元数据的力度。
always(默认值)会清除每个附件的元数据,不论其标记如何,并以相同方式递归处理嵌套容器;
auto 仅清理带有 AI/C2PA 标记的附件;never 则保持不变。需要 qpdf。
不接受其他值)、detect_before / detect_after(文本和
图像:对输入和清理后的输出运行水印检测,并纳入报告),以及 strategy(文本:
按顺序排列的 tactic@intensity 列表,例如 "[email protected],[email protected]",会在
Layer A 之后运行 Layer B 改写;省略时使用 config/clean_strategy.json 中的默认值;
如果某个步骤的后端 / 模型未配置,/clean 将返回 400)。
先检查(做判断,不要猜测):
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/inspect" -H 'Content-Type: application/json' \
-d "{\"file\": \"$(base64 < notes.md | tr -d '\n')\", \"name\": \"notes.md\"}"
清理(根据名称和字节内容自动检测文本 / 图像 / 容器):
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/clean" -H 'Content-Type: application/json' \
-d "{\"file\": \"$(base64 < notes.md | tr -d '\n')\", \"name\": \"notes.md\"}"
将返回的 cleaned base64 解码到输出文件(默认使用 *.cleaned.*,除非用户要求原地处理),并如实概述 report。
(对于 Windows Agent,可使用以下命令构建 base64:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("notes.md"))。)
伦理
仅用于你自己的内容(隐私、卫生、研究)。不要将结果宣传为“证明由人类撰写”。如果用户明确想要学术造假或非法隐瞒,请参考 references/ethics.md 发出警告,并且仍然只能对其拥有的内容进行技术清理。
工作流
1. 对输入分类
| 输入 | 路由 |
|---|---|
| 粘贴 / 剪贴板文本 | 临时文件 → /inspect,然后 /clean(文本) |
.txt / 代码 | 文本 Layer A(代码另加格式化工具) |
.md / .html / .tex / .ltx | 容器清理(frontmatter/meta 或 \hypersetup/\pdfinfo + 注释来源信息)+ Layer A;通过 /clean 文本处理或 Agent 改写模型,对正文应用 Layer B |
.png / .jpg / .jpeg / .webp / .avif / .heic / .bmp / .gif / .tiff | 清除图像元数据 |
.svg / .pdf / .docx / .epub / .odt | 清除容器元数据 |
| 目录 / 网站 | 通过服务 CLI 进行汇总审计(见下文) |
服务会先根据文件名扩展名进行路由,再根据魔数路由,因此通常只需发送文件即可。
2. 先检查
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/inspect" -H 'Content-Type: application/json' \
-d "{\"file\": \"$(base64 < path | tr -d '\n')\", \"name\": \"$(basename path)\"}"
显示简短摘要(可疑代码点;C2PA/AI 标记;置信度标签
confirmed / probable / informational / likely_false_positive)。
可选的像素域检测(SynthID 评分)和像素去除
(CtrlRegen / DiffusionPurification),以及 MarkDiffusion/MarkLLM 测试框架,
都需要外部重型后端。它们运行在服务的可选容器或主机检出目录中——在承诺提供这些功能前,请检查 /capabilities,绝不要把本地检测器冒充为官方供应商检测器。
2b. 水印检测前后对比(已配置时)
当 /capabilities 报告了检测器(text_detectors.markllm)或图像
评分器(scorers.synthid_http / scorers.synthid)时,请在清理前后进行检测以测量结果:
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/detect" -H 'Content-Type: application/json' \
-d '{"file": "'"$(base64 < notes.txt | tr -d '\n')"'", "name": "notes.txt"}'
也可以将检测合并到清理中:使用 /clean 和
{"options": {"detect_before": true, "detect_after": true}},报告会返回
text_detectors.before/after(文本)或 synthid_before/synthid_after
(图像)。MarkLLM 仅支持相同配置下的研究;Claude 的检测器尚未公开。(Google 于 2026 年 8 月从 API 中停用了 SynthID-text 检测器——参见 references/vendor-notes.md。)
3. 确定性清理(始终适用于匹配的输入)
任何受支持的文件(统一接口):
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/clean" -H 'Content-Type: application/json' \
-d "{\"file\": \"$(base64 < INPUT | tr -d '\n')\", \"name\": \"$(basename INPUT)\"}"
解码 cleaned → OUTPUT(除非用户要求原位处理,否则文件名为 *.cleaned.*)。
当残留风险很重要时,重新检查结果。
PDF 需要服务端安装 exiftool + qpdf 才能真正剥除;缺少其中任一项时,报告会注明结果已降级(尽力而为)——请检查 /capabilities。
**图像——可选像素去除:**仅当 capabilities.pixel_backends
表明后端可用时:
curl -s -X POST "${AUTH_HEADER[@]}" "$WM/clean" -H 'Content-Type: application/json' \
-d "{\"file\": \"$(base64 < shot.png | tr -d '\n')\", \"name\": \"shot.png\", \
\"options\": {\"remove_pixel\": \"ctrlregen\"}}"
4. Layer B——始终提供改写选项(散文)
完成 Layer A 后,始终提供统计水印痕迹减弱处理,以处理自然语言内容。不要默默跳过此步骤。
对于纯文本(粘贴内容 / .txt),/clean 要求执行 Layer B:在 Layer A 之后应用默认策略(config/clean_strategy.json,例如
[email protected],[email protected])或 options.strategy 覆盖值,
报告 report.layer_b;如果未配置所需后端,则返回 400(mlm 步骤需要 transformers + roberta-large;LLM 步骤需要 WATERMARKS_REWRITE_* 配置)。Markdown/HTML 和其他容器文件(.md、.html、.tex、.pdf、.docx 等)会作为容器进行清理(元数据 +
Layer A),不会在 /clean 中执行 Layer B 改写;请提取其中的散文并将文本传给 /clean 来应用 Layer B,或者使用下方提示词并选用与疑似来源不同的模型(Claude 文本 → 不用 Claude;Gemini → 不用 Gemini;以此类推)。优先使用本地开放权重模型,并避免使用任何已知带水印的供应商。
多轮处理方案:
- Layer A 清理(通过
/clean) - 改写(默认)——明确调整用词 + 句法:更改从句顺序、连接词、过渡词和句子边界;在不影响含义的前提下替换实词和功能词;保留事实、数字、名称和代码 ID
- 可选的强力处理——
humanize(写得自然、像人写的)、回译,或先拟结构提纲再重写 - 再次对结果执行 Layer A(
/clean) - 如实报告残留风险(短文本/高度可预测文本 = 风险较低;长文本/高熵散文 = 风险较高)
**代码文件:**优先使用格式化工具(prettier、black、gofmt 等)+ Layer A。提供代码改写处理(注释/文档字符串/字符串字面量措辞 + 局部标识符重命名)时,必须明确征得用户同意,因为重命名标识符可能影响行为。
改写提示词(照原样使用)
保留含义的改写(用词 + 句法):
Rewrite the following text so that it uses substantially different wording at
the token level. Change clause order, connectors, and transition words; vary
sentence boundaries and length; and replace both content words and function
words where meaning allows. Preserve all facts, numbers, names, and technical
identifiers. Do not add or remove claims. Output only the rewritten text.
---
{TEXT}
自然化(写得像人写的):
Rewrite the following text so it reads as if a human wrote it from scratch.
Vary sentence rhythm and length, replace formulaic AI-style transitions and
filler with concrete natural phrasing, and use plain, varied wording. Preserve
all facts, numbers, names, and technical identifiers. Do not add or remove
claims. Output only the rewritten text.
---
{TEXT}
代码(注释 / 文档字符串 / 标识符):
Rewrite the natural-language parts of this code — comments, docstrings, and
string literals — using different wording. Rename local variables, function
parameters, and private helper names to semantically equivalent names. Preserve
program behavior, public API names, and all values that affect output. Output
only the rewritten code.
---
{TEXT}
回译(两步):
Translate the following text to {LANG}. Output only the translation.
Translate the following text to {ORIGINAL_LANG}. Preserve meaning; use natural
phrasing. Output only the translation.
结构化:
Extract a bullet outline of all claims and structure from the text (no full sentences).
然后:
Write a complete document from this outline in natural, varied human prose.
Avoid formulaic transitions. Do not omit any bullet. Output only the document.
聚合审计(目录 / 网站)
服务映像还附带了审计 CLI。需要审计目录或网站时,可将它们作为一次性容器运行:
# Local checkout, or inside the service image:
docker run --rm -v "$(pwd)/src:/data:ro" watermarks-remover \
/app/scripts/audit_dir.py /data --json
也可以针对仓库的本地检出运行:python3 service/scripts/audit_dir.py DIR --json。
审计退出码(在 --json、--sarif 和人类可读输出中相同):0 表示没有可采取行动的发现,1 表示有可采取行动的发现,2 表示用法错误 / 拒绝执行,3 表示部分扫描(部分文件或 URL 无法扫描——应视为结论不明;审计未完成,而非结果干净)。
5. 报告
务必说明:
- Layer A / 容器可验证地移除了什么(数量、操作)——依据
report。 - Layer B 做了什么(尽力而为的统计处理;不能声称官方“无法检测”)。对于简短 / 高度可预测的文本,残留风险较低;对于较长 / 熵较高的文本,残留风险较高。
- 不在处理范围内:音频水印和音频 / 视频 SynthID、C2PA 软绑定、密钥检测器、训练后门。像素域视频 TrustMark 仅会按帧选择性移除(部分移除——请参阅“限制”)。
- 软绑定 / 媒体水印经我们剥除后,厂商工具仍可能检测到。
- 除非用户要求原地修改,否则优先写入
*.cleaned.*。 - 伦理声明:仅处理自有内容 / 不搞合规作秀。
限制
- A 层不会移除 Token 采样水印。
- 没有供应商检测器/密钥,就无法对 B 层进行黄金标准验证。可选的 MarkLLM/MarkDiffusion 测试框架(
harness服务容器)会在操作前后验证特定方案配置,但仅限相同配置,不是供应商检测器的判定依据。 - 如果没有
exiftool,PDF 清理只能尽力而为;如果服务器端没有qpdf,清理也不完整。 - 嵌入图像(扫描件、Photoshop 导出文件)内部携带的 PDF 元数据还需要服务器端安装
ghostscript——请检查/capabilities。默认的deep_images: "auto"只会在文档级清理后仍留有标记时处理这类图像;"always"也会清除非 AI 相机和编辑器的 EXIF 信息,但需要重新蒸馏。如果要清除 JPEG 自身 APP 段中存储的任何内容,就必须重新压缩图像,因此"lossless"会在此之前停止。任何残留内容都会显示在报告常见的still_has_c2pa/still_has_ai_metadata/post_findings字段中,而不会出现在专属字段中。无法识别的值会报错,不会静默回退。 - “不改动图像数据”这一保证仅适用于 Ghostscript 能原样传递的编解码格式:JPEG(DCTDecode)和 JPEG2000(JPXDecode)。PDF 中的其他图像编解码格式——Flate、CCITT、LZW——会在重新蒸馏时解码并重新编码。这些格式在实际使用中是无损的,但字节不会完全一致。如果必须精确保留文档的图像流,请使用
deep_images: "never"。 - PDF 嵌入文件附件(回形针图标所示的文件,与图像不同)由
clean_attachments选项检查和清理,该选项需要qpdf。它会递归处理嵌套容器,直至达到深度上限;超过单个附件大小上限的附件会被跳过并保持不变,同时发出警告;清理后的字节会通过 qpdf 重新嵌入,因此 PDF 会被重写(线性化),不会保留原字节,且任何数字签名都会失效。always(默认值)会清除每个附件的元数据(递归处理时也遵循相同规则);auto只清理带有 AI/C2PA 标记的附件。如果运行了 Ghostscript 深度图像处理流程,附件会在之后从原文件重新添加,因此不会丢失。 .tex/.ltx:清理在源文件级别进行(清除\hypersetup/\pdfinfo中的来源字段和来源/工具注释行)。它不会处理编译后的输出文件——如果也需要清理编译后的 PDF,请对相应的.pdf再运行/clean。清理范围较广:也会清除通用来源字段名(pdfauthor/pdfcreator/pdfproducer、/Author//Creator//Producer,以及pdfsubject/pdfkeywords和 PDF 日期字段),并删除% !TEX工具注释及 Emacs/Vim modeline,因此无害文件中的这些内容也会被清除。- 可选地通过外部 CtrlRegen 后端(
remove_pixel: ctrlregen)或 MarkDiffusion 的 DiffusionPurification(remove_pixel: diffusion)移除像素域图像水印;两者计算开销都很大,会造成图像偏移,并且需要安装相应后端(/capabilities)。TrustMark 视频水印(逐帧处理并进行时间投票)只能根据公开协议选择性地逐帧移除:请检查/capabilities(tools.ffmpeg和pixel_backends.ctrlregen/diffusion),然后对.mp4/.mov调用 POST/clean,并设置options.remove_pixel=ctrlregen|diffusion。此操作只能部分移除水印,会重新编码视频,且未经供应商检测器验证。音频水印(silentcipher / AudioSeal / WavMark)也只能通过同一协议选择性地移除:请检查/health和/capabilities(tools.ffmpeg),然后对音频文件名(.wav/.mp3/.flac)调用 POST/clean,并设置options.remove_audio_watermark= true。此操作会应用有损变换链(变速 + 变调 + 均衡 + 低码率有损重新编码),会改变音频的音高/速度/音质/时长;无论输入容器为何,输出字节都封装在 M4A (AAC) 容器中,且未经供应商检测器验证。 - 逆向 SynthID 评分器来自外部,效果尽力而为,且受非商业研究许可约束;它不是 Google 官方检测器。Google 于 2026 年 8 月退役了 API 上的官方 SynthID 文本检测器,因此目前仅剩 MarkLLM 同配置测试框架。Claude 的检测 API 已宣布推出,但目前尚未公开——正式发布前,
claude-text检测器会报告不可用。 - C2PA 软绑定(元数据清理后重新链接到远程清单的内容水印)不在范围内——清除硬绑定 C2PA 不会将其清除。
- 数据驱动/后门模型标记(触发短语)不在范围内。
服务无法访问?
如果 $WM/health 失败:请告知用户服务已停止运行,以及如何启动服务
(docker compose up -d、make serve 或已发布的 GHCR 镜像)。不要
尝试在本地清理——此技能不包含任何清理代码。