Validate inputs and outputs for safety and reliability.
Check and validate inputs before agent execution.
/**
* Input guardrail for validating inputs before agent execution
*/
interface InputGuardrail<TContext = any> {
/** Guardrail identifier */
name: string;
/**
* Execute the guardrail check
* @param args - Guardrail execution arguments
* @returns Guardrail result with tripwire status
*/
execute: (args: {
agent: Agent;
input: AgentInputItem[];
context: RunContext<TContext>;
}) => Promise<GuardrailFunctionOutput>;
/** Run this guardrail in parallel with others (default: false) */
runInParallel?: boolean;
}
interface GuardrailFunctionOutput {
/** Whether the guardrail was triggered/violated */
tripwireTriggered: boolean;
/** Additional information about the check */
outputInfo: any;
}
interface InputGuardrailResult {
/** Guardrail name */
name: string;
/** Whether tripwire was triggered */
tripwireTriggered: boolean;
/** Output information from the check */
outputInfo: any;
/** Error if guardrail execution failed */
error?: Error;
}Usage Examples:
import { Agent, run, InputGuardrail } from '@openai/agents';
// Basic input guardrail
const profanityGuardrail: InputGuardrail = {
name: 'profanity_check',
execute: async ({ input, context }) => {
const text = input
.map(item => item.type === 'user_message' ? item.content : '')
.join(' ');
const hasProfanity = /\b(bad|word|list)\b/i.test(text);
return {
tripwireTriggered: hasProfanity,
outputInfo: { filtered: hasProfanity },
};
},
};
const agent = new Agent({
name: 'SafeAgent',
instructions: 'You are a helpful assistant',
inputGuardrails: [profanityGuardrail],
});
try {
const result = await run(agent, 'Hello there!');
console.log(result.finalOutput);
} catch (error) {
if (error instanceof InputGuardrailTripwireTriggered) {
console.log('Input was blocked by guardrail');
}
}
// Context-aware guardrail
const rateLimitGuardrail: InputGuardrail = {
name: 'rate_limit',
execute: async ({ context }) => {
const userId = context.context.userId;
const requestCount = await getRequestCount(userId);
return {
tripwireTriggered: requestCount > 100,
outputInfo: { requestCount },
};
},
};
const rateLimitedAgent = new Agent({
name: 'RateLimitedAgent',
instructions: 'You are helpful',
inputGuardrails: [rateLimitGuardrail],
});
const result2 = await run(rateLimitedAgent, 'Hello', {
context: { userId: 'user123' },
});
// Multiple guardrails
const lengthGuardrail: InputGuardrail = {
name: 'max_length',
execute: async ({ input }) => {
const text = input
.map(item => item.type === 'user_message' ? item.content : '')
.join(' ');
return {
tripwireTriggered: text.length > 10000,
outputInfo: { length: text.length },
};
},
};
const languageGuardrail: InputGuardrail = {
name: 'language_check',
execute: async ({ input }) => {
// Check if input is in allowed languages
const allowedLanguages = ['en', 'es', 'fr'];
const language = detectLanguage(input);
return {
tripwireTriggered: !allowedLanguages.includes(language),
outputInfo: { detectedLanguage: language },
};
},
};
const multiGuardAgent = new Agent({
name: 'MultiGuardAgent',
instructions: 'You are helpful',
inputGuardrails: [
profanityGuardrail,
lengthGuardrail,
languageGuardrail,
],
});
// Parallel execution guardrails
const fastGuardrail: InputGuardrail = {
name: 'fast_check',
runInParallel: true, // Run concurrently with other parallel guardrails
execute: async ({ input }) => {
// Fast validation
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
const anotherFastGuardrail: InputGuardrail = {
name: 'another_fast_check',
runInParallel: true,
execute: async ({ input }) => {
// Another fast validation
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
const parallelAgent = new Agent({
name: 'ParallelGuardAgent',
instructions: 'You are helpful',
inputGuardrails: [fastGuardrail, anotherFastGuardrail],
});
// Helper function for example
async function getRequestCount(userId: string): Promise<number> {
return 50; // Mock implementation
}
function detectLanguage(input: any[]): string {
return 'en'; // Mock implementation
}Check and validate outputs after agent generation.
/**
* Output guardrail for validating outputs after agent execution
*/
interface OutputGuardrail<TOutput = any, TContext = any> {
/** Guardrail identifier */
name: string;
/**
* Execute the guardrail check
* @param args - Guardrail execution arguments
* @returns Guardrail result with tripwire status
*/
execute: (args: {
agent: Agent;
agentOutput: TOutput;
context: RunContext<TContext>;
details?: {
rawOutput: AgentOutputItem[];
};
}) => Promise<GuardrailFunctionOutput>;
}
interface OutputGuardrailResult {
/** Guardrail name */
name: string;
/** Whether tripwire was triggered */
tripwireTriggered: boolean;
/** Output information from the check */
outputInfo: any;
/** Error if guardrail execution failed */
error?: Error;
}
/**
* Helper function to define output guardrails with type safety
* @param config - Output guardrail configuration
* @returns OutputGuardrail instance
*/
function defineOutputGuardrail<TOutput = any, TContext = any>(
config: OutputGuardrailConfig<TOutput, TContext>
): OutputGuardrail<TOutput, TContext>;
interface OutputGuardrailConfig<TOutput, TContext> {
/** Guardrail identifier */
name: string;
/**
* Execute the guardrail check
*/
execute: (args: {
agent: Agent;
agentOutput: TOutput;
context: RunContext<TContext>;
details?: {
rawOutput: AgentOutputItem[];
};
}) => Promise<GuardrailFunctionOutput>;
}Usage Examples:
import { Agent, run, OutputGuardrail, defineOutputGuardrail } from '@openai/agents';
// Basic output guardrail
const toxicityGuardrail: OutputGuardrail = {
name: 'toxicity_check',
execute: async ({ agentOutput }) => {
const outputText = String(agentOutput);
const isToxic = await checkToxicity(outputText);
return {
tripwireTriggered: isToxic,
outputInfo: { toxicityScore: 0.2 },
};
},
};
const agent = new Agent({
name: 'SafeAgent',
instructions: 'You are a helpful assistant',
outputGuardrails: [toxicityGuardrail],
});
try {
const result = await run(agent, 'Tell me a story');
console.log(result.finalOutput);
} catch (error) {
if (error instanceof OutputGuardrailTripwireTriggered) {
console.log('Output was blocked by guardrail');
}
}
// Using defineOutputGuardrail helper
const piiGuardrail = defineOutputGuardrail({
name: 'pii_detection',
execute: async ({ agentOutput }) => {
const text = String(agentOutput);
// Check for PII patterns
const hasPII =
/\b\d{3}-\d{2}-\d{4}\b/.test(text) || // SSN
/\b\d{16}\b/.test(text); // Credit card
return {
tripwireTriggered: hasPII,
outputInfo: { piiDetected: hasPII },
};
},
});
const piiAgent = new Agent({
name: 'PIIAwareAgent',
instructions: 'You are helpful',
outputGuardrails: [piiGuardrail],
});
// Structured output guardrail
import { z } from 'zod';
const dataAgent = new Agent({
name: 'DataAgent',
instructions: 'Extract data',
outputType: z.object({
name: z.string(),
age: z.number(),
email: z.string(),
}),
outputGuardrails: [
defineOutputGuardrail<{ name: string; age: number; email: string }>({
name: 'age_validation',
execute: async ({ agentOutput }) => {
return {
tripwireTriggered: agentOutput.age < 0 || agentOutput.age > 150,
outputInfo: { age: agentOutput.age },
};
},
}),
],
});
// Context-aware output guardrail
const complianceGuardrail = defineOutputGuardrail({
name: 'compliance_check',
execute: async ({ agentOutput, context }) => {
const userRegion = context.context.region;
const outputText = String(agentOutput);
// Region-specific compliance check
const isCompliant = await checkRegionCompliance(outputText, userRegion);
return {
tripwireTriggered: !isCompliant,
outputInfo: { region: userRegion, compliant: isCompliant },
};
},
});
const complianceAgent = new Agent({
name: 'ComplianceAgent',
instructions: 'You provide information',
outputGuardrails: [complianceGuardrail],
});
await run(complianceAgent, 'Give me information', {
context: { region: 'EU' },
});
// Access raw output items
const detailedGuardrail = defineOutputGuardrail({
name: 'detailed_check',
execute: async ({ agentOutput, details }) => {
// Access raw output items for detailed inspection
const hasRefusal = details?.rawOutput.some(
item => item.type === 'refusal'
);
return {
tripwireTriggered: hasRefusal,
outputInfo: { refusalDetected: hasRefusal },
};
},
});
// Helper functions for examples
async function checkToxicity(text: string): Promise<boolean> {
return false; // Mock implementation
}
async function checkRegionCompliance(text: string, region: string): Promise<boolean> {
return true; // Mock implementation
}Apply guardrails to all agents using Runner configuration.
interface RunnerConfig<TContext = any> {
/** Global input guardrails applied to all agents */
inputGuardrails?: InputGuardrail[];
/** Global output guardrails applied to all agents */
outputGuardrails?: OutputGuardrail[];
}Usage Examples:
import { Agent, Runner, InputGuardrail, OutputGuardrail } from '@openai/agents';
// Define global guardrails
const globalInputGuardrail: InputGuardrail = {
name: 'global_input_check',
execute: async ({ input }) => {
console.log('Global input check');
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
const globalOutputGuardrail: OutputGuardrail = {
name: 'global_output_check',
execute: async ({ agentOutput }) => {
console.log('Global output check');
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
// Create runner with global guardrails
const runner = new Runner({
inputGuardrails: [globalInputGuardrail],
outputGuardrails: [globalOutputGuardrail],
});
const agent1 = new Agent({
name: 'Agent1',
instructions: 'You are agent 1',
});
const agent2 = new Agent({
name: 'Agent2',
instructions: 'You are agent 2',
});
// Global guardrails apply to all agents
await runner.run(agent1, 'Hello');
await runner.run(agent2, 'Hi there');
// Combine global and agent-specific guardrails
const specificGuardrail: InputGuardrail = {
name: 'agent_specific',
execute: async ({ input }) => {
console.log('Agent-specific check');
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
const agent3 = new Agent({
name: 'Agent3',
instructions: 'You are agent 3',
inputGuardrails: [specificGuardrail], // Added to global guardrails
});
// Both global and agent-specific guardrails run
await runner.run(agent3, 'Test');Access guardrail execution results from RunResult.
interface RunResult<TOutput = any> {
/** Input guardrail results */
inputGuardrailResults: InputGuardrailResult[];
/** Output guardrail results */
outputGuardrailResults: OutputGuardrailResult[];
}Usage Examples:
import { Agent, run, InputGuardrail, OutputGuardrail } from '@openai/agents';
const inputGuardrail: InputGuardrail = {
name: 'input_validator',
execute: async ({ input }) => {
return {
tripwireTriggered: false,
outputInfo: { validated: true },
};
},
};
const outputGuardrail: OutputGuardrail = {
name: 'output_validator',
execute: async ({ agentOutput }) => {
return {
tripwireTriggered: false,
outputInfo: { score: 0.95 },
};
},
};
const agent = new Agent({
name: 'GuardedAgent',
instructions: 'You are helpful',
inputGuardrails: [inputGuardrail],
outputGuardrails: [outputGuardrail],
});
const result = await run(agent, 'Hello!');
// Check input guardrail results
for (const result of result.inputGuardrailResults) {
console.log(`Input guardrail: ${result.name}`);
console.log(`Triggered: ${result.tripwireTriggered}`);
console.log(`Info: ${JSON.stringify(result.outputInfo)}`);
if (result.error) {
console.log(`Error: ${result.error.message}`);
}
}
// Check output guardrail results
for (const result of result.outputGuardrailResults) {
console.log(`Output guardrail: ${result.name}`);
console.log(`Triggered: ${result.tripwireTriggered}`);
console.log(`Info: ${JSON.stringify(result.outputInfo)}`);
if (result.error) {
console.log(`Error: ${result.error.message}`);
}
}
// Check if any guardrails were triggered
const anyInputTriggered = result.inputGuardrailResults.some(
r => r.tripwireTriggered
);
const anyOutputTriggered = result.outputGuardrailResults.some(
r => r.tripwireTriggered
);
console.log(`Input blocked: ${anyInputTriggered}`);
console.log(`Output blocked: ${anyOutputTriggered}`);Handle guardrail-related errors.
/**
* Base error for guardrail execution failures
*/
class GuardrailExecutionError extends AgentsError {
/** Guardrail name */
guardrailName: string;
/** Original error */
cause: Error;
}
/**
* Error thrown when input guardrail tripwire is triggered
*/
class InputGuardrailTripwireTriggered extends AgentsError {
/** Triggered guardrail results */
guardrailResults: InputGuardrailResult[];
}
/**
* Error thrown when output guardrail tripwire is triggered
*/
class OutputGuardrailTripwireTriggered extends AgentsError {
/** Triggered guardrail results */
guardrailResults: OutputGuardrailResult[];
/** Agent output that was blocked */
agentOutput: any;
}Usage Examples:
import {
Agent,
run,
InputGuardrail,
OutputGuardrail,
InputGuardrailTripwireTriggered,
OutputGuardrailTripwireTriggered,
GuardrailExecutionError,
} from '@openai/agents';
const strictInputGuardrail: InputGuardrail = {
name: 'strict_input',
execute: async ({ input }) => {
return {
tripwireTriggered: true, // Always trigger
outputInfo: { reason: 'Input not allowed' },
};
},
};
const agent = new Agent({
name: 'StrictAgent',
instructions: 'You are strict',
inputGuardrails: [strictInputGuardrail],
});
try {
await run(agent, 'Hello');
} catch (error) {
if (error instanceof InputGuardrailTripwireTriggered) {
console.log('Input guardrail triggered');
console.log('Triggered guardrails:');
for (const result of error.guardrailResults) {
console.log(` - ${result.name}: ${JSON.stringify(result.outputInfo)}`);
}
}
}
// Output guardrail error
const strictOutputGuardrail: OutputGuardrail = {
name: 'strict_output',
execute: async ({ agentOutput }) => {
return {
tripwireTriggered: true,
outputInfo: { reason: 'Output not allowed' },
};
},
};
const outputAgent = new Agent({
name: 'OutputAgent',
instructions: 'You are helpful',
outputGuardrails: [strictOutputGuardrail],
});
try {
await run(outputAgent, 'Hello');
} catch (error) {
if (error instanceof OutputGuardrailTripwireTriggered) {
console.log('Output guardrail triggered');
console.log('Blocked output:', error.agentOutput);
console.log('Triggered guardrails:');
for (const result of error.guardrailResults) {
console.log(` - ${result.name}: ${JSON.stringify(result.outputInfo)}`);
}
}
}
// Guardrail execution error
const faultyGuardrail: InputGuardrail = {
name: 'faulty',
execute: async () => {
throw new Error('Guardrail crashed');
},
};
const faultyAgent = new Agent({
name: 'FaultyAgent',
instructions: 'You are helpful',
inputGuardrails: [faultyGuardrail],
});
try {
await run(faultyAgent, 'Hello');
} catch (error) {
if (error instanceof GuardrailExecutionError) {
console.log('Guardrail execution failed');
console.log('Guardrail name:', error.guardrailName);
console.log('Error:', error.cause.message);
}
}Guardrail Design Guidelines:
import { Agent, run, InputGuardrail, OutputGuardrail, defineOutputGuardrail } from '@openai/agents';
// 1. Keep guardrails fast
const fastGuardrail: InputGuardrail = {
name: 'fast_check',
execute: async ({ input }) => {
// Use efficient validation methods
// Avoid expensive API calls or complex processing
return {
tripwireTriggered: false,
outputInfo: {},
};
},
};
// 2. Use parallel execution for independent checks
const check1: InputGuardrail = {
name: 'check_1',
runInParallel: true,
execute: async ({ input }) => {
// Independent check
return { tripwireTriggered: false, outputInfo: {} };
},
};
const check2: InputGuardrail = {
name: 'check_2',
runInParallel: true,
execute: async ({ input }) => {
// Another independent check
return { tripwireTriggered: false, outputInfo: {} };
},
};
// 3. Provide meaningful outputInfo
const informativeGuardrail: OutputGuardrail = {
name: 'content_policy',
execute: async ({ agentOutput }) => {
const violations = checkContentPolicy(String(agentOutput));
return {
tripwireTriggered: violations.length > 0,
outputInfo: {
violations,
categories: violations.map(v => v.category),
severity: violations.length > 0 ? 'high' : 'none',
},
};
},
};
// 4. Use context for user-specific rules
const contextAwareGuardrail = defineOutputGuardrail({
name: 'user_permissions',
execute: async ({ agentOutput, context }) => {
const userRole = context.context.userRole;
const outputText = String(agentOutput);
// Check if output is appropriate for user role
const isAllowed = checkPermissions(outputText, userRole);
return {
tripwireTriggered: !isAllowed,
outputInfo: { userRole, allowed: isAllowed },
};
},
});
// 5. Layer guardrails from fast to slow
const agent = new Agent({
name: 'LayeredAgent',
instructions: 'You are helpful',
inputGuardrails: [
fastGuardrail, // Run cheap checks first
check1,
check2,
// More expensive checks last
],
});
// Helper functions
function checkContentPolicy(text: string): Array<{ category: string }> {
return []; // Mock implementation
}
function checkPermissions(text: string, role: string): boolean {
return true; // Mock implementation
}