<!-- title: 高危即拦：工具人审门控四栈实测 -->

## 概述

工具使用能力评测一直被简化为"能否正确调用"和"参数对不对"，却跳过了生命周期里最昂贵的一环——副作用落地前的**人审门控**（Human Approval Gating）。当一个智能体决定扣款、发邮件、删表、部署时，模型调对函数只是开始，真正决定事故率的是框架能否在执行瞬间**拦截、呈现、求决策、再恢复**。本期横评四大主力栈——LangGraph、OpenAI Agents SDK、CrewAI、AutoGen——外加作为跨服务标准的 MCP elicitation，沿"触发粒度、状态持久化、拒绝后恢复、批量审批、可审计性"五轴实测。核心发现：四栈的人审原语存在数量级差异，LangGraph 的 `interrupt()` 是唯一一等公民，CrewAI 的布尔开关在"只审高危"场景下近乎失效，而 MCP elicitation 把人审从框架私有原语升级成了跨边界的协议层能力。

## 四栈人审门控对比

| 维度 | LangGraph | OpenAI Agents SDK | CrewAI | AutoGen | MCP elicitation |
|------|-----------|-------------------|--------|---------|-----------------|
| 原语等级 | 一等公民 `interrupt()` | guardrail（近门控）+ tool wrapper | `human_input=True` 任务布尔 | `UserProxy.human_input_mode` 三档 | `elicitation/create` 协议原语 |
| 触发粒度 | 图节点/任意断点 | 工具入口（手搓） | 整个 Task | 每条消息 | 任意工具调用 |
| 状态持久化 | checkpointer 内置 | 需自挂 session | 框架内部 | 对话历史 | client 实现 |
| 拒绝后恢复 | `Command(resume)` 显式分支 | 返回结构化拒绝 | 重新跑 task | 终止对话 | accept/decline 语义 |
| 批量调用审批 | 可聚合中断 | 逐个 wrapper | 不支持 | 逐条 | 逐次请求 |
| 可审计性 | checkpoint 即日志 | 需自建 | 弱 | 对话日志 | client 审计 |

## 深度分析

### 一、评测设计：四态门控框架

人审门控不是"加个 if"那么简单。一个完整的门控必须显式回答四个状态：**拦截点**（在哪一层切断执行流）、**呈现面**（把什么信息给到审批人）、**决策语义**（批准/拒绝/编辑的三态是否齐全）、**恢复路径**（被拒后智能体走哪条分支）。四栈的差异本质上是这四态的完整度差异。LangGraph 把四态都做成了一等公民——拦截点是节点、呈现面是 `interrupt()` 的 payload、决策语义是 `Command(resume=...)` 的任意值、恢复路径由图边定义。其他三栈至少缺一个态。本期实测以"扣款工具 + 发邮件工具 + 只读查询工具"三类混合任务跑同一用例，看各栈能否做到"只拦扣款、放过查询"。**变现点**：把这套四态框架做成"生产级人审合规检查清单"，金融、医疗行业刚需，训练营可包装成"从 demo 到合规上线的最后一公里"。

### 二、LangGraph：唯一的一等公民原语

```python
from langgraph.types import interrupt, Command

def approve_payment(state):
    decision = interrupt({             # 拦截点 + 呈现面
        "question": "批准转账？",
        "amount": state["amount"],
        "to": state["payee"],
    })
    if decision == "no":
        return {"branch": "rejected"}  # 显式恢复路径
    return {"branch": "approved"}

# 恢复
graph.invoke(Command(resume="yes"), config)
```

`interrupt()` 的杀手锏是它和 checkpointer（`MemorySaver`/`PostgresSaver`）深度耦合——执行流在断点被序列化，审批可以发生在数小时甚至数天后，恢复时状态完整无损。这对真实生产（审批人在另一个时区）是刚需。优点：粒度最细、可聚合中断、checkpoint 天然审计日志。缺点：心智负担高，开发者必须先理解图、checkpointer、thread_id 三件套；过度使用会让图变成"到处埋雷"。**实测**：在"只拦扣款"场景下，只需把 `approve_payment` 节点接在扣款工具前、查询路径绕开即可，干净利落。**变现点**：LangGraph 人审是合规场景（理赔审批、跨境支付复核）的护城河，可做企业内训专题"长事务型人审"。

### 三、OpenAI Agents SDK：guardrail 的近门控边界

