A red-team scan produces hundreds of raw verdicts; a hardening sprint needs a short, ranked list of real problems with owners. The gap between them is triage.
Tier: Core · Workflow area: AI red-team program & tooling
This playbook turns the noisy JSONL from Garak, the pass/fail grid from Promptfoo, and the transcripts from PyRIT into a de-duplicated, severity-ranked backlog of confirmed findings — each one reproducible, mapped to a risk class, and assigned a fix. It is the connective tissue of the red-team program: without disciplined triage, teams either drown in false positives or fix the loudest finding while a quiet critical one ships.
Consolidate every raw finding into one table. Pull the failing rows from each tool into a common shape: source tool, probe/test, the exact prompt, the model's output, the detector verdict.
Confirm each finding by hand before it is a finding. Paste the prompt into your app and check the model actually does the unsafe thing. Detector and rubric false positives are common; an unconfirmed row is a lead, not a finding.
De-duplicate by root cause, not by payload. Twenty jailbreak strings that all exploit one missing output filter are one finding, not twenty. Cluster by the underlying weakness.
Use an LLM to cluster and draft — then verify its grouping. For a large scan, an LLM can propose clusters and severity rationale far faster than manual sorting; you keep the judgment.
import anthropic
from pydantic import BaseModel
class Finding(BaseModel):
cluster: str
root_cause: str
owasp_class: str # e.g. "LLM01 Prompt Injection"
severity: str # Critical / High / Medium / Low
example_prompt: str
recommended_fix: str
class TriageReport(BaseModel):
findings: list[Finding]
client = anthropic.Anthropic()
response = client.messages.parse(
model="claude-opus-4-8",
max_tokens=4000,
thinking={"type": "adaptive"},
messages=[{
"role": "user",
"content": f"Cluster these red-team results by root cause and draft a triage "
f"report. Do not invent findings not present in the data.\n\n{raw_rows}",
}],
output_format=TriageReport,
)
report = response.parsed_output
Assign severity from real impact, not detector labels. Weigh data sensitivity, whether the bypass reaches a dangerous sink (RCE, exfil, PII disclosure), reproducibility, and exploit effort. A reliably reproducible system-prompt leak outranks a once-in-ten toxic completion.
Map each cluster to a risk class and an owner. Tag with OWASP LLM Top 10 / Agentic ASI and MITRE ATLAS (pb-45), assign an engineering owner, and file it as a tracked ticket with the reproduction attached.
An LLM can group and draft the triage, but severity and the decision to fix are human calls — verify every cluster the model proposes against the raw evidence before it enters the backlog.
Triage is trustworthy when every backlog item is independently reproducible and every raw failure is accounted for. Pick each finding in the ranked list and reproduce it cold from the written steps — a teammate who was not in the scan should be able to trigger it. Then run the reverse check for completeness: confirm that every failing raw row maps to either a confirmed finding or an explicit "false positive / won't-fix" disposition with a reason. A row that is neither fixed, tracked, nor consciously dismissed is a gap. If you used an LLM to cluster, spot-check that no proposed finding is a hallucination absent from the raw data, and that no genuine failure was silently dropped from a cluster.
Triage output travels further than raw scans — it is what leadership reads — so scrub it. In a client engagement, produce the ranked backlog inside the client's environment, keep example prompts and model outputs in an appendix that stays within their boundary, and share upward a summary that names the risk class, severity, and fix without the verbatim exploit. If you use an LLM to cluster findings, use the client's approved AI endpoint (or a local model) so their prompts and outputs are not sent to an unapproved service, and redact identifiers and business logic from anything pasted into the model. Hand the client a reproducible backlog their own engineers own; do not retain their findings after the engagement.