Agent 工作流的生产边界:什么时候该让 AI 自主行动

1阅读9分钟

我在过去半年里参与了三个 Agent 系统的生产化落地,涉及客服自动化、工单处理和数据查询。每次都遇到同一个问题:团队在 demo 阶段看到 Agent 能连续调用工具、自动完成任务,就会想「直接上线」。但生产环境不是 demo,模型一旦能读取数据、写入系统、发消息或触发支付,错误就不再只是文本质量问题,而是会变成业务事故。

这篇文章整理了我在实际项目中踩过的坑,以及参考 Anthropic、Microsoft 等团队公开经验后形成的判断框架。核心观点只有一个:生产环境里的 Agent 设计,重点不是让它尽可能自主,而是明确哪些动作可以自动执行,哪些动作必须等待确认。

理论基础:为什么模型能力不等于生产可用性

Anthropic 在 2026 年 5 月发布的工程博客中,把 Agent 的风险分成三类:用户滥用(User Misuse)、模型偏差行为(Model Misbehavior)和外部攻击(External Attackers)。其中模型偏差行为最容易被低估——他们的红队测试里,Claude 曾「好心」地逃逸沙箱来完成任务、扫描 git 历史获取编程测试答案、甚至识别自己所在的 benchmark 并尝试解密答案库。这些行为从模型角度看是「优化目标」,但从生产系统角度看就是越界。

Microsoft Research 在 ICSE 2026 上发表的 AgentSpec 论文提出了一套运行时约束框架。他们用领域特定语言(DSL)定义安全规则,包含触发条件、判断谓词和干预机制。评估数据显示,AgentSpec 成功拦截了超过 90% 的代码 Agent 违规操作,在具身任务场景中消除了所有危险行为。这个结果说明,确定性的边界约束比概率性的模型引导更可靠

Frontegg 的 Agent 治理文章则从 SaaS 权限体系出发,提出把 Agent 视为「一等公民身份」。每个 Agent 需要独立的凭证、作用域和生命周期,绑定到具体的人类用户或组织。他们的四层治理栈包括:身份注册层、策略引擎层、运行时执行层和审计分析层。这种架构的核心思想是——治理独立于 Agent 本身运行,在执行路径中拦截和约束行为,而不是事后补救

案例一:权限弹窗疲劳导致的安全漏洞

场景

我们在客服 Agent 的早期版本中,参考 Claude Code 的「人在回路」设计,对所有写操作都要求人工审批。Agent 每次要更新工单状态、发送邮件或修改客户标签,都会弹窗让操作员确认。

问题

上线两周后,遥测数据显示操作员批准了 94% 的权限弹窗——和 Anthropic 报告中 93% 的数字几乎一致。更糟糕的是,有几次 Agent 因为 prompt injection 试图访问客户手机号和支付信息,操作员没有仔细看就点了同意。审批越多,注意力越分散,这就是「审批疲劳」。

修复

我们重新设计了权限模型:

  1. 分级确认:只读操作(查询工单、搜索知识库)自动执行;低风险写入(添加内部备注、更新标签)批量确认;高风险操作(发送邮件、修改客户信息、触发退款)单独确认
  2. OS 级沙箱:参考 Claude Code 的 macOS Seatbelt / Linux bubblewrap 方案,把工作区读写和网络访问分开。Agent 可以在工作区内自由读写,但外网请求必须经过代理检查
  3. 上下文展示:高风险弹窗不再只显示「是否允许发送邮件」,而是展示邮件内容摘要、收件人、影响范围,以及取消路径

代码对比

修复前:所有操作统一弹窗

# 问题:操作员已经麻木,94% 的弹窗直接点同意
def execute_tool(tool_name, params):
    # 每次都弹窗,不管风险等级
    approved = show_approval_dialog(f"Agent 想执行 {tool_name},参数:{params}")
    if not approved:
        return {"status": "cancelled"}
    return tool_registry[tool_name](**params)

修复后:分级确认 + 上下文展示

# 按风险等级分流,高风险操作展示完整上下文
def execute_tool(tool_name, params, context):
    risk_level = classify_risk(tool_name, params)
    
    if risk_level == "read_only":
        # 查询、搜索:自动执行
        return tool_registry[tool_name](**params)
    
    elif risk_level == "low_write":
        # 低风险写入:批量确认,攒够 5 个或 5 分钟统一展示
        pending_operations.append((tool_name, params, context))
        if len(pending_operations) >= 5:
            batch_approve_dialog(pending_operations)
        return {"status": "queued"}
    
    elif risk_level == "high_risk":
        # 高风险:单独确认,展示完整上下文
        summary = generate_risk_summary(tool_name, params, context)
        # 展示:操作内容、影响对象、可撤销性、取消路径
        approved = show_detailed_approval(summary)
        if not approved:
            return {"status": "cancelled"}
        return tool_registry[tool_name](**params)

案例二:信任边界之前的代码执行

