欢迎光临
我们一直在努力

三权分立式 Agent 架构:为什么“感知、规划、执行”必须彼此制衡?(第4期)

三权分立式 Agent 架构:为什么“感知、规划、执行”必须彼此制衡?(第4期)

专栏:《大模型落地之道:智能体生态卷》
作者:Valhalla Matrix治理实验室
文章类型:原创技术实践与方法论总结
适用读者:技术负责人、架构师、AI 产品负责人、研发管理者
摘要:当智能体从“回答问题”走向“修改文件、调用接口、执行运维任务”时,最大的风险往往不是模型不会规划,而是感知结论、行动计划与实际执行权限被放进了同一条信任链。本文提出一种“三权分立式 Agent”架构:将感知、规划、执行拆分为三个职责边界,并通过结构化决策内存、独立授权、风险分级和不可抵赖审计实现相互制衡。文章包含架构设计、Python 示例、风险控制清单与落地建议,适合企业智能体、Agent 平台和 AI 安全工程实践。

阅读提示:本文是工程方法论与参考实现,不代表任何特定系统已经完成安全认证或生产验证。示例代码用于说明设计思想,正式上线前仍需结合业务权限、威胁模型和合规要求进行测试。


一、Agent 真正危险的地方,不是“会犯错”,而是“犯错后能直接行动”

传统聊天机器人答错一个问题,通常只会造成信息质量下降;但企业 Agent 一旦拥有以下能力,风险性质就发生了变化:

  • 修改配置文件;
  • 删除云资源或数据库记录;
  • 发布代码、创建工单;
  • 发送邮件、消息或付款指令;
  • 调用内部系统 API;
  • 读取包含个人信息、密钥或商业机密的数据。

这时,一次错误的感知可能被模型写进计划,计划再被执行器当成授权,最终变成真实的破坏性操作。

例如,用户说:“把仓库清理一下。”

Agent 可能经历这样的链路:

扫描文件
-> 判断哪些内容“可以清理”
-> 生成删除计划
-> 调用文件删除工具
-> 修改真实系统状态

