mcpField
R
remove-ai-marks

remove-ai-marks

github.com/guillaumemeyerクリエイティブ・メディア25.3k931 回インストール1 週間前に更新
リポジトリ

remove-ai-marks について

remove-ai-marksは、テキストやファイルからAI関連の痕跡を除去するスキルです。プライバシー、衛生管理、研究のために自分のコンテンツを扱う人を対象とし、処理は別のHTTPサービスに委ねます。利用可能なバックエンドを確認してから、検出や画像処理を案内します。

主な機能

  1. 01テキストやファイルの痕跡を検査
  2. 02テキストとファイルのメタデータを除去
  3. 03対応するテキスト・画像の透かしを検出
  4. 04オプションのピクセル除去バックエンド
  5. 05処理前にサービス機能を確認

活用シーン

  1. 01文書に疑わしい痕跡がないか確認
  2. 02対応ファイルのメタデータを除去
  3. 03処理前後の透かし検出結果を比較

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/guillaumemeyer/watermarks-remover --skill remove-ai-marks

インストール後、Claude Code で/remove-ai-marksを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
ethics.md
how-claude-marks.md
mark-classes.md
markdiffusion.md
removal-matrix.md
vendor-notes.md

詳細

AI マークを削除する

テキスト(Unicode + 統計的な書き換え)とファイル(一般的なコンテナに含まれる C2PA / AI メタデータ)を対象とした、複数ベンダー対応の検出回避のための衛生処理です。

必要に応じて、以下をお読みください。

  • references/mark-classes.md — Unicode /サンプリング/ C2PA /コンテナ
  • references/vendor-notes.md — Claude、Gemini/SynthID、OpenAI、オープン LLM
  • references/removal-matrix.md — 対象に応じた処理レイヤー
  • references/ethics.md — 想定される用途
  • references/how-claude-marks.md — Anthropic 固有の詳細
  • references/markdiffusion.md — オプションの MarkDiffusion 画像ハーネス(方式、誠実さに関する注意事項)

このスキルは薄いクライアントです。決定論的なクリーニング処理はすべて別の HTTP サービス(このリポジトリの service/)で実行されるため、エージェントホストに 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)

ペイロードは、ファイルを base64 でエンコードした JSON です。エージェントは 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(テキスト:"[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 エージェントでは、 [Convert]::ToBase64String([IO.File]::ReadAllBytes("notes.md")) を使って base64 を生成してください。)

倫理

自身のコンテンツ(プライバシー、衛生管理、研究)を対象としています。結果を「人間が書いたことの証明」として宣伝しないでください。 ユーザーが学術不正や違法な非開示を明確に意図している場合は、references/ethics.md を参照して警告し、 それでも本人が所有するコンテンツの技術的なクリーニングのみを実施してください。

ワークフロー

1. 入力を分類する
入力処理先
貼り付け/クリップボードのテキスト一時ファイル → /inspect、次に /clean(テキスト)
.txt /コードテキスト Layer A(コードにはフォーマッターも適用)
.md /.html /.tex /.ltxコンテナーのクリーニング(フロントマター/メタデータまたは \hypersetup/\pdfinfo とコメント内の来歴情報)+ Layer A。Layer B は /clean のテキスト処理またはエージェントの書き換えモデルを使って文章に適用
.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"}'

または、検出をクリーニングに組み込みます。{"options": {"detect_before": true, "detect_after": true}} を指定して /clean を実行すると、レポートに 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. レイヤー B — 書き換えを必ず提案する(文章)

レイヤー A の後で、自然言語コンテンツには統計的マーク削減パスを必ず提案してください。 この手順を黙って省略しないでください。

プレーンテキスト(貼り付けたテキスト/.txt)の場合、/clean ではレイヤー B が必須です。 レイヤー 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 など)はコンテナーとしてクリーニングされ (メタデータ+レイヤー A)、/clean ではレイヤー B の書き換えを実行しません。 テキストを抽出して /clean にテキストとして渡すか、出所が疑われるモデルとは異なるモデル (Claude のテキストなら Claude 以外、Gemini なら Gemini 以外など)を使って、以下のプロンプトを 実行し、その文章にレイヤー B を適用してください。ローカルのオープンウェイトモデルを優先し、 ウォーターマークが付いていることが知られているベンダーは避けてください。

複数パスの手順:

  1. レイヤー A のクリーニング(/clean 経由)
  2. 言い換え(デフォルト)— 語句の選択と構文を明示的に変化させます。節の順序、接続表現、つなぎの語、文の区切りを変更し、意味を保てる範囲で内容語と機能語を置き換えます。事実、数値、名前、コード ID は保持します
  3. オプションの強力なパス — humanize(自然な人間の文章にする)、逆翻訳、または構造化アウトラインからの再生成
  4. 結果に対してレイヤー A を再度実行(/clean)
  5. 残存リスクを正直に報告します(短く予測しやすいテキストは低く、長くエントロピーの高い文章は高くなります)