Agents SDK 提供的 `InputGuardrail`/`OutputGuardrail` 本质是**输入输出的安全校验**，不是工具执行前的暂停原语。要做工具门控，得在 tool wrapper 里手搓：

```python
def transfer_funds(ctx, amount, to):
    if not ctx.approved.get(("transfer", amount, to)):
        return {"status": "pending_approval", "request_id": "..."}
    # 真正执行
```

这套手搓方案缺三样东西：无内置状态持久化（`ctx.approved` 存哪、崩溃后还在不在全靠开发者）、无统一呈现面（每个工具自己定义审批 payload 格式）、无标准恢复语义。优点：轻量、与原生 function calling 贴合、guardrail 做"输入侧是否触发敏感意图"的预筛很合适。缺点：把生产级人审的责任全甩给应用层，团队间实现不互通。**实测**：同一用例下手搓版本能达到 LangGraph 八成效果，但代码量是后者三倍，且批量调用必须逐个 wrapper。**变现点**：填补"Agents SDK 缺人审"这个明确空白，做一个开源 `approval-toolkit` 中间件，配套训练营"OpenAI 智能体合规化改造"。

### 四、CrewAI：布尔开关的"全审或全不审"陷阱

```python
Task(
    description="处理退款请求",
    agent=finance_agent,
    human_input=True,   # 整个 task 都要人审
)
```

`human_input=True` 是任务级布尔开关——它**无法只审 task 内的某个高危工具调用**，而是对整个任务的中间步骤一视同仁地请求人输入。在"查询账户 + 决定退款"这种混合任务里，要么两步都问、要么都不问。实测中，把查询和退款拆成两个 task 又会破坏 CrewAI 的任务流语义。优点：上手最快、零认知成本、对纯审批流（每步都要人）恰好够用。缺点：粒度太粗导致**审批疲劳**——当智能体每步都问，人会肌肉记忆式地全点"通过"，高危步骤反而被淹没。**变现点**：CrewAI 的人审只适合"演示型 demo"，做训练营时要明确划线"生产慎用"，否则学员上线即翻车。

### 五、AutoGen：对话级人审的信号噪音

```python
user_proxy = UserProxyAgent(
    "reviewer",
    human_input_mode="TERMINATE",  # ALWAYS / TERMINATE / NEVER
    is_termination_msg=lambda x: "approved" in x.get("content","").lower(),
)
```

AutoGen 的 `UserProxyAgent` 是为"人类作为对话参与者"设计的，`human_input_mode` 控制触发频率。问题在于它是**消息级**而非**工具级**——它拦的是"是否回复这条消息"，不是"是否执行这个工具调用"。当 assistant agent 报告"我即将调用 transfer()"时，UserProxy 实际上拦不住工具执行本身，只能在下一轮对话里纠正。优点：把人当作一个 agent 嵌入群聊，对"人在环中讨论"场景天然；与 GroupChat 协同好。缺点：工具副作用已经发生的"事后纠正"在金钱类操作上是不可接受的。**实测**：在扣款场景下，AutoGen 必须给高危工具套同步锁+预提交，人审实质上又退化成手搓。**变现点**：AutoGen 适合"知识讨论型"人审（如科研、咨询复核），做成"协作式人审"专题，避免碰硬副作用场景。

### 六、MCP elicitation：跨服务统一原语

2025-06-18 规范引入的 `elicitation/create` 把人审从框架私有原语提升到协议层——任何 MCP server 都可以标准化地向 client 的人类用户请求输入，client 返回 `accept`/`decline`/`cancel` 三态。

```jsonc
// server -> client
{"method": "elicitation/create",
 "params": {"message": "确认删除表 users？",
            "requestedSchema": {"type":"object",
              "properties":{"confirm":{"type":"boolean"}}}}}
// client -> server
{"result": {"action":"accept", "content":{"confirm": true}}}
```

这是本期最有前瞻性的一环：当工具来自第三方 MCP 服务（如支付、CRM），应用层框架不再需要为每个外部工具写 wrapper，server 自己声明"这一步需要人"。优点：跨工具、跨框架统一语义、`requestedSchema` 让呈现面标准化。缺点：client 实现成熟度参差——Claude Desktop、Cursor、各家 SDK 对 elicitation 的支持时间不一，"server 要人"和"client 能不能弹"之间存在鸿沟；且无统一审批日志归属。**变现点**：MCP elicitation 咨询是 2026 蓝海，可做"MCP server 合规化"评估服务，帮第三方工具补齐人审协议支持。

### 七、三场景实测：超时、拒绝、批量

