这是论文《An Efficient and Effective Agentic Group Shilling Attack on Recommender Systems》的官方代码。该论文介绍了 AGAS,这是一种针对黑盒协同过滤推荐系统的 LLM 驱动刷单攻击。一个协调者在多个轮次中编排一个由虚假用户工作者组成的池。在每一轮中,协调者从八种策略中选择一种,并为每个工作者分配一个角色。随后,工作者使用各自的 ReAct 风格推理循环来决定对哪些物品进行评分。
agent_attack_rs/
bash/ # Reviewer-friendly shell scripts (RQ1–RQ5)
prompts/ # Coordinator + per-role prompt templates
scripts/run_agas.py # Single entry point (--dataset --victim ...)
src/agas/
roles.py # Role enum {PR, SN, CA, IN} (paper symbols)
signals.py # WorkerSignals (τ, γ, φ) + EnvSignals (ρ, Δρ, η, ξ, a)
strategies.py # 8-strategy enum
agents/ # Coordinator + Worker policies
simulation/ # Episode runner (= AGAS algorithm outer loop)
llm/ # OpenAI / Ollama
recsys/ # Surrogate + 11-victim backends
data/ # Dataset loaders + preprocessing pipeline
tests/ # Pytest suite
AGAS 实例化四种工作角色(roles.py 中的论文符号):
| 符号 | 全称 | 功能 |
|---|---|---|
PR | Profiler | 安全填充项评分,用于探测平台并构建桥接池。 |
SN | Sniper | 载荷角色;直接目标推送或桥接项提升。 |
CA | Camouflageur | 隐蔽角色;通过看似良性的活动重建信任。 |
IN | Inactive | 本轮无操作(冷却或隔离)。 |
每轮 Coordinator 从 strategies.py 中精确选择八种策略之一
(参见 method_strategies.tex):
S1_VICTIM_PROBE)S2_BRIDGE_BUILDING,仅图受害者)S3_WARM_UP)S4_FIRST_PUSH)S5_SILENT_SLOWDOWN)S6_PROFILE_CLEANUP)S7_SAFE_REPLACEMENT)S8_MAIN_ATTACK)Coordinator 根据两组信号(signals.py)驱动这些决策:
τ_{t,w}, γ_{t,w}, φ_{t,w} — 信任、风险和一个
结构验证器。更新方程与 method_coordinator.tex
完全一致(eq:trust_update、eq:risk_update、eq:risk_decay、
eq:profile_validator)。ρ^{(t)}, Δρ^{(t)}, η_t, ξ_t = (q_t, s_t), a_t —
排名、排名变动、接受率、抑制信号、警报标志。
可疑度分数 q_t 是来自 eq:round_suppression_terms 和
eq:round_suppression_score 的五个归一化项 (d̂_t, δ̂_t, m̂_t, ŝ_t, g_t) 的 0.2 加权和。 ┌─────────────────────────────────────────────────┐
t=0…T-1 ──► │ 1. Observe ρ^{(t)}, update memory m_t │
│ 2. Update τ, γ, φ, η, ξ, a │
│ 3. Coordinator picks Strategy ∈ {S1…S8} │
│ and assigns Role ∈ {PR, SN, CA, IN} per worker│
│ 4. Workers act (filler / bridge / target items) │
│ 5. Validate + accept actions → ΔR̃^{(t+1)} │
│ 6. Refit / query victim → ρ^{(t+1)} │
└─────────────────────────────────────────────────┘
│
▼
t* = argmin_t ρ^{(t)}, return R* = [R ; R̃^{(≤t*)}]
外层循环在 src/agas/simulation/episode.py 中实现,并与
algorithms/agas_end_to_end.tex 保持一致。
| 组件 | 要求 | 测试版本 |
|---|---|---|
| Python | ≥ 3.10 | 3.13.5 |
| PyTorch | ≥ 2.1 (仅 targets) | 2.11.0+cu128 |
| CUDA | 可选 | 12.8 |
| NumPy | ≥ 1.24 | 2.4.2 |
| Pandas | ≥ 2.0 | 3.0.1 |
| SciPy | ≥ 1.10 | 1.17.0 |
| scikit-learn | ≥ 1.3 | 1.8.0 |
| openai SDK | ≥ 1.12 | 2.21.0 |
PyTorch 和 CUDA 仅用于深度学习受害模型([targets] 附加项)。核心 AGAS 循环以及基于规则/代理的路径在 CPU 上运行,不依赖 GPU。
pip install -e .
# If you want to use the deep-learning victim models (LightGCN, NeuMF, …)
pip install -e '.[targets]'
必需的环境变量:
| 变量 | 用途 | 默认值 |
|---|---|---|
OPENAI_API_KEY | 用于 Coordinator / worker LLMs 的 OpenAI Responses API 密钥。 | (未设置 → 回退) |
OPENAI_MODEL | 传递给 OpenAI 的模型名称。 | gpt-5.1 |
论文在六个公开的 CF 基准数据集上进行评估(参见 experiment.tex):
| 简称 | 来源 | 用户数 | 物品数 | 交互数 | 下载 | 将原始文件放入 |
|---|---|---|---|---|---|---|
| ML-100K | MovieLens 100K | 943 | 1,682 | 100,000 | GroupLens | data/ml-100k/ |
| ML-1M | MovieLens 1M | 6,040 | 3,706 | 1,000,209 | GroupLens | data/ml-1m/ |
| Genome 2021 | MovieLens Tag Genome 2021 | 37,941 | 84,661 | 2,000,000(上限) | GroupLens | data/genome2021/ |
| Netflix | Netflix Prize | 342,445 | 17,434 | 2,000,000(上限) | Kaggle | data/netflix/ |
| Douban | Douban Movie | 28,057 | 49,176 | 8,085,679 | HKUST | data/douban/ |
| Amazon | Amazon Reviews 2018 | 998,653 | 30,964 | 2,000,000(上限) | UCSD | data/amazon/ |
将原始下载文件放入 data/<dataset>/ 后,运行:
python scripts/preprocess_all.py --data-root data --output-root processed
每个数据集都会被重写为规范化的 interactions.csv + items.csv 文件,存放在 processed/<dataset>/ 下。冒烟测试使用 MovieLens 自带的更小的 ml-latest-small 样本。
预处理流水线不存储划分文件——它导出完整的交互日志。划分在运行时应用:
| 阶段 | 使用的数据 | 详情 |
|---|---|---|
| 训练 | interactions.csv 中的所有交互 | 代理模型(以及任何目标模型)在完整的历史评分集上进行拟合。 |
| 攻击评估 | 对分段用户进行排名 | 每轮之后,目标物品的平均排名会在真实良性用户中测量,这些用户对至少一个目标簇物品的评分 ≥ 4.0(最多 2 000 名用户)。不会将留出的测试集写入磁盘。 |
| 虚假注入 | 在内存中追加 | 虚假用户交互被追加,模型每轮增量重新拟合。它们永远不会混入规范化的 CSV 文件。 |
这遵循标准的 shilling 攻击评估协议:攻击者观察受害者在训练集用户上的排名并据此进行优化,模拟黑盒部署场景。