问题在于:

  • 感知结果可能不完整或过期;
  • 规划模型可能误解“清理”的业务含义;
  • 执行器可能只验证参数格式,没有验证业务授权;
  • 整条链路可能使用同一个上下文和同一套信任假设。
  • 因此,Agent 安全不能只靠一句系统提示词,也不能只依赖模型“自觉谨慎”。更可靠的方向是:

    让不同阶段承担不同职责,让每个高风险动作都必须重新验证,而不是沿用上游结论。


    二、三权分立:感知 ≠ 规划 ≠ 执行

    “三权分立”不是把一个 Agent 简单拆成三个函数,而是拆分三种不同的信任边界。

    权力核心职责主要输入必须回答的问题
    感知权 观察外部世界、读取数据、提取事实 文件、接口、日志、用户输入 看到的信息可靠吗?是否完整、过期?
    规划权 将目标转化为步骤,比较可选方案 用户目标、感知事实、约束条件 这个计划是否合理、必要、可回滚?
    执行权 调用工具并改变外部状态 已审批计划、明确授权、工具参数 这个动作是否被授权?能否安全执行?

    三者之间最重要的关系不是流水线,而是后一个环节不能盲信前一个环节:

    ┌──────────────────────┐
    │ 策略中心 / 授权中心 │
    └──────────┬───────────┘
    │ 独立授权
    ┌────────┐ 事实快照 ┌────────┐ 计划草案 ┌────────┐
    │ 感知层 │ ─────────> │ 规划层 │ ─────────> │ 执行层 │
    └───┬────┘ └───┬────┘ └───┬────┘
    │ │ │
    └────────────── 决策内存 / 审计链 ──────────┘

    这里有一条必须坚持的原则:

    规划可以提出行动建议,但不能自动获得执行权限;执行器可以执行已授权动作,但不能自行扩大授权范围。


    三、为什么只拆模块还不够?关键是拆分“信任依据”

    很多系统看起来有感知模块、规划模块和执行模块,但实际上仍然存在以下问题:

    • 三个模块共享一份可以被模型任意修改的上下文;
    • 规划输出直接作为执行参数;
    • 执行器只检查“格式正确”,不检查“权限正确”;
    • 没有记录每次决策依赖了哪些事实;
    • 出现问题后无法判断是感知、规划还是执行出了错。

    所以,真正需要隔离的不是函数名,而是以下内容:

  • 数据边界:感知层输出事实快照,而不是任意自然语言结论;
  • 决策边界:规划层只能提交计划,不能改变授权策略;
  • 权限边界:执行层必须从独立策略中心获得授权;
  • 状态边界:各阶段通过不可随意篡改的结构化记录传递信息;
  • 审计边界:每次真实写操作都留下完整证据链。

  • 四、结构化决策内存:让后续环节“看见结论,但不继承信任”

    可以设计一个只保存阶段产物的决策内存。它不保存一段无限增长的聊天上下文,而是保存可验证的结构化对象:

    from dataclasses import dataclass, field
    from datetime import datetime, timezone
    from typing import Any
    import hashlib
    import json

    def digest(data: Any) > str:
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True).encode()
    return hashlib.sha256(payload).hexdigest()

    @dataclass(frozen=True)
    class DecisionRecord:
    stage: str # perception / planning / execution
    task_id: str
    payload: dict[str, Any]
    source_ids: tuple[str, ...] = ()
    risk_level: str = "low"
    created_at: str = field(
    default_factory=lambda: datetime.now(timezone.utc).isoformat()
    )

    @property
    def record_id(self) > str:
    return digest({
    "stage": self.stage,
    "task_id": self.task_id,
    "payload": self.payload,
    "source_ids": self.source_ids,
    "risk_level": self.risk_level,
    "created_at": self.created_at,
    })

    感知层输出的应该更接近事实:

    {
    "stage": "perception",
    "task_id": "task-20260822-001",
    "payload": {
    "path": "./workspace",
    "candidates": [
    {
    "name": "cache.tmp",
    "reason": "匹配临时文件规则",
    "last_modified": "2026-08-20T10:00:00Z"
    }
    ],
    "unknowns": ["未确认该文件是否被定时任务依赖"]
    },
    "risk_level": "medium"
    }

    注意其中的 unknowns。一个成熟系统不仅要记录“知道什么”,还要明确记录“还不知道什么”。

    规划层读取这份事实快照后,重新判断:

    {
    "stage": "planning",
    "task_id": "task-20260822-001",
    "source_ids": ["perception-record-id"],
    "payload": {
    "objective": "降低工作区临时文件占用",
    "steps": [
    {
    "action": "list",
    "target": "./workspace",
    "mode": "read_only"
    },
    {
    "action": "request_approval",
    "target": "cache.tmp",
    "mode": "delete_after_confirmation"
    }
    ],
    "rollback": "保留回收站副本 7 天"
    },
    "risk_level": "medium"
    }

    规划层不能把“候选文件”直接升级成“允许删除”。它只能提出一个需要审批的计划。


    五、执行权前的最后一道墙:独立授权与策略判定

    执行器的设计目标不是“尽可能聪明”,而是“严格执行边界”。

    一个最小化的策略判断示例如下:

    from dataclasses import dataclass

    @dataclass(frozen=True)
    class Authorization:
    allowed: bool
    reason: str
    requires_human: bool = False

    class PolicyEngine:
    DESTRUCTIVE_ACTIONS = {"delete", "overwrite", "publish", "send", "transfer"}

    def authorize(self, *, actor: str, action: str,
    target: str, risk_level: str,
    approved: bool = False) > Authorization:
    if action in self.DESTRUCTIVE_ACTIONS and not approved:
    return Authorization(
    allowed=False,
    reason="破坏性动作必须经过明确审批",
    requires_human=True,
    )

    if target.startswith("/system/"):
    return Authorization(
    allowed=False,
    reason="目标位于受保护路径",
    )

    if risk_level == "high" and actor != "human-approved-agent":
    return Authorization(
    allowed=False,
    reason="高风险动作需要人工授权身份",
    requires_human=True,
    )

    return Authorization(allowed=True, reason="通过策略检查")

    执行前至少应检查:

    动作是否在允许列表中?
    目标资源是否在授权范围内?
    当前身份是否有权限?
    计划是否仍然有效、未过期?
    事实快照是否发生变化?
    是否属于高风险动作?
    是否需要人工确认?
    是否具备回滚方案?

    特别要避免这种危险设计:

    # 不推荐:把模型输出直接交给工具
    result = tool.execute(planner_output)

    更稳妥的执行链路应该是:

    plan = planner.create_plan(observation)
    auth = policy.authorize(
    actor=actor,
    action=plan.action,
    target=plan.target,
    risk_level=plan.risk_level,
    approved=human_approved,
    )

    if not auth.allowed:
    raise PermissionError(auth.reason)

    result = executor.execute(plan, authorization=auth)
    audit_log.write(plan=plan, authorization=auth, result=result)

    **默认拒绝(fail closed)**应当成为高风险 Agent 的基本原则:授权服务不可用、证据不完整、状态冲突或审批过期时,应暂停执行,而不是“先做了再说”。


    六、风险分级:不是所有动作都需要同样的审批成本

    如果每次读取文件都要求人工确认,系统会变得难以使用;如果删除、发布和转账也走自动快通道,系统又会失去安全边界。

    可以采用分级策略:

    风险级别典型动作建议控制
    低风险 查询公开信息、读取普通日志 自动执行,记录审计
    中风险 修改非生产配置、创建测试资源 沙箱执行或用户确认
    高风险 删除数据、发布代码、发送外部消息 强制人工审批、最小权限、可回滚
    极高风险 资金划转、权限提升、生产破坏性变更 双人审批或禁止 Agent 直接执行

    风险分级不应只由模型自行决定。模型可以提出风险判断,但最终级别应由策略引擎根据动作类型、资源敏感度、环境和身份共同计算。

    例如:

    同样是“修改配置”:
    测试环境 + 非敏感配置 = 中风险
    生产环境 + 鉴权配置 = 高风险
    核心支付系统 + 权限配置 = 极高风险

    动作风险来自动作、目标、环境和后果的组合,不能只看动作名称。


    七、审计链:没有记录,就没有真正的分权

    三权分立的价值之一,是出了问题以后能够回答:

    • 感知层当时看到了什么?
    • 数据来自哪里,是否已经过期?
    • 规划层为什么选择这个方案?
    • 哪条策略允许了执行?
    • 最终调用了什么工具、修改了什么资源?
    • 是否经过人工审批?
    • 能否恢复到变更前状态?

    因此,每个执行事件至少应记录:

    {
    "task_id": "task-20260822-001",
    "actor": "agent-runtime",
    "action": "delete",
    "target": "./workspace/cache.tmp",
    "observation_id": "obs-123",
    "plan_id": "plan-456",
    "policy_version": "policy-2026-08-22",
    "approval_id": "approval-789",
    "authorization": "allowed",
    "before_hash": "…",
    "after_hash": "…",
    "rollback_ref": "backup-001",
    "timestamp": "2026-08-22T10:00:00Z"
    }

    审计日志应尽量满足:

  • 完整:记录决策上下文,而不是只记录“成功/失败”;
  • 不可随意篡改:写入受保护存储,并具备完整性校验;
  • 可关联:通过 task_id、observation_id、plan_id 串起全链路;
  • 可检索:支持按身份、资源、动作、策略版本查询;
  • 可复盘:能够重建关键动作的前因后果;
  • 可脱敏:避免将密钥、完整个人信息和敏感提示词直接写入日志。

  • 八、三个常见误区

    误区一:三个函数就是三权分立

    如果三个函数共享同一个可变上下文,并且规划结果能直接调用工具,那么只是代码分层,不是信任分层。

    改进方式:使用结构化产物、独立策略判定和显式授权令牌。

    误区二:所有动作都强制人工确认

    这会让 Agent 失去效率,也会导致用户形成“无脑点击批准”的习惯。

    改进方式:低风险动作自动化,高风险动作审批,极高风险动作禁止或采用双人复核。

    误区三:只看成功率,不看副作用

    如果 Agent 通过跳过困难任务来提升成功率,指标看起来变好,真实能力却可能下降。

    改进方式:同时定义收益指标、失败条件和副作用指标,例如:

    任务成功率提升
    且跳过率不升高
    且越权尝试为 0
    且回滚成功率达到目标
    且长尾延迟不超过上限

    一个不满足硬性安全条件的版本,即使业务指标更高,也不应自动发布。


    九、如何从零落地一套三权分立式 Agent?

    建议按以下顺序推进,而不是一开始就追求复杂的多 Agent 系统。

    第一步:先盘点工具和动作

    建立工具清单,标记每个工具的:

    • 读/写属性;
    • 目标资源;
    • 是否可逆;
    • 最大影响范围;
    • 所需身份;
    • 是否允许自动执行。

    第二步:把自然语言输出改成结构化协议

    不要让规划模型直接输出一段供执行器解析的自然语言。应使用严格 Schema,例如:

    {
    "action": "update_config",
    "target": "test-service",
    "parameters": {
    "key": "timeout",
    "value": 30
    },
    "risk_level": "medium",
    "rollback": "restore-config-version-17"
    }

    服务端仍需重新校验字段、类型、范围和目标权限,不能因为格式符合 Schema 就自动放行。

    第三步:建立策略中心

    将授权规则从 Prompt 和业务代码中抽离出来,集中管理:

    • 允许的动作;
    • 资源范围;
    • 用户与 Agent 身份;
    • 环境限制;
    • 审批要求;
    • 频率限制;
    • 策略版本和生效时间。

    第四步:为高风险动作设计回滚

    如果动作不可逆,就不应轻易交给自动执行器。能回滚的动作,也必须先验证回滚方案确实可用,而不是只在文档里写一句“支持回滚”。

    第五步:先在沙箱中验证

    第一阶段建议限制为:

    只读工具
    测试环境
    虚拟资源
    固定数据集
    短生命周期凭证
    完整审计

    经过一段时间的异常样本积累后,再逐步扩大授权范围。


    十、一个可执行的上线检查清单

    架构层

    • 感知、规划、执行是否有明确职责边界?
    • 执行器是否不信任模型直接给出的权限结论?
    • 是否存在独立策略判定?
    • 高风险动作是否默认拒绝?

    数据层

    • 是否记录事实来源和时间戳?
    • 是否区分事实、推断和未知项?
    • 是否防止提示词注入内容直接成为授权依据?
    • 敏感数据是否经过最小化和脱敏?

    执行层

    • 工具参数是否进行服务端校验?
    • 是否限制目标资源范围?
    • 是否设置超时、限流和幂等机制?
    • 是否支持预览、模拟执行和回滚?

    治理层

    • 是否保留完整审计链?
    • 是否可以定位到策略版本和审批人?
    • 是否定义了失败条件和停止条件?
    • 是否进行了异常、越权和故障恢复演练?

    十一、总结:优秀的 Agent,不是更敢做,而是更知道何时不能做

    当 Agent 只有问答能力时,提示词和模型效果可能是主要关注点;当 Agent 开始操作真实系统时,权限、审计、隔离、回滚和策略就必须成为一等公民。

    “三权分立式 Agent”并不是要求每个系统都部署三个独立模型,而是要求系统在架构上明确区分:

    • 感知层负责提供事实,不负责授予权限;
    • 规划层负责提出方案,不负责直接执行;
    • 执行层负责落实动作,但必须重新验证授权。

    最终可以用一句话概括这套方法:

    让能力可以演进,让权限不能漂移;让决策可以加速,让高风险动作必须留下证据。

    Agent 的成熟度,不只体现在它能完成多少任务,也体现在它能否在证据不足、权限不明、状态冲突或风险超限时,稳定地选择“暂停”。

    这不是 Agent 的退缩,而是企业级智能体真正可靠的开始。


    赞(0)
    未经允许不得转载:171主机测评 » 三权分立式 Agent 架构:为什么“感知、规划、执行”必须彼此制衡?(第4期)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址