护栏
护栏可以与您的智能体并行运行,或在其完成前阻塞执行,从而对用户输入或智能体输出进行检查与校验。比如,您可以在调用昂贵模型之前运行一个轻量模型作为护栏。如果护栏检测到恶意使用,它可以触发错误并阻止高成本模型运行。
护栏有两种类型:
- 输入护栏 运行于初始用户输入。
- 输出护栏 运行于最终智能体输出。
输入护栏分三步运行:
- 护栏接收与智能体相同的输入。
- 护栏函数执行并返回一个
GuardrailFunctionOutput,包装在InputGuardrailResult中。 - 如果
tripwireTriggered为true,会抛出InputGuardrailTripwireTriggered错误。
注意 输入护栏用于用户输入,因此仅当该智能体是工作流中的第一个智能体时才会运行。护栏在智能体上进行配置,因为不同的智能体通常需要不同的护栏。
runInParallel: true(默认)在 LLM/工具调用的同时启动护栏。这可最小化延迟,但如果护栏之后才触发,模型可能已经消耗了 tokens 或运行了工具。runInParallel: false在调用模型之前运行护栏,当护栏阻止请求时可避免 token 消耗和工具执行。当您更注重安全和成本而非延迟时使用此模式。
输出护栏分三步运行:
- 护栏接收智能体产生的输出。
- 护栏函数执行并返回一个
GuardrailFunctionOutput,包装在OutputGuardrailResult中。 - 如果
tripwireTriggered为true,会抛出OutputGuardrailTripwireTriggered错误。
注意 仅当该智能体是工作流中的最后一个智能体时才会运行输出护栏。关于实时语音交互,请参见构建语音智能体。
工具护栏包装函数工具,允许您在执行前后对工具调用进行校验或拦截。它们在工具本身(通过 tool() 选项)上进行配置,并在每次工具调用时运行。
- 输入工具护栏 在工具执行前运行,可用消息拒绝调用或抛出触发线。
- 输出工具护栏 在工具执行后运行,可用拒绝消息替换输出或抛出触发线。
工具护栏返回一个 behavior:
allow— 继续下一个护栏或工具执行。rejectContent— 以消息短路(跳过工具调用或替换输出)。throwException— 立即抛出触发线错误。
工具护栏适用于用 tool() 创建的函数工具。托管工具和本地内置工具(computerTool、shellTool、applyPatchTool)不使用此护栏流水线。
当护栏失败时,会通过触发线发出信号。一旦触发线被触发,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?'); console.log("Guardrail didn't trip - this is unexpected"); } catch (e) { if (e instanceof InputGuardrailTripwireTriggered) { console.log('Math homework guardrail tripped'); } }}
main().catch(console.error);输出护栏的工作方式相同。
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); console.log("Guardrail didn't trip - this is unexpected"); } catch (e) { if (e instanceof OutputGuardrailTripwireTriggered) { console.log('Math output guardrail tripped'); } }}
main().catch(console.error);工具的输入/输出护栏如下所示:
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],});
void agent;guardrailAgent在护栏函数内部使用。- 护栏函数接收智能体的输入或输出并返回结果。
- 可在护栏结果中包含额外信息。
agent定义应用护栏的实际工作流。