ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

如何给智能体装上输入输出双防护:openai-agents-python Guardrail 实践指南

如何给智能体装上输入输出双防护:openai-agents-python Guardrail 实践指南 如何给智能体装上输入输出双防护openai-agents-python Guardrail 实践指南【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python一次线上复盘客服智能体被用户追问帮我解 2x511它竟一本正经地开始解题——更糟的是下一位用户直接拿到了上一位用户留在上下文里的电话号码。这类失控在规模化落地时几乎必然发生根因是模型既会答错事也可能吐隐私。openai-agents-python 框架内置的 Guardrail防护机制就是为此设计的它让一个轻量的检查函数或廉价模型在主智能体运行的同时并行裁决这段输入能不能进、这条输出能不能发。读完本文你能独立写出输入/输出防护函数、选择合适的执行模式并按业务场景搭起一套完整的智能体安全方案。防护到底在防什么一条安检线上的三道闸口把一次智能体运行想象成机场安检Guardrail 就是安在三个位置的闸口触发时机各不相同入口闸输入防护只在用户原始输入进入时启动且只挂在工作链的第一个智能体上。用户说一句帮我写个破解脚本检查函数立刻看到这句话并裁决。工具闸工具防护挂在具体的FunctionTool上每次调用都过一遍——执行前检查参数tool_input_guardrail执行后检查返回值tool_output_guardrail。有 handoff 或多智能体协作时只有它能覆盖每一次工具调用而 agent 级防护覆盖不到中间环节。出口闸输出防护只在产出最终输出的那个智能体完成后启动校验的是final_output。它永远是先出稿、后审核所以不支持并行参数。三道闸口共用同一套裁决语言防护函数返回GuardrailFunctionOutput核心字段是tripwire_triggered是否拉响绊线和output_info附带证据。tripwire_triggeredTrue时Runner 立即抛出对应的InputGuardrailTripwireTriggered/OutputGuardrailTripwireTriggered/ToolInputGuardrailTripwireTriggered等异常并中止运行——你拿到异常就能接住、降级、回话。理解这张时序图有个关键细节输入防护默认与主智能体并行跑run_in_parallelTrue延迟最优但代价是触发时昂贵模型可能已消耗部分 token若设为run_in_parallelFalse则防护先跑完、主流程才启动能零成本拦截。输出防护则恒为主智能体完成后运行。把防护网搭起来从判定标准到降级响应第 1 步先定义判定标准——防护函数怎么写防护函数本身不复杂常见套路是再跑一个便宜的小模型做裁判用 Pydantic 模型约束它的结论from pydantic import BaseModel from agents import Agent, GuardrailFunctionOutput, Runner from agents.decorators import input_guardrail class MathHomeworkCheck(BaseModel): is_math_homework: bool reasoning: str guardrail_agent Agent( nameGuardrail check, instructionsCheck if the user is asking you to do their math homework., output_typeMathHomeworkCheck, ) input_guardrail async def math_guardrail(ctx, agent, input): result await Runner.run(guardrail_agent, input, contextctx.context) return GuardrailFunctionOutput( tripwire_triggeredresult.final_output.is_math_homework, output_inforesult.final_output, )要点有三裁判模型要便宜快速主流程用的是贵模型防护的意义就是花小钱拦大雷判定结果尽量结构化bool 理由方便日志与审计output_info可以塞任意证据触发时你直接能读到为什么拦。纯规则场景比如检测密钥字符串sk-则可以完全不调模型直接在函数里写 if 判断更快更稳。第 2 步再挂到主流程——配置防护链与执行模式防护是挂在 Agent 上的不同 Agent 可以挂不同防护代码就近可读agent Agent( nameCustomer support agent, instructionsYou are a customer support agent. You help customers with their questions., input_guardrails[math_guardrail], # 入口闸 output_guardrails[sensitive_data_check], # 出口闸 )工具级防护则挂在工具装饰器上对每次调用生效支持放行 / 拦截并给模型一条替代消息 / 抛绊线三种动作from agents import ToolGuardrailFunctionOutput from agents.decorators import tool, tool_input_guardrail tool_input_guardrail def block_secrets(data): args json.loads(data.context.tool_arguments or {}) if sk- in json.dumps(args): return ToolGuardrailFunctionOutput.reject_content(参数含密钥拒绝执行) return ToolGuardrailFunctionOutput.allow() tool(tool_input_guardrails[block_secrets]) def classify_text(text: str) - str: Classify text for internal routing. return flength:{len(text)}需要提醒工具防护只作用于tool创建的函数工具托管工具WebSearch 等、handoff 调用不走这条管线。第 3 步处理触发后的降级——让拦截体面落地绊线触发就是抛异常你要做的只是接住并说人话。输入防护触发后把拒绝消息作为 assistant 消息追加回上下文即可会话能自然继续from agents import Runner, InputGuardrailTripwireTriggered try: result await Runner.run(agent, user_input) except InputGuardrailTripwireTriggered as e: info e.guardrail_result.output_info print(f拦截原因: {info.reasoning}) # 裁判模型给出的理由 user_reply 抱歉这个问题我无法协助。输出防护触发时同理捕获OutputGuardrailTripwireTriggered区别在于被拒的候选最终输出不会写入会话持久化——已完成的工具调用会保留违规的那版终稿会被丢弃。流式场景下可以在生成过程中每 N 个 token 跑一次检查发现越界立即cancel()避免长篇违规内容刷完才拦截参考 examples/agent_patterns/streaming_guardrails.py。按场景选配置输入防护与输出校验怎么配业务场景推荐防护组合关键参数/做法参考实现客服对话输入过滤拒题/违规话题 输出 PII 检测裁判模型用小而快的型号run_in_parallelTrue控延迟examples/customer_service/main.py内容生成输出主题检测 格式/长度校验output_type用严格 Pydantic 模型约束终稿结构examples/agent_patterns/output_guardrails.py高成本模型入口输入防护前置拦截run_in_parallelFalse阻断执行触发时主模型零消耗docs/guardrails.md Execution modes 一节工具密集流程工具级入参/出参双向防护tool_input_guardrailstool_output_guardrails出参可reject_content脱敏examples/basic/tool_guardrails.py选型口诀怕花钱、怕副作用 → 入口阻断式怕延迟 → 并行式多智能体/多工具链路 → 补上工具闸。真实项目里长这样一个证据审计员的合规链路仓库自带的金融研究多智能体examples/financial_research_agent/值得拆着看搜索、财报、风控、写作等智能体各司其职而安全的关键一环藏在agents/verifier_agent.py——一个专职的 VerificationAgent。它的做法值得借鉴输入侧planner 只接受结构化研究请求超出白名单的指令在入口就被挡下工具侧联网检索类工具带输出防护来源 URL 不在允许清单内的内容不进入上下文输出侧最终报告交给证据审计员终审——它拿着原始请求、研究截止日期、报告全文和带来源 URL 的结构化证据逐条核对数字与时间敏感声明产出VerificationResultverified: bool加一份issues清单每条 issue 标明类别unsupported/contradicted/stale_or_unreleased和解释。报告没过审就不发布。这套生成者与审核者分离的模式本质是把 Guardrail 的思想放大到报告粒度审核者只看证据、不看记忆结论结构化可直接进 CI 或人工复核流程。别踩这些坑三个高频问题与对策坑一加了防护会不会拖慢响应默认并行模式下防护与主流程同时起跑额外延迟≈ max(两者) 而非相加通常可感知成本很小。若你的裁判函数是纯规则正则、白名单耗时可忽略若裁判本身是 LLM务必选小快模型。真正要权衡的是run_in_parallel的取舍并行省延迟但拦不干净 token 消耗阻断式省成本但多等一次裁判——按入口值不值得先花一秒来定。坑二误拦了正常请求怎么办把output_info.reasoning落日志先攒一段时间再调阈值而不是直接改判断逻辑。实践建议裁判输出是否违规 置信理由两个字段低置信的只记录不拦截确需拦截的场景用结构化拒绝话术安抚用户并把拒绝消息回写上下文见第 3 步示例保证会话不断。坑三多智能体链路里防护没生效多半是挂错了位置。输入防护只在链首智能体生效输出防护只在链尾生效如果危险发生在中间 handoff 或某次工具调用只有工具级防护能覆盖。链路越长越要把工具闸补上。落地检查清单从基础到进阶逐项打勾推进最小防线首个对用户敞开的智能体上挂 1 个输入防护哪怕纯规则 1 个输出防护执行模式定调按成本敏感度决定run_in_parallel并在代码里写注释说明理由异常全捕获InputGuardrailTripwireTriggered/OutputGuardrailTripwireTriggered都有 try/except 与用户话术拒绝消息回写上下文工具闸补齐所有会写数据、发请求的tool都配置入参/出参防护留痕审计guardrail_result.output_info进日志便于回溯为什么拦流式早停长文本生成场景接入 examples/agent_patterns/streaming_guardrails.py 的周期性检查终稿审核者高价值输出报告、合规文档仿照金融研究智能体增设独立验证 Agent 出结构化终审结论完整 API 与边界行为说明见官方文档docs/guardrails.md输入、输出、工具三类防护的可运行示例分别在 examples/agent_patterns/input_guardrails.py、examples/agent_patterns/output_guardrails.py 与 examples/basic/tool_guardrails.py跑一遍即可对照本文动手。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进