跳到主要内容
AI教程

从自有文本和文件中移除 AI 来源标记

本教程介绍如何安装和运行 watermarks-remover,以检查并移除您拥有或获准处理的内容中的 Unicode 载体、文档元数据和受支持的来源标记。

移除文本和文件中的 AI 来源标记

watermarks-remover 的作用

watermarks-remover 是一项智能体技能和 Python 服务,用于检查和清理文本及受支持文件格式中的 AI 来源标记。它适用于对您拥有或获准处理的材料进行隐私保护、研究和内容清理。

该智能体技能是一个轻量级 HTTP 客户端。它不包含清理实现,也不要求智能体主机安装 Python。它会将任务发送到一个单独运行、使用 Python 标准库构建的服务。

该项目将其工作分为三个领域:

  • 文本 A 层:以确定性方式移除不可见 Unicode 载体、特殊空格、双向文本控制符和标签字符。
  • 文本 B 层:通过大幅重写来减少统计型令牌采样水印。此操作仅尽力而为,并可能改变文体或表达风格。
  • 文件清理:从多种文件类型中移除受支持的 C2PA、EXIF、XMP、文档属性和容器元数据。

任何工具都无法保证供应商的检测器不再将内容识别出来。请保留原始文件,检查每个清理后的结果,并且仅对您拥有或获准处理的内容使用本项目。

主要功能和支持的格式

核心脚本要求使用 Python 3.10 或更高版本,并且仅使用标准库。系统会在可用时使用 c2patoolexiftoolqpdf 等可选工具。

支持的清理对象

  • 图像:PNG、JPEG、WebP、AVIF、HEIC、BMP、GIF、TIFF 和 SVG。
  • 文档:PDF、DOCX、XLSX、PPTX、EPUB 和 ODT。
  • 文本和网页文件:HTML 和 Markdown,包括受支持的元数据、JSON-LD、AI frontmatter 键和 A 层文本标记。
  • 媒体容器:MP4、MOV、M4A、M4V、WAV、MP3 和 FLAC。

无法识别的格式不会被自动清理。文本专用命令也会拒绝二进制文件,并引导您使用通用文件工具。

重要限制

核心清理不涵盖软绑定 C2PA,也不涵盖纯像素、音频和视频水印。PDF 清理需要使用 qpdf 进行结构性剥离,因为增量式元数据编辑可能留下可恢复的字节。可选的 Ghostscript 处理流程可以清除 PDF 内嵌图像中的元数据。

检测与清理相互独立。MarkLLM、keyed-Gumbel、Claude seams 和图像 SynthID 评分的可选检测器均需主动启用,并且被设计为在不可用时平稳失败。

安装智能体技能

克隆或下载代码仓库,进入其目录,然后运行安装程序。以下命令会为个人 Claude Code 配置安装由完整服务支持的技能:

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

可用的安装目标包括:

  • --target claude-code 会安装到 ~/.claude/skills/<skill>
  • --target claude-project --project-dir PATH 会安装到 PATH/.claude/skills/<skill>
  • --target cowork 会生成 dist/<skill>.zip,以便通过云端 Skills 界面上传。
  • --target cursor 会安装到 ~/.cursor/skills/<skill>

使用 python3 install_skill.py --list 可列出随项目提供的技能。该仓库提供完整的 remove-ai-marks 技能,以及独立运行且仅处理文本的 clean-user-facing-text 技能。除非使用 --force,否则系统会备份现有安装。如需直接基于检出目录进行实时编辑,请添加 --link

安装 Claude Code 插件

Claude Code 用户可以直接安装 marketplace 插件:

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

随后,这些技能将以 /watermarks-remover:remove-ai-marks/watermarks-remover:clean-user-facing-text 的形式加载。使用以下命令更新插件:

/plugin marketplace update watermarks-remover

为 Grok 链接技能

mkdir -p ~/.grok/skills
ln -sfn "$(pwd)/skills/remove-ai-marks" ~/.grok/skills/remove-ai-marks

启动服务

从代码仓库运行本地 HTTP 服务:

make serve

也可以显式启动服务器脚本:

python3 service/scripts/server.py --host 127.0.0.1 --port 8765

默认地址为 http://127.0.0.1:8765。如果服务运行在其他位置,请为该技能设置 WATERMARKS_SERVICE_URL。服务器默认绑定到回环地址,从而避免直接向其他机器公开服务。

检查服务是否正常响应:

curl -s http://127.0.0.1:8765/health

健康检查端点会返回一个包含 ok 和服务版本的对象。

从命令行检查和清理文件

最安全的工作流程是先检查文件,将清理结果写入新路径,然后与原始文件进行比较。

SCRIPTS=service/scripts

python3 "$SCRIPTS/inspect_file.py" draft.md
python3 "$SCRIPTS/clean_file.py" draft.md -o draft.cleaned.md
python3 "$SCRIPTS/clean_file.py" photo.png -o photo.cleaned.png
python3 "$SCRIPTS/clean_file.py" notes.docx -o notes.cleaned.docx

对文本和二进制容器都可以使用 inspect_file.pyclean_file.py。这些命令会根据文件选择合适且受支持的清理器。

清理 A 层文本标记

对于纯文本输入,可使用以下命令检查不可见 Unicode 载体和基于编辑的 Unicode 载体:

python3 "$SCRIPTS/inspect_text.py" draft.md

然后创建清理后的副本并输出统计信息:

python3 "$SCRIPTS/clean_text.py" draft.md -o draft.cleaned.md --stats

A 层是确定性的,并且旨在确保可见文本不受损失。请勿将 DOCX、PDF、图像或其他二进制输入传递给这些文本命令;请改用文件命令。

准备 B 层重写

