An LLM-powered agent that triages vulnerability scan findings, retrieves CVE context, scores risk, and auto-generates a prioritized remediation report — using tool-calling.
Security teams drown in scanner output. This project is an autonomous AI agent that takes raw vulnerability findings and does the analyst's first pass automatically:
- Looks up each CVE for real context, impact, and a known fix
- Scores every finding with a deterministic risk model (severity × exposure × exploit availability)
- Prioritizes findings into P1–P4 bands with remediation SLAs
- Writes a clean, ready-to-share remediation report
It is built as a genuine tool-calling agent: the language model is given the findings plus a set of tools and autonomously decides when to call them — the same perceive → decide → act loop used by frameworks like LangChain and CrewAI, implemented directly here so the internals are transparent and the dependency footprint stays tiny.
Built by a security engineer — it bridges practical penetration-testing knowledge with modern AI agent design.
- 🤖 Real agent loop — LLM-driven tool calling, not a hard-coded script
- 🔌 Provider-agnostic — any OpenAI-compatible endpoint (OpenAI, Azure OpenAI, OpenRouter, or a local model via Ollama / LM Studio)
- 🧰 Pluggable tools —
lookup_cveandscore_risk, easy to extend with new ones - 📴 Runs offline — a deterministic
--demomode needs no API key, so the project is instantly reviewable - 📊 Two output formats — human-readable Markdown or machine-readable JSON
- 🔐 No secrets in code — all configuration via environment variables
- 🧩 Modular architecture — clean separation of LLM client, tools, agent, and reporting
┌──────────────────────────────────────────────┐
scan.json ──► │ TriageAgent │
│ │
│ ┌─────────┐ decide ┌──────────────┐ │
│ │ LLM │ ──────────► │ Tool layer │ │
│ │ (gpt-4o)│ ◄────────── │ │ │
│ └─────────┘ results │ lookup_cve │ │
│ │ │ score_risk │ │
│ │ final report └──────────────┘ │
└────────┼─────────────────────────────────────┘
▼
Markdown / JSON remediation report
ai-security-triage-agent/
├── agent_triage/
│ ├── agent.py # agent loop (LLM + tool calling) and offline pipeline
│ ├── llm.py # OpenAI-compatible client, configured via env vars
│ ├── tools.py # lookup_cve + score_risk, with tool-calling schemas
│ ├── report.py # Markdown / JSON rendering and prioritization
│ └── cli.py # command-line interface
├── data/
│ └── sample_scan.json
├── examples/
│ ├── sample_report.md
│ └── sample_report.json
├── main.py
└── requirements.txt
git clone https://github.com/Amirmuhammadmarvi/ai-security-triage-agent.git
cd ai-security-triage-agent
pip install -r requirements.txtpython main.py --scan data/sample_scan.json --democp .env.example .env # then add your OPENAI_API_KEY
export $(grep -v '^#' .env | xargs)
python main.py --scan data/sample_scan.json --verbose| Flag | Description |
|---|---|
--scan PATH |
Scan findings JSON (required) |
--demo |
Force the offline deterministic pipeline |
--format md|json |
Output format (default: md) |
--out PATH |
Write the report to a file |
--model NAME |
Override the model (default $LLM_MODEL or gpt-4o-mini) |
--verbose |
Print each tool call the agent makes |
{
"target": "192.168.148.130",
"findings": [
{
"port": 21,
"service": "vsftpd 2.3.4",
"cve": "CVE-2011-2523",
"severity": "critical",
"exposure": "internet"
}
]
}severity ∈ critical / high / medium / low / info · exposure ∈ internet / external / dmz / internal. The format maps cleanly from Nmap + Nikto output.
# Vulnerability Triage Report — 192.168.148.130
## Executive Summary
- P1 (critical): 2 · P2 (high): 2 · P3 (medium): 2 · P4 (low): 0
2 critical (P1) issues require immediate action, led by vsftpd 2.3.4 (port 21)
and OpenSSL 1.0.1 (port 443). Prioritize internet-exposed services with known
public exploits.
### 1. [P1] vsftpd 2.3.4 (port 21)
- Risk score: 100/100 — Remediate within 24 hours
- CVE: CVE-2011-2523
- Impact: Unauthenticated remote root command execution.
- Remediation: Upgrade vsftpd to a vendor-supported release (3.x) or migrate to SFTP.Full samples: examples/sample_report.md · examples/sample_report.json
In live mode the agent runs a standard reasoning loop:
- The findings and the tool schemas are sent to the LLM.
- The model returns tool calls (e.g.
lookup_cve("CVE-2011-2523"),score_risk("critical", "internet", true)). - The tools execute locally and their results are fed back to the model.
- Steps 2–3 repeat until the model has enough information.
- The model writes the final remediation report.
This is exactly how production agent frameworks operate; doing it by hand here keeps the control flow, prompt design, and tool contracts fully visible.
- Live CVE enrichment from the NVD API (replacing the local knowledge base)
- RAG over an internal asset inventory to refine exposure scoring
-
LangChainandn8nintegrations to embed the agent in automation workflows - Slack / email delivery of generated reports
This tool performs defensive analysis and remediation guidance only — it does not scan, exploit, or attack any system. Use it on findings you are authorized to assess. Generated reports are advisory and should be validated before acting in production.
Author: Amir Mohammad Marwi