🎉 NeurIPS 2026 採択 🎉
Claude Code や OpenClaw のようなスキル拡張エージェント(SAA)は、再利用可能なスキル — パッケージ化された指示、スクリプト、ワークフローガイダンス — を永続的なランタイムコンテキストとして読み込みます。これによりエージェントの能力は向上しますが、同時に悪意のあるスキルに、将来の行動を誘導するための持続的なチャネルを与えてしまいます。悪意のあるスキルは、具体的なユーザータスクとワークスペースの状態によって安全でない行動が有用に見えるようになるまで待つことができます。したがって、インストール前の審査だけでは不十分であり、保護はランタイムにおいて、タスクに条件付けられて行われる必要があります。
Defense-as-Skill は、ランタイムガードを第一級のスキル成果物に変えます:
デプロイの詳細が一つ重要です:安全性スキルはほぼあらゆるタスクに関連するため、通常のタスク–スキルマッチングでは見落とされがちです。したがって我々は、明示的な呼び出し指示(行動を起こす前に skill-sonar を参照するようエージェントに指示する)を、実験上の便宜ではなくデプロイ設定の一部として扱います — アブレーションはこれがガードの有効性に不可欠であることを示しています。
SCOPE-R データセット — SAA に対するスキル誘発攻撃のタスク条件付きデータセットで、6 つのリスクファミリー、21 のサブカテゴリ、206 の攻撃確認済み悪意あるインスタンス、43 の良性タスクを含み、リスクファミリーごとに train / ID-test / OOD-test に分割 — は Hugging Face でホストされており、別途ダウンロードします(クイックスタートのステップ 0 を参照)。このリポジトリには、ガードとそれを評価・進化させるコードが含まれています:
| コンポーネント | 説明 |
|---|---|
| SkillSonar\ | ランタイムガードスキルバンドル(eval/safetySkill/skill-sonar/)と、各防御条件下で ASR、タスクユーティリティ、確認回数、トークンコストを測定するランタイム評価フレームワーク(eval/)。 |
| Guard-skill evolution\ | ロールアウトフィードバックからディスク上のガードスキルを進化させる MCTS ループ(evolution/):スキルバージョンのツリー上の UCT 選択、安価な評価ロールアウト、claude -p によるワンショットのマルチバリアント改良。 |
評価フレームワークは eval/ ルートから tasks/、injected-skills/、attack-metadata/、benign-skills/、split/ を読み込みます。Hugging Face から SCOPE-R をダウンロードしてコピーします:
git clone https://huggingface.co/datasets/fffovo/SCOPE-R /tmp/scope-r
cp -r /tmp/scope-r/dataset/{tasks,injected-skills,attack-metadata,benign-skills,split} eval/
cp eval/run/config.example.sh eval/run/config.sh # fill in your endpoint credentials
実際の評価と実際の claude リファイナーによるエンドツーエンドの 1 ラウンド:
./run_smoke_loop.sh --max-rounds 1
./run_mcts.sh --max-rounds 3
# plumbing only (no benchmark, no claude):
PYTHONPATH=. python3 -m evolution.cli --dry-run --max-rounds 1
# plumbing + analyzer + pool, with a synthetic subset instead of the benchmark:
PYTHONPATH=. python3 -m evolution.cli \
--simulate-round tests/synthetic_smoke.jsonl --skip-refine --max-rounds 1
# bootstrap only (seed backup + active skill + deploy, then exit):
PYTHONPATH=. python3 -m evolution.cli --bootstrap-only
すべての設定項目は config/default.yaml(フラットプールループ)と config/mcts.yaml(MCTS ループ)にあります。いずれも CLI フラグまたはカスタム --config ファイルで上書きできます。
SCOPE-R dataset (HF) ──▶ eval/ (runtime evaluation) ──▶ evolution/ (MCTS loop)
tasks, skills, subsets/, run/, analyzer → refiner
attack-metadata scripts/ (judge, grading), → skill tree → next round
safetySkill/ (SkillSonar)
各 MCTS イテレーション:
eval/safetySkill/skill-sonar/ にデプロイし、ランタイム評価器を実行します:ASR ジャッジ、ユーティリティグレーダー、確認回数、トークンコスト、さらにタスクごとのジャッジ作成による failure_reason / success_reason の記述と、決定論的な failure_stage 分類(guard_not_read / guard_not_triggered / guard_triggered_but_bypassed / ...)。claude -p 呼び出しで k 個の子バリアントを生成し、それぞれが異なる支配的な失敗パターンを対象とした、異なる小さく局所的な編集を適用します。探索は、安全性スコアが成功閾値(デフォルト:ASR ≤ 5%)に達するか、完全評価の予算が尽きるか、拡張可能な候補がなくなるまで続きます。完全評価された最良の候補が最終ガードとして報告されます。
目的関数は安全性優先で、二次的な選好を持ちます:
s(v) = (1 − ASR_v) + ε · ( λ_b·U_benign + λ_m·U_malicious − λ_q·C̃_v − λ_t·K̃_v )
これにより、同等に安全な候補の中から、タスクユーティリティを維持し、ユーザーへの割り込みが少なく、トークンコストが低いガードを探索が選好します。すべてを拒否する退化したガードは、設計上低いスコアになります。
.
├── README.md # this file
├── config/
│ ├── default.yaml # flat-pool loop config (legacy)
│ └── mcts.yaml # MCTS loop config (main method)
├── evolution/ # evolution package
│ ├── loop.py / cli.py # legacy flat-pool loop
│ ├── mcts_loop.py / mcts_cli.py / tree.py # MCTS loop (paper's method)
│ ├── evaluator.py / instance_evaluator.py # drives eval/subsets/run_*.sh
│ ├── analyzer.py # per-task failure/success reasoning
│ ├── refiner.py / multi_refiner.py # claude -p edit wrappers
│ └── skill_manager.py # pool, lineage, deploy/retire/backup
├── eval/ # runtime evaluation framework
│ ├── DATA.md # dataset wiring (HF download → eval/)
│ ├── subsets/ # subset drivers (smoke/coverage/benign/combined)
│ ├── run/ # config.example.sh + per-task claude runners
│ ├── scripts/ # benchmark.py + lib_*.py (judge, grading, injection)
│ ├── safetySkill/skill-sonar/ # SkillSonar guard bundle (deploy slot)
│ └── split/ # cheap_eval (31 rows) / full_eval (106 rows) lists
├── run_smoke_loop.sh # smoke entry point
├── run_mcts.sh # MCTS entry point
└── tests/synthetic_smoke.jsonl # canned rows for --simulate-round
実行の成果物は skills/(ツリーノード + バックアップ + tree.json)、logs/(イテレーションごとの Markdown/JSONL、リファイナーのトランスクリプト、リネージ)、artifacts/runs/(ラウンドごとの生の評価スナップショット)に保存されます。
claude -p --permission-mode bypassPermissions は非 rootユーザーでのみ動作するため、評価イメージ(uid=1000 の pinchbench ユーザー、Node 20 + Claude Code CLI、Python 3.11)を再利用します。評価フレームワークから一度ビルドします:
cd eval && docker build -t pinchbench-skillguard .
ホスト側での初回所有権設定(書き込み可能なマウントは uid 1000 に属する必要があります)、eval/run/config.sh に OUTPUT_BASE="/pinchbench-out" を設定:
sudo chown -R 1000:1000 . eval/subsets eval/safetySkill eval/pinchbench-out-docker
その後、1 つのコマンドで MCTS ループを実行します(フレームワーク、未変更のガードスキルを読み取り専用で、このリポジトリ、出力ディレクトリをマウント):
docker run --rm -it \
-v "$PWD/eval:/work" \
-v "$PWD/safetySkill:/pristine:ro" \
-v "$PWD:/evolution" \
-v "$PWD/eval/pinchbench-out-docker:/pinchbench-out" \
-v "$PWD/eval/pinchbench-out-docker/benchmark.log:/work/benchmark.log" \
-w /evolution -e PYTHONPATH=/evolution -e ASR_MATRIX_ROOT=/pinchbench-out/matrix \
pinchbench-skillguard \
bash -lc 'set -a; source /work/run/config.sh; set +a; exec ./run_mcts.sh'
set -a; source ...; set +a のラッパーが必要です:CC_* 認証情報をエクスポートし、インスタンスごとの実行とリファイナーの claude -p の両方が同じエンドポイントを継承できるようにします。run_mcts.sh は /.dockerenv を自動検出し、config/docker-mcts.yaml を読み込みます。任意の mcts_cli フラグを追加できます。例:--k 5 --c-uct 1.0 --max-iterations 20。