A Detector scores model outputs on a 0.0–1.0 scale to identify vulnerabilities, inheriting from Configurable and requiring subclasses to implement the detect method. Garak provides three concrete detectors: HFDetector (HuggingFace text classifiers), StringDetector (substring matching with Unicode normalization), and TriggerListDetector (dynamic per-attempt trigger matching). Detector.active defaults to True (enabled by default) and respects a skip parameter to disable detectors without removing them from config, while Detector.modality specifies the data type it accepts (defaulting to text outputs). FileDetector logs and skips outputs whose file format does not match the expected type rather than raising an unhandled exception, preventing a single format mismatch from aborting an entire scan.
garak/detectors/base.py defines Detector, the base class all detector plugins must inherit from; it inherits from Configurable and scores model outputs on a 0.0–1.0 scale where 1.0 represents a successful attack hit.[1] Detector.detect must be overridden by subclasses — the base implementation raises NotImplementedError. Its return type is Iterable[float | None]: 0.0 = no hit, 1.0 = vulnerability found, None = unscored output.[1] Detector.active defaults to True, meaning detectors are included in scans by default (the opposite of Probe.active, which defaults to False).[1] Detector.modality defaults to {"out": {"text"}}, indicating detectors assess text outputs from the model.[1] Detector exposes a skip default parameter (DEFAULT_PARAMS = {"skip": False}) that disables a detector without removing it from configuration.[1] Detector.__init__ raises a ValueError if the detector class has no docstring, because the human-readable description is derived from the docstring's first line.[1] Detector instances default their name attribute to the class name string when no explicit name is set; this value is used for report rendering and plugin-cache lookups.
HFDetector, a Detector subclass in the same module, uses a HuggingFace TextClassificationPipeline to score outputs. Its defaults are device: cpu, padding: True, truncation: True, and graceful_fail: True.[1] On initialisation, HFDetector forces torch.multiprocessing start method to spawn to avoid forking issues with CUDA.[1] During model loading, HFDetector.__init__ temporarily sets DISABLE_SAFETENSORS_CONVERSION=true in the environment to prevent HuggingFace from opening PRs in public model repositories, then restores the original value.[1] HFDetector.detect normalises the raw classifier score to 0.0–1.0: if the predicted label matches detector_target_class, score = (1.0 + raw_score) / 2; otherwise score = (1.0 - raw_score) / 2. None outputs are passed through as None without being sent to the classifier.[1] When HFDetector.graceful_fail is True (the default), exceptions from the underlying pipeline are logged at CRITICAL level and a list of None values (one per output) is returned instead of propagating the exception.[1]
StringDetector matches model outputs against a list of substrings, defaulting to case-insensitive (case_sensitive: False) full-string search (matchtype: "str"). Supported matchtype values are "str", "word" (word-boundary regex), and "startswith".[1] StringDetector also supports a normalize option for Unicode normalisation of both substrings and model outputs before matching. Valid values are None (no normalisation), "NFKC", or "NFKC+strip_format" (NFKC followed by stripping Unicode format characters, category Cf). The parameter was added in v0.16.0 — defaulting to None for backward compatibility — to prevent false negatives from fullwidth homoglyphs and zero-width joiners.[1][2] When StringDetector encounters an invalid normalize value while processing substrings, it logs a warning and returns None for every output rather than raising an exception and terminating the run.[1]
TriggerListDetector is a Detector subclass that reads its match strings from attempt.notes["triggers"] at detect time rather than from a constructor-supplied list, enabling per-attempt trigger customisation.[1]
Sources