AGT 深度拆解:微软如何用确定性策略引擎终结「提示词求饶式安全」,让 Agent 结构性不可作恶
一句话总结:当整个行业还在 System Prompt 里写"请不要删库"的时候,微软掀了桌子——Agent Governance Toolkit(AGT)把治理逻辑从概率性的模型层拽回确定性的应用层,每一次工具调用在到达网络之前都要过一道策略内核。被内核拒绝的动作不是"不太可能发生",而是结构性不可能发生。
一、背景:为什么「让模型听话」是一场注定失败的战争
2026 年的 AI Agent 已经不是聊天玩具了。它们调用工具、浏览网页、查询数据库、给其他 Agent 派活。一旦部署上线,它们就在自主做决策。而绝大多数团队对 Agent 的"安全管控",本质上还停留在三板斧:
- System Prompt 里写一堆"你不可以做 XXX"
- 工具描述里加免责声明
- 出事之后看日志(如果有日志的话)
这套东西有个学名,叫 prompt-level safety。AGT 的 README 里有一句话把它撕得很碎:
"Prompt-level safety is not a control surface. It is a polite request to a stochastic system."
(提示词层面的安全不是控制面,它只是对一个随机系统的礼貌请求。)
这不是嘴炮,是有论文背书的。OWASP LLM01:2025 明确写着"目前尚不清楚是否存在万无一失的提示注入防御方法"。Andriushchenko 等人在 ICLR 2025 的论文报告:使用自适应攻击(logprob 访问 + 后缀优化),对 GPT-4o、GPT-3.5、Claude 3、Llama-3 的攻击成功率是 100%——注意,是百分之百,在 JailbreakBench 基准上复现。微软自家的 AI Red Teaming Agent 干脆把 Attack Success Rate(ASR,对抗输入下的策略违规率)定为这类失败的标准度量指标。微软红队测试 100 个生成式 AI 产品的复盘报告结论也很冷静:"缓解措施无法完全消除风险",因为模型层的防御从构造上就是概率性的。
换句话说:你在 Prompt 里写的每一条规矩,攻击者都有办法让模型忘掉。这不是模型不够好,这是这条技术路线的天花板。
于是问题变成:如果模型层守不住,那守在哪?
微软给的答案是:守在模型的"手"和真实世界之间。每一次工具调用、消息发送、任务委派,在模型的意图变成网络请求之前,先被一段确定性的应用代码拦截、评估、放行或拒绝。这就是 Agent Governance Toolkit(AGT)——目前正在 GitHub Trending 上爬升的微软官方开源项目,MIT 协议,公开预览阶段,宣称覆盖 OWASP Agentic Top 10 的全部 10 项风险。
二、核心概念:生产环境 Agent 必须回答的三个问题
AGT 的整个设计围绕三个灵魂拷问展开,每一个都直指现有 Agent 基础设施的盲区。
2.1 这个动作被允许吗?(Policy)
一个有 send_email 和 query_database 权限的 Agent,不应该能执行 drop_table。听起来是废话?但想想现实:OAuth scope 和 IAM Role 控制的是 Agent 能连上哪些服务,而不是连上之后能干什么。你的 Agent 拿着一个能读写数据库的连接串,SQL 层面它想 DROP 就 DROP——IAM 管不到语句级别。
这中间缺了一层:动作级别(action-level)的策略引擎。AGT 补的就是这一层。
2.2 是哪个 Agent 干的?(Identity)
多 Agent 系统里,五个 Agent 共享一个 API Key 是常态。出了事故,日志里只能看到"某个 Agent 干的"。AGT 的文档里有句话很扎心:
"'An agent did it' is not an incident response."
("是某个 Agent 干的"不算事故响应。)
AGT 引入零信任身份体系:SPIFFE、DID(去中心化标识符)、mTLS,每个 Agent 有独立的加密身份,每个动作都能溯源到具体的 Agent 个体,包括多级委派链(Agent A 让 Agent B 让 Agent C 干的,链条完整可查)。
2.3 你能证明发生了什么吗?(Audit)
审计员和监管机构要的不是"我们的日志里应该有",而是防篡改的决策记录:当时生效的是哪个版本的策略、Agent 请求了什么、为什么被允许或拒绝。AGT 用 Merkle 树结构做审计日志,任何事后修改都会破坏哈希链——这是从区块链和证书透明度(Certificate Transparency)借来的成熟工程手段,不是什么玄学。
这三个问题——Policy、Identity、Audit——构成了 AGT 的铁三角。缺任何一个,你的 Agent 系统在合规意义上都是裸奔。
三、架构分析:九个包组成的「Agent 操作系统」
AGT 不是一个库,是一整套体系。看它的包结构就知道野心有多大:
Agent ──► Policy Engine ──► Identity ──► Audit Log
(YAML/OPA/Cedar) (SPIFFE/DID/mTLS) (防篡改)
│ │
├── Allowed ──► 工具真正执行 │
└── Denied ──► GovernanceDenied ▼
Decision Record
3.1 九大组件逐个拆
| 组件 | 干什么的 | 我的点评 |
|---|---|---|
| Agent OS | 策略引擎、Agent 生命周期、治理闸门 | 整个体系的内核,"OS"这个命名暴露了微软想做 Agent 时代 Windows 的野心 |
| Agent Control Specification (ACS) | 无状态、确定性、fail-closed 的策略决策运行时,Rust 内核 | 最硬核的部分:fail-closed 意味着策略引擎自己挂了默认拒绝一切,而不是放行一切 |
| Agent Mesh | Agent 发现、路由、信任网格 | 对标服务网格(Service Mesh),把 Istio 那套思路搬到 Agent 通信上 |
| Agent Runtime | 四层特权环的执行沙箱 | 直接借用 CPU 保护环(Ring 0-3)的概念给 Agent 分级 |
| Agent SRE | Kill Switch、SLO 监控、混沌测试 | 给 Agent 配"急停按钮",这个思路国内团队普遍还没有 |
| Agent Compliance | OWASP 验证、策略 lint、完整性检查 | 把合规检查做成了 CI 里能跑的命令 |
| Agent Marketplace | 插件治理与信任评分 | 针对 MCP 生态野蛮生长的回应 |
| Agent Lightning | 强化学习训练治理,违规惩罚 | 在 RL 训练阶段就把违规行为纳入损失函数,训练期治理 |
| Agent Hypervisor | 执行审计、增量引擎、命令黑名单 | "虚拟机管理器"隐喻:Agent 是 Guest,Hypervisor 是不可绕过的 Host |
3.2 值得细品的三个设计决策
决策一:Rust 写策略内核,且无状态。
ACS(Agent Control Specification)是整个策略层的地基,用 Rust 实现,无状态、确定性、fail-closed。这三个词每个都有讲究:
- 无状态:同样的输入永远得到同样的裁决,方便水平扩展和形式化验证;
- 确定性:裁决过程不掺任何 LLM 判断——用 AI 管 AI 会陷入无限套娃,AGT 很清醒地没走这条路;
- fail-closed:引擎崩溃、策略文件损坏、超时,一律默认拒绝。对比一下多少公司的鉴权中间件是 fail-open 的(挂了就裸奔),高下立判。
决策二:规格先行,992 个一致性测试。
AGT 的每个主要组件都有 RFC 2119 风格的正式规范(MUST/SHOULD/MAY),配套一致性测试:策略引擎 68 个、身份与信任 135 个、执行控制 80 个、SRE 治理 111 个、MCP 安全网关 127 个、审计合规 157 个、框架适配器 152 个……总计 992 个一致性测试,外加 29 份架构决策记录(ADR)。
这是典型的"标准化打法":微软不只是在发一个工具,是在给"什么叫 Agent 治理"下定义。以后别家做治理产品,很可能被迫按 AGT 的规范来对齐——就像当年的 OpenAPI 和 CloudEvents。
决策三:五语言 SDK + 全框架适配。
Python(全栈)、TypeScript、.NET、Rust、Go 五个官方 SDK,覆盖 Microsoft Agent Framework、Semantic Kernel、AutoGen、LangGraph/LangChain、CrewAI、OpenAI Agents SDK、LlamaIndex、Dify、Google ADK 等十几个框架,连 Claude Code 和 GitHub Copilot CLI 都有第一方治理插件。
注意这个细节:微软给竞争对手的产品(Claude Code、Google ADK)做了第一方适配。这说明 AGT 的定位不是"微软全家桶的一部分",而是想当整个 Agent 生态的水电煤。
四、代码实战:两行代码给任意工具上治理
说了这么多,上手到底有多重?答案是出乎意料地轻。
4.1 Python:最小可用治理
pip install agent-governance-toolkit[full]
核心 API 就一个函数 govern():
from agentmesh.governance import govern
# 你原来的工具函数
def my_tool(action: str, table: str):
...
# 两行,套上治理
safe_tool = govern(my_tool, policy="policy.yaml")
从此 safe_tool 的每次调用都会:评估 YAML 策略 → 记录裁决 → 违规则抛出 GovernanceDenied。策略文件长这样:
apiVersion: governance.toolkit/v1
name: production-policy
default_action: allow
rules:
- name: block-destructive
condition: "action.type in ['drop', 'delete', 'truncate']"
action: deny
description: "破坏性操作需要人工审批"
- name: require-approval-for-send
condition: "action.type == 'send_email'"
action: require_approval
approvers: ["security-team"]
实际效果:
>>> safe_tool(action="read", table="users")
{'table': 'users', 'rows': 42}
>>> safe_tool(action="drop", table="users")
GovernanceDenied: Action denied by policy rule 'block-destructive':
Destructive operations require human approval
注意第二条规则的 require_approval——不是简单的允许/拒绝二元世界,还有第三态:挂起,等安全团队人工批准。这正是"人在回路"(human-in-the-loop)该有的工程形态:不是在 Prompt 里写"重要操作请询问用户",而是在策略层强制卡住。
4.2 需要更细粒度?上 PolicyEvaluator
from agent_os.policies import (
PolicyEvaluator, PolicyDocument, PolicyRule,
PolicyCondition, PolicyAction, PolicyOperator, PolicyDefaults
)
evaluator = PolicyEvaluator(policies=[PolicyDocument(
name="my-policy", version="1.0",
defaults=PolicyDefaults(action=PolicyAction.ALLOW),
rules=[PolicyRule(
name="block-dangerous-tools",
condition=PolicyCondition(
field="tool_name",
operator=PolicyOperator.IN,
value=["execute_code", "delete_file"]
),
action=PolicyAction.DENY, priority=100,
)],
)])
result = evaluator.evaluate({"tool_name": "web_search"}) # 放行
result = evaluator.evaluate({"tool_name": "delete_file"}) # 拦截
规则带 priority,多条策略文档可以合并,合并语义在规范里有 68 个一致性测试兜底——不会出现"两条规则打架时行为看心情"的经典事故。
(一个工程细节:agent_os 这个导入路径目前处于兼容期,import 时会报 DeprecationWarning,新代码官方建议直接用 agent-governance-toolkit-core 里的 agt-policies/ACS API。生产接入前先看一眼 CHANGELOG,这个项目还在 Public Preview,破坏性变更是明牌。)
4.3 Go:白名单式治理
Go SDK 的姿势更符合云原生工程师的直觉——默认全拒,显式放行:
import agentmesh "github.com/microsoft/agent-governance-toolkit/agent-governance-golang"
client, _ := agentmesh.NewClient("my-agent",
agentmesh.WithPolicyRules([]agentmesh.PolicyRule{
{Action: "data.read", Effect: agentmesh.Allow},
{Action: "*", Effect: agentmesh.Deny}, // 兜底全拒
}),
)
result := client.ExecuteWithGovernance("data.read", nil)
{Action: "*", Effect: Deny} 这一条就是最小权限原则的代码化。建议所有生产策略都以这条收尾。
4.4 .NET:MCP 服务器一行接入
.NET 这边最有意思的是和 MCP(Model Context Protocol)的深度集成:
using AgentGovernance;
using AgentGovernance.Extensions.ModelContextProtocol;
// MCP 服务器直接挂治理中间件
builder.Services.AddMcpServer()
.WithGovernance(options => options.PolicyPaths.Add("policies/mcp.yaml"));
考虑到 2026 年 MCP 已经泛滥成灾、工具投毒(tool poisoning)攻击层出不穷,这一行 .WithGovernance() 的现实价值可能比前面所有示例加起来都大。AGT 专门有个 MCP Security Gateway 组件,检测工具投毒、描述漂移(drift:MCP 工具悄悄改描述注入指令)、typosquatting(山寨相似名工具)和隐藏指令扫描,规范配了 127 个一致性测试。
4.5 CLI:把合规塞进 CI
agt doctor # 检查安装
agt verify # OWASP 合规检查
agt verify --evidence ./agt-evidence.json --strict # 证据不足直接让 CI 挂掉
agt red-team scan ./prompts/ --min-grade B # 提示注入审计,低于 B 级不过
agt lint-policy policies/ # 策略文件 lint
agt red-team scan 值得单独说:它内置 PromptDefense 评估器,对你仓库里的提示词做 12 向量的注入审计并打分。把这条命令加进 CI,相当于每次 PR 都自动过一遍红队——提示词安全第一次有了可以量化、可以卡门禁的工程指标。
4.6 Claude Code 用户的零成本接入
如果你在用 Claude Code,接入成本约等于零:
/plugin marketplace add microsoft/agent-governance-toolkit
/plugin install agt-governance@agent-governance-toolkit
装完之后你的编码 Agent 的每一次危险操作都会先过策略引擎。对于那些让 Agent 直接操作生产环境的勇士,这两行命令可能是你和删库跑路之间唯一的距离。
五、深水区:特权环、委派链与防篡改审计的实现逻辑
前面的 govern() 是 AGT 的入门姿势,真正的硬骨头在下面三块。理解了它们,你才能判断这套体系到底是营销包装还是真功夫。
5.1 四层特权环:把 CPU 保护环搬进 Agent 运行时
Agent Runtime 组件的核心是**四层特权环(four privilege rings)**执行沙箱。这个设计直接致敬了 x86 CPU 的 Ring 0-3 保护模型:
- Ring 0(内核环):治理内核自身——策略引擎、审计写入器、Kill Switch。Agent 代码永远碰不到这一层,就像用户态程序碰不到内核内存;
- Ring 1(受信环):经过完整性校验、信任评分达标的核心 Agent,可以调用高危工具(需策略放行);
- Ring 2(普通环):常规业务 Agent,只能调用白名单工具,任何越环请求触发策略评估 + 审计记录;
- Ring 3(隔离环):来源不明或信任分低的 Agent(比如从 Marketplace 装的第三方插件),跑在最严格的沙箱里,网络与文件系统访问默认全关。
关键的工程含义是:特权分级不再依赖 Prompt 里的角色扮演("你是一个只读 Agent"这种话术),而是由运行时结构强制。一个 Ring 3 的 Agent 就算被提示注入攻陷、满脑子想着删库,它的执行环境里根本不存在能删库的系统调用路径。这和操作系统对付恶意进程的思路完全一致——不指望进程自觉,只限制它的地址空间。
配套的还有 saga 编排与终止控制:长链条的多步 Agent 任务被建模成 saga(分布式事务模式),每一步可补偿、可回滚,Kill Switch 拍下去的时候不是粗暴 kill -9,而是沿着 saga 链有序回滚已产生的副作用。执行控制规范配了 80 个一致性测试。
5.2 委派链与信任评分:多 Agent 系统的「责任链路追踪」
多 Agent 协作最阴间的问题是权限的传递性放大:Agent A 有读权限,Agent B 有写权限,A 委派 B 干活时,这个组合动作到底该按谁的权限算?现实中大量系统的答案是"按 B 的算"——于是 A 通过委派实现了自己不具备的写能力,这就是经典的 confused deputy(混淆代理人)攻击在 Agent 时代的翻版。
AGT 的身份层(AgentMesh Identity and Trust,135 个一致性测试)对此的处理有三个要点:
- 每个 Agent 独立 DID 身份,格式如
did:mesh:agent-1,配 SPIFFE 工作负载证书和 mTLS 双向认证。五个 Agent 共享一个 API Key 的时代该结束了; - 委派链显式建模:C 执行动作时,裁决上下文里带着完整的 A→B→C 委派链,策略可以写"委派链上任意一环无权限则整体拒绝"(权限取交集而非并集),从结构上封死混淆代理人;
- 动态信任评分:Agent 的历史行为(违规次数、异常模式、来源可信度)折算成信任分,策略条件里可以直接引用——信任分低于阈值的 Agent,哪怕权限齐全也进不了敏感操作的门。
.NET 示例里能看到这个身份体系的实际形态:
var result = kernel.EvaluateToolCall(
"did:mesh:agent-1", // 谁在请求 —— 精确到 Agent 个体
"web_search", // 请求什么动作
new() { ["query"] = "latest AI news" } // 带什么参数
);
三元组(身份、动作、参数)齐全,事后审计时"是哪个 Agent、经谁授权、干了什么"一条查询全出来。
5.3 Merkle 审计日志:让「改日志」在数学上不可行
传统日志的问题不是记不下来,是记下来之后可以改。数据库里的 audit 表,DBA 一条 UPDATE 就能重写历史;文件日志,root 权限一个 sed 就面目全非。对内部威胁和事后甩锅场景,可写的审计日志约等于没有审计。
AGT 的审计层(157 个一致性测试)用 Merkle 树组织决策记录:每条 Decision Record 的哈希参与构建哈希树,根哈希可以周期性锚定到外部系统。任何一条历史记录被篡改,从该节点到根的整条哈希链全部失配,篡改行为本身变成显式可检测事件。这套机制和证书透明度(Certificate Transparency)日志、Git 的对象模型同源,工程上非常成熟。
更进一步的是 Decision BOM(决策物料清单)的概念——类比软件供应链的 SBOM,每个裁决记录不光记结果,还记"当时用的哪个版本的策略文件、哪个版本的引擎、输入上下文是什么"。监管问起来,你交付的不是一句"我们拒绝了",而是一个可独立复验的证据包:拿同样的策略版本和输入重放一遍,必然得到同样的裁决(还记得吗,引擎是确定性的)。审计从"信任我们的日志"升级成"你自己可以验算"。
5.4 Shadow AI Discovery:先找到你不知道的 Agent
一个容易被忽略的现实:治理的前提是知道自己有多少 Agent。而 2026 年的大公司里,业务团队用 LangChain 攒的自动化脚本、某个员工挂在 crontab 里的 GPT 轮询、接了生产库的实验性 Copilot——这些"影子 Agent"没人登记、没人治理,出了事故连排查起点都没有。
AGT 的 Shadow AI Discovery 组件干的就是资产盘点:扫描进程、配置文件和代码仓库,识别未注册的 Agent 实例。配合 Governance Dashboard(基于 Streamlit 的舰队可视化面板),健康度、信任分、合规状态一屏看全。这个功能对工程师来说平平无奇,但对甲方安全团队是刚需中的刚需——买单的人看重什么,这个项目想得很清楚。
六、工程实践:分层接入策略与边界清醒剂
6.1 渐进式接入路线(官方推荐 + 个人补充)
AGT 官方有句很实在的话:"每一层都是可选的。大多数团队只跑策略执行 + 审计日志,永远用不到完整栈。"结合它的架构,我给一条实操路线:
第一阶段(一天搞定):只用 govern() 包住高危工具(数据库写、文件删除、邮件外发、支付类),策略文件从"黑名单破坏性动作 + 高危动作转人工审批"起步。这一步的投入产出比最高。
第二阶段(一周):接入审计日志,把 Decision Record 落到你现有的日志管道;CI 里加 agt lint-policy 和 agt red-team scan。
第三阶段(按需):多 Agent 系统上身份层(每个 Agent 独立 DID),共享 API Key 的历史债该还了;对外暴露 MCP 服务的,上 MCP Security Gateway。
第四阶段(重度用户):特权环沙箱、Kill Switch、SLO 与混沌测试。到这一步你基本是在运营一个 Agent 机房了。
6.2 冷静的边界分析:AGT 不能帮你做什么
吹完了,泼点冷水,这些边界想清楚再上车:
1. 策略表达能力受限于你对动作的建模。 策略引擎只能裁决它看得见的字段。如果你的工具函数把 SQL 拼在一个大字符串参数里传进去,condition: "action.type in ['drop']" 是拦不住 query="DROP TABLE users" 的。治理的前提是工具接口本身结构化——这活 AGT 替不了你干。
2. 确定性引擎防不了"合规但恶意"的动作序列。 每一步单看都合法、连起来是攻击(比如分批读取敏感数据再分批外发),单点策略裁决天然看不见全局。AGT 的 Hypervisor 有执行审计和承诺追踪来缓解,但这是缓解不是根治。
3. Public Preview 的含金量。 45 个 Python 包刚在 v4.1.0 合并成 5 个发行版,旧包名靠 stub 重定向续命,官方明说 GA 前可能有破坏性变更。核心裁决 API 相对稳,但别在这个阶段深度耦合它的高级特性。
4. 性能开销要自己测。 每次工具调用多一跳策略评估,Rust 内核的单次裁决延迟应该在微秒到亚毫秒级(无状态纯计算),但审计日志的落盘和 Merkle 更新在高频调用场景下的吞吐影响,官方没给硬数字。上生产前拿你自己的负载压一轮。
5. 治理不等于安全的全部。 AGT 管的是"Agent 的手",管不了模型权重被投毒、训练数据被污染、依赖链被供应链攻击。它是纵深防御里非常关键的一层,但只是一层。
6.3 和现有方案的对比定位
- 对比 OPA/Cedar 直接裸用:AGT 的策略层本身就支持 YAML/OPA/Cedar 三种后端,它的增量价值在于 Agent 语义的原生建模(工具调用、委派链、信任分)+ 身份 + 审计 + 沙箱的一体化,你不用自己发明"Agent 动作"的 schema。
- 对比各框架自带的 Guardrails:LangChain、CrewAI 们的护栏是框架内的,换框架就得重写;AGT 是框架外的独立层,十几个框架用同一份策略文件。策略即代码,一次编写,处处执行。
- 对比纯网关方案(如各类 LLM Gateway):网关看得见模型的进出流量,看不见工具调用的语义。两者是互补关系,不是替代。
七、总结展望:Agent 基础设施的「合规化拐点」
把 AGT 放到 2026 年的时间线上看,它标志着一个拐点:Agent 工程的重心正在从"能力"转向"控制"。
过去两年,社区拼的是谁的 Agent 更能干——更长的上下文、更多的工具、更复杂的多 Agent 编排。但 EU AI Act 落地执行、NIST AI RMF 成为采购门槛、OWASP Agentic Top 10 发布之后,企业采购 Agent 方案的第一个问题不再是"它能做什么",而是"它做错了怎么办、你怎么证明"。AGT 直接把 NIST AI RMF、EU AI Act、SOC 2 的控制项映射和自动化证据导出做成了产品功能——这不是给开发者的糖,是给 CISO 和审计委员会的定心丸。
三个判断:
确定性治理层会成为 Agent 技术栈的标配,就像十年前的 API Gateway。"直接让 LLM 输出碰生产系统"会像"SQL 语句里拼接用户输入"一样,从常规操作变成事故复盘里的耻辱柱。
规范之争已经开始。 992 个一致性测试和 RFC 2119 规范不是给自己看的,是在抢"Agent 治理"这个品类的定义权。留给其他厂商的窗口不多了。
对个人开发者,现在的最优动作是低成本试水。 一条
pip install、一个govern()、一份二十行的 YAML,就能让你的 Agent 从"求它别删库"进化到"它根本删不了库"。这笔投资的回报周期,大概是你的 Agent 第一次试图执行DROP TABLE的那一刻。
最后回到开头那句话:让 Agent 安全的方式,从来不是请求它守规矩,而是让它没有能力越界。这个朴素的道理,操作系统用保护环讲了五十年,数据库用权限系统讲了四十年,现在轮到 Agent 了。
项目地址:github.com/microsoft/agent-governance-toolkit(MIT 协议,Public Preview)
本文基于 AGT 公开仓库文档与相关公开论文分析撰写,版本信息以官方 CHANGELOG 为准。