Detectors¶
Every production detector along with its supporting types.
Base¶
Detector
¶
Bases: ABC
Abstract base class for a chatbot failure detector.
Subclasses must declare the class-level attributes name, description,
failure_mode, and requires_llm, then implement detect().
Example::
class MyDetector(Detector):
name = "my_detector"
description = "Detects my specific failure pattern"
failure_mode = FailureMode.DEATH_LOOP
requires_llm = False
def detect(self, conversation: Conversation) -> list[Detection]:
...
detect
abstractmethod
¶
detect(conversation: Conversation) -> list[Detection]
Analyze a conversation and return zero or more detections.
Return an empty list if no failures are found. A single conversation may produce multiple detections (e.g., both a death loop and an escalation burial).
Implementations must not mutate the input conversation.
DetectorRegistry
¶
DetectorRegistry(detectors: list[Detector] | None = None)
Holds the set of detectors to run on a conversation.
run
¶
run(conversation: Conversation) -> list[Detection]
Run every registered detector against a single conversation.
Phase 1 — statistical¶
DeathLoopDetector
¶
DeathLoopDetector(*, similarity_threshold: float = 0.85, min_repeats: int = 3, min_content_length: int = 15, similarity_fn: SimilarityFn | None = None, frustration_keywords: Sequence[str] | None = None)
Bases: Detector
Detect consecutive similar bot responses indicating a conversational loop.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
similarity_threshold
|
float
|
Pairwise similarity (0.0–1.0) above which two bot responses count as "the same answer." Default 0.85. |
0.85
|
min_repeats
|
int
|
Minimum number of consecutive similar responses required to trigger a detection. Default 3. |
3
|
min_content_length
|
int
|
Bot messages shorter than this (after normalization would be trivial) are ignored — short messages like "OK" trivially match and cause false positives. Default 15 characters. |
15
|
similarity_fn
|
SimilarityFn | None
|
Function comparing two strings, returning [0.0, 1.0].
Defaults to |
None
|
frustration_keywords
|
Sequence[str] | None
|
Sequence of lowercase substrings that indicate customer frustration. Detections containing these get a small confidence bonus. Defaults to a curated English list. |
None
|
SilentChurnDetector
¶
SilentChurnDetector(*, confirmation_keywords: Sequence[str] | None = None, min_user_messages: int = 2, min_bot_messages: int = 2)
Bases: Detector
Detect conversations that ended without a customer confirmation signal.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confirmation_keywords
|
Sequence[str] | None
|
Lowercase substrings that indicate customer satisfaction / resolution. If any appears in any user message the conversation is considered healthy. |
None
|
min_user_messages
|
int
|
Minimum number of user-role messages required to count as a "substantive" interaction worth flagging. Default 2. |
2
|
min_bot_messages
|
int
|
Minimum number of bot-role messages required to count as a "substantive" interaction worth flagging. Default 2. |
2
|
EscalationBurialDetector
¶
EscalationBurialDetector(*, escalation_keywords: Sequence[str] | None = None, transfer_confirmation_keywords: Sequence[str] | None = None)
Bases: Detector
Detect when the customer asks for a human and the bot refuses to transfer.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
escalation_keywords
|
Sequence[str] | None
|
Lowercase substrings indicating an explicit human-agent request in a user message. |
None
|
transfer_confirmation_keywords
|
Sequence[str] | None
|
Lowercase substrings indicating the bot acknowledged the transfer (i.e. did NOT bury the request). |
None
|
Phase 2 — content-aware¶
SentimentCollapseDetector
¶
SentimentCollapseDetector(*, scorer: SentimentScorer | None = None, min_user_messages: int = 3, min_drop: float = 0.4, end_threshold: float = -0.2)
Bases: Detector
Detect a customer-sentiment drop over the course of a conversation.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scorer
|
SentimentScorer | None
|
Sentiment scoring backend. Defaults to |
None
|
min_user_messages
|
int
|
Minimum user-role messages required to compute a meaningful trend. Default 3. |
3
|
min_drop
|
float
|
Minimum difference (early-third average - late-third average) that counts as a collapse. Default 0.4. |
0.4
|
end_threshold
|
float
|
The late third must also be below this absolute threshold. Default -0.2 — ensures the conversation actually ended in negative territory, not just less positive. |
-0.2
|
BrandDamageDetector
¶
BrandDamageDetector(*, checker: ContentSafetyChecker | None = None, competitor_names: Sequence[str] | None = None)
Bases: Detector
Detect bot messages likely to damage brand trust if seen publicly.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
checker
|
ContentSafetyChecker | None
|
Pluggable content safety checker. Defaults to
|
None
|
competitor_names
|
Sequence[str] | None
|
Names (case-insensitive) of competitors the bot
should not endorse. Only used if |
None
|
ConfidentLiesDetector
¶
ConfidentLiesDetector(*, policy: PolicyBase | None = None, commitment_patterns: Sequence[Pattern[str]] | None = None)
Bases: Detector
Detect bot commitments that may not match company policy.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
PolicyBase | None
|
Optional knowledge base describing allowed and disallowed commitments. Without one, all commitments are flagged at medium confidence for human review. |
None
|
commitment_patterns
|
Sequence[Pattern[str]] | None
|
Custom list of regex patterns matching commitment-style language. Defaults to a curated set. |
None
|
ConfidentMisinformationDetector
¶
ConfidentMisinformationDetector(*, facts: FactBase | None = None, claim_patterns: Sequence[Pattern[str]] | None = None)
Bases: Detector
Detect confident factual claims that may contradict ground truth.
Configure the detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
facts
|
FactBase | None
|
Optional ground-truth facts. Without one, confident claims are flagged as "review recommended." |
None
|
claim_patterns
|
Sequence[Pattern[str]] | None
|
Custom claim detection patterns. Defaults to a curated set covering pricing, hours, availability, and policy. |
None
|
Pluggable backends¶
SentimentScorer
¶
Bases: Protocol
Callable contract: given a text, return sentiment in [-1.0, 1.0].
KeywordSentimentScorer
dataclass
¶
KeywordSentimentScorer(positive: frozenset[str] = _POSITIVE_TOKENS, negative: frozenset[str] = _NEGATIVE_TOKENS)
Default SentimentScorer implementation using keyword counts.
ContentSafetyChecker
¶
Bases: Protocol
A pluggable safety checker. Return a list of violation labels (empty if the text is safe).
PatternSafetyChecker
dataclass
¶
PatternSafetyChecker(profanity: tuple[str, ...] = _DEFAULT_PROFANITY, self_deprecation: tuple[str, ...] = _DEFAULT_SELF_DEPRECATION, offbrand_patterns: tuple[Pattern[str], ...] = _DEFAULT_OFFBRAND_PATTERNS, competitor_names: tuple[str, ...] = tuple())
Default stdlib-only content safety checker.