コードファイル: フォーマッター(prettier、black、gofmt など)とレイヤー A の使用を優先してください。 コードの書き換えパス(コメント/docstring/文字列リテラルの文言+ローカル識別子の名前変更)は、 識別子の名前変更が動作に関わる可能性があるため、ユーザーの明示的な承認を得たうえで提案してください。

書き換えプロンプト(そのまま使用)

意味を保った言い換え(語句の選択+構文):

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}

コード(コメント/docstring/識別子):

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}

逆翻訳(2 段階):

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. レポート

必ず次の内容を記載してください。

  • レイヤー A/コンテナが検証可能な形で削除した内容(件数、処理内容) — report から取得します。
  • レイヤー B の処理内容(統計的なベストエフォートであり、公式に「検出不能」とは主張できません)。短く予測しやすいテキストでは残存リスクが低く、長くエントロピーの高い文章では高くなります。
  • 対象外:音声ウォーターマークおよび音声/動画の SynthID、C2PA のソフトバインディング、秘密鍵を用いる検出器、学習データへのバックドア。ピクセルドメインの動画 TrustMark は、フレームごとにオプションで削除されるにとどまります(部分的です。制限事項を参照)。
  • ソフトバインディング/メディアウォーターマークは、除去処理後もベンダーのツールで検出される可能性があります。
  • ユーザーからその場での処理を依頼されていない限り、*.cleaned.* への書き込みを優先してください。
  • 倫理に関する一文:自分のコンテンツを対象とし、コンプライアンスを装う行為はしないでください。

制限事項

  • レイヤー A では、トークンのサンプリングに埋め込まれたウォーターマークは削除されません。
  • ベンダーの検出器やキーがなければ、レイヤー B をゴールド検証することはできません。オプションの MarkLLM/MarkDiffusion ハーネス(サービス harness コンテナー)は、処理の前後で特定のスキーム設定を検証しますが、同一設定の場合に限られ、ベンダー検出器のオラクルではありません。
  • PDF のストリップ処理は、exiftool がない場合はベストエフォートであり、サーバー側に 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 の埋め込みファイル添付(画像とは別の、クリップアイコンで表示されるファイル)は、qpdf が必要な clean_attachments オプションで検査およびクリーニングされます。入れ子になったコンテナーを深さの上限まで再帰的に処理します。添付ファイルごとのサイズ上限を超えるものは処理されず、警告を表示してそのまま残します。また、クリーニングしたバイト列は 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 のモデルラインも取り除きます。そのため、無害なファイルからもこれらの情報が失われます。
  • ピクセル領域の画像ウォーターマークは、外部の CtrlRegen バックエンド(remove_pixel: ctrlregen)または MarkDiffusion の DiffusionPurification(remove_pixel: diffusion)を使って、オプションで削除できます。どちらも負荷が高く、画像に変化をもたらし、バックエンドが利用可能である必要があります(/capabilities)。TrustMark の動画ウォーターマーク(フレームごとに処理し、時間方向の投票を行うもの)は、公開コントラクトを通じてフレームごとにオプションでのみ削除できます。/capabilities(tools.ffmpeg および pixel_backends.ctrlregen/diffusion)を確認し、.mp4/.mov に対して options.remove_pixel = ctrlregen|diffusion を指定して POST /clean を実行してください。削除は部分的で、動画を再エンコードするため、ベンダー検出器による検証はされません。音声ウォーターマーク(silentcipher/AudioSeal/WavMark)も、同じコントラクトを通じてオプションでのみ削除できます。/health と /capabilities(tools.ffmpeg)を確認し、音声ファイル名(.wav/.mp3/.flac)に対して options.remove_audio_watermark = true を指定して POST /clean を実行してください。これにより、音声のピッチ/テンポ/品質/長さが変わる破壊的な変換処理(テンポ + ピッチ + EQ + 低ビットレートの非可逆再エンコード)が適用されます。入力コンテナーにかかわらず、バイト列は M4A(AAC) コンテナーで返され、ベンダー検出器による検証はされません。
  • 逆 SynthID スコアラーは外部サービスで、ベストエフォートでの提供となり、非商用の Research License が適用されます。Google の公式検出器ではありません。Google は 2026 年 8 月に API 上の公式 SynthID-text 検出器を廃止したため、現在利用できるのは MarkLLM の同一設定ハーネスのみです。Claude の検出 API は発表されていますが、まだ公開されていません。提供が開始されるまでは、claude-text 検出器は利用不可と報告します。
  • C2PA ソフトバインディング(メタデータをストリップした後にリモートマニフェストへ再リンクするコンテンツウォーターマーク)は対象外です。ハードバインドされた C2PA をストリップしても、ソフトバインディングは削除されません。
  • データ駆動型/バックドア型のモデルマーク(トリガーフレーズ)は対象外です。

サービスに接続できませんか?

$WM/health が失敗した場合は、サービスが停止していることと、起動方法 (docker compose up -d、make serve、または公開済みの GHCR イメージ)をユーザーに伝えてください。ローカルのクリーンアップは試みないでください。このスキルにはクリーンアップ用のコードは含まれていません。

コメント