
LLM-gesteuertes agentisches Framework für Group-Shilling-Angriffe, das Black-Box-Collaborative-Filtering-Empfehlungsrankings mithilfe adaptiver Multi-Rollen-Strategien manipuliert und dabei der Erkennung entgeht.
Dies ist der offizielle Code zum Paper: „An Efficient and Effective Agentic Group Shilling Attack on Recommender Systems“. Dieses Paper stellt AGAS vor, einen LLM-gesteuerten Shilling-Angriff gegen Black-Box-Collaborative-Filtering-Empfehlungssysteme. Ein Coordinator orchestriert einen Pool von Fake-User-Workern über eine Sequenz von Runden. In jeder Runde wählt der Coordinator eine von acht Strategien und weist jedem Worker eine Rolle zu. Die Worker entscheiden dann, welche Items sie bewerten, indem sie ihre eigene ReAct-artige Reasoning-Schleife verwenden.
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
## 2. Methodenrückblick
AGAS instanziiert vier Worker-Rollen (Papiersymbole in `roles.py`):
| Symbol | Langname | Was es tut |
|--------|----------------|-------------------------------------------------------------------------|
| `PR` | Profiler | Sichere Filler-Item-Bewertungen, um die Plattform zu sondieren und Bridge-Pools aufzubauen. |
| `SN` | Sniper | Payload-Rolle; direkter Ziel-Push oder Bridge-Item-Promotion. |
| `CA` | Camouflageur | Stealth-Rolle; baut Vertrauen mit harmlos wirkender Aktivität wieder auf. |
| `IN` | Inactive | Keine Aktion in dieser Runde (Cool-down oder Quarantäne). |
Jede Runde wählt der Coordinator genau eine von acht Strategien aus
`strategies.py` (siehe `method_strategies.tex`):
1. **Victim Probe** (`S1_VICTIM_PROBE`)
2. **Bridge Building** (`S2_BRIDGE_BUILDING`, nur Graph-Opfer)
3. **Warm-up** (`S3_WARM_UP`)
4. **First Push** (`S4_FIRST_PUSH`)
5. **Silent Slowdown** (`S5_SILENT_SLOWDOWN`)
6. **Profile Cleanup** (`S6_PROFILE_CLEANUP`)
7. **Safe Replacement** (`S7_SAFE_REPLACEMENT`)
8. **Main Attack** (`S8_MAIN_ATTACK`)
Der Coordinator steuert diese Entscheidungen aus zwei Signalgruppen (`signals.py`):
* **Worker-Signale** `τ_{t,w}, γ_{t,w}, φ_{t,w}` — Vertrauen, Risiko und ein
struktureller Validator. Die Aktualisierungsgleichungen stimmen exakt mit
`method_coordinator.tex` überein (`eq:trust_update`, `eq:risk_update`, `eq:risk_decay`,
`eq:profile_validator`).
* **Umgebungssignale** `ρ^{(t)}, Δρ^{(t)}, η_t, ξ_t = (q_t, s_t), a_t` —
Rang, Rangbewegung, Akzeptanzrate, Unterdrückungssignal, Alarm-Flag. Der
Verdachtswert `q_t` ist die mit 0,2 gewichtete Summe der fünf normalisierten
Terme `(d̂_t, δ̂_t, m̂_t, ŝ_t, g_t)` aus `eq:round_suppression_terms` und
`eq:round_suppression_score`.
### Runden-Schleife (ASCII)```
┌─────────────────────────────────────────────────┐
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*)}]
Die äußere Schleife ist in src/agas/simulation/episode.py implementiert und spiegelt
algorithms/agas_end_to_end.tex wider.
| Komponente | Anforderung | Getestet mit |
|---|---|---|
| Python | ≥ 3.10 | 3.13.5 |
| PyTorch | ≥ 2.1 (nur targets) | 2.11.0+cu128 |
| CUDA | optional | 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 und CUDA werden nur für die Deep-Learning-Victim-Modelle benötigt (Extra [targets]). Die Kern-AGAS-Schleife und die regelbasierten / Surrogat-Pfade laufen auf der CPU ohne GPU-Abhängigkeit.
pip install -e .
pip install -e '.[targets]'
Erforderliche Umgebungsvariablen:
| Variable | Zweck | Standard |
|--------------------|---------------------------------------------------------------|--------------------------|
| `OPENAI_API_KEY` | OpenAI Responses API-Schlüssel für die Coordinator-/Worker-LLMs. | *(nicht gesetzt → Fallback)* |
| `OPENAI_MODEL` | An OpenAI übergebener Modellname. | `gpt-5.1` |
## 4. Datensätze
Das Paper evaluiert auf sechs öffentlichen CF-Benchmarks (siehe `experiment.tex`):
| Kurzname | Quelle | Nutzer | Elemente | Interaktionen | Download | Rohdateien ablegen in |
|-------------|---------------------------|----------:|-------:|-------------------:|-------------------------------------------------------------------|---------------------|
| ML-100K | MovieLens 100K | 943 | 1,682 | 100,000 | [GroupLens](https://files.grouplens.org/datasets/movielens/ml-100k.zip) | `data/ml-100k/` |
| ML-1M | MovieLens 1M | 6,040 | 3,706 | 1,000,209 | [GroupLens](https://files.grouplens.org/datasets/movielens/ml-1m.zip) | `data/ml-1m/` |
| Genome 2021 | MovieLens Tag Genome 2021 | 37,941 | 84,661 | 2,000,000 (begrenzt) | [GroupLens](https://grouplens.org/datasets/movielens/tag-genome-2021/) | `data/genome2021/` |
| Netflix | Netflix Prize | 342,445 | 17,434 | 2,000,000 (begrenzt) | [Kaggle](https://www.kaggle.com/datasets/netflix-inc/netflix-prize-data) | `data/netflix/` |
| Douban | Douban Movie | 28,057 | 49,176 | 8,085,679 | [HKUST](http://shichuan.org/HIN_dataset.html) | `data/douban/` |
| Amazon | Amazon Reviews 2018 | 998,653 | 30,964 | 2,000,000 (begrenzt) | [UCSD](https://nijianmo.github.io/amazon/index.html) | `data/amazon/` |