Part 10: Cancel on tripwire
Parallel execution removes the extra wait when guardrails pass. We also want cancellation when a guardrail fails, because the answer will be blocked anyway.
Create a guardrail exception
Start with a dataclass for the guardrail result:
from dataclasses import dataclass
@dataclass
class GuardrailResult:
"""Result from a guardrail check."""
reasoning: str
triggered: bool
Create an exception that carries the result:
class GuardrailException(Exception):
"""Raised when a guardrail trips."""
def __init__(self, result: GuardrailResult):
self.result = result
super().__init__(result.reasoning)
This mirrors the SDK tripwire idea with plain Python objects. A failed guardrail raises a specific exception, and the runner handles that exception.
Create a failing guardrail
The failing guardrail sleeps for 1.5 seconds, then raises:
async def failing_guardrail(input: str) -> str:
"""Simulates a guardrail that takes time to process."""
print(f"[Failing Guardrail] Starting work on: {input}")
await asyncio.sleep(1.5)
raise GuardrailException(GuardrailResult(
reasoning="Content is not appropriate",
triggered=True
))
If we run this with mock_agent, the guardrail fails before the agent's
two-second sleep finishes.
See the failure with gather
Run both coroutines through asyncio.gather:
results = await asyncio.gather(
failing_guardrail("hello"),
mock_agent("hello"),
)
You should see both start messages, then the guardrail exception interrupts the cell. Depending on scheduling, the mock agent can still finish unless you cancel it explicitly.
Cancel the agent task
Create tasks so the agent can be cancelled:
guard_task = asyncio.create_task(failing_guardrail("hello"))
agent_task = asyncio.create_task(mock_agent("hello"))
Catch the guardrail exception and cancel the agent:
try:
await asyncio.gather(agent_task, guard_task)
except GuardrailException:
agent_task.cancel()
try:
await agent_task
except asyncio.CancelledError:
print("Agent was cancelled - saved tokens!")
Expected output:
[Failing Guardrail] Starting work on: hello
[Agent] Starting work on: hello
Agent was cancelled - saved tokens!
This is where guardrails save work. Once the policy fails, continuing the model call has no value for the user.
Continue with Part 11: DIY runner for the FAQ agent to package this into a reusable helper.