Add HallucinationGuardrail no-op implementation with tests (#2869)
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled

- Add `HallucinationGuardrail` class as enterprise feature placeholder
- Update LLM guardrail events to support `HallucinationGuardrail` instances
- Add comprehensive tests for `HallucinationGuardrail` initialization and behavior
- Add integration tests for `HallucinationGuardrail` with task execution system
- Ensure no-op behavior always returns True
This commit is contained in:
Greyson LaLonde
2025-05-21 13:47:41 -04:00
committed by GitHub
parent 31ffa90075
commit 9945da7dbe
4 changed files with 244 additions and 2 deletions

View File

@@ -0,0 +1,96 @@
"""Hallucination Guardrail Placeholder for CrewAI.
This is a no-op version of the HallucinationGuardrail for the open-source repository.
Classes:
HallucinationGuardrail: Placeholder guardrail that validates task outputs.
"""
from typing import Any, Optional, Tuple
from crewai.llm import LLM
from crewai.tasks.task_output import TaskOutput
from crewai.utilities.logger import Logger
class HallucinationGuardrail:
"""Placeholder for the HallucinationGuardrail feature.
Attributes:
context: The reference context that outputs would be checked against.
llm: The language model that would be used for evaluation.
threshold: Optional minimum faithfulness score that would be required to pass.
tool_response: Optional tool response information that would be used in evaluation.
Examples:
>>> # Basic usage with default verdict logic
>>> guardrail = HallucinationGuardrail(
... context="AI helps with various tasks including analysis and generation.",
... llm=agent.llm
... )
>>> # With custom threshold for stricter validation
>>> strict_guardrail = HallucinationGuardrail(
... context="Quantum computing uses qubits in superposition.",
... llm=agent.llm,
... threshold=8.0 # Would require score >= 8 to pass in enterprise version
... )
>>> # With tool response for additional context
>>> guardrail_with_tools = HallucinationGuardrail(
... context="The current weather data",
... llm=agent.llm,
... tool_response="Weather API returned: Temperature 22°C, Humidity 65%"
... )
"""
def __init__(
self,
context: str,
llm: LLM,
threshold: Optional[float] = None,
tool_response: str = "",
):
"""Initialize the HallucinationGuardrail placeholder.
Args:
context: The reference context that outputs would be checked against.
llm: The language model that would be used for evaluation.
threshold: Optional minimum faithfulness score that would be required to pass.
tool_response: Optional tool response information that would be used in evaluation.
"""
self.context = context
self.llm: LLM = llm
self.threshold = threshold
self.tool_response = tool_response
self._logger = Logger(verbose=True)
self._logger.log(
"warning",
"""Hallucination detection is a no-op in open source, use it for free at https://app.crewai.com\n""",
color="red",
)
@property
def description(self) -> str:
"""Generate a description of this guardrail for event logging."""
return "HallucinationGuardrail (no-op)"
def __call__(self, task_output: TaskOutput) -> Tuple[bool, Any]:
"""Validate a task output against hallucination criteria.
In the open source, this method always returns that the output is valid.
Args:
task_output: The output to be validated.
Returns:
A tuple containing:
- True
- The raw task output
"""
self._logger.log(
"warning",
"Premium hallucination detection skipped (use for free at https://app.crewai.com)\n",
color="red",
)
return True, task_output.raw

View File

@@ -19,10 +19,13 @@ class LLMGuardrailStartedEvent(BaseEvent):
from inspect import getsource
from crewai.tasks.llm_guardrail import LLMGuardrail
from crewai.tasks.hallucination_guardrail import HallucinationGuardrail
super().__init__(**data)
if isinstance(self.guardrail, LLMGuardrail):
if isinstance(self.guardrail, LLMGuardrail) or isinstance(
self.guardrail, HallucinationGuardrail
):
self.guardrail = self.guardrail.description.strip()
elif isinstance(self.guardrail, Callable):
self.guardrail = getsource(self.guardrail).strip()