에이전트 실행
에이전트는 스스로 아무 작업도 하지 않습니다. Runner 클래스나 run() 유틸리티로 실행해야 합니다.
턴 실행, 이벤트 스트리밍, 대화 상태 관리를 하려면 에이전트 문서를 읽은 다음 이 페이지를 읽으세요. 아직 에이전트를 어떻게 정의할지 결정 중이라면 먼저 에이전트부터 시작하세요.
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', instructions: 'You are a helpful assistant',});
const result = await run( agent, 'Write a haiku about recursion in programming.',);console.log(result.finalOutput);
// Code within the code,// Functions calling themselves,// Infinite loop's dance.커스텀 runner 가 필요하지 않다면, 싱글턴 기본 Runner 인스턴스를 실행하는 run() 유틸리티를 사용할 수도 있습니다.
또는 직접 runner 인스턴스를 만들 수도 있습니다:
import { Agent, Runner } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', instructions: 'You are a helpful assistant',});
// You can pass custom configuration to the runnerconst runner = new Runner();
const result = await runner.run( agent, 'Write a haiku about recursion in programming.',);console.log(result.finalOutput);
// Code within the code,// Functions calling themselves,// Infinite loop's dance.에이전트를 실행하면 최종 출력과 전체 실행 이력을 담고 있는 실행 결과 객체를 받게 됩니다.
Runner 수명 주기 및 설정
섹션 제목: “Runner 수명 주기 및 설정”에이전트 루프
섹션 제목: “에이전트 루프”Runner 의 run 메서드를 사용할 때는 시작 에이전트와 입력을 전달합니다. 입력은 문자열(사용자 메시지로 간주됨)이거나, OpenAI Responses API 의 항목들인 입력 항목 목록일 수 있습니다.
그러면 runner 는 다음 루프를 실행합니다:
- 현재 입력으로 현재 에이전트의 모델을 호출합니다.
- LLM 응답을 검사합니다.
- 최종 출력 → 반환
- 핸드오프 → 새 에이전트로 전환하고, 누적된 대화 이력을 유지한 채 1로 이동
- 도구 호출 → 도구를 실행하고, 그 결과를 대화에 추가한 뒤 1로 이동
maxTurns에 도달하면MaxTurnsExceededError를 발생시킵니다.
Runner 수명 주기
섹션 제목: “Runner 수명 주기”앱이 시작할 때 Runner 를 생성하고 요청 간에 재사용하세요. 인스턴스는 모델 provider 나 트레이싱 옵션 같은 전역 설정을 저장합니다. 완전히 다른 설정이 필요할 때만 다른 Runner 를 만드세요. 간단한 스크립트에서는 내부적으로 기본 runner 를 사용하는 run() 을 호출해도 됩니다.
실행 인자
섹션 제목: “실행 인자”run() 메서드의 입력은 실행을 시작할 초기 에이전트, 실행용 입력, 그리고 옵션 집합입니다.
입력은 문자열(사용자 메시지로 간주됨)이거나, input items 목록이거나, 휴먼 인 더 루프 (HITL) 에이전트를 만들 때의 RunState 객체일 수 있습니다.
추가 옵션은 다음과 같습니다:
| Option | Default | Description |
|---|---|---|
stream | false | true 이면 호출은 StreamedRunResult 를 반환하고 모델에서 이벤트가 도착하는 대로 방출합니다. |
context | – | 모든 도구 / 가드레일 / 핸드오프에 전달되는 컨텍스트 객체입니다. 자세한 내용은 컨텍스트 관리 가이드를 참고하세요. |
maxTurns | 10 | 안전 제한입니다. 도달하면 MaxTurnsExceededError를 발생시킵니다. |
signal | – | 취소를 위한 AbortSignal 입니다. |
session | – | 세션 지속성 구현입니다. 세션 가이드를 참고하세요. |
sessionInputCallback | – | 세션 이력과 새 입력을 병합하는 커스텀 로직입니다. 모델 호출 전에 실행됩니다. 세션을 참고하세요. |
callModelInputFilter | – | 모델 호출 직전에 모델 입력(항목 + 선택적 instructions)을 편집하는 훅입니다. Call model input filter를 참고하세요. |
toolErrorFormatter | – | 모델에 반환되는 도구 승인 거부 메시지를 커스터마이즈하는 훅입니다. Tool error formatter를 참고하세요. |
reasoningItemIdPolicy | – | 이전 실행 항목을 다시 모델 입력으로 변환할 때 reasoning-item id 를 유지할지 생략할지 제어합니다. Reasoning item ID policy를 참고하세요. |
tracing | – | 실행별 트레이싱 설정 재정의입니다(예: export API key). |
errorHandlers | – | 지원되는 런타임 오류용 핸들러입니다(현재는 maxTurns). Error handlers를 참고하세요. |
conversationId | – | 서버 측 대화를 재사용합니다(OpenAI Responses API + Conversations API 전용). |
previousResponseId | – | 대화를 만들지 않고 이전 Responses API 호출에서 이어갑니다(OpenAI Responses API 전용). |
스트리밍
섹션 제목: “스트리밍”스트리밍을 사용하면 LLM 이 실행되는 동안 스트리밍 이벤트도 함께 받을 수 있습니다. 스트림이 시작되면 StreamedRunResult 에는 새로 생성된 모든 출력을 포함해 실행에 대한 전체 정보가 들어 있습니다. for await 루프로 스트리밍 이벤트를 순회할 수 있습니다. 자세한 내용은 스트리밍 가이드를 참고하세요.
실행 설정
섹션 제목: “실행 설정”직접 Runner 인스턴스를 만드는 경우, runner 를 설정하기 위해 RunConfig 객체를 전달할 수 있습니다.
| Field | Type | Purpose |
|---|---|---|
model | string | Model | 실행의 모든 에이전트에 대해 특정 모델을 강제합니다. |
modelProvider | ModelProvider | 모델 이름을 해석합니다. 기본값은 OpenAI provider 입니다. |
modelSettings | ModelSettings | 에이전트별 설정을 덮어쓰는 전역 튜닝 매개변수입니다. opt-in 재시도 설정을 포함한 자세한 내용은 모델 가이드를 참고하세요. |
handoffInputFilter | HandoffInputFilter | 핸드오프 수행 시 입력 항목을 변경합니다(핸드오프 자체에 이미 정의되어 있지 않은 경우). |
inputGuardrails | InputGuardrail[] | 초기 사용자 입력에 적용되는 가드레일입니다. |
outputGuardrails | OutputGuardrail[] | 최종 출력에 적용되는 가드레일입니다. |
tracingDisabled | boolean | OpenAI Tracing 을 완전히 비활성화합니다. |
traceIncludeSensitiveData | boolean | span 은 계속 방출하면서 trace 에서 LLM/도구 입력 및 출력을 제외합니다. |
workflowName | string | Traces 대시보드에 표시되며 관련 실행을 그룹화하는 데 도움이 됩니다. |
traceId / groupId | string | SDK 가 생성하도록 두는 대신 trace 또는 group ID 를 수동으로 지정합니다. |
traceMetadata | Record<string, string> | 모든 span 에 첨부할 임의의 메타데이터입니다. |
tracing | TracingConfig | 실행별 트레이싱 재정의입니다(예: export API key). |
sessionInputCallback | SessionInputCallback | 이 runner 의 모든 실행에 대한 기본 이력 병합 전략입니다. |
callModelInputFilter | CallModelInputFilter | 각 모델 호출 전에 모델 입력을 편집하는 전역 훅입니다. |
toolErrorFormatter | ToolErrorFormatter | 모델에 반환되는 도구 승인 거부 메시지를 커스터마이즈하는 전역 훅입니다. |
reasoningItemIdPolicy | ReasoningItemIdPolicy | 생성된 항목을 이후 모델 호출에 다시 재생할 때 reasoning-item id 를 유지하거나 생략하는 기본 정책입니다. |
상태 및 대화 관리
섹션 제목: “상태 및 대화 관리”메모리 전략 선택
섹션 제목: “메모리 전략 선택”다음 턴으로 상태를 전달하는 일반적인 방법은 네 가지입니다:
| Strategy | Where state lives | Best for | What you pass on the next turn |
|---|---|---|---|
result.history | 앱 메모리 | 작은 채팅 루프, 완전한 수동 제어, 모든 provider | result.history |
session | 사용자 스토리지 + SDK | 영속적인 채팅 상태, 재개 가능한 실행, 커스텀 스토어 | 동일한 session 인스턴스(또는 스토어 기반 인스턴스) |
conversationId | OpenAI Conversations API | 워커/서비스 간 공유되는 서버 측 상태 | 동일한 conversationId 와 새 사용자 턴만 |
previousResponseId | OpenAI Responses API 전용 | 대화를 만들지 않는 가장 단순한 서버 관리형 이어가기 | result.lastResponseId 와 새 사용자 턴만 |
result.history 와 session 은 클라이언트 관리형입니다. conversationId 와 previousResponseId 는 OpenAI 관리형이며 OpenAI Responses API 를 사용할 때만 적용됩니다. 대부분의 애플리케이션에서는 대화마다 하나의 지속성 전략을 선택하세요. 의도적으로 두 계층을 조정하는 경우가 아니라면 클라이언트 관리형 이력과 서버 관리형 상태를 섞으면 컨텍스트가 중복될 수 있습니다.
대화 / 채팅 스레드
섹션 제목: “대화 / 채팅 스레드”runner.run()(또는 run() 유틸리티)의 각 호출은 애플리케이션 수준 대화의 한 턴 을 나타냅니다. RunResult 중 최종 사용자에게 얼마나 보여줄지는 직접 선택합니다. 때로는 finalOutput 만, 다른 경우에는 생성된 모든 항목을 보여줄 수 있습니다.
import { Agent, run } from '@openai/agents';import type { AgentInputItem } from '@openai/agents';
let thread: AgentInputItem[] = [];
const agent = new Agent({ name: 'Assistant',});
async function userSays(text: string) { const result = await run( agent, thread.concat({ role: 'user', content: text }), );
thread = result.history; // Carry over history + newly generated items return result.finalOutput;}
await userSays('What city is the Golden Gate Bridge in?');// -> "San Francisco"
await userSays('What state is it in?');// -> "California"대화형 버전은 chat 예제를 참고하세요.
서버 관리형 대화
섹션 제목: “서버 관리형 대화”매 턴마다 전체 로컬 대화 이력을 보내는 대신, OpenAI Responses API 가 대화 이력을 대신 저장하도록 할 수 있습니다. 이는 긴 대화나 여러 서비스를 조율할 때 유용합니다. 아래의 두 서버 관리형 접근 방식 모두에서 각 요청마다 새 턴의 입력만 전달하면 됩니다. API 가 이전 상태를 재사용합니다. 자세한 내용은 Conversation state guide를 참고하세요.
OpenAI 는 서버 측 상태를 재사용하는 두 가지 방법을 제공합니다:
1. 전체 대화를 위한 conversationId
섹션 제목: “1. 전체 대화를 위한 conversationId”Conversations API를 사용해 한 번 대화를 만들고, 모든 턴에서 해당 ID 를 재사용할 수 있습니다. SDK 는 새로 생성된 항목만 자동으로 포함합니다.
import { Agent, run } from '@openai/agents';import { OpenAI } from 'openai';
const agent = new Agent({ name: 'Assistant', instructions: 'Reply very concisely.',});
async function main() { // Create a server-managed conversation: const client = new OpenAI(); const { id: conversationId } = await client.conversations.create({});
const first = await run(agent, 'What city is the Golden Gate Bridge in?', { conversationId, }); console.log(first.finalOutput); // -> "San Francisco"
const second = await run(agent, 'What state is it in?', { conversationId }); console.log(second.finalOutput); // -> "California"}
main().catch(console.error);2. 마지막 턴에서 이어가기 위한 previousResponseId
섹션 제목: “2. 마지막 턴에서 이어가기 위한 previousResponseId”어차피 Responses API 만으로 시작하려는 경우, 이전 응답에서 반환된 ID 를 사용해 각 요청을 연결할 수 있습니다. 이렇게 하면 전체 대화 리소스를 만들지 않고도 턴 간 컨텍스트를 유지할 수 있습니다.
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', instructions: 'Reply very concisely.',});
async function main() { const first = await run(agent, 'What city is the Golden Gate Bridge in?'); console.log(first.finalOutput); // -> "San Francisco"
const previousResponseId = first.lastResponseId; const second = await run(agent, 'What state is it in?', { previousResponseId, }); console.log(second.finalOutput); // -> "California"}
main().catch(console.error);conversationId 와 previousResponseId 는 함께 사용할 수 없습니다. 시스템 간에 공유할 수 있는 이름 있는 대화 리소스가 필요하면 conversationId 를, 한 응답에서 다음 응답으로 이어지는 가장 저렴한 SDK 수준 이어가기 기본 요소만 원하면 previousResponseId 를 사용하세요.
훅 및 커스터마이즈
섹션 제목: “훅 및 커스터마이즈”Call model input filter
섹션 제목: “Call model input filter”callModelInputFilter 를 사용하면 모델이 호출되기 직전 에 모델 입력을 편집할 수 있습니다. 이 훅은 현재 에이전트, 컨텍스트, 그리고 결합된 입력 항목(session 이 있으면 세션 이력 포함)을 받습니다. 민감한 데이터를 가리거나, 오래된 메시지를 제거하거나, 추가 시스템 가이드를 주입하려면 업데이트된 input 배열과 선택적 instructions 를 반환하세요.
실행별로는 runner.run(..., { callModelInputFilter }) 에서 설정하거나, Runner 설정(RunConfig 의 callModelInputFilter)에서 기본값으로 설정할 수 있습니다.
반환값은 반드시 ModelInputData 객체여야 합니다: { input: AgentInputItem[], instructions? }. input 필드는 필수이며 배열이어야 합니다. 다른 형태를 반환하면 UserError 가 발생합니다.
SDK 는 필터를 호출하기 전에 준비된 턴 입력을 복제합니다. session 도 함께 사용 중이라면 필터링된 복제본이 저장되므로, 여기서 적용한 마스킹이나 잘라내기는 저장된 세션 이력에도 반영됩니다.
conversationId 또는 previousResponseId 를 사용할 때 이 훅은 다음 Responses API 호출을 위한 준비된 payload 에서 실행됩니다. 이전 서버 관리형 컨텍스트는 API 가 복원하므로, 해당 호출에 대한 필터링 배열은 이미 이전 이력 전체 재생이 아니라 새 턴의 delta 만 나타낼 수 있습니다. 이 최종 필터 단계 전에 저장된 이력과 현재 턴이 병합되는 방식을 바꾸고 싶다면 sessionInputCallback 을 사용하세요.
Tool error formatter
섹션 제목: “Tool error formatter”toolErrorFormatter 를 사용하면 도구 호출이 거부되었을 때 모델로 다시 전송되는 승인 거부 메시지를 커스터마이즈할 수 있습니다. 이를 통해 SDK 기본 메시지 대신 도메인별 표현(예: 컴플라이언스 가이드)을 반환할 수 있습니다.
formatter 는 실행별(runner.run(..., { toolErrorFormatter })) 또는 전역적으로 RunConfig(new Runner(...) 의 toolErrorFormatter)에서 설정할 수 있습니다.
이 formatter 는 승인 거부에 대한 전역 fallback 입니다. 특정 인터럽션을 result.state.reject(interruption, { message: '...' }) 로 거부하면, 호출별 message 가 toolErrorFormatter 보다 우선합니다. 둘 다 제공되지 않으면 SDK 는 기본 거부 텍스트인 Tool execution was not approved. 를 사용합니다.
현재 formatter 는 approval_rejected 이벤트에서 실행되며 다음을 받습니다:
kind(현재는 항상'approval_rejected')toolType('function','computer','shell', 또는'apply_patch')toolNamecallIddefaultMessage(SDK fallback 메시지, 현재Tool execution was not approved.)runContext
메시지를 재정의하려면 문자열을 반환하고, SDK 기본값을 유지하려면 undefined 를 반환하세요. formatter 가 예외를 발생시키거나(또는 문자열이 아닌 값을 반환하면) SDK 는 경고를 기록하고 기본 승인 거부 메시지로 fallback 합니다.
Reasoning item ID policy
섹션 제목: “Reasoning item ID policy”reasoningItemIdPolicy 를 사용하면 SDK 가 이전에 생성된 실행 항목을 이후 모델 입력용 AgentInputItem[] 로 다시 변환할 때 reasoning item 이 id 필드를 유지할지 제어할 수 있습니다.
이는 SDK 가 생성된 모델 항목을 입력으로 다시 재생하는 다음과 같은 경우에 영향을 줍니다:
- 같은 실행 내의 후속 모델 호출(예: 도구 실행 후)
- 생성된 항목을 입력/이력으로 재사용하는 후속 턴
- 저장된
RunState에서 재개된 실행 result.history/result.output같은 파생된 결과 뷰(모델 입력 형태의 배열)'preserve'(기본값)는 reasoning-item ID 를 유지합니다'omit'는 입력으로 다시 보내기 전에 reasoning item 에서id필드를 제거합니다- reasoning item 이 아닌 항목은 영향을 받지 않습니다
이 설정으로 변경되지 않는 것:
- 원문 모델 응답(
result.rawResponses) - 실행 항목(
result.newItems) - provider 가 반환한 모델의 현재 턴 출력
즉, 이 정책은 SDK 가 이전에 생성된 항목으로부터 다음 입력 을 구성할 때 적용됩니다.
정책은 실행별로 (runner.run(..., { reasoningItemIdPolicy: 'omit' })) 또는 runner 기본값으로 (new Runner({ reasoningItemIdPolicy: 'omit', ... })) 설정할 수 있습니다. 저장된 RunState 에서 재개할 때는 재정의하지 않는 한 이전에 결정된 정책이 재사용됩니다.
callModelInputFilter 와의 상호작용
섹션 제목: “callModelInputFilter 와의 상호작용”reasoningItemIdPolicy 는 callModelInputFilter 보다 먼저 적용됩니다. 커스텀 동작이 필요하다면, callModelInputFilter 가 준비된 입력을 검사하고 모델 호출 전에 reasoning ID 를 수동으로 다시 추가하거나 제거할 수 있습니다.
'omit' 을 사용할 때
섹션 제목: “'omit' 을 사용할 때”재생된 reasoning item 을 ID 없이 정규화하고 싶다면 'omit' 을 사용하세요(예: 전달/재생되는 모델 입력을 더 단순하게 유지하거나 앱 파이프라인의 통합 요구사항에 맞추기 위해).
또한 백엔드/provider 가 재생된 reasoning item 을 요청 검증 오류로 거부하는 경우(예: 후속 입력의 reasoning item ID 와 관련된 HTTP 400 오류) 유용한 문제 해결 옵션이기도 합니다. 이런 경우 'omit' 으로 재생된 reasoning ID 를 제거하면 백엔드가 새 요청에 대해 유효하지 않다고 간주하는 ID 전송을 피할 수 있습니다.
SDK 가 재생된 입력 전반에 reasoning-item ID 를 유지하길 원하고 통합 환경에서도 이를 허용한다면 'preserve' 를 유지하세요.
오류 및 복구
섹션 제목: “오류 및 복구”Error handlers
섹션 제목: “Error handlers”errorHandlers 를 사용하면 지원되는 런타임 오류를 throw 하지 않고 최종 출력으로 변환할 수 있습니다. 현재는 maxTurns 만 지원됩니다.
errorHandlers.maxTurns는 max-turn 오류만 처리합니다errorHandlers.default는 지원되는 종류에 대한 fallback 으로 사용됩니다- 핸들러는
{ error, context, runData }를 받고{ finalOutput, includeInHistory? }를 반환할 수 있습니다
SDK 는 잡아서 처리할 수 있는 소수의 오류를 발생시킵니다:
MaxTurnsExceededError–maxTurns도달ModelBehaviorError– 모델이 잘못된 출력을 생성함(예: 잘못된 JSON, 알 수 없는 도구)InputGuardrailTripwireTriggered/OutputGuardrailTripwireTriggered– 가드레일 위반ToolInputGuardrailTripwireTriggered/ToolOutputGuardrailTripwireTriggered– 도구 가드레일 위반GuardrailExecutionError– 가드레일이 완료되지 못함ToolTimeoutError– 함수 도구가timeoutMs를 초과했고timeoutBehavior: 'raise_exception'을 사용함ToolCallError– 함수 도구 실행이 타임아웃이 아닌 오류로 실패함UserError– 설정 또는 사용자 입력을 기반으로 발생한 모든 오류
모두 기본 AgentsError 클래스를 확장하며, 현재 실행 상태에 접근할 수 있는 state 속성을 제공할 수 있습니다.
다음은 GuardrailExecutionError 를 처리하는 코드 예제입니다. 입력 가드레일은 첫 번째 사용자 입력에서만 실행되므로, 이 예제는 원래 입력과 컨텍스트로 실행을 다시 시작합니다. 또한 저장된 상태를 재사용해 모델을 다시 호출하지 않고 출력 가드레일을 재시도하는 방법도 보여줍니다:
import { Agent, GuardrailExecutionError, InputGuardrail, InputGuardrailTripwireTriggered, OutputGuardrail, OutputGuardrailTripwireTriggered, run,} from '@openai/agents';import { z } from 'zod';
// Shared guardrail agent to avoid re-creating it on every fallback run.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(), }),});
async function main() { const input = 'Hello, can you help me solve for x: 2x + 3 = 11?'; const context = { customerId: '12345' };
// Input guardrail example
const unstableInputGuardrail: InputGuardrail = { name: 'Math Homework Guardrail (unstable)', execute: async () => { throw new Error('Something is wrong!'); }, };
const fallbackInputGuardrail: InputGuardrail = { name: 'Math Homework Guardrail (fallback)', execute: async ({ input, context }) => { const result = await run(guardrailAgent, input, { context }); const isMathHomework = result.finalOutput?.isMathHomework ?? /solve for x|math homework/i.test(JSON.stringify(input)); return { outputInfo: result.finalOutput, tripwireTriggered: isMathHomework, }; }, };
const agent = new Agent({ name: 'Customer support agent', instructions: 'You are a customer support agent. You help customers with their questions.', inputGuardrails: [unstableInputGuardrail], });
try { // Input guardrails only run on the first turn of a run, so retries must start a fresh run. await run(agent, input, { context }); } catch (e) { if (e instanceof GuardrailExecutionError) { console.error(`Guardrail execution failed (input): ${e}`); try { agent.inputGuardrails = [fallbackInputGuardrail]; // Retry from scratch with the original input and context. await run(agent, input, { context }); } catch (ee) { if (ee instanceof InputGuardrailTripwireTriggered) { console.log('Math homework input guardrail tripped on retry'); } else { throw ee; } } } else { throw e; } }
// Output guardrail example
const replyOutputSchema = z.object({ reply: z.string() });
const unstableOutputGuardrail: OutputGuardrail<typeof replyOutputSchema> = { name: 'Answer review (unstable)', execute: async () => { throw new Error('Output guardrail crashed.'); }, };
const fallbackOutputGuardrail: OutputGuardrail<typeof replyOutputSchema> = { name: 'Answer review (fallback)', execute: async ({ agentOutput }) => { const outputText = typeof agentOutput === 'string' ? agentOutput : (agentOutput?.reply ?? JSON.stringify(agentOutput)); const flagged = /math homework|solve for x|x =/i.test(outputText); return { outputInfo: { flaggedOutput: outputText }, tripwireTriggered: flagged, }; }, };
const agent2 = new Agent<unknown, typeof replyOutputSchema>({ name: 'Customer support agent (output check)', instructions: 'You are a customer support agent. Answer briefly.', outputType: replyOutputSchema, outputGuardrails: [unstableOutputGuardrail], });
try { await run(agent2, input, { context }); } catch (e) { if (e instanceof GuardrailExecutionError && e.state) { console.error(`Guardrail execution failed (output): ${e}`); try { agent2.outputGuardrails = [fallbackOutputGuardrail]; // Output guardrails can be retried using the saved state without another model call. await run(agent2, e.state); } catch (ee) { if (ee instanceof OutputGuardrailTripwireTriggered) { console.log('Output guardrail tripped after retry with saved state'); } else { throw ee; } } } else { throw e; } }}
main().catch(console.error);입력 vs. 출력 재시도:
- 입력 가드레일은 실행의 첫 번째 사용자 입력에서만 실행되므로, 재시도하려면 같은 입력/컨텍스트로 새 실행을 시작해야 합니다. 저장된
state를 전달해도 입력 가드레일은 다시 실행되지 않습니다 - 출력 가드레일은 모델 응답 후에 실행되므로,
GuardrailExecutionError의 저장된state를 재사용해 모델을 다시 호출하지 않고 출력 가드레일을 다시 실행할 수 있습니다
위 예제를 실행하면 다음 출력이 표시됩니다:
Guardrail execution failed (input): Error: Input guardrail failed to complete: Error: Something is wrong!Math homework input guardrail tripped on retryGuardrail execution failed (output): Error: Output guardrail failed to complete: Error: Output guardrail crashed.Output guardrail tripped after retry with saved state