コンテンツにスキップ

ガードレール

ガードレールはエージェントと並行して実行することも、完了するまで実行をブロックすることもでき、ユーザー入力やエージェント出力のチェックと検証を行えます。たとえば、高コストなモデルを呼び出す前に、軽量なモデルをガードレールとして実行できます。ガードレールが悪意のある使用を検出した場合、エラーを発生させて、高コストなモデルの実行を停止できます。

ガードレールには 3 つの種類があります。

  1. 入力ガードレール は、最初のユーザー入力に対して実行されます。
  2. 出力ガードレール は、エージェントの最終出力に対して実行されます。
  3. ツールガードレール は、カスタム関数ツールの各呼び出しの前後で実行されます。

ガードレールはエージェントに設定されますが、ワークフロー内のすべてのエージェントで実行されるとは限りません。

  • 入力ガードレール は、チェーン内の最初のエージェントに対してのみ実行されます。
  • 出力ガードレール は、最終出力を生成するエージェントに対してのみ実行されます。
  • ツールガードレール は、関数ツールの呼び出しごとに実行されます。入力ガードレールは実行前に、出力ガードレールは実行後に実行されます。

マネージャーやハンドオフを含むワークフローで、カスタム関数ツールの呼び出しごとにチェックする必要がある場合は、エージェントレベルの入力ガードレールと出力ガードレールではなく、 ツールガードレール を使用してください。

入力ガードレールは、次の 3 ステップで実行されます。

  1. ガードレールは、エージェントに渡されたものと同じ入力を受け取ります。
  2. ガードレール関数が実行され、InputGuardrailResult 内にラップされた GuardrailFunctionOutput を返します。
  3. tripwireTriggeredtrue の場合、InputGuardrailTripwireTriggered エラーがスローされます。

注記 入力ガードレールはユーザー入力を対象としているため、エージェントがワークフロー内の 最初 のエージェントである場合にのみ実行されます。エージェントごとに異なるガードレールが必要になることが多いため、ガードレールはエージェント自体に設定されます。

  • runInParallel: true(デフォルト)では、入力ガードレールとエージェントの実行が同時に開始されます。同時実行によりレイテンシーを最小限に抑えられますが、その後ガードレールが作動した場合でも、モデルがすでにトークンを消費したり、ツールを実行したりしている可能性があります。
  • runInParallel: false では、モデルを呼び出す 前に ガードレールが実行されるため、ガードレールがリクエストをブロックした場合のトークン消費とツール実行を防止できます。レイテンシーより安全性とコストを優先する場合に使用してください。

出力ガードレールは、次の 3 ステップで実行されます。

  1. ガードレールは、エージェントが生成した出力を受け取ります。
  2. ガードレール関数が実行され、OutputGuardrailResult 内にラップされた GuardrailFunctionOutput を返します。
  3. tripwireTriggeredtrue の場合、OutputGuardrailTripwireTriggered エラーがスローされます。

注記 出力ガードレールは、エージェントがワークフロー内の 最後 のエージェントである場合にのみ実行されます。リアルタイムの音声対話については、音声エージェントの構築を参照してください。

出力ガードレール関数は、基になる modelResponse と、そのターンで生成された出力項目を含む、オプションの details オブジェクトも受け取ります。最終出力だけではレスポンスを通過させるべきか判断できない場合に使用してください。たとえば、ガードレールを作動させる前に、生成された項目の完全なリストやプロバイダーのレスポンスメタデータを調べる場合に使用できます。

toolUseBehavior により、完了した関数ツールの実行結果が実行全体の最終出力になる場合、SDK がその実行結果をリプレイ可能な最終データとして扱う前に、出力ガードレールが評価します。ガードレールは、元の出力候補を受け取ります。ガードレールが作動すると、SDK は、SDK が管理する実行状態、リプレイデータ、セッション履歴、公開されるトリップワイヤーエラーに含まれる拒否された終端結果を、Output withheld by an output guardrail. に置き換えます。