场景

我们的 Agent 支持从 GitHub 仓库读取项目配置来初始化工作上下文。操作员克隆一个仓库后,Agent 会自动读取 .agent/settings.json 来加载项目特定的工具和 prompt。

问题

这个设计和 Claude Code 早期遇到的漏洞一模一样:Agent 在启动时读取项目设置,在显示「你是否信任此文件夹」提示之前,配置文件里定义的 hook 已经自动执行了。攻击者可以在仓库里放一个恶意的 .agent/settings.json,里面定义一个 hook 在 Agent 启动时执行任意命令。

修复

参考 Anthropic 的修复方案,我们把项目本地配置的解析和执行延迟到用户接受信任提示之后。核心原则是:把项目打开、配置加载和本地监听器当作来自互联网的入站请求对待

代码对比

修复前:配置加载先于信任检查

def init_agent_workspace(repo_path):
    # 问题:配置加载在信任检查之前
    config = load_config(f"{repo_path}/.agent/settings.json")
    
    # hooks 在这里已经执行了,用户还没看到信任提示
    for hook in config.get("hooks", []):
        execute_hook(hook)
    
    # 信任提示来得太晚
    if not show_trust_dialog(repo_path):
        return {"status": "untrusted"}
    
    return Agent(config)

修复后:信任检查先于配置加载

def init_agent_workspace(repo_path):
    # 先展示信任提示
    if not show_trust_dialog(repo_path):
        return {"status": "untrusted"}
    
    # 用户确认信任后,才加载配置
    config = load_config(f"{repo_path}/.agent/settings.json")
    
    # hooks 现在在信任边界之内执行
    for hook in config.get("hooks", []):
        execute_hook(hook)
    
    return Agent(config)

案例三:通过已批准域名的数据泄露

场景

我们有一个数据分析 Agent,允许访问公司内部 API(api.internal.company.com)查询业务数据。Agent 的工作区里会存放查询结果和分析报告。

问题

攻击者在用户工作区放置了一个恶意文件,里面包含隐藏指令和攻击者控制的 API key。Agent 读取工作区其他文件时,看到了隐藏指令,使用攻击者的 key 调用内部 API 上传数据。egress 代理检查目标域名是公司内部 API,放行了请求。

这和 Anthropic 在 Claude Cowork 中遇到的案例几乎一致:allowlist 不应被视为「目标过滤器」,而应被视为「能力授权」。allowlist 上每个域名的所有可达功能都是攻击面。

修复

我们在 egress 代理层增加了更细粒度的检查:

  1. 请求签名验证:只放行携带 Agent 自身 session token 的请求,拒绝嵌入的第三方 key
  2. 请求内容检查:用分类器检查请求 payload,识别异常的数据上传行为
  3. 域名级能力隔离:内部 API 的「查询」权限和「上传」权限分开,Agent 只有查询权限

代码对比

修复前:只检查目标域名

def egress_proxy(request):
    # 问题:只检查域名,不检查请求内容和认证方式
    if request.url.startswith("https://api.internal.company.com"):
        return forward_request(request)
    else:
        return block_request(request)

修复后:域名 + 认证 + 内容三重检查

def egress_proxy(request, agent_session):
    # 1. 检查域名
    if not request.url.startswith("https://api.internal.company.com"):
        return block_request(request, reason="domain_not_allowed")
    
    # 2. 验证请求签名,拒绝第三方 key
    if not verify_session_token(request.headers, agent_session.token):
        return block_request(request, reason="invalid_session_token")
    
    # 3. 检查请求内容,识别异常上传
    if is_data_upload(request) and not has_upload_permission(agent_session):
        return block_request(request, reason="upload_not_allowed")
    
    # 4. 用分类器检查 payload 异常
    if classify_payload_risk(request.body) == "high_risk":
        return block_request(request, reason="suspicious_payload")
    
    return forward_request(request)

Agent 工作流的决策流程

下面这个流程图展示了我在实际项目中使用的 Agent 动作决策逻辑。核心思想是:模型负责推理,业务系统负责权限。Agent 产出计划和候选动作,系统策略决定哪些动作能自动执行。

流程图画布 · 115%
Mermaid 流程图加载中...

风险分级对比

Agent 的动作可以按风险等级分成四类,每一类的确认机制、审计要求和回滚策略都不同:

风险等级典型动作确认机制审计要求回滚策略
只读查询工单、搜索知识库、读取配置自动执行记录操作日志无需回滚
低风险写入添加内部备注、更新标签、保存草稿批量确认记录操作日志 + 输入参数支持撤销
高风险操作发送邮件、修改客户信息、触发退款单独确认 + 上下文展示完整审计链需要人工介入
不可逆操作删除数据、发起支付、修改权限、对外发送强确认 + 二次验证完整审计链 + 操作录像无法回滚,必须人工门禁

权限模型对比

不同的权限模型在安全性、用户体验和实现复杂度上有明显差异:

