ライブデモ: https://prompt-injection-firewall.streamlit.app 2分間のデモ動画: https://drive.google.com/file/d/1tzb75nFysisrCYa11Lqj6egDs5VNmc2n/view?usp=drivesdk
LLMサポートボット向けの2層ファイアウォール: ユーザーが送信する内容と、ボットが送信する内容の両方を検査します。
ユーザーはボットのルールを上書きしようとしたり(「以前の指示を無視して」)、ペルソナを切り替えたり、システムプロンプトや秘密情報を明かさせようとしたりする可能性があります。本プロジェクトはそうした入力をブロックし、ボットの回答における情報漏洩を検出し、失敗するケースを含めてその有効性を測定します。
user input
|
v
[1] Rule layer (regex, fast, free) --match--> BLOCK
|no match
v
[2] LLM classifier (Gemini, JSON output, Pydantic validation, retries, fail-closed) --attack--> BLOCK
|benign
v
AcmeBot (Gemini + system prompt)
|
v
[3] Output check (canary token, secret patterns, system-prompt fragments) --leak--> BLOCK
|clean
v
answer to user
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .env # then put your Gemini key in .env
python src\run_eval.py dev
python src\eval_output.py dev
python src\compare.py dev
streamlit run app.py # local demo
使用モデル: gemini-3.1-flash-lite。無料枠は混雑時に503を返すことがあるため、コードは待機してリトライします。
data\cases.jsonl を再ビルドしたい場合を除き、src\build_cases.py は実行しないでください(上書きされます。同じシードなら同じケースが生成されます)。
deepset/prompt-injections(Apache-2.0)から25件をサンプリング(シード7): 攻撃12件、正常13件。分割: dev 15件、hidden 10件。data/train.parquet はリポジトリに含まれています(出典: deepset/prompt-injections、Apache-2.0)。| セット | レイヤー | 結果 |
|---|---|---|
| dev | ルールのみ | 検出 2/9、誤検知 0/6 |
| dev | ルール + Gemini(最終) | 検出 8/9、誤検知 0/6 |
| dev | 出力チェック(最終) | リーク検出 4/4、誤検知 0/4 |
| hidden | ルール + Gemini | 検出 3/3、誤検知 0/7 |
| hidden | 出力チェック | リーク検出 3/3、誤検知 0/1 |
ファイアウォールあり vs なし:
| なし | あり | |
|---|---|---|
| dev: ボットに到達した攻撃 | 9/9 | 1/9 |
| dev: 誤ってブロックされた正常 | 0/6 | 0/6 |
| hidden: ボットに到達した攻撃 | 3/3 | 0/3 |
| hidden: 誤ってブロックされた正常 | 0/7 | 0/7 |
hiddenセットには攻撃が3件しかないため、弱いシグナルです。devで分類器のプロンプトを調整したため、devとhiddenは別々に報告しています。
数値を含む完全な履歴は CHANGELOG.md にあります。要約すると: