<!-- title: 一停就丢：人机中断四栈实测 -->

# 一停就丢：人机中断四栈实测

## 概述

四大主流 Agent 框架——LangGraph、AutoGen、CrewAI、OpenAI Agents SDK——在 2026 年的官方文档里无一例外都写着"支持人机协作（Human-in-the-Loop）"。但实测下来，"停一下等人批复"这件看似简单的事，在四个栈里是四种完全不同的东西：LangGraph 靠**检查点（Checkpoint）**把整张图冻在内存里再续命；AutoGen 靠 **UserProxyAgent** 的对话轮次代理；CrewAI 靠 Task 上的 `human_input=True` 一个布尔开关；OpenAI Agents SDK 靠 **handoff 转交 + guardrail 拦截**。一句话概括四个栈的共同宿命：**只要中断，上下文和状态就有丢失风险**。谁来存、存在哪、能不能跨进程恢复、并发任务会不会撕裂——这才是 HITL 真正的战场。本文用同一个"退款审批"用例，把四栈的中断语义、恢复成本、并发安全拆给你看。

## 多维度对比

| 维度 | LangGraph | AutoGen | CrewAI | OpenAI Agents SDK |
|------|-----------|---------|--------|-------------------|
| 中断原语 | `interrupt(value)` 抛出 | `human_input_mode` 轮询 | `human_input=True` 布尔 | handoff + input_guardrail |
| 恢复机制 | `Command(resume=...)` | 下一条人工消息 | 弹窗输入 | 重新触发 run |
| 状态持久化 | **检查点强持久化** | 对话历史 | Crew 状态对象 | 运行上下文 |
| 粒度 | **任意节点任意行** | 整条消息 | 单个 Task 完成点 | Agent 切换点 |
| 跨会话恢复 | ✅ 天然支持 | ⚠️ 需自管 | ❌ 进程内 | ⚠️ 需 session |
| 并发中断 | 线程隔离，稳 | 易串话 | ⚠️ 实测撕裂 | 需 session_id |
| 上手成本 | 中（需懂图/checkpoint） | 低（一个参数） | 极低（一行） | 中（需懂 guardrail） |
| 变现包装度 | ★★★★★（最像产品） | ★★★ | ★★ | ★★★★ |

## 深度分析

### 一、LangGraph：唯一把"中断"做成一等公民的栈

LangGraph 是四个栈里唯一把暂停/恢复提升为**语言级原语**的。`interrupt(value)` 不是 sleep、不是阻塞，而是把当前图的状态整个序列化进 Checkpointer（`MemorySaver` 或 Postgres/Redis 后端），然后向调用方"抛"出一个值。人工批复后，调用方再 `graph.invoke(Command(resume="批准"), config)`，图会从 `interrupt` 那一行**精确续行**，`feedback` 变量直接拿到批复内容。

```python
from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import MemorySaver

def review_node(state):
    draft = state["draft"]
    feedback = interrupt({"need_review": draft})  # 冻结整图，抛给上层
    return {"draft": apply_feedback(draft, feedback)}  # resume 后从这里继续

graph = build_graph().compile(checkpointer=MemorySaver())
cfg = {"configurable": {"thread_id": "refund-42"}}
graph.invoke({"draft": "..."}, cfg)            # 跑到 interrupt 停下
graph.invoke(Command(resume="批准，加一句致歉"), cfg)  # 精确续行
```

**优点**：粒度最细，可在任意节点的任意一行打断；检查点是强持久化，进程崩了也能恢复；`thread_id` 天然隔离并发会话。**缺点**：心智负担最重——开发者必须理解"图是有状态的、检查点是可重放的、纯函数才有可重放性"，节点里写个 `print` 到外部副作用都会让重放出问题。**变现评估**：最适合包装成"企业级审批流 Agent"训练营，因为它最像真正的 BPMS（业务流程引擎），能讲清楚"为什么比 Zapier 强"。

### 二、AutoGen：人机协作绑死在"代理"对象上

AutoGen 的 HITL 不是图的节点属性，而是 **Agent 实例的属性**。核心是 `UserProxyAgent` + 三态开关 `human_input_mode`：`ALWAYS` 每条消息都问人、`TERMINATE` 只在终止条件命中时问人、`NEVER` 完全自治。人工介入的本质是"在对话流里插入一条来自人类的消息"，框架用 `input()` 或自定义回调把流卡住。

```python
from autogen import UserProxyAgent, ConversableAgent

user_proxy = UserProxyAgent(
    "approver",
    human_input_mode="TERMINATE",
    is_termination_msg=lambda m: m.get("content","").strip().endswith("APPROVE"),
)
analyst = ConversableAgent("analyst", llm_config=cfg)
user_proxy.initiate_chat(analyst, message="起草退款意见，等我批复")
```

**优点**：上手极快，一个参数就有人机协作；对话式交互对"代码评审、问答澄清"这类场景自然。**缺点**：状态就是对话历史，**没有独立的检查点层**——进程一挂，未保存的对话就没了；并发多任务时 `UserProxy` 容易把不同会话的消息串到一起。AutoGen 0.4 改成事件驱动后语义有迁移税。**变现评估**：适合做"对话式助手"产品，不适合做合规审批——因为它无法证明"批复发生在流程的哪一步、状态是否可重放"。

### 三、CrewAI：一行布尔值的人机协作

CrewAI 把 HITL 压缩成了一个布尔参数 `human_input=True`，挂在 Task 上。当某个 Task 执行完，框架在控制台弹出提示，让人工批准/拒绝/修改输出，Task 才算完成。另有 Flows 抽象支持条件路由，但 HITL 仍主要靠 Task 级开关。

```python
from crewai import Agent, Task, Crew

analyst = Agent(role="退款分析员", goal="给出意见", llm=llm)
task = Task(
    description="撰写退款审批意见",
    expected_output="审批结论",
    agent=analyst,
    human_input=True,   # 完成前弹出人工确认
)
Crew(agents=[analyst], tasks=[task]).kickoff()
```

**优点**：学习成本最低，"加一个参数就有人工审批"的卖点极强，训练营第一课首选。**缺点**：**控制台弹窗本质是 `input()` 阻塞**，无法跨进程、无法 Web 化、无法持久化；中断点被钉死在 Task 完成时，不能在工具调用前拦；并发 Crew 实测会因为共享 stdin 互相打断。**变现评估**：做"快速原型"和"AI 训练营入门演示"极佳，但交付给企业生产环境会立刻露馅——没法对接审批系统的回调 webhook。

### 四、OpenAI Agents SDK：用"转交"和"护栏"拼出人机协作

OpenAI Agents SDK（2025 年 3 月发布，2026 年已成生产主流之一）没有 `interrupt()` 这种原语，它的 HITL 由三个零件拼装：**handoff**（把控制权转给另一个 Agent，可转给"人工 Agent"）、**input_guardrail**（在 run 真正开始前拦截输入，可用来强制人工确认）、**工具调用钩子**（在副作用工具执行前后插入审批回调）。中断的恢复靠重新触发一次 `Runner.run()` 并传入 session 上下文。

```python
from agents import Agent, Runner, InputGuardrail, GuardrailFunctionOutput

async def must_approve(ctx, agent, input):
    ok = await ask_human(input)          # 自行实现：弹审批
    return GuardrailFunctionOutput(output_info={"ok": ok},
                                   tripwire_triggered=not ok)

guard = InputGuardrail(guardrail_function=must_approve)
agent = Agent(name="退款审批", handoffs=[human_agent], input_guardrails=[guard])
```

**优点**：与 OpenAI 模型/可观测性生态深度绑定，`tripwire` 语义清晰（触发即拦截）；handoff 让"转人工"成为一等路径，适合客服/工单。**缺点**：**没有图的检查点，中断后恢复全靠你自己管 session 状态**；多步审批要手工编排 handoff 链；和厂商绑定深，迁移到 Anthropic/自托管模型代价大。**变现评估**：包装成"OpenAI 原生客服 Agent"产品力强，但要说"框架中立"就站不住。

### 五、中断持久化：谁能扛过一次进程重启

把四栈放在"进程崩溃后能否恢复未完成审批"这个判据下，差距立刻拉开。LangGraph 把 Checkpointer 指向 Postgres，重启后用同一个 `thread_id` invoke `Command(resume=...)` 即可精确续行——**这是唯一开箱即用的强持久化**。AutoGen 的状态是对话历史，需要你自己写快照逻辑存进数据库。CrewAI 的 `input()` 阻塞在内存里，进程一死审批上下文全丢，只能靠重跑。OpenAI Agents SDK 提供 `session` 概念但默认是内存的，生产必须接外部存储。**结论**：如果你的审批流必须满足审计合规（"停在哪一步、谁批复的、何时恢复"都可追溯），只有 LangGraph 能直接交付，其余三个都要补一层自研持久化——而这层自研往往就是项目从一周拖到三个月的真凶。

### 六、并发中断：多任务并行审批谁会撕裂

真实业务里一个客服同时处理五个工单是常态。LangGraph 靠 `thread_id` 给每个审批流独立的状态轨，并发安全。AutoGen 的 `GroupChat` 在多会话并发时消息路由容易串——A 会话的批复被 B 会话的 UserProxy 吞掉是经典 bug。CrewAI 多 Crew 并发时，多个 `input()` 抢同一个 stdin，实测会出现"弹窗内容串到另一个 Task"的撕裂。OpenAI Agents SDK 要求每次 run 显式传 `session_id`，传错就串、不传就单线。**实战建议**：除了 LangGraph，其余三栈做并发审批都必须自己加一层"会话锁 + 消息队列"把人工输入精确路由，否则越并发越乱。

### 七、超时与拒绝：四栈的"等不到批复"语义

审批最大的现实问题不是"批准"，而是"人没回"。四栈对"超时/拒绝"的处理差别巨大：LangGraph 可在 `interrupt` 后由调度器判断超时再走拒绝分支，语义完整。AutoGen 的 `TERMINATE` 模式若人一直不回，对话会无限挂起，需要自己加超时回调。CrewAI 的 `input()` 没有原生超时，必须用外层 `signal.alarm` 之类的 hack。OpenAI Agents SDK 的 guardrail 是同步的，适合"批准/拒绝"二选一，但"等待超时"要靠你自己的异步编排。**变现洞察**：把"超时降级为自动驳回/升级上级"做成一个通用中间件，是横跨四栈都能复用的训练营王牌模块——因为它戳中每个做审批流的人都踩过的坑。

## 架构图：HITL 中断-恢复工作流

```mermaid
flowchart TD
    U[用户触发任务] --> R[Agent 运行]
    R --> D{需要人工?}
    D -- 否 --> X[自动执行完成]
    D -- 是 --> I[发起中断 interrupt]
    I --> S[状态持久化]
    S --> P{持久层}
    P -- LangGraph --> CK[Checkpointer: thread_id 隔离]
    P -- AutoGen --> H[对话历史快照-自管]
    P -- CrewAI --> M[内存 input-易丢]
    P -- OpenAI --> SS[Session-需外部存储]
    CK --> W[等待人工批复]
    H --> W
    M --> W
    SS --> W
    W -->|批准| RES[恢复执行]
    W -->|拒绝| RJ[走拒绝分支]
    W -->|超时| TO[降级/升级]
    RES --> X
    RJ --> X
    TO --> X
```

## 推荐方案

- **合规审批流（金融/法务，需审计追溯）**：LangGraph 唯一选择。检查点 + `thread_id` 给你"可重放、可追溯、可并发"的全部三件套。
- **对话式澄清（代码评审、需求确认）**：AutoGen 的 `UserProxyAgent` 最自然，`ALWAYS/TERMINATE` 两态够用。
- **快速原型 / 训练营入门演示**：CrewAI 的 `human_input=True`，一行参数、当场见效。
- **客服工单"转人工"**：OpenAI Agents SDK 的 handoff 把人工当成一个 Agent 节点，与现有 OpenAI 栈无缝。
- **跨厂商、要中立**：避开 OpenAI Agents SDK，LangGraph 是模型中立的最佳选择。
- **必须并发**：除 LangGraph 外，其余三栈都自配"会话锁 + 输入路由"中间件，否则别上生产。

## 参考来源

1. [AI Agent Framework Comparison 2026 | paperclip.space](https://paperclip.space/guides/ai-agent-framework-comparison-2026/) — 2026 年四大框架横评，含 Governance、State Management、Model Flexibility 等维度
2. [LangGraph 官方文档 - Human-in-the-loop](https://langchain-ai.github.io/langgraph/) — `interrupt()` / `Command(resume)` / Checkpointer 原语与审批工作流模式
3. [OpenAI Agents SDK - GitHub](https://github.com/openai/openai-agents-python) — handoff、input_guardrail、tripwire 拦截与中断机制
4. [AI Agent Framework Comparison 2026: LangGraph vs CrewAI vs AutoGen vs ... | shipsquad.ai](https://shipsquad.ai/blog/ai-agent-framework-comparison-2026) — 同一多智能体用例在四框架的实测对比
5. [LangGraph vs CrewAI vs AutoGen vs OpenAI Agents SDK | nomadx.ae](https://nomadx.ae/ai-agent-framework-comparison-2026/) — 生产场景选型与 LlamaIndex 等补充框架

> [!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)
