# Week 3 | 第1课：为什么需要状态机

**课程编号**: 3.1
**时长**: 30 分钟
**前置**: Week 1（Agent 基础）、Week 2（多 Agent 协作）

---

## 学习目标

- 理解自由形态 Agent 的局限性和潜在问题
- 掌握状态机的核心概念和工作原理
- 学会判断什么时候用 CrewAI（自由流），什么时候用 LangGraph（可控流）
- 能够画出简单的状态转换图

---

## 1. 自由形态 Agent 的问题

在前两周的课程中，我们学习了如何构建单个 Agent（Week 1）以及如何让多个 Agent 协作（Week 2）。无论是单个 ReAct Agent 还是 CrewAI 的多 Agent 编排，它们都有一个共同特点：**Agent 自主决定下一步做什么**。

这种自由形态（free-form）的设计在简单场景下效果很好，但在生产环境中会遇到以下问题：

### 1.1 不可预测的行为

```python
# CrewAI 示例：你无法精确控制执行顺序
from crewai import Agent, Task, Crew

researcher = Agent(role="研究员", goal="收集信息")
analyst = Agent(role="分析师", goal="分析数据")
writer = Agent(role="写手", goal="撰写报告")

# 问题：你无法保证 researcher 一定在 analyst 之前完成
# CrewAI 会自动调度，但顺序和重试逻辑是黑盒
crew = Crew(agents=[researcher, analyst, writer], tasks=[...])
result = crew.kickoff()
```

当流程变复杂时，你无法回答：
- 当前执行到哪一步了？
- 为什么 Agent 选择了这个路径？
- 能不能保证某个步骤一定会执行？

### 1.2 调试困难

自由形态 Agent 出错时，你面对的是一个黑盒：

```
用户提问 → [???] → 输出结果
                   ↑
              中间发生了什么？
              调了几次 LLM？
              为什么返回了这个结果？
```

没有明确的状态记录，出了问题只能看日志猜。

### 1.3 流程无法保证

假设你需要一个审批流程：

```
提交申请 → 主管审批 → (通过) → 财务审批 → 完成
                      → (拒绝) → 退回修改
```

用自由形态 Agent 实现，你需要在 prompt 里反复强调流程规则，但 LLM 仍然可能：
- 跳过主管审批直接到财务
- 审批通过后忘记通知申请人
- 进入死循环反复询问

---

## 2. 状态机：让流程可控

### 2.1 什么是状态机？

状态机（State Machine）的核心思想很简单：

> 程序在任何时刻都处于一个**明确的状态**，根据当前状态和输入，**确定性地**转换到下一个状态。

三个基本要素：
- **状态（State）**: 程序当前所处的阶段
- **转换（Transition）**: 从一个状态到另一个状态的规则
- **动作（Action）**: 状态转换时执行的操作

### 2.2 状态机示意图

以客户问题分类系统为例：

```
┌─────────────┐
│   Start     │
└──────┬──────┘
       │ 用户输入问题
       ▼
┌─────────────┐
│  分类意图    │ ◄── 状态：判断问题是账单/技术/售后
└──────┬──────┘
       │
   ┌───┴──────────┬──────────────┐
   ▼              ▼              ▼
┌──────┐    ┌──────────┐   ┌──────────┐
│ 账单  │    │  技术     │   │  售后     │ ◄── 条件分支
└──┬───┘    └────┬─────┘   └────┬─────┘
   │             │              │
   └─────────────┼──────────────┘
                 ▼
        ┌──────────────┐
        │  生成回复     │ ◄── 动作：调用对应领域的处理逻辑
        └──────┬───────┘
               │
               ▼
        ┌──────────────┐
        │ 检查满意度    │ ◄── 条件：满意？→ End / 不满意？→ 回到分类
        └──────┬───────┘
               │
          ┌────┴────┐
          ▼         ▼
       满意 End   不满意 ──────► 回到分类（循环）
```