SDK は、拒否された出力の別名を保持する可能性があるメタデータもサニタイズします。現在のレスポンスでは、OutputGuardrailResult.agentOutput が同じプレースホルダーになり、OutputGuardrailResult.outputInfo は削除されます。現在のツール出力ガードレールの結果では判定内容は保持されますが、outputInfo は省略されます。rejectContent の結果では、プレースホルダーがメッセージとして使用されます。以前に受け入れられたターンの結果と履歴は変更されません。

認識済みの関数呼び出しと実行結果の組み合わせについて、SDK は、実行結果の内容を置き換えつつ、リプレイに必要な識別情報とステータスフィールドを保持します。現在のレスポンス項目のうち、どれが拒否された終端出力に属するかを SDK が確定できない場合は、リプレイせず、現在のレスポンスに含まれる曖昧な末尾部分を破棄するか、安全側に倒して失敗させます。

この保護機能は、外部ツールの副作用を取り消したり、アプリケーションコードにすでに出力された内容を撤回したり、SDK の制御外ですでに保存されたデータを消去したり、プロバイダーの元データに対するアプリケーション所有の参照を変更したりするものではありません。

ツールガードレールは 関数ツール をラップし、実行前後にツール呼び出しを検証またはブロックできるようにします。ツール自体に(tool() のオプションを介して)設定され、そのツールの呼び出しごとに実行されます。

具体的には、tool({...})inputGuardrailsoutputGuardrails、またはその両方を設定したカスタム関数ツールが対象です。

  • 入力ツールガードレール は、ツールの実行前に実行され、メッセージを伴って呼び出しを拒否するか、トリップワイヤーをスローできます。
  • 出力ツールガードレール は、ツールの実行後に実行され、出力を拒否メッセージに置き換えるか、トリップワイヤーをスローできます。

ローカル関数ツールで人間の承認も必要な場合、通常、入力ツールガードレールは承認後、実行直前に実行されます。保留中の承認リクエストより前にもこれらの入力ガードレールを実行するには、run() または RunnertoolExecution: { preApprovalInputGuardrails: true } を設定します。ガードレールは承認後にも再度実行され、その後にツールが実行されます。

ツールガードレールは behavior を返します。

  • allow — 次のガードレールまたはツールの実行に進みます。
  • rejectContent — メッセージを返して後続処理を中断します(ツール呼び出しがスキップされるか、出力が置き換えられます)。
  • throwException — トリップワイヤーエラーを即座にスローします。

ツールガードレールは、tool() で定義した関数ツールに適用されます。ハンドオフは関数に似たツールとしてモデルに提示されますが、通常の関数ツールパイプラインではなく SDK のハンドオフ経路を通じて実行されるため、ツールガードレールはハンドオフ呼び出し自体には適用されません。組み込みツール(Hosted)と組み込み実行ツール(computerToolshellToolapplyPatchTool)も、このガードレールパイプラインを使用しません。また、agent.asTool() は現在、ツールガードレールのオプションを直接公開していません。

ガードレールが失敗すると、トリップワイヤーによって通知されます。Runner はまず、同じバッチで開始された他のガードレールの完了を待ち、完了した実行結果を記録します。その後、Runner は対応するエラーをスローし、それ以降の実行処理を停止します。入力ガードレールを並列実行する場合、実行モードで説明したとおり、モデルまたはツールの処理がすでに開始されている可能性があります。

ガードレールは、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 agent
const MessageOutput = z.object({ response: z.string() });
type MessageOutput = z.infer<typeof MessageOutput>;
// The output by the math guardrail agent
const MathOutput = z.object({ reasoning: z.string(), isMath: z.boolean() });
// The guardrail agent
const guardrailAgent = new Agent({
name: 'Guardrail check',
instructions: 'Check if the output includes any math.',
outputType: MathOutput,
});
// An output guardrail using an agent internally
const 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],
});
  1. guardrailAgent はガードレール関数内で使用されます。
  2. ガードレール関数はエージェントの入力または出力を受け取り、実行結果を返します。
  3. ガードレールの実行結果には、追加情報を含めることができます。
  4. agent は、ガードレールが適用される実際のワークフローを定義します。