가드레일
가드레일은 에이전트와 함께 실행되거나 완료될 때까지 실행을 차단할 수 있으므로, 사용자 입력이나 에이전트 출력에 대한 검사와 검증을 수행할 수 있습니다. 예를 들어 비용이 많이 드는 모델을 호출하기 전에 경량 모델을 가드레일로 실행할 수 있습니다. 가드레일이 악의적인 사용을 감지하면 오류를 발생시켜 비용이 많이 드는 모델의 실행을 중지할 수 있습니다.
가드레일은 세 가지 유형으로 나뉩니다.
- 입력 가드레일은 최초 사용자 입력에 대해 실행됩니다.
- 출력 가드레일은 최종 에이전트 출력에 대해 실행됩니다.
- 도구 가드레일은 각 사용자 정의 함수 도구 호출 전후에 실행됩니다.
워크플로 경계
섹션 제목: “워크플로 경계”가드레일은 에이전트에 연결되지만, 워크플로의 모든 에이전트에서 반드시 실행되는 것은 아닙니다.
- 입력 가드레일은 체인의 첫 번째 에이전트에서만 실행됩니다.
- 출력 가드레일은 최종 출력을 생성하는 에이전트에서만 실행됩니다.
- 도구 가드레일은 모든 함수 도구 호출에 대해 실행되며, 입력 가드레일은 실행 전에, 출력 가드레일은 실행 후에 실행됩니다.
관리자나 핸드오프가 포함된 워크플로에서 각 사용자 정의 함수 도구 호출을 검사해야 한다면, 에이전트 수준의 입력 가드레일과 출력 가드레일 대신 도구 가드레일을 사용하세요.
입력 가드레일
섹션 제목: “입력 가드레일”입력 가드레일은 다음 세 단계로 실행됩니다.
- 가드레일은 에이전트에 전달된 것과 동일한 입력을 받습니다.
- 가드레일 함수가 실행되고
InputGuardrailResult로 래핑된GuardrailFunctionOutput을 반환합니다. tripwireTriggered가true이면InputGuardrailTripwireTriggered오류가 발생합니다.
참고 입력 가드레일은 사용자 입력을 대상으로 하므로 에이전트가 워크플로의 첫 번째 에이전트인 경우에만 실행됩니다. 에이전트마다 필요한 가드레일이 다른 경우가 많으므로 가드레일은 에이전트 자체에 구성합니다.
실행 모드
섹션 제목: “실행 모드”runInParallel: true(기본값)는 에이전트 실행과 동시에 입력 가드레일을 시작합니다. 동시 실행은 지연 시간을 최소화하지만, 나중에 가드레일이 작동하면 모델이 이미 토큰을 소비했거나 도구를 실행했을 수 있습니다.runInParallel: false는 모델을 호출하기 전에 가드레일을 실행하여, 가드레일이 요청을 차단할 때 토큰 소비와 도구 실행을 방지합니다. 지연 시간보다 안전성과 비용을 우선할 때 사용하세요.
출력 가드레일
섹션 제목: “출력 가드레일”출력 가드레일은 다음 세 단계로 실행됩니다.
- 가드레일은 에이전트가 생성한 출력을 받습니다.
- 가드레일 함수가 실행되고
OutputGuardrailResult로 래핑된GuardrailFunctionOutput을 반환합니다. tripwireTriggered가true이면OutputGuardrailTripwireTriggered오류가 발생합니다.
참고 출력 가드레일은 에이전트가 워크플로의 마지막 에이전트인 경우에만 실행됩니다. 실시간 음성 상호작용에 대해서는 음성 에이전트 구축을 참고하세요.
출력 가드레일 함수는 해당 턴의 기본 modelResponse와 생성된 출력 항목이 포함된 선택적 details 객체도 받습니다. 최종 출력만으로 응답의 통과 여부를 판단하기에 충분하지 않을 때 사용하세요. 예를 들어 가드레일을 작동시키기 전에 생성된 전체 항목 목록이나 제공자 응답 메타데이터를 검사하려는 경우에 사용할 수 있습니다.
거부된 최종 도구 출력
섹션 제목: “거부된 최종 도구 출력”toolUseBehavior가 완료된 함수 도구 결과를 실행의 최종 출력으로 만들면, SDK가 그 결과를 재생 가능한 최종 데이터로 처리하기 전에 출력 가드레일이 해당 결과를 평가합니다. 가드레일은 원래의 후보 출력을 받습니다. 가드레일이 작동하면 SDK는 SDK가 소유한 실행 상태, 재생 데이터, 세션 기록 및 공개 트립와이어 오류에서 거부된 최종 결과를 Output withheld by an output guardrail.로 대체합니다.
SDK는 거부된 출력의 별칭을 유지할 수 있는 메타데이터도 정리합니다. 현재 응답에서는 OutputGuardrailResult.agentOutput이 동일한 플레이스홀더가 되고 OutputGuardrailResult.outputInfo는 제거됩니다. 현재 도구 출력 가드레일 결과는 판정을 유지하지만 outputInfo는 생략하며, rejectContent 결과는 해당 플레이스홀더를 메시지로 사용합니다. 이전에 수락된 턴의 결과와 기록은 변경되지 않습니다.
식별된 함수 호출과 결과 쌍에 대해 SDK는 재생에 안전한 식별 정보와 상태 필드를 유지하면서 결과 콘텐츠를 대체합니다. SDK가 현재 응답의 어떤 항목이 거부된 최종 출력에 속하는지 확정할 수 없으면, 모호한 현재 응답의 뒷부분을 삭제하거나 이를 재생하는 대신 안전하게 차단합니다.
이 보호 기능은 외부 도구의 부수 효과를 되돌리거나, 애플리케이션 코드로 이미 전달된 출력을 회수하거나, SDK의 제어 범위 밖에 이미 저장된 데이터를 삭제하거나, 원문 제공자 데이터에 대한 애플리케이션 소유 참조를 수정하지 않습니다.
애플리케이션에 데이터가 포함되지 않은 다른 플레이스홀더가 필요한 경우 Runner 또는 개별 run() 호출의 옵션에 outputGuardrailBlockedMessage를 설정하세요. 실행별 값이 Runner 값보다 우선합니다. 비어 있지 않은 문자열이나 defaultMessage, guardrailName, agent, runContext를 받는 포매터를 제공할 수 있습니다. 포매터는 비동기일 수 있지만 거부된 출력은 받지 않습니다. 포매터가 오류를 발생시키거나, 거부되거나, 비어 있거나 문자열이 아닌 값을 반환하면 SDK는 포매터 실패를 노출하지 않고 기본 플레이스홀더를 사용해 안전하게 차단합니다.
도구 가드레일
섹션 제목: “도구 가드레일”도구 가드레일은 함수 도구를 감싸며 실행 전후에 도구 호출을 검증하거나 차단할 수 있도록 합니다. tool() 옵션을 통해 개별 도구에 가드레일을 구성하거나 로컬 MCP 서버에 구성하여 SDK가 해당 서버에서 변환한 모든 도구에 가드레일이 실행되도록 할 수 있습니다.
사용자 정의 함수 도구의 경우 tool({...})에 inputGuardrails, outputGuardrails 또는 둘 다 설정하세요. MCPServerStreamableHttp, MCPServerStdio 또는 MCPServerSSE의 경우 서버 생성자 옵션에 toolInputGuardrails, toolOutputGuardrails 또는 둘 다 설정하세요. 서버 전체에 적용되는 MCP 가드레일은 동일한 로컬 함수 도구 실행 파이프라인을 사용하며 해당 서버에서 변환된 모든 도구에 적용됩니다.
- 입력 도구 가드레일은 도구 실행 전에 실행되며 메시지와 함께 호출을 거부하거나 트립와이어 오류를 발생시킬 수 있습니다.
- 출력 도구 가드레일은 도구 실행 후에 실행되며 출력을 거부 메시지로 대체하거나 트립와이어 오류를 발생시킬 수 있습니다.
로컬 함수 도구에 사람의 승인도 필요한 경우 입력 도구 가드레일은 일반적으로 승인 후, 실행 직전에 실행됩니다. 대기 중인 승인 요청 전에도 해당 입력 가드레일을 실행하려면 run() 또는 Runner에 toolExecution: { preApprovalInputGuardrails: true }를 설정하세요. 가드레일은 승인 후 도구가 실행되기 전에도 다시 실행됩니다.
도구 가드레일은 behavior를 반환합니다.
allow— 다음 가드레일 또는 도구 실행을 계속합니다.rejectContent— 메시지와 함께 조기에 종료합니다(도구 호출을 건너뛰거나 출력을 대체함).throwException— 즉시 트립와이어 오류를 발생시킵니다.
도구 가드레일은 tool()로 정의한 함수 도구와, 서버에 가드레일이 구성된 경우 로컬 MCP 서버에서 변환된 도구에 적용됩니다. 핸드오프는 모델에 함수와 유사한 도구로 제공되지만 일반 함수 도구 파이프라인이 아닌 SDK의 핸드오프 경로를 통해 실행되므로 도구 가드레일은 핸드오프 호출 자체에 적용되지 않습니다. 호스티드 MCP 도구, 기타 호스티드 툴 및 기본 제공 실행 도구(computerTool, shellTool, applyPatchTool)도 이 가드레일 파이프라인을 사용하지 않으며, 현재 agent.asTool()은 도구 가드레일 옵션을 직접 제공하지 않습니다.
트립와이어
섹션 제목: “트립와이어”가드레일이 실패하면 트립와이어를 통해 이를 알립니다. 러너는 먼저 동일한 배치에서 시작된 다른 가드레일이 완료될 때까지 기다리고 완료된 결과를 기록합니다. 그런 다음 해당 오류를 발생시키고 추가 실행 처리를 중단합니다. 병렬 입력 가드레일을 사용하는 경우 실행 모드에 설명된 대로 모델 또는 도구 작업이 이미 시작되었을 수 있습니다.
가드레일 구현
섹션 제목: “가드레일 구현”가드레일은 단순히 GuardrailFunctionOutput을 반환하는 함수입니다. 다음은 내부적으로 다른 에이전트를 실행하여 사용자가 수학 숙제 도움을 요청하는지 확인하는 최소한의 예제입니다.
import { Agent, run, InputGuardrailTripwireTriggered, InputGuardrail,} from '@openai/agents';import { z } from 'zod';
const guardrailAgent = new Agent({ name: 'Guardrail check', instructions: 'Check if the user is asking you to do their math homework.', outputType: z.object({ isMathHomework: z.boolean(), reasoning: z.string(), }),});
const mathGuardrail: InputGuardrail = { name: 'Math Homework Guardrail', // Set runInParallel to false to block the model until the guardrail completes. runInParallel: false, execute: async ({ input, context }) => { const result = await run(guardrailAgent, input, { context }); return { outputInfo: result.finalOutput, tripwireTriggered: result.finalOutput?.isMathHomework ?? false, }; },};
const agent = new Agent({ name: 'Customer support agent', instructions: 'You are a customer support agent. You help customers with their questions.', inputGuardrails: [mathGuardrail],});
async function main() { try { await run(agent, 'Hello, can you help me solve for x: 2x + 3 = 11?'); throw new Error('Expected the math homework guardrail to trip.'); } catch (e) { if (e instanceof InputGuardrailTripwireTriggered) { console.log('Math homework guardrail tripped'); return; } throw e; }}
main().catch((error) => { console.error(error); process.exit(1);});출력 가드레일도 같은 방식으로 작동합니다.
import { Agent, run, OutputGuardrailTripwireTriggered, OutputGuardrail,} from '@openai/agents';import { z } from 'zod';
// The output by the main agentconst MessageOutput = z.object({ response: z.string() });type MessageOutput = z.infer<typeof MessageOutput>;
// The output by the math guardrail agentconst MathOutput = z.object({ reasoning: z.string(), isMath: z.boolean() });
// The guardrail agentconst guardrailAgent = new Agent({ name: 'Guardrail check', instructions: 'Check if the output includes any math.', outputType: MathOutput,});
// An output guardrail using an agent internallyconst mathGuardrail: OutputGuardrail<typeof MessageOutput> = { name: 'Math Guardrail', async execute({ agentOutput, context }) { const result = await run(guardrailAgent, agentOutput.response, { context, }); return { outputInfo: result.finalOutput, tripwireTriggered: result.finalOutput?.isMath ?? false, }; },};
const agent = new Agent({ name: 'Support agent', instructions: 'You are a user support agent. You help users with their questions.', outputGuardrails: [mathGuardrail], outputType: MessageOutput,});
async function main() { try { const input = 'Hello, can you help me solve for x: 2x + 3 = 11?'; await run(agent, input); throw new Error('Expected the math output guardrail to trip.'); } catch (e) { if (e instanceof OutputGuardrailTripwireTriggered) { console.log('Math output guardrail tripped'); return; } throw e; }}
main().catch((error) => { console.error(error); process.exit(1);});도구 입력 가드레일과 도구 출력 가드레일은 다음과 같습니다.
import { Agent, ToolGuardrailFunctionOutputFactory, defineToolInputGuardrail, defineToolOutputGuardrail, tool,} from '@openai/agents';import { z } from 'zod';
const blockSecrets = defineToolInputGuardrail({ name: 'block_secrets', run: async ({ toolCall }) => { const args = JSON.parse(toolCall.arguments) as { text?: string }; if (args.text?.includes('sk-')) { return ToolGuardrailFunctionOutputFactory.rejectContent( 'Remove secrets before calling this tool.', ); } return ToolGuardrailFunctionOutputFactory.allow(); },});
const redactOutput = defineToolOutputGuardrail({ name: 'redact_output', run: async ({ output }) => { const text = String(output ?? ''); if (text.includes('sk-')) { return ToolGuardrailFunctionOutputFactory.rejectContent( 'Output contained sensitive data.', ); } return ToolGuardrailFunctionOutputFactory.allow(); },});
const classifyTool = tool({ name: 'classify_text', description: 'Classify text for internal routing.', parameters: z.object({ text: z.string(), }), inputGuardrails: [blockSecrets], outputGuardrails: [redactOutput], execute: ({ text }) => `length:${text.length}`,});
const agent = new Agent({ name: 'Classifier', instructions: 'Classify incoming text.', tools: [classifyTool],});guardrailAgent는 가드레일 함수 내부에서 사용됩니다.- 가드레일 함수는 에이전트 입력 또는 출력을 받고 결과를 반환합니다.
- 가드레일 결과에 추가 정보를 포함할 수 있습니다.
agent는 가드레일이 적용되는 실제 워크플로를 정의합니다.