使用护栏进行自动检查,并使用人工审查进行审批决策。它们共同决定了运行何时应继续、暂停或停止。
- 护栏 自动验证输入、输出或工具行为。
- 人工审查 暂停运行,以便由人工或策略批准或拒绝敏感操作。
选择合适的控制方式
| 用例 | 起始项 |
|---|---|
| 在主模型运行前阻止不允许的用户请求 | 输入护栏 |
| 在最终输出离开系统前对其进行验证或脱敏 | 输出护栏 |
| 检查函数工具调用的参数或结果 | 工具护栏 |
| 在产生取消、编辑、shell 命令或敏感 MCP 操作等副作用之前暂停 | 人工介入审批 |
添加阻塞性护栏
当您希望在开销大或带有副作用的工作流部分开始前,运行一个快速的验证步骤时,请使用输入护栏。
使用输入护栏阻止请求
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import {
Agent,
InputGuardrailTripwireTriggered,
run,
} from "@openai/agents";
import { z } from "zod";
const guardrailAgent = new Agent({
name: "Homework check",
instructions: "Detect whether the user is asking for math homework help.",
outputType: z.object({
isMathHomework: z.boolean(),
reasoning: z.string(),
}),
});
const agent = new Agent({
name: "Customer support",
instructions: "Help customers with support questions.",
inputGuardrails: [
{
name: "Math homework guardrail",
runInParallel: false,
async execute({ input, context }) {
const result = await run(guardrailAgent, input, { context });
return {
outputInfo: result.finalOutput,
tripwireTriggered: result.finalOutput?.isMathHomework === true,
};
},
},
],
});
try {
await run(agent, "Can you solve 2x + 3 = 11 for me?");
} catch (error) {
if (error instanceof InputGuardrailTripwireTriggered) {
console.log("Guardrail blocked the request.");
}
}当启动主代理的成本或风险过高时,请使用阻塞执行。当较低的延迟比避免推测性工作更重要时,请使用并行护栏。
暂停以进行人工审查
审批是针对工具调用的人工介入路径。模型仍然可以决定需要执行某项操作,但运行会暂停,直到您批准或拒绝该操作。
在敏感操作前暂停以等待审批
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { Agent, run, tool } from "@openai/agents";
import { z } from "zod";
const cancelOrder = tool({
name: "cancel_order",
description: "Cancel a customer order.",
parameters: z.object({ orderId: z.number() }),
needsApproval: true,
async execute({ orderId }) {
return `Cancelled order ${orderId}`;
},
});
const agent = new Agent({
name: "Support agent",
instructions: "Handle support requests and ask for approval when needed.",
tools: [cancelOrder],
});
let result = await run(agent, "Cancel order 123.");
if (result.interruptions?.length) {
const state = result.state;
for (const interruption of result.interruptions) {
state.approve(interruption);
}
result = await run(agent, state);
}
console.log(result.finalOutput);即使审批工具位于工作流的更深处(例如在交接之后或嵌套内部),也同样适用这种中断模式 agent.asTool()
审批生命周期
当工具调用需要审查时,SDK 每次都会遵循相同的模式:
- 运行会记录一次审批中断,而不是执行工具。
- The result returns
interruptions外加一个可恢复的state. - 您的应用程序批准或拒绝待处理的项目。
- 您从同一运行中恢复
state而不是开始一个新的用户轮次。
如果审查可能需要一些时间,请序列化 state,存储它,稍后再恢复。那仍是同一次运行。
工作流边界很重要
代理级别的护栏并不会在所有地方运行:
- 输入护栏仅针对链中的第一个代理运行。
- 输出护栏仅针对产生最终输出的代理运行。
- 工具护栏会在其附加的函数工具上运行。
如果您需要在管理器风格的工作流中检查每一个自定义工具调用,请勿仅依赖代理级别的输入或输出护栏。请将验证逻辑放在产生副作用的工具旁边。
流式处理与延迟审查使用相同的状态模型
流式处理并不会创建一个单独的审批系统。如果流式运行暂停,请等待其稳定下来,检查 interruptions,解决这些审批,并从同一处恢复 state。如果审查稍后进行,请存储序列化的状态,并在决定到达时继续同一次运行。
后续步骤
一旦控制边界明确,请继续阅读涵盖围绕它们的运行时或工具层面的指南。