🎉 已被 NeurIPS 2026 接收 🎉
技能增强型智能体(SAA),如 Claude Code 和 OpenClaw,会将可复用的技能——打包好的指令、脚本和工作流指南——作为持久化的运行时上下文加载。这使智能体能力更强,但也为恶意技能提供了一条持久化通道来操纵未来的行为:它可以等待,直到具体的用户任务和工作区状态使某个不安全操作看起来有用。因此,仅靠安装前审查是不够的——防护必须在运行时、以任务为条件进行。
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/),以及运行时评估框架(eval/),用于测量每种防御条件下的 ASR、任务效用、确认次数和 token 成本。 |
| Guard-skill evolution\ | MCTS 循环(evolution/),根据 rollout 反馈演化磁盘上的防护技能:在技能版本树上的 UCT 选择、廉价评估 rollout,以及通过 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 精炼器进行一次端到端轮次:
./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 评判器、效用评分器、确认次数、token 成本,以及每个任务由评判器撰写的 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 )
因此在同等安全的候选之间,搜索偏好那些保持任务效用、更少打断用户、消耗更少 token 的防护。一个退化的“全部拒绝”防护按设计得分很低。
.
├── 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
然后用一条命令运行 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。
| 标志 | 作用 |
|---|---|
--config PATH | 备用 YAML 配置 |
--subset {smoke,coverage} | 评估子集(扁平池循环) |
--max-rounds N / --max-iterations N | 轮次 / 迭代上限 |
--asr-target F | 恶意 ASR ≤ F 时停止 |
--k N | 每次 MCTS 扩展的子变体数(默认 3) |
--c-uct F | UCT 探索权重(默认 0.7) |
--max-full-evals N | 完整评估预算(默认 10) |
--score-fn {asr_inv,guard_effective_rate} | 廉价评估分数映射 |
--eval-jobs N | 每次评估的并行实例工作进程数 |
--dry-run | 跳过基准测试 + 精炼器,仅执行日志记录 |
--simulate-round PATH | 向分析器/池提供合成子集 jsonl |
--skip-refine | 执行评估 + 分析器 + 池,但不调用精炼器 |
--bootstrap-only | 初始化工作区 + 部署初始技能,然后退出 |
--refiner-model ALIAS | 覆盖精炼器的 claude -p 模型 |