三个压垮门控的真实场景实测结论：**超时**——LangGraph 依赖 checkpointer 可跨进程跨天恢复，唯一满分；OpenAI 手搓版若没把 `ctx.approved` 落库则崩溃即丢；CrewAI/AutoGen 默认同步阻塞，超时即任务失败。**拒绝后恢复**——LangGraph 走显式图边（可定义"拒绝→改用降级工具"）；OpenAI/CrewAI 只能返回拒绝让智能体重想；AutoGen 多半直接终止对话。**批量审批**——LangGraph 可把多个 pending tool call 聚合成单次中断（关键体验），其余三栈全部退化成逐个弹窗，10 笔转账弹 10 次窗，疲劳指数爆表。**变现点**：把"超时/拒绝/批量"做成可复现的 benchmark 工程包，定价给选型团队，这是甲方真正愿意付费的"避坑清单"。

## 四栈人审门控架构流程

```mermaid
flowchart TD
    A[智能体决定调用工具] --> B{工具是否高危?}
    B -- 只读/低危 --> C[直接执行]
    B -- 高危/副作用 --> D{框架拦截层}
    D --> L[LangGraph: interrupt 节点]
    D --> O[OpenAI: tool wrapper 手搓]
    D --> CR[CrewAI: human_input 任务级]
    D --> AU[AutoGen: UserProxy 消息级]
    D --> M[MCP: elicitation/create 协议]
    L --> P[checkpointer 持久化]
    O --> Q[ctx 手挂 session]
    CR --> Q
    AU --> Q
    M --> R[client 弹窗实现]
    P --> H[人类审批]
    Q --> H
    R --> H
    H -- 批准 --> E[执行 + 审计日志]
    H -- 拒绝 --> F{恢复路径}
    F -- LangGraph --> G1[Command resume 显式分支]
    F -- 其他 --> G2[返回拒绝/重想/终止]
    H -- 超时 --> T{状态是否落库?}
    T -- 是 --> H
    T -- 否 --> FAIL[任务失败/状态丢失]
```

## 推荐方案

**纯副作用门控（扣款、删除、部署）——LangGraph**：唯一能把"拦截、持久化、恢复、审计"四态一次凑齐的栈，跨天审批的刚需场景无替代品。

**OpenAI 原生生态 + 强工程团队 —— Agents SDK + 自研 approval-toolkit**：guardrail 做意图预筛，tool wrapper 做执行门控，配一个统一的 session 持久层补齐 LangGraph 的能力，代价是三倍代码量。

**演示、教学、纯审批流 —— CrewAI**：`human_input=True` 开箱即用，但要在交付文档里写死"禁止用于混合高危任务"。

**人在环中讨论（非硬副作用）—— AutoGen**：把人当 agent 嵌入群聊，科研、咨询复核场景天然，碰钱碰删一律另配同步锁。

**跨第三方工具、跨框架的统一人审 —— MCP elicitation**：长线标准，但选型前必须验证目标 client 的支持成熟度，否则协议要人、端上弹不出来。

一句话选型：**生产级硬副作用认 LangGraph，生态原生认 Agents SDK 配自研中间件，跨服务认 MCP elicitation；CrewAI/AutoGen 的人审止步于演示和讨论。**

## 参考来源

1. [Human Approval Gates for AI Agents (LangGraph / AutoGen / CrewAI)](https://www.bestaiweb.ai/how-to-add-human-approval-gates-to-agents-with-langgraph-autogen-and-crewai-in-2026/) — 2026 年三大框架人审门控实现对比，综合技术博客
2. [CrewAI 官方文档：Human Input on Execution](https://docs.crewai.com/v1.14.7/en/learn/human-input-on-execution) — `human_input=True` 任务级人审的官方说明，官方文档
3. [MCP 规范 2025-06-18：Elicitation](https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation) — `elicitation/create` 跨服务人审协议原语定义，官方规范
4. [MCP Elicitation: Human-in-the-Loop for MCP Servers](https://dev.to/kachurun/mcp-elicitation-human-in-the-loop-for-mcp-servers-m6a) — elicitation 与 sampling 区别及实战解读，开发者社区
5. [LangGraph vs AutoGen vs CrewAI vs DSPy: 2026 Multi-Agent 对比](https://agentmarketcap.ai/blog/2026/04/11/langgraph-autogen-crewai-dspy-multi-agent-orchestration-2026) — 四框架性能与控制粒度数据驱动横评，综合博客

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
