OpenAI Agents SDK 护栏与人工审查

2026-11-06 16:09 更新

护栏用于自动检查,人工审查用于批准决策。两者共同决定一次运行何时继续、暂停或停止。

  • 护栏:自动验证输入、输出或工具行为。
  • 人工审查:暂停运行,让人员或策略批准或拒绝敏感操作。

选择合适的控制方式

使用场景 起点
主模型运行前阻止不允许的用户请求 输入护栏
最终输出离开系统前验证或脱敏 输出护栏
在函数工具调用前后检查参数或结果 工具护栏
在取消、编辑、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遵循同一流程:

  1. 记录批准中断,不执行工具。
  2. 结果返回interruptions及可恢复的state。
  3. 应用批准或拒绝待处理项目。
  4. 从state恢复同一次运行,而不是开始新的用户轮次。

审查可能耗时较久时,序列化并保存state,之后再恢复;它仍属于同一次运行。

工作流边界很重要

智能体级护栏并非处处执行:输入护栏只用于链中的第一个智能体,输出护栏只用于生成最终输出的智能体,工具护栏只用于其所附加的函数工具。

管理者式工作流若要检查每次自定义工具调用,不能只依赖智能体级输入或输出护栏,应把验证放在产生副作用的工具旁。

执行前审查网络安全操作

获授权的网络安全工作流中,应在敏感工具调用执行前逐一评估。用工具护栏和批准中断,在副作用发生边界落实书面约定的作业范围:

  1. 对照批准范围,检查目标、操作、工具参数、调用身份及允许的作业时间。
  2. 向独立策略组件或审查人员提供确切的拟执行操作,以及评估必需的上下文。
  3. 拒绝范围外主机、凭证窃取、持久化、数据外传、破坏性变更、生产环境访问及绕过策略的尝试。
  4. 对模糊或高风险操作,在工具运行前暂停并取得明确人工批准。
  5. 独立实施文件系统、网络、身份和项目边界,记录决策及执行结果;审查超时或不可用时按拒绝处理。

Responses API与Agents SDK应用不会自动继承Codex自动审查,应在自己的执行框架中加入审查与强制执行。开源Codex审查策略展示了一种方法。获准模型访问见模型与可信访问,作业配置见推荐配置。

流式与延迟审查使用相同状态模型

流式运行没有另一套批准系统。运行暂停时,先等待流式过程结束,再检查interruptions、处理批准,从同一state恢复。若之后才审查,保存序列化状态,等决策到达后继续同一次运行。

后续步骤

控制边界明确后,可阅读:

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号