Principle:Protectai Llm guard Output Scanner Factory Pattern
| Knowledge Sources | |
|---|---|
| Domains | Factory_Pattern, Configuration |
| Last Updated | 2026-02-14 12:00 GMT |
Overview
Dynamic instantiation of output scanner objects by name using the factory pattern.
Description
The output scanner factory pattern mirrors the input scanner factory but is specialized for output-side guardrail scanners -- those that analyze and validate text after it has been generated by the language model. This principle enables the same configuration-driven pipeline assembly approach on the output side of the guardrail architecture.
The output scanner factory maintains its own registry mapping scanner name strings to the corresponding output scanner class constructors. This separation from the input scanner factory is important because input and output scanners serve fundamentally different roles: input scanners validate and sanitize user prompts before they reach the model, while output scanners validate and filter model responses before they reach the user.
When a pipeline configuration specifies which output scanners to use, the factory looks up each scanner by name and instantiates it with the provided configuration parameters. The configuration dictionary is unpacked as keyword arguments, allowing each scanner to receive its specific settings (thresholds, model paths, matching modes, etc.) without the factory needing to understand the details of any individual scanner.
Usage
Apply this principle when building configurable output validation pipelines:
- Systems that need to dynamically select which output checks to apply based on context or configuration.
- Deployment pipelines where output scanner sets vary between environments (development, staging, production).
- Applications that allow administrators to enable or disable specific output validations.
- Architectures where the set of output scanners may evolve independently from the pipeline orchestration code.
Theoretical Basis
The factory pattern for output scanners operates as follows:
1. Maintain a registry: a dictionary mapping output scanner name strings to class references.
registry = { "OutputScannerA": OutputScannerAClass, "OutputScannerB": OutputScannerBClass, ... }
2. When an output scanner is requested by name:
a. Look up the name in the registry to obtain the class reference.
b. If the name is not found, raise an error indicating an unknown output scanner.
3. If an optional configuration dictionary is provided:
a. Unpack it as keyword arguments to the constructor:
instance = registry[name](**config)
b. Otherwise, invoke the constructor with default parameters:
instance = registry[name]()
4. Return the instantiated output scanner object.
5. The pipeline orchestrator invokes the scanner through its common interface
(e.g., a scan() method that accepts the prompt and the output text),
without needing to know the specific class being used.