Skip to content

Guardrails 防护机制

Guardrails 与你的 agents 并行运行,让你能够对用户输入进行检查和验证。想象一下,你有一个使用超级智能(但速度慢且昂贵)模型来处理客户请求的 agent。你肯定不希望有人恶意让模型帮他们做数学作业吧?这时,你可以用一个快速且便宜的模型运行 guardrail。如果 guardrail 检测到恶意使用,它会立即抛出错误,阻止昂贵模型运行,为你节省时间和金钱。

Guardrails 分为两种类型:

  1. Input guardrails(输入防护)在初始用户输入时运行
  2. Output guardrails(输出防护)在 agent 最终输出时运行

Input guardrails 输入防护

Input guardrails 分三步运行:

  1. 首先,guardrail 接收与 agent 相同的输入。
  2. 接着,guardrail 函数运行并生成 GuardrailFunctionOutput,然后被包装在 InputGuardrailResult 中。
  3. 最后,我们检查 .tripwire_triggered 是否为 true。如果是,就会抛出 InputGuardrailTripwireTriggered 异常,这样你就可以适当地回应用户或处理异常。

注意

Input guardrails 旨在处理用户输入,所以 agent 的 guardrails 只有在该 agent 是第一个 agent 时才会运行。你可能会想,为什么 guardrails 属性在 agent 上而不是传给 Runner.run?这是因为 guardrails 通常与实际的 Agent 相关 - 不同的 agents 会运行不同的 guardrails,所以把代码放在一起有助于提高可读性。

Output guardrails 输出防护

Output guardrails 同样分三步运行:

  1. 首先,guardrail 接收与 agent 相同的输入。
  2. 接着,guardrail 函数运行并生成 GuardrailFunctionOutput,然后被包装在 OutputGuardrailResult 中。
  3. 最后,我们检查 .tripwire_triggered 是否为 true。如果是,就会抛出 OutputGuardrailTripwireTriggered 异常,这样你就可以适当地回应用户或处理异常。

注意

Output guardrails 旨在处理 agent 的最终输入,所以 agent 的 guardrails 只有在该 agent 是最后一个 agent 时才会运行。与输入防护类似,我们这样做是因为 guardrails 通常与实际的 Agent 相关 - 不同的 agents 会运行不同的 guardrails,所以把代码放在一起有助于提高可读性。

Tripwires 触发机制

如果输入或输出未通过 guardrail,Guardrail 可以通过 tripwire 发出信号。一旦我们看到 guardrail 触发了 tripwires,我们会立即抛出 {Input,Output}GuardrailTripwireTriggered 异常并停止 Agent 执行。

实现一个 guardrail

你需要提供一个接收输入并返回 GuardrailFunctionOutput 的函数。在这个例子中,我们将通过在底层运行一个 Agent 来实现这一点。

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( # (1)!
    name="Guardrail check",
    instructions="检查用户是否在要求你帮他们做数学作业。",
    output_type=MathHomeworkOutput,
)


@input_guardrail
async def math_guardrail( # (2)!
    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, # (3)!
        tripwire_triggered=result.final_output.is_math_homework,
    )


agent = Agent(  # (4)!
    name="客户支持助手",
    instructions="你是一个客户支持助手。你帮助客户解答他们的问题。",
    input_guardrails=[math_guardrail],
)

async def main():
    # 这应该会触发 guardrail
    try:
        await Runner.run(agent, "你好,能帮我解一下这个方程吗:2x + 3 = 11?")
        print("Guardrail 没有触发 - 这很意外")

    except InputGuardrailTripwireTriggered:
        print("数学作业 guardrail 已触发")
  1. 我们将在 guardrail 函数中使用这个 agent。
  2. 这是接收 agent 输入/上下文并返回结果的 guardrail 函数。
  3. 我们可以在 guardrail 结果中包含额外信息。
  4. 这是定义工作流程的实际 agent。

Output guardrails 的实现类似。

from pydantic import BaseModel
from agents import (
    Agent,
    GuardrailFunctionOutput,
    OutputGuardrailTripwireTriggered,
    RunContextWrapper,
    Runner,
    output_guardrail,
)
class MessageOutput(BaseModel): # (1)!
    response: str

class MathOutput(BaseModel): # (2)!
    is_math: bool
    reasoning: str

guardrail_agent = Agent(
    name="Guardrail check",
    instructions="检查输出是否包含任何数学内容。",
    output_type=MathOutput,
)

@output_guardrail
async def math_guardrail(  # (3)!
    ctx: RunContextWrapper, agent: Agent, output: MessageOutput
) -> GuardrailFunctionOutput:
    result = await Runner.run(guardrail_agent, output.response, context=ctx.context)

    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=result.final_output.is_math,
    )

agent = Agent( # (4)!
    name="客户支持助手",
    instructions="你是一个客户支持助手。你帮助客户解答他们的问题。",
    output_guardrails=[math_guardrail],
    output_type=MessageOutput,
)

async def main():
    # 这应该会触发 guardrail
    try:
        await Runner.run(agent, "你好,能帮我解一下这个方程吗:2x + 3 = 11?")
        print("Guardrail 没有触发 - 这很意外")

    except OutputGuardrailTripwireTriggered:
        print("数学输出 guardrail 已触发")
  1. 这是实际 agent 的输出类型。
  2. 这是 guardrail 的输出类型。
  3. 这是接收 agent 输出并返回结果的 guardrail 函数。
  4. 这是定义工作流程的实际 agent。