OpenAI Agents SDK 护栏与人工审查
护栏用于自动检查,人工审查用于批准决策。两者共同决定一次运行何时继续、暂停或停止。
- 护栏:自动验证输入、输出或工具行为。
- 人工审查:暂停运行,让人员或策略批准或拒绝敏感操作。
选择合适的控制方式
| 使用场景 | 起点 |
|---|---|
| 主模型运行前阻止不允许的用户请求 | 输入护栏 |
| 最终输出离开系统前验证或脱敏 | 输出护栏 |
| 在函数工具调用前后检查参数或结果 | 工具护栏 |
| 在取消、编辑、shell命令、敏感MCP操作等副作用发生前暂停 | 人工参与批准 |
添加阻塞式护栏
希望在昂贵或可能产生副作用的工作开始前快速验证,使用输入护栏:
来源示例 1(javascript):
// [中文] 示例1:添加阻塞式护栏。
// [中文] 护栏智能体检测请求是否为数学作业求助;客户支持智能体负责支持问题,测试输入是“帮我解2x+3=11”。
// [中文] 检测结果触发tripwire时捕获输入护栏异常;JavaScript显式设置runInParallel:false,Python显式设置run_in_parallel=False,均先校验输入再启动支持智能体。
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.");
} else {
throw error;
}
}
来源示例 2(python):
## [中文] 示例2:添加阻塞式护栏。
## [中文] 护栏智能体检测请求是否为数学作业求助;客户支持智能体负责支持问题,测试输入是“帮我解2x+3=11”。
## [中文] 检测结果触发tripwire时捕获输入护栏异常;JavaScript显式设置runInParallel:false,Python显式设置run_in_parallel=False,均先校验输入再启动支持智能体。
import asyncio
from pydantic import BaseModel
from agents import (
Agent,
GuardrailFunctionOutput,
InputGuardrailTripwireTriggered,
RunContextWrapper,
Runner,
TResponseInputItem,
input_guardrail,
)
class MathHomeworkOutput(BaseModel):
is_math_homework: bool
reasoning: str
guardrail_agent = Agent(
name="Homework check",
instructions="Detect whether the user is asking for math homework help.",
output_type=MathHomeworkOutput,
)
## Validate input before starting the support agent.
@input_guardrail(run_in_parallel=False)
async def math_guardrail(
ctx: RunContextWrapper[None],
agent: Agent,
input: str | list[TResponseInputItem],
) -> GuardrailFunctionOutput:
result = await Runner.run(guardrail_agent, input, context=ctx.context)
return GuardrailFunctionOutput(
output_info=result.final_output,
tripwire_triggered=result.final_output.is_math_homework,
)
agent = Agent(
name="Customer support",
instructions="Help customers with support questions.",
input_guardrails=[math_guardrail],
)
async def main() -> None:
try:
await Runner.run(agent, "Can you solve 2x + 3 = 11 for me?")
except InputGuardrailTripwireTriggered:
print("Guardrail blocked the request.")
if __name__ == "__main__":
asyncio.run(main())
提前启动主智能体的成本或风险过高时,使用阻塞式执行;更重视低延迟、可以接受推测执行时,使用并行护栏。
暂停并等待人工审查
批准是工具调用的人工参与路径。模型仍可决定需要某项操作,但运行会暂停,直到该操作被批准或拒绝。
来源示例 3(javascript):
// [中文] 示例3:暂停并等待人工审查。
// [中文] 取消订单工具标记为需要批准;示例请求取消订单123,工具函数只返回“已取消订单”文本,没有接入真实订单系统。
// [中文] 来源示例直接批准所有interruptions来演示恢复状态;它没有实现实际审查界面或决策策略,产品中应先取得相应决策再调用approve。
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: "Use cancel_order to handle cancellation requests.",
tools: [cancelOrder],
});
let result = await run(agent, "Cancel order 123.");
if (result.interruptions?.length) {
const state = result.state;
for (const interruption of result.interruptions) {
console.log(`Approval required: ${interruption.name}`);
state.approve(interruption);
}
result = await run(agent, state);
}
console.log(result.finalOutput);
来源示例 4(python):
## [中文] 示例4:暂停并等待人工审查。
## [中文] 取消订单工具标记为需要批准;示例请求取消订单123,工具函数只返回“已取消订单”文本,没有接入真实订单系统。
## [中文] 来源示例直接批准所有interruptions来演示恢复状态;它没有实现实际审查界面或决策策略,产品中应先取得相应决策再调用approve。
import asyncio
from agents import Agent, Runner, function_tool
@function_tool(needs_approval=True)
async def cancel_order(order_id: int) -> str:
return f"Cancelled order {order_id}"
agent = Agent(
name="Support agent",
instructions="Use cancel_order to handle cancellation requests.",
tools=[cancel_order],
)
async def main() -> None:
result = await Runner.run(agent, "Cancel order 123.")
if result.interruptions:
state = result.to_state()
for interruption in result.interruptions:
print("Approval required:", interruption.name)
state.approve(interruption)
result = await Runner.run(agent, state)
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main())
即使需要批准的工具位于工作流深层,例如交接后,或嵌套在TypeScript的agent.asTool()、Python的agent.as_tool()调用内,也采用相同中断模式。
批准生命周期
工具调用需要审查时,SDK遵循同一流程:
- 记录批准中断,不执行工具。
- 结果返回
interruptions及可恢复的state。 - 应用批准或拒绝待处理项目。
- 从
state恢复同一次运行,而不是开始新的用户轮次。
审查可能耗时较久时,序列化并保存state,之后再恢复;它仍属于同一次运行。
工作流边界很重要
智能体级护栏并非处处执行:输入护栏只用于链中的第一个智能体,输出护栏只用于生成最终输出的智能体,工具护栏只用于其所附加的函数工具。
管理者式工作流若要检查每次自定义工具调用,不能只依赖智能体级输入或输出护栏,应把验证放在产生副作用的工具旁。
执行前审查网络安全操作
获授权的网络安全工作流中,应在敏感工具调用执行前逐一评估。用工具护栏和批准中断,在副作用发生边界落实书面约定的作业范围:
- 对照批准范围,检查目标、操作、工具参数、调用身份及允许的作业时间。
- 向独立策略组件或审查人员提供确切的拟执行操作,以及评估必需的上下文。
- 拒绝范围外主机、凭证窃取、持久化、数据外传、破坏性变更、生产环境访问及绕过策略的尝试。
- 对模糊或高风险操作,在工具运行前暂停并取得明确人工批准。
- 独立实施文件系统、网络、身份和项目边界,记录决策及执行结果;审查超时或不可用时按拒绝处理。
Responses API与Agents SDK应用不会自动继承Codex自动审查,应在自己的执行框架中加入审查与强制执行。开源Codex审查策略展示了一种方法。获准模型访问见模型与可信访问,作业配置见推荐配置。
流式与延迟审查使用相同状态模型
流式运行没有另一套批准系统。运行暂停时,先等待流式过程结束,再检查interruptions、处理批准,从同一state恢复。若之后才审查,保存序列化状态,等决策到达后继续同一次运行。
后续步骤
控制边界明确后,可阅读:

TRAE-AI编程


更多建议: