MCP 中的 Action、Context、Permission 是如何协同工作的?
一、从抽象概念到具体机制
在前面几章中,我们从多个角度讨论了 MCP 的价值和意义:它是什么、为什么需要它、它如何重新定义 Skill。现在,是时候进入工程的层面,拆解 MCP 协议层的具体运作机制了。
理解 MCP 的“为什么”很重要,但理解 MCP 的“怎么做”同样重要。如果你只知道 MCP 能做什么,却不知道它是怎么做的,你就无法在实际系统中正确地使用它,也无法在遇到问题时有效地调试它。
本章将聚焦于 MCP 核心机制中的三个关键概念:Action、Context 和 Permission。这三个概念是 MCP 协议层的“三根支柱”,它们共同工作,构成了 Agent 和 Skill 之间安全、可控、可观测的交互通道。
二、Action:行为的标准化表达
在 MCP 体系中,Agent 对 Skill 的每一次调用都被抽象为一个 Action。Action 不是简单的“函数调用”,而是一个包含了完整调用信息的标准化数据结构。
Action 的结构
一个完整的 Action 通常包含以下字段:
- action_id:全局唯一的标识符,用于追踪和关联
- action_type:操作类型,如“调用”“查询”“订阅”等
- target:目标 Skill 的名称或标识符
- parameters:调用参数,结构化的键值对
- context_id:关联的上下文标识符
- timestamp:发起时间
- caller_id:调用者的身份标识
这个结构化的设计使得每一个 Action 都是自描述的、可追踪的、可验证的。
为什么需要标准化 Action?
在没有标准化的系统中,不同的 Skill 可能期望不同格式的调用请求。有的接收 JSON,有的接收 XML,有的接收纯文本。有的在 HTTP Header 中传递认证信息,有的在请求体中传递。这种多样性使得统一治理几乎不可能。
MCP 通过标准化 Action 解决了这个问题。无论背后是什么 Skill,Agent 发起的调用都被表达为同一格式的Action。MCP 网关只需要理解这一种格式,就可以处理所有调用。
Action 的生命周期
一个 Action 从创建到完成,经历以下阶段:
- 创建:Agent 根据用户请求和上下文,构造一个 Action 对象
- 提交:Agent 通过 MCP Client 将 Action 提交给 MCP 网关
- 验证:网关验证 Action 的结构是否合法、参数是否符合目标 Skill 的规范
- 授权:网关查询策略引擎,判断这个 Action 是否被允许
- 路由:网关将 Action 转发给目标 Skill 对应的 MCP Server
- 执行:MCP Server 执行 Action,产生结果
- 返回:执行结果被封装为 ActionResult,返回给网关
- 记录:网关记录 Action 和 ActionResult 的完整信息到审计日志
- 交付:网关将 ActionResult 返回给 Agent
这个生命周期中的每一个步骤都是可观测的、可审计的。当出现问题时,你可以精确地知道 Action 在哪个阶段失败了。
三、Context:行为的上下文环境
Action 不是孤立存在的。每一个 Action 都发生在一个特定的 Context 中。Context 是理解“为什么这个 Action 会发生”的关键。
Context 包含什么?
一个完整的 Context 通常包含以下信息:
- conversation_id:所属的对话会话标识符
- user_id:最终用户的身份标识
- session_state:会话状态,如对话历史、用户偏好等
- environment:环境标识,如生产、测试、开发
- parent_action_id:如果这个 Action 是由另一个 Action 触发的,记录父 Action 的标识符
- metadata:其他元数据,如来源渠道、客户端版本等
Context 的作用
Context 的作用体现在以下几个方面:
第一,授权决策依赖 Context。一个 Action 是否被允许,不仅取决于“谁在调用”和“调用什么”,还取决于“在什么上下文中调用”。例如,同一个 Agent,在生产环境中可能被禁止调用某些高风险 Skill,但在测试环境中是允许的。同一个用户,在正常工作时间内可以调用某些 Skill,但在非工作时间需要额外审批。这些规则都依赖于Context。
第二,审计和追溯依赖 Context。当问题发生时,仅仅知道“Agent X 调用了 Skill Y”是不够的。你还需要知道:是在哪个对话中调用的?是为哪个用户服务的?是什么原因导致了这次调用?Context 提供了这些信息。
第三,行为关联依赖 Context。一个复杂的任务可能需要多个 Action 协作完成。通过 Context,特别是parent_action_id 字段,这些 Action 可以被关联成一颗调用树。你可以清楚地看到:Action A 触发了 Action B 和 Action C,Action B 又触发了 Action D。这种调用链追踪对于调试和优化至关重要。
Context 的传递机制
在 MCP 体系中,Context 不是由 Agent 自由定义的,而是由 MCP 网关管理和传递的。当 Agent 首次与网关建立会话时,网关会创建一个 Context 对象。Agent 在后续的 Action 提交中,只需要携带 context_id,不需要重复传递完整的 Context 信息。
这种设计的优点是:Context 信息不会被 Agent 篡改;Context 的格式和内容由网关统一控制;减少网络传输开销。
四、Permission:行为的授权边界
Permission 是 MCP 治理体系的核心。它定义了“什么 Action 在什么 Context 下是被允许的”。
Permission 的组成
一个完整的 Permission 规则通常包含以下要素:
- subject:主体,可以是 Agent、用户、角色或一组条件的组合
- action:操作,可以是具体的 Action 类型、Skill 名称或通配符
- resource:资源,可以是 Skill、数据或服务
- condition:条件,一组布尔表达式,描述允许的前置条件
- effect:效果,允许或拒绝
- priority:优先级,用于处理多条规则之间的冲突
策略引擎的工作方式
MCP 控制平面中的策略引擎负责评估每一个 Action 是否被 Permission 规则允许。其工作流程如下:
- 收集所有与当前 Action 相关的 Permission 规则
- 按照优先级排序
- 依次评估每条规则的条件是否满足
- 如果遇到一条匹配的规则,根据其 effect 决定允许或拒绝
- 如果没有规则匹配,应用默认策略
Permission 与 Action、Context 的协同
Permission 的评估依赖于 Action 和 Context。Action 提供了“要做什么”,Context 提供了“在什么环境下做”,Permission 决定了“是否允许做”。
例如:
- Action 说:Agent A 要调用 delete_order Skill,参数 order_id=12345
- Context 说:这个调用发生在 production 环境,服务于 user_id=100,当前时间是 3 AM
- Permission 说:Agent A 在 production 环境下只能调用 delete_order 当 order_id 属于当前用户且当前时间在 9 AM 到 5 PM 之间
在这个例子中,Permission 规则会拒绝这个 Action,因为时间条件不满足。
静态权限与动态权限
在传统的权限系统中,权限通常是静态的——用户在登录时获得一组权限,在整个会话期间保持不变。但在Agent 系统中,静态权限远远不够。
MCP 支持动态权限,即权限规则可以在运行时评估,并且可以依赖于 Action 的参数和 Context 的动态属性。例如,“只能删除自己的订单”这个规则,在评估时需要知道 order_id 是否属于当前用户。这个信息只有在运行时才能获得。
动态权限是 MCP 能够应对 Agent 系统复杂性的关键。没有动态权限,你就无法表达那些依赖于调用参数的细粒度策略。
五、三者的协同:一个完整的调用流程
现在,让我们把 Action、Context 和 Permission 放在一起,看一个完整的调用流程示例。
场景设定
假设我们有一个客服 Agent,它可以调用 query_order 和 delete_order 两个 Skill。系统配置了以下策略:
- query_order:任何 Agent 在任何时间都可以调用,但只能查询当前用户的订单
- delete_order:只有超级管理员角色的 Agent 可以调用,且需要人工审批
流程步骤
第一步:Agent 收到用户请求“帮我查询订单 12345”。Agent 创建一个 Action,action_type 为 call,target 为query_order,parameters 包含 order_id=12345。
第二步:Agent 将 Action 提交给 MCP 网关,同时携带 context_id。这个 Context 包含了 conversation_id、user_id=100、environment=production 等信息。
第三步:MCP 网关收到 Action 后,首先验证 Action 的结构是否合法。然后提取 Context,准备进行授权评估。
第四步:策略引擎评估与 query_order 相关的 Permission 规则。规则要求 order_id 必须属于 user_id=100。策略引擎调用一个外部服务验证这个条件。验证通过。
第五步:网关将 Action 转发给 query_order 对应的 MCP Server。MCP Server 执行查询,返回订单详情。
第六步:网关记录 Action 和 ActionResult 到审计日志,然后将结果返回给 Agent。
第七步:Agent 收到结果,展示给用户。用户说“帮我删除这个订单”。Agent 创建一个新的 Action,target 为delete_order,parameters 包含 order_id=12345。
第八步:同样的流程,策略引擎评估 delete_order 的 Permission 规则。规则要求调用者必须是超级管理员。当前 Agent 的角色是普通客服,条件不满足。策略引擎返回拒绝。
第九步:网关记录被拒绝的 Action,然后向 Agent 返回“权限不足”的错误。Agent 将这个错误转换为用户友好的消息:“抱歉,您没有权限删除订单,请联系管理员。”
如果这个 Action 通过了权限检查,但被标记为需要审批,网关会将其挂起,等待人工审批。审批通过后,网关再转发给 MCP Server。
六、工程实践中的关键考量
在实际工程中,实现 Action、Context、Permission 的协同工作,需要注意以下几个关键问题。
考量一:Action 的幂等性
由于网络故障或系统重启,同一个 Action 可能被多次提交。Skill 的实现应该支持幂等性——多次执行同一个Action 的效果应该与执行一次相同。MCP 网关可以通过 action_id 来检测重复提交,但 Skill 本身也应该做好防护。
考量二:Context 的序列化和传递
Context 可能包含大量信息,如果每次 Action 都完整传递,会造成网络和存储的开销。建议的设计是:Context 在会话创建时建立,后续 Action 只传递 context_id。网关维护 Context 的缓存,需要时再加载完整信息。
考量三:Permission 规则的性能
策略引擎可能在每次 Action 时都被调用。如果规则数量多或条件评估复杂,可能成为性能瓶颈。建议的措施包括:规则索引、条件评估缓存、异步评估等。
考量四:审计日志的存储和查询
每个 Action 都会产生审计日志。在高并发场景下,日志量可能非常大。需要考虑日志的压缩存储、热冷分离、索引优化等问题。Peta 这样的控制平面提供了内置的审计日志管理,可以减轻开发者的负担。
七、小结:三根支柱撑起 MCP 的治理能力
本章的核心结论如下:
- Action 是 MCP 中行为的标准化表达。它将 Agent 对 Skill 的每一次调用封装为自描述、可追踪、可验证的数据结构。标准化的 Action 是统一治理的前提。
- Context 是理解行为的背景信息。它回答了“在什么环境下发生”的问题。授权决策、审计追溯、行为关联都依赖于 Context。
- Permission 是行为的授权边界。它定义了“什么 Action 在什么 Context 下被允许”。MCP 支持动态权限,可以依赖 Action 的参数和 Context 的动态属性进行细粒度评估。
- 三者协同工作:Action 提供“做什么”,Context 提供“在哪里做”,Permission 决定“是否允许做”。三者共同构成了 MCP 治理体系的核心。
- 工程实践中需要关注几个关键问题:Action 的幂等性、Context 的高效传递、Permission 规则的性能、审计日志的存储管理。
在下一章,我们将进入更深入的工程讨论,探讨 Skill 在 MCP 中如何被设计——一套正确的 Skill 抽象长什么样。这将是一篇非常关键的工程文章,它会帮助你实际动手设计符合 MCP 规范的 Skill。
更多推荐

所有评论(0)