|
| 1 | +# Qwen Direct-Prompt Judge Baseline - 2026-06-08 |
| 2 | + |
| 3 | +## Question |
| 4 | + |
| 5 | +Can the same local Qwen sensor model simply be prompted to classify tool |
| 6 | +poisoning, instead of reading its hidden activations and training a probe? |
| 7 | + |
| 8 | +This tests a common LLM-as-judge shape against the current activation-probe |
| 9 | +lane. It does not replace the product scanner. |
| 10 | + |
| 11 | +## Setup |
| 12 | + |
| 13 | +- Model: `Qwen/Qwen2.5-0.5B` |
| 14 | +- Device: Apple MPS |
| 15 | +- Prompt: fixed zero-shot `CLEAN` vs `POISONED` tool-security prompt |
| 16 | +- Script: `research/benchmark_qwen_prompt_judge.py` |
| 17 | +- Seed: `42` |
| 18 | +- Methods: |
| 19 | + - `choice-logprob`: compare the model probability of the next label |
| 20 | + ` CLEAN` vs ` POISONED`; |
| 21 | + - `generate`: ask the model to generate an answer, then parse the generated |
| 22 | + text. |
| 23 | + |
| 24 | +## Commands |
| 25 | + |
| 26 | +```bash |
| 27 | +.venv/bin/python -m research.benchmark_qwen_prompt_judge \ |
| 28 | + --dataset family_curated_v0 \ |
| 29 | + --max-samples 9999 \ |
| 30 | + --method choice-logprob \ |
| 31 | + --device auto \ |
| 32 | + --pretty |
| 33 | + |
| 34 | +.venv/bin/python -m research.benchmark_qwen_prompt_judge \ |
| 35 | + --dataset family_curated_v0 \ |
| 36 | + --max-samples 9999 \ |
| 37 | + --method generate \ |
| 38 | + --device auto \ |
| 39 | + --pretty |
| 40 | + |
| 41 | +.venv/bin/python -m research.benchmark_qwen_prompt_judge \ |
| 42 | + --dataset routeguard_external_v0 \ |
| 43 | + --max-samples 200 \ |
| 44 | + --method choice-logprob \ |
| 45 | + --device auto \ |
| 46 | + --pretty |
| 47 | + |
| 48 | +.venv/bin/python -m research.benchmark_qwen_prompt_judge \ |
| 49 | + --dataset routeguard_external_v0 \ |
| 50 | + --max-samples 100 \ |
| 51 | + --method generate \ |
| 52 | + --device auto \ |
| 53 | + --pretty |
| 54 | +``` |
| 55 | + |
| 56 | +## Results |
| 57 | + |
| 58 | +| Dataset | Method | n | Accuracy | Precision | Recall | F1 | Clean FPR | Unknown | |
| 59 | +| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | |
| 60 | +| `family_curated_v0` | `choice-logprob` | 76 | 0.500 | 0.500 | 1.000 | 0.667 | 1.000 | 0 | |
| 61 | +| `family_curated_v0` | `generate` | 76 | 0.500 | 0.500 | 0.789 | 0.612 | 0.789 | 16 | |
| 62 | +| `routeguard_external_v0` sample | `choice-logprob` | 200 | 0.500 | 0.500 | 1.000 | 0.667 | 1.000 | 0 | |
| 63 | +| `routeguard_external_v0` sample | `generate` | 100 | 0.590 | 0.696 | 0.320 | 0.438 | 0.140 | 77 | |
| 64 | + |
| 65 | +Saved outputs: |
| 66 | + |
| 67 | +- `research/_results/qwen_prompt_judge/20260608T072516Z-family-curated-qwen-choice-logprob-full.json` |
| 68 | +- `research/_results/qwen_prompt_judge/20260608T072539Z-family-curated-qwen-generate-full.json` |
| 69 | +- `research/_results/qwen_prompt_judge/20260608T072602Z-routeguard-qwen-choice-logprob-sample200.json` |
| 70 | +- `research/_results/qwen_prompt_judge/20260608T072711Z-routeguard-qwen-generate-sample100.json` |
| 71 | + |
| 72 | +## Read |
| 73 | + |
| 74 | +The direct-prompt baseline is not competitive with the activation scanner. |
| 75 | + |
| 76 | +The label-logprob version is deterministic and parse-free, but it collapses into |
| 77 | +an all-poison policy on both tested gates. That gives perfect poison recall but |
| 78 | +blocks every clean item, so it is not usable as a scanner default. |
| 79 | + |
| 80 | +The generation version reduces false positives on the RouteGuard sample, but it |
| 81 | +misses most poisoned rows and produces many unparseable outputs. That is a poor |
| 82 | +hot-path security contract: the scanner has to decide whether to allow, warn, or |
| 83 | +block, not interpret arbitrary text continuations. |
| 84 | + |
| 85 | +Important nuance: LLM-as-judge can be made more deterministic with fixed |
| 86 | +decoding, especially at `temperature=0`. The bigger product problem is prompt |
| 87 | +fragility, parseability, latency, and model/version drift. A fixed activation |
| 88 | +artifact has a simpler contract: same input, same model, same probe, same |
| 89 | +threshold, same score. |
| 90 | + |
| 91 | +## Current Position |
| 92 | + |
| 93 | +Keep raw Qwen activation probing as the v0 product default. Keep direct-prompt |
| 94 | +LLM judge baselines in the benchmark suite as a comparison lane, not as the |
| 95 | +scanner implementation. |
0 commit comments