Summary
Add two new built-in checks that verify whether the output contains any or all items from a provided list of strings. This is a common need for topic coverage validation (e.g., "does the response mention at least one of these required topics?").
Motivation
Currently, users must write custom FnCheck lambdas for list-based string matching. Competitors like DeepEval and promptfoo ship this as a built-in. Having a registered, serializable check improves usability and enables YAML/JSON-based test definitions.
Implementation Guide
Pattern to follow
Reference: libs/giskard-checks/src/giskard/checks/builtin/text_matching.py (StringMatching)
Steps
- Create checks in
libs/giskard-checks/src/giskard/checks/builtin/text_matching.py (or a new file)
- Subclass
Check and register with @Check.register("contains_any") and @Check.register("contains_all")
- Implement
async run(self, trace: Trace) -> CheckResult
- Support:
values: list[str] — the list of strings to check against
case_sensitive: bool = False — case sensitivity toggle
- JSONPath extraction via
key: JSONPathStr for the value to check
- Unicode normalization (reuse
normalize_string from utils/normalization.py)
- Add to
__init__.py exports
- Add tests in
tests/builtin/
Example usage
from giskard.checks import ContainsAny, ContainsAll, Scenario
scenario = (
Scenario(name="topic_coverage")
.interact(inputs="Explain machine learning", outputs="ML is a subset of AI...")
.check(ContainsAny(values=["machine learning", "ML", "artificial intelligence"]))
.check(ContainsAll(values=["definition", "example"]))
)
Acceptance Criteria
Summary
Add two new built-in checks that verify whether the output contains any or all items from a provided list of strings. This is a common need for topic coverage validation (e.g., "does the response mention at least one of these required topics?").
Motivation
Currently, users must write custom
FnChecklambdas for list-based string matching. Competitors like DeepEval and promptfoo ship this as a built-in. Having a registered, serializable check improves usability and enables YAML/JSON-based test definitions.Implementation Guide
Pattern to follow
Reference:
libs/giskard-checks/src/giskard/checks/builtin/text_matching.py(StringMatching)Steps
libs/giskard-checks/src/giskard/checks/builtin/text_matching.py(or a new file)Checkand register with@Check.register("contains_any")and@Check.register("contains_all")async run(self, trace: Trace) -> CheckResultvalues: list[str]— the list of strings to check againstcase_sensitive: bool = False— case sensitivity togglekey: JSONPathStrfor the value to checknormalize_stringfromutils/normalization.py)__init__.pyexportstests/builtin/Example usage
Acceptance Criteria
ContainsAnypasses if output contains at least one item from the listContainsAllpasses if output contains every item from the list