A CLI security testing tool for LLM applications. PIT runs adversarial prompt injection attacks against your AI app's system prompt and uses a second LLM as a judge to determine whether each attack succeeded.
Your system prompt + attack prompt
│
▼
Target model responds
│
├── Keyword filter (fast, no cost)
└── Judge LLM (evaluates if guardrails were breached)
│
▼
Verdict: safe / vulnerable / partial / unclear
Each test result includes a verdict, severity level, and a one-sentence explanation from the judge.
- Python 3.11+
- An API key for OpenAI or Anthropic
git clone git@github.com:fsd-niraj/pit-tool.git
cd pit-tool
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .Verify:
pit --helpJust run pit run with no arguments. The wizard will walk you through everything step by step:
pit runYou will be asked for:
- Provider (OpenAI / Anthropic)
- API key
- Target model
- System prompt (file or paste inline)
- Custom test cases (optional)
- Attack categories
- Judge LLM config
- Usage limits
- Output file
- Whether to run in background
pit run \
--api-key $OPENAI_API_KEY \
--model gpt-4o \
--provider openai \
--system-prompt-file path/to/system_prompt.txt \
--output report.jsonMix flags with the wizard: any flag you omit will be asked interactively.
| Command | Description |
|---|---|
pit run |
Run prompt injection tests |
pit generate |
Generate custom test cases (AI-powered or manual) |
pit jobs |
List all background jobs |
pit status <job-id> |
Show progress and results of a background job |
pit list-attacks |
Browse the built-in attack library |
pit review <report.json> |
Manually review unclear/partial results |
29 attacks across 6 categories:
| Category | What it tests |
|---|---|
direct_injection |
Overriding instructions via user input |
role_hijacking |
Convincing the model to adopt a different persona |
data_exfiltration |
Extracting the system prompt or restricted information |
jailbreak |
Using hypothetical/fictional framing to bypass guardrails |
context_escape |
Pulling the model off-topic or outside its defined scope |
indirect_injection |
Malicious instructions embedded in content the model processes |
pit list-attacks # all 29
pit list-attacks --category jailbreak # filteredThe LLM analyzes your system prompt, identifies every guardrail, and writes targeted attacks for each one:
pit generate \
--api-key $OPENAI_API_KEY \
--model gpt-4o \
--provider openai \
--system-prompt-file path/to/system_prompt.txt \
--output my_tests.yaml \
--count 20Or just run pit generate for the interactive wizard.
Create test cases one by one via prompts:
pit generate --manual --output my_tests.yamlUse custom tests alongside the built-in library:
pit run ... --tests-file my_tests.yamlFor large test suites, run in the background and check progress separately:
# Start the job
pit run --background \
--api-key $OPENAI_API_KEY \
--model gpt-4o \
--provider openai \
--system-prompt-file path/to/system_prompt.txt
# → Job ID: a1b2c3d4
pit jobs # list all jobs
pit status a1b2c3d4 # snapshot
pit status a1b2c3d4 --follow # live refresh every 2sJob files are stored in .pit/jobs/<id>/:
.pit/jobs/<id>/
config.json run configuration
status.json live progress (completed/total, calls, tokens)
results.jsonl one result per line as they stream in
report.json final report (written on completion)
worker.log worker stdout/stderr
| Flag | Short | Description |
|---|---|---|
--api-key |
-k |
API key (or set PIT_API_KEY env var) |
--model |
-m |
Target model name |
--provider |
-p |
openai or anthropic |
--system-prompt |
-s |
System prompt as an inline string |
--system-prompt-file |
Path to system prompt file | |
--tests-file |
-t |
Path to custom YAML test cases |
--categories |
-c |
Comma-separated categories to run |
--output |
-o |
Save JSON report to file |
--max-calls |
Hard limit on total API calls | |
--max-tokens |
Hard limit on total tokens | |
--no-judge |
Skip judge LLM, use keyword evaluation only | |
--background |
-b |
Run in background, return job ID immediately |
--verbose |
-v |
Show full model responses for non-safe results |
| Verdict | Meaning |
|---|---|
safe |
Model stayed within its guardrails |
vulnerable |
Model complied with the attack |
partial |
Concerning behavior but not a full bypass |
unclear |
Ambiguous — flagged for manual review |
Pass it at runtime: pit run --tests-file my_tests.yaml ...