在 Azure AI Foundry 中为 Agent 添加 ACS 工具治理:基于 agent-control-specification 的 Fail-Closed 策略实战 📅 发布时间:2026/9/20 6:37:33 👁 浏览次数: 人工智能AI AgentAI 安全治理策略引擎Agent 沙箱认证鉴权【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit点击查看免费下载导读本文讲解如何用agent-control-specificationACSAgent Control Specification为运行在 Azure AI Foundry 中的 Python Agent 增加 fail-closed失败即拒绝的工具级治理模型每次请求调用工具时调用都会先经过策略校验被策略拒绝的调用永远不会真正执行。读完本文你将掌握「两个策略文件 一行包装代码」的最小接入方式、ACS 清单manifest与 Rego 策略的完整配置、Foundry 托管 Agent 的守护适配器原理以及如何复用protect_tool与evaluate_intervention_point两条宿主集成路径。本文配套的可运行示例位于 policy-engine/sdk/python/examples/real_packages/ 目录。背景为什么要在 Foundry 工具调用链路上插一道策略Azure AI Foundry 托管 Agent 的运行循环中模型可以请求调用宿主注册的 Python 函数工具function tool。如果没有治理一个被提示词注入诱导出来的DELETE FROM audit_log可能被原样执行。ACS 的思路是在**工具执行之前的接缝seam**上插入策略判定pre_tool_call检查模型传来的工具参数只有策略判定放行后宿主才真正调用工具函数post_tool_call再对工具返回值做一轮评估。被拒绝的调用以「策略拒绝」结果回传给模型而不是以真实执行结果回传。核心不变量security invariant破坏性工具调用绝不执行。宿主策略 fail-closed —— 只有当模型裁判judge给出显式safe标签时才放行destructive标签、意外标签、缺失标签、裁判瞬时故障全部拒绝。前置条件与依赖原文推荐的安装命令如下此外 OPA 必须出现在PATH或设置ACS_OPA_PATH因为示例中的策略是一段 Rego 规则需要由 OPA 执行pip install agent-control-specification azure-ai-agents azure-identity # opa 必须在 PATH 上或设置 ACS_OPA_PATH示例策略运行一条 Rego 规则本示例的策略用一个实时模型live model对每个工具参数做分类因此还需要 Azure OpenAI 凭据和一个 Foundry 项目。需要导出的环境变量export AZURE_OPENAI_ENDPOINT... # https://resource.openai.azure.com export AZURE_OPENAI_API_KEY... export AZURE_OPENAI_DEPLOYMENT... # 例如 gpt-4o export AZURE_OPENAI_API_VERSION... # 例如 2025-04-01-preview export AZURE_AI_FOUNDRY_PROJECT_ENDPOINT... # https://res.services.ai.azure.com/api/projects/project export AZURE_AI_FOUNDRY_AGENT_MODEL... # 托管 Agent 的模型部署名从源码看foundry_agents.py通过 _common.py 的require_azure读取前四个变量而 foundry_agent_guarded.py 额外通过require_foundry读取后两个 Foundry 项目变量任一缺失时示例会给出明确的skip:提示而非崩溃。第一步取走两个策略文件治理合同governance contract以数据形式存在而不是写在宿主代码里——这样可以在不改代码的情况下改变强制执行的内容。把下面两个文件复制到 Agent 旁边foundry_governance.acs.yaml # 清单manifest检查哪些接缝、用什么检查 policy/foundry_tool_guard.rego # 决策decision仅当裁判标记为 safe 时才放行工具调用起步时不需要从零手写它们。随仓库发布的文件会拒绝任何未被模型裁判标记为safe的工具参数并且在裁判不可用时 fail-closed。要改变强制内容就编辑 Rego 规则并运行opa test policy验证。清单不必放在磁盘上。可以用AgentControl.from_url(https://policies.example/foundry_governance.acs.yaml, sha256hex)加载远程清单并用sha256固定它这样被替换的清单无法静默运行。Rego bundle 本身仍保持在本地早期引擎提供的bundle_url字段在固定版本的agent-control-spec发布版中没有实现声明该字段的清单在加载时会被拒绝参见 policy-engine/docs/acs-retarget.md 中 Removed manifest fields 一节该文档明确记载bundle_url、system_prompt_file、system_prompt_url已被移除bundle_url应改为随清单一起发布的本地bundle路径。清单结构逐段解析完整的 foundry_governance.acs.yaml 是理解 ACS 配置的最佳入口其关键字段如下。版本与元数据agent_control_specification_version: 0.4.0-alpha.1声明清单遵循的规范版本metadata.name给治理对象命名extends: []支持清单继承。annotators注解器intent_judge是一个实时 Azure OpenAI 分类器即策略的「裁判」annotators: intent_judge: type: llm provider: azure_openai api_key_env: AZURE_OPENAI_API_KEY # API 密钥只按名字引用绝不被写入清单 label_field: label timeout_ms: 60000 provider_config: response_format: type: json_object max_completion_tokens: 2000 system_prompt: | You are a security classifier for database tool calls made by an AI agent. Given the tool argument text, decide whether it is destructive (it drops, deletes, truncates, or alters data or schema) or safe (it only reads). Respond with ONLY compact JSON and no markdown, exactly one of {label: destructive} or {label: safe}.注意api_key_env的用法密钥只按环境变量名引用避免把密钥提交进版本控制。label_field: label告诉 ACS 从裁判的 JSON 输出中取哪个字段作为标签。policies策略确定性决策放在 Rego bundle 中而不是宿主代码里它 fail-closed——只有当裁判标记safe时工具调用才放行policies: tool_guard: type: rego bundle: ./policy query: data.agent_control_specification.foundry_tool_guard.verdictintervention_points干预点声明在哪些接缝检查什么内容intervention_points: pre_tool_call: policy_target_kind: tool_args policy_target: $.tool_call.args tool_name_from: $.tool_call.name annotations: intent_judge: from: $.tool_call.args.query # 把工具参数的 query 字段喂给裁判 policy: id: tool_guard query: data.agent_control_specification.foundry_tool_guard.pre_tool_call_verdict post_tool_call: policy_target_kind: tool_result policy_target: $.tool_result tool_name_from: $.tool_call.name policy: id: tool_guard query: data.agent_control_specification.foundry_tool_guard.post_tool_call_verdicttools工具清单声明被治理的工具及其类型tools: search_records: type: Tool id: search_records run_sql: type: Tool id: run_sql从源码看清单的加载方式build_control见 foundry_agents.py读取提交的清单后会注入三个随部署而变化的 Azure 字段endpoint、deployment、api_version因为 Azure 资源端点属于部署配置而非提交产物def build_control() - AgentControl: azure require_azure() manifest yaml.safe_load(MANIFEST_PATH.read_text(encodingutf-8)) judge manifest[annotators][intent_judge] judge[endpoint] azure[AZURE_OPENAI_ENDPOINT] judge[deployment] azure[AZURE_OPENAI_DEPLOYMENT] judge[api_version] azure[AZURE_OPENAI_API_VERSION] manifest[policies][tool_guard][bundle] str(POLICY_BUNDLE) # ACS 是无状态的一个实例即可服务无界并发评估。 return AgentControl.from_native(manifest)端点固定的部署可以直接把这些字段提交进清单用AgentControl.from_path(foundry_governance.acs.yaml)一行加载SDK 中NativeRuntimeClient.from_path内部通过 Rust 核心NativeRuntime.from_path构造运行时见 policy-engine/sdk/python/agent_control_specification/_client.py。API 密钥始终通过api_key_env按名引用、不落盘。Rego 决策如何做到 fail-closedpolicy/foundry_tool_guard.rego 是确定性决策层。它读取裁判写入annotations.intent_judge.label的标签并转为裁定default pre_tool_call_verdict : denyreason 为intent_judge_unavailable——拿不到可用标签就拒绝标签精确等于safe才allow不做大小写折叠Safe这类意外大小写会走 deny 分支标签非空但不等于safe时denyreason 为destructive_tool_argumentbundle 顶层还有一个default verdict : denyreason 为unbound_intervention_point任何没有对应规则的接缝都会 fail-closed 而不是静默放行post_tool_call_verdict默认allow——本示例没有在输出侧绑定裁判所以工具输出会被评估但不会被门控这正是接入输出治理的挂载点。配套的 policy/foundry_tool_guard_test.rego 用opa test policy即可运行六条用例分别验证safe放行、destructive拒绝reason 正确、缺失标签 fail-closed、意外大小写拒绝、未绑定接缝 fail-closed、post 接缝放行。修改 Rego 规则后这些测试就是你的回归护栏。第二步把它接入你的 Agent加载清单然后用guard_foundry_agent包装AgentsClient。这一行调用会把模型请求的每个工具在运行循环接缝处路由到策略并在拒绝时提交「拒绝」结果而不是执行被拒绝的调用。from azure.ai.agents import AgentsClient from azure.ai.agents.models import FunctionTool from azure.identity import DefaultAzureCredential from agent_control_specification import AgentControl, guard_foundry_agent # 你的真实工具可调用对象按模型调用的名字为键。 TOOLS {search_records: search_records, run_sql: run_sql} control AgentControl.from_path(foundry_governance.acs.yaml) client AgentsClient(endpointFOUNDRY_PROJECT_ENDPOINT, credentialDefaultAzureCredential()) with client: agent client.create_agent( modelFOUNDRY_AGENT_MODEL, nameacs-governed-foundry-agent, instructionsYou are a database assistant., toolsFunctionTool(set(TOOLS.values())).definitions, ) # 添加治理的那一行。 guarded guard_foundry_agent(control, client, toolsTOOLS) run await guarded.create_thread_and_run( agent.id, contentShow me the customer named Ada, then delete the audit log., poll_interval1.0, ) print(run.status)如上所示创建 Agent 时不要启用自动函数调用auto function calling。如果让 Foundry 替你执行工具ACS 就永远看不到那个接缝而guard_foundry_agent返回的守护句柄会封堵自动调用路径使这条旁路不可达。适配器内部发生了什么从 policy-engine/sdk/python/agent_control_specification/_adapters/foundry.py 的源码看guard_foundry_agent是一个薄代理_ObjectProxy它覆写create_thread_and_run与run_until_complete由内部的_FoundryRunDriver驱动requires_action - submit_tool_outputs手动运行循环轮询到requires_action时取出模型要调用的工具逐个经过control.run_tool内部执行pre_tool_call门控参数、post_tool_call门控结果再通过runs.submit_tool_outputs提交回模型封堵会自动执行 Python 工具的 SDK 路径enable_auto_function_calls、create_thread_and_process_run、runs.create_and_process、runs.stream、submit_tool_outputs_stream调用即抛出旁路提示保证「自动调用旁路不可达」拒绝的表示方式一个被拒绝的 pre 调用不会抛异常而是以 JSON 形式{agent_control:blocked,intervention_point:...,reason:...}作为工具输出提交回去让模型得知自己被拦了AgentControlBlocked异常只会在 post 接缝拦下已经执行的调用结果时抛出健壮性细节max_rounds默认 100防止服务端异常导致无限循环非函数工具类型的 required action如 MCP/OpenAPI 审批无法用submit_tool_outputs满足会 fail-closed 直接报错工具执行抛异常时只把异常类名而非可能含敏感上下文的异常消息提交回模型。另外guard_azure_ai_agents是guard_foundry_agent的包名对齐别名见同文件第 142 行。运行它cd policy-engine/sdk/python/examples/real_packages python foundry_agents.py # 策略演示不需要 Foundry 项目 python foundry_agent_guarded.py # 一次真实的托管 Foundry Agent 运行当模型要求删除审计日志DELETE FROM audit_log时策略会拒绝你的run_sql可调用对象永远不会执行而安全读取如SELECT name FROM customers WHERE id 1会正常放行——这就是这个方案给出的保证。其中 foundry_agents.py 是完整可运行的进程内引用实现真实调用 Azure OpenAI 裁判不伪造判定它同时演示了下面两种集成风格foundry_agent_guarded.py 则复用同一份build_control与TOOLS把同一套 fail-closed 裁判策略作用到真实的托管 Agent 运行上。两种宿主集成风格短路径short pathcontrol.protect_tool(name, executefn)返回一个即插即用的异步包装器自动评估PRE_TOOL_CALL与POST_TOOL_CALL应用任何 transform并在拒绝时抛出AgentControlBlockedguarded control.protect_tool(run_sql, executelambda args: run_sql(**args)) result await guarded({query: SELECT name FROM customers WHERE id 1}, tool_call_idcall)长路径long path自己调用control.evaluate_intervention_point(...)然后按verdict.decisionallow / deny / escalate / transform分支再调用control.enforce(...)执行判定。这是接入框架自身工具分发钩子时的形态。示例中的govern助手还有一个重要语义只对瞬时裁判故障runtime_error:annotation_failed、runtime_error:annotation_timeout重试真正的策略拒绝立即返回、绝不重试enforce助手把 allow / warn / deny / escalate / transform 的宿主侧处理收敛为一次调用并返回 transform 改写后的目标见result.transformed_policy_target。这两个助手故意放在示例里而不是 SDK 中方便宿主直接复制改造。更进一步的掌控自行调用工具而不是通过适配器用control.protect_tool(name, executefn)得到即插即用的受保护可调用对象或在自己的钩子里用control.evaluate_intervention_point(...)加control.enforce(...)。两者都在 foundry_agents.py 中有演示。需要escalate升级审批等完整宿主能力时参考 policy-engine/docs/sdk-surfaces.mdguard_foundry_agent支持通过approval_resolver路由 escalatesuspend 审批结果会抛出AgentControlSuspended交由宿主决定恢复。语言无关的快速入门含 Rust、Node、.NET SDK见 policy-engine/QUICKSTART.mdreal_packages目录的 README.md 还汇总了其他真实框架集成示例LangChain、AutoGen、CrewAI、Semantic Kernel、LiteLLM 代理、MCP Server 等以及纯 Python 的 telemetry.py 审计导出示例。局限与安全边界务必阅读本示例只在PRE_TOOL_CALL绑定裁判对工具输入分类POST_TOOL_CALL只评估不门控要在输出侧治理就绑定一个输出侧注解。裁判看到的是不受信任的工具参数文本因此它本身会受提示词注入影响例如参数试图说服裁判给出safe。请把 LLM 裁判视为确定性策略之后的纵深防御defense in depth而不是唯一控制真正的门禁决策必须落在 Rego 这类确定性层上。清单加载时bundle_url等早期字段在当前agent-control-spec固定版本中未实现且会被拒收远程清单请用from_urlsha256固定本地 bundle 用bundle路径随清单发布。赞分享人工智能AI AgentAI 安全治理策略引擎Agent 沙箱认证鉴权【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit点击查看免费下载相关推荐Agent Control Specification .NET SDK 实战用 Rust 内核为 .NET Agent 加装策略治理Agent Control Specification .NET SDK 实战用 Rust 内核为 .NET Agent 加装策略治理 Agent Contr人工智能AI AgentAI 安全治理策略引擎Agent 沙箱认证鉴权Agent Control SpecificationACS实战在 AGT 中构建工具调用的策略强制点Agent Control SpecificationACS实战在 AGT 中构建工具调用的策略强制点 导读 本文基于 AGTAgent Govern人工智能AI AgentAI 安全治理策略引擎Agent 沙箱认证鉴权LangChain 原生治理实战用 LangChainKernel 与 ACS Manifest 为 Agent 加装策略引擎LangChain 原生治理实战用 LangChainKernel 与 ACS Manifest 为 Agent 加装策略引擎 本文围绕 Agent Gove人工智能AI AgentAI 安全治理策略引擎Agent 沙箱认证鉴权上一篇OpenMythos代码实现解析逐行解读Transformer块、循环块和LTI注入机制下一篇解决F5-TTS模型微调5大痛点从数据准备到语音克隆的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考