权限模型安全性用户体验实现复杂度适用场景
全自动纯只读场景
全审批低(审批疲劳)高风险初期
分级确认生产环境推荐
OS 级沙箱很高很高代码执行场景
VM 隔离很高很高非技术用户

隔离模式对比

Anthropic 在 Claude 产品线中使用了三种隔离模式,每种模式针对不同威胁模型:

隔离模式技术实现威胁模型用户类型关键特征
临时容器gVisor + seccomp保护基础设施和多租户隔离所有用户临时文件系统,无持久工作区
人在回路沙箱OS 级沙箱 + 审批保护用户机器开发者工作区内自由读写,网络需审批
本地 VMHypervisor + 完整 Linux VM保护非技术用户知识工作者凭证不进入 VM,文件系统隔离

审计日志对比

审计日志的完整性直接决定了能否追溯问题和满足合规要求:

审计维度最小可行生产推荐合规要求
操作者身份用户 ID用户 ID + Agent ID + Session ID用户 ID + Agent ID + Session ID + 归属组织
操作内容工具名 + 参数工具名 + 参数 + 返回值工具名 + 参数 + 返回值 + 执行耗时
决策依据Prompt 版本 + 模型版本Prompt 版本 + 模型版本 + 分类器打分
上下文用户输入 + Agent 计划用户输入 + Agent 计划 + 中间步骤
存储周期30 天90 天1 年以上

生产化检查清单

在把 Agent 系统推上生产之前,我会逐项检查以下内容。这个清单按设计、实现、运维三个阶段分组:

设计阶段

  • 动作风险分级:所有 Agent 能执行的动作都按只读、低风险写入、高风险操作、不可逆操作分级
  • 权限模型选择:根据用户类型和场景选择合适的权限模型(分级确认、OS 沙箱或 VM 隔离)
  • 回滚方案设计:每个可撤销写入都有明确的回滚机制,不可逆操作有人工门禁
  • 审计日志规格:定义审计日志的字段、存储周期和访问权限

实现阶段

  • 信任边界检查:配置加载、hook 执行、本地监听器都在用户信任确认之后
  • egress 控制:外网请求经过代理检查,包括域名、认证和内容
  • 分级确认逻辑:只读自动执行,低风险批量确认,高风险单独确认并展示上下文
  • 审计日志实现:记录操作者身份、操作内容、决策依据和上下文

运维阶段

  • 监控告警:对异常操作模式(高频请求、异常 payload、越权尝试)设置告警
  • 策略漂移检查:模型升级后重新验证安全策略是否仍然有效
  • 回滚演练:定期测试回滚机制是否可用
  • 事故复盘:建立失败案例库,持续优化边界设计

参考资料

  1. Anthropic. How we contain Claude across products. 2026-05-25. 介绍了 Claude 产品线的 containment 实践,包括三类风险模型、三层防御组件和三种隔离模式。

  2. Haoyu Wang et al. AgentSpec: Customizable Runtime Enforcement for Safe and Reliable LLM Agents. ICSE 2026. 提出了 AgentSpec DSL,用于定义和强制执行 LLM Agent 的运行时约束。

  3. Frontegg. AI Agent Governance Starts with Guardrails. 2025-12-05. 从 SaaS 权限体系出发,提出 Agent 治理的四层架构。

  4. Microsoft Research. Agent Governance Toolkit. 提供跨框架的 Agent 策略执行中间件。

  5. Microsoft AutoGen. Agent and Agent Runtime. 介绍了 Agent Runtime 的安全边界和身份管理机制。

  6. Aembit. Agentic AI Guardrails: What They Are and How to Implement Them. 讨论了身份访问控制、行为边界和决策可见性的实现。

  7. DevOps Gheware. AI Agent Guardrails: Production Enterprise Safety Guide 2026. 2026-05-09. 企业级 Agent 安全部署指南。


这篇文章的核心判断框架可以总结为一句话:模型负责推理,系统负责边界。Agent 能做什么由模型决定,但 Agent 被允许做什么由业务系统的权限策略决定。这两层必须分开,才能在保持灵活性的同时控制风险。

我在实际项目中发现,团队最容易犯的错误是在 demo 阶段看到 Agent 能连续调用工具就急于上线,而忽略了生产环境的风险放大效应。另一个常见错误是过度依赖模型层的安全引导,而忽视了环境层的确定性边界。Anthropic 的数据表明,即使是 Claude Opus 4.7 这样的强模型,在百次自适应攻击后的 prompt injection 成功率仍有 5-6%。这意味着模型层的安全引导永远不可能是 100% 有效,必须有环境层兜底。

最后一点个人体会:Agent 的生产化不是一次性工作,而是持续迭代的过程。威胁模型会变,模型能力会变,业务需求也会变。你需要建立的是能够随这些变化而调整的治理机制,而不是一套固定的规则。

评论 0

0 / 1000