统计型文本水印需要通过重写处理,而不能仅靠移除字符。默认情况下,重写命令会输出一段提示词:

python3 "$SCRIPTS/rewrite_text.py" draft.md --backend print-prompt --strength paraphrase

B 层采用迭代方式且仅尽力而为。它可能降低对原始文体和表达风格的忠实度。当质量比水印清理更重要时,项目建议使用 A 层和文件清理,同时保留原始文本。

使用 HTTP API

该服务提供检查、检测、清理、批处理、能力发现以及 OpenAPI 规范。

  • GET /health 报告服务健康状态和版本。
  • GET /capabilities 报告可用的可选工具和后端。
  • GET /openapi.json 返回 OpenAPI 3.0.3 规范。
  • POST /inspect 返回输入类型、可疑状态和报告。
  • POST /detect 返回已配置检测器的结果。
  • POST /clean 返回清理后的 base64 数据和报告。
  • POST /inspect/batchPOST /clean/batch 每次请求最多可处理 50 个文件。

以下示例将一个 Markdown 文件编码为 base64,并将其发送到清理端点:

WM="http://127.0.0.1:8765"
curl -s "$WM/health"
curl -s -X POST "$WM/clean" -H 'Content-Type: application/json' \
  -d "{\"file\": \"$(base64 < notes.md | tr -d '\n')\", \"name\": \"notes.md\"}"

设置 WATERMARKS_SERVER_API_KEY 可要求使用 bearer 身份验证。如果部署范围超出本地开发机器,请保留身份验证和适当的网络控制措施。

使用 Docker 运行服务

使用只读文件系统和临时目录构建并运行核心镜像:

make docker-core-build
docker run --rm -p 127.0.0.1:8765:8765 --read-only --tmpfs /tmp watermarks-remover

Docker Compose 支持多种 profile:

docker compose up -d
docker compose --profile harness up -d
docker compose --profile heavy up -d
  • 默认配置会启动核心服务。
  • harness profile 会添加 MarkLLM 和 MarkDiffusion 组件。
  • heavy profile 会添加本地构建的 CtrlRegen 和 SynthID 组件。

核心、MarkLLM 和 MarkDiffusion 镜像发布在 GHCR 上。由于上游许可限制,CtrlRegen 和 SynthID 评分器仍只能在本地使用。将 .env.example 复制为 .env 可进行可选配置;基本文本清理不需要任何额外设置。

使用钩子启用自动检查

智能体技能本质上是一组指令,因此是否调用它由模型决定。钩子则更具确定性:每当发生匹配的工具调用时,它都会运行。

Claude Code 插件会为 WriteEditMultiEditNotebookEdit 注册一个 PostToolUse 钩子。该钩子会以以下两种模式之一调用 service/scripts/hook_written_file.py

  • check:默认模式,仅报告标记而不修改文件。
  • clean:原地移除受支持的标记并通知模型。

通过插件的 Hook mode 设置选择模式,或设置:

WATERMARKS_HOOK_MODE=clean

如果不使用插件,可以在 ~/.claude/settings.json 中手动注册钩子。钩子会覆盖智能体写入的文件和 pre-commit 检查关卡,但直接清理聊天记录中的文本仍然只能尽力而为,并依赖该技能。

添加 pre-commit 检查

如需在带标记的文件进入 Git 提交前将其拦截,请将该仓库的检查钩子添加到 .pre-commit-config.yaml

repos:
  - repo: https://github.com/guillaumemeyer/watermarks-remover
    rev: v0.5.0
    hooks:
      - id: watermarks-remover-check

发现标记时,watermarks-remover-check 钩子会检查失败。另一种 watermarks-remover-clean 钩子会原地清理文件,并且必须显式选择启用。

高级技巧

保留原始文件并比较结果

尽可能将清理后的数据写入单独的输出路径。这对于 B 层重写和复杂文档容器尤其重要,因为处理过程可能影响文本、内嵌资源或特定于应用程序的属性。

安装合适的 PDF 工具

需要真正的 PDF 结构性剥离时,请使用 qpdf。README 警告称,仅使用 exiftool 会执行增量更新,可能留下可恢复的旧字节。如果内嵌图像中可能存在元数据,请使用可选的 Ghostscript 深度处理流程。

将检测和清理视为不同操作

清理操作会移除受支持的载体和元数据,而检测器则用于估计是否存在已配置的水印方案。例如,只有使用相同配置时,MarkLLM 验证才有意义;keyed-Gumbel 重放则需要生成密钥。这些工具并不是适用于所有供应商的万能判定器。

谨慎选择 B 层

如果使用 B 层,项目建议选择非原始生成模型,以降低再次应用同类标记的可能性。由于大幅改写可能破坏语气和准确性,因此当保留写作质量更为重要时,应跳过此步骤。

探索可选后端

service/scripts/ 下的引导脚本可配置用于图像评分的 reverse-SynthID、用于像素域移除的 CtrlRegen、用于验证已配置文本水印的 MarkLLM,以及用于图像水印实验的 MarkDiffusion。这些后端有不同的要求和限制;启用前请查阅其设置脚本。

负责任地使用

仅可将 watermarks-remover 用于对您拥有或获准处理的内容进行隐私保护、研究和清理。它不应用于学术欺诈,也不应用于谎称由 AI 生成的材料是人类创作的。请遵守适用法律和机构政策。

该项目采用 MIT License。有关版本发布和源代码,请访问 watermarks-remover GitHub 代码仓库

总结

watermarks-remover 集成了确定性文本清理、多种文件容器的元数据移除、可选检测后端、智能体集成、钩子和 HTTP API。请先执行检查,保留原始文件,应用范围最窄且合适的清理层,并检查结果,而不要将任何检测器的结果视为绝对可靠的结论。