Part 4: Tripwire handling
The input guardrail is attached, but a blocked request currently raises an exception in the notebook. In this step we catch the tripwire exception and return a normal blocked message.
Catch one blocked call
Run the guarded agent inside a try block:
try:
result = await Runner.run(guarded_faq_agent, "How do I cook pizza?")
print(result.final_output)
except InputGuardrailTripwireTriggered as e:
print(f"[BLOCKED] {e.guardrail_result.output.output_info}")
Expected output:
[BLOCKED] The question is about cooking, not data engineering.
The guardrail result is nested because the SDK preserves the full
guardrail run. For a notebook or app, you usually want the short output_info
string.
This is the shape you want in a product. If a UI has already started showing output, replace it with the guardrail response. If you call through an API, this is the same kind of flow as a refusal: the user gets a controlled blocked message instead of the agent's attempted answer.
Extract a helper
Wrap the pattern in one function:
async def run_with_input_guardrail(agent, user_input):
"""Run an agent with input guardrail handling."""
try:
result = await Runner.run(agent, user_input)
return result.final_output
except InputGuardrailTripwireTriggered as e:
return f"[BLOCKED] {e.guardrail_result.output.output_info}"
This helper keeps SDK exception details out of the rest of the notebook. That is the same shape you would want in an app endpoint: callers ask for an answer and receive either the answer or a blocked message.
Test allowed and blocked prompts
Run a relevant course question:
response = await run_with_input_guardrail(
guarded_faq_agent,
"How do I submit homework?"
)
print(f"Q: How do I submit homework?\n{response}\n")
The FAQ assistant should run normally because the topic check passes.
Now run the pizza prompt:
response = await run_with_input_guardrail(
guarded_faq_agent,
"What's the best pizza recipe?"
)
print(f"Q: What's the best pizza recipe?\n{response}")
A typical blocked response looks like this:
Q: What's the best pizza recipe?
[BLOCKED] About cooking, not course
The exact reasoning text can vary because the guardrail is an LLM call. The stable contract is the prefix and the fact that the FAQ assistant does not answer the cooking question.
Input guardrail behavior
Now the workshop has an enforced input boundary:
- Related questions proceed to
faq_agent. - Unrelated questions raise
InputGuardrailTripwireTriggered. - The helper catches the exception and returns a blocked response.
This is stronger than asking the FAQ assistant to stay on topic. The off-topic message is blocked before the assistant has a chance to answer.
Continue with Part 5: Output guardrail to check the assistant response before returning it to the user.