### 2.3 状态机带来的好处

| 特性 | 自由形态 Agent | 状态机 Agent |
|------|---------------|-------------|
| 执行顺序 | 不可预测 | 完全确定 |
| 调试 | 看日志猜 | 当前状态一目了然 |
| 可视化 | 难以画出流程图 | 天然就是流程图 |
| 循环控制 | 容易死循环 | 可设置最大循环次数 |
| 单元测试 | 困难 | 每个状态可独立测试 |
| 适用场景 | 探索性任务 | 有明确流程的业务 |

---

## 3. CrewAI vs LangGraph：什么时候用哪个？

### 3.1 CrewAI —— 自由流编排

**适合场景：**
- 多个角色协作完成一个开放式任务
- 不需要严格的执行顺序
- 任务是探索性的（比如调研、头脑风暴）
- 你信任 Agent 的自主决策能力

```
典型用例：
市场调研 → 数据收集 → 分析报告 → 撰写总结
（每个步骤可以独立，顺序不完全固定）
```

### 3.2 LangGraph —— 可控流编排

**适合场景：**
- 有明确的业务流程（审批、客服、订单处理）
- 需要保证某些步骤一定执行
- 需要循环和条件分支
- 需要精确控制重试和错误处理

```
典型用例：
用户提问 → 意图分类 → 路由到对应处理 → 生成回复 → 满意度检查
（每一步都有明确的先后关系和分支逻辑）
```

### 3.3 对比总结

```
                CrewAI                    LangGraph
                ──────                    ─────────
控制级别        低（Agent 自主决定）       高（你定义流程）
学习曲线        低                        中
调试难度        高                        低
适用场景        开放式任务                有流程约束的任务
可视化          弱                        强（内置图可视化）
循环支持        有限                      原生支持
条件分支        隐式                      显式
```

**经验法则：**
- 如果你的流程可以用一张流程图清晰画出来，用 LangGraph
- 如果你的任务是"让几个专家一起讨论某个话题"，用 CrewAI

---

## 4. 动手练习

### 练习 1：画出你业务中的状态图

找一个你工作中的真实流程（比如订单处理、用户注册、工单处理），用 ASCII 画出它的状态转换图：

```
┌─────────┐
│  状态1   │ ──条件──► ┌─────────┐
└─────────┘           │  状态2   │
                      └─────────┘
```

要求：
1. 至少包含 4 个状态
2. 至少包含 1 个条件分支
3. 标注每个转换的触发条件

### 练习 2：判断工具选型

判断以下场景适合用 CrewAI 还是 LangGraph，并说明理由：

1. 客服系统：用户提问 → 分类 → 路由 → 回复 → 满意度调查
2. 代码评审：多个 reviewer 独立审查代码，汇总意见
3. 订单处理：下单 → 支付 → 发货 → 确认收货 → 评价
4. 竞品分析：收集多个竞品信息，交叉分析，生成报告

<details>
<summary>参考答案</summary>

1. **LangGraph** — 明确的流程，需要条件分支（分类结果不同路由不同）
2. **CrewAI** — 多个角色独立工作，没有严格的先后顺序
3. **LangGraph** — 严格的线性流程，每步依赖上一步结果
4. **CrewAI** — 探索性任务，多个信息源并行收集后综合分析

</details>

---

## 5. 小结

本课要点：

- **自由形态 Agent** 的问题：不可预测、调试困难、流程无法保证
- **状态机** 通过定义明确的状态和转换规则，让 Agent 流程可控、可调试、可可视化
- **CrewAI 适合开放式任务**，**LangGraph 适合有明确流程约束的任务**
- 实际项目中，两者可以结合使用：LangGraph 编排整体流程，其中的某些节点调用 CrewAI 处理开放式子任务

**下节课预告**: 学习 LangGraph 的核心概念 —— State、Node、Edge，从零搭建第一个状态图。
