构建 LLM 应用时,”Agent” 和 “Workflow” 是两种不同的编排思路,核心差异在于:图中是否允许环(Cycle)。
LangGraph 构建的是有向图(允许循环),LLM 运行时自主决定走哪条路;Dify Workflow 构建的是有向无环图(DAG),所有分支在设计阶段就画好了。
一、有环图 vs 无环图
1.1 DAG(有向无环图)
DAG(Directed Acyclic Graph)的特点是节点之间只能单向前进、不能形成回路。在工作流编排中:
- 每个节点只执行一次
- 执行路径设计时就确定了
- 数据只能从上游流向下游
Dify 的 Workflow 和 Chatflow 都基于 DAG。用户在可视化画布上拖拽节点、连线,路径必须提前画好。
1.2 有向循环图
有向循环图允许节点之间形成回路——下游输出可以重新流回上游。在 Agent 场景下:
- LLM 调用工具后,可以回到自身继续推理
- 循环多少次由 LLM 运行时决定
- 每次执行的路径可能不同
LangGraph 的 StateGraph 通过条件边(conditional edges)支持这种循环结构。
二、LangGraph:基于循环图的 Agent
2.1 核心架构
LangGraph 是 LangChain 生态中的图编排框架,核心是 StateGraph——一个以共享状态驱动的有向图。

图的三要素:
| 要素 | 说明 | 示例 |
|---|---|---|
| State(状态) | 节点间共享的数据结构,常用 TypedDict 定义 |
messages: list、user_info: dict |
| Node(节点) | Python 函数,接收 state 并返回状态更新 | call_model()、tool_node() |
| Edge(边) | 连接节点,分为固定边和条件边 | add_edge("tools", "agent") |
2.2 ReAct 模式:Agent 循环的核心
LangGraph 中最典型的 Agent 模式是 ReAct(Reasoning + Acting),本质是一个双节点循环:

每轮循环三个阶段:
- Thought:LLM 分析当前状态,决定下一步
- Action:调用工具
- Observation:拿到工具返回结果,判断是否需要继续
循环持续执行,直到 LLM 不再调用任何工具,路由函数将流程导向 END。
2.3 代码实现
标准 ReAct Agent 骨架:
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
# 1. 定义共享状态
class State(TypedDict):
messages: Annotated[list, add_messages]
# 2. 定义工具
tools = [query_weather, query_sales_data, search_knowledge_base]
# 3. 定义 Agent 节点
model = ChatOpenAI(model="gpt-4o").bind_tools(tools)
def agent(state: State):
response = model.invoke(state["messages"])
return {"messages": [response]}
# 4. 路由函数:决定是否继续循环
def should_continue(state: State):
last_message = state["messages"][-1]
if last_message.tool_calls:
return "tools" # 有工具调用 → 继续循环
return END # 无工具调用 → 结束
# 5. 构建图
graph = StateGraph(State)
graph.add_node("agent", agent)
graph.add_node("tools", ToolNode(tools))
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue) # 条件路由
graph.add_edge("tools", "agent") # ← 关键:工具执行后回到 agent(形成循环)
app = graph.compile()
重点在最后一行:graph.add_edge("tools", "agent") 把工具节点的输出接回 Agent,形成了环。should_continue 充当出口——LLM 不再产生 tool_calls 时循环停止。
三、Dify Workflow:可视化 DAG 编排
3.1 核心架构
Dify 的 Workflow 是一个可视化 DAG 画布——拖拽连线定义数据流和控制流。节点的连接关系在设计时确定,运行时不变。

3.2 Workflow 与 Chatflow
Dify 提供两种编排模式:
| 维度 | Workflow | Chatflow |
|---|---|---|
| 执行模式 | 调用一次跑完,类似脚本 | 支持多轮对话 |
| 触发方式 | 用户输入、触发器(定时/事件) | 始终由用户消息触发 |
| 典型场景 | 后端自动化(报告生成、数据处理) | 客服、语义搜索等对话场景 |
两者共享同一套画布和节点系统,都是 DAG,不允许回路。
3.3 主要节点类型
Dify 内置了丰富的节点,常用的包括:
- LLM 节点:调用大语言模型,支持 Jinja-2 模板构造 prompt
- 问题分类器:LLM 驱动的意图识别,将输入路由到不同分支
- 工具节点:调用内置或自定义工具
- IF/ELSE:条件分支
- 迭代节点:对数组数据循环执行相同步骤
- 参数提取器:用 LLM 从自然语言提取结构化参数
- HTTP 请求、代码执行(Python/Node.js) 等
3.4 多工具场景的处理
当需要调用多个工具时,Dify Workflow 有两种变通方式:
方式一:问题分类器(只能选一条路)

局限:一次只走一条分支。用户同时问天气和销售数据,只能命中其中一个。
方式二:迭代节点(按数组遍历)

局限:循环次数由输入数组长度决定,不是 LLM 动态判断的;本质是对列表的批处理,不是”推理-行动”循环。
四、核心对比
4.1 架构层面
| 维度 | LangGraph | Dify Workflow / Chatflow |
|---|---|---|
| 图类型 | 有向图(允许循环) | DAG(无环) |
| 能否回头 | 能,tools → agent 形成循环 |
不能,节点只能向后连接 |
| 谁决定流程 | LLM 运行时自主决定 | 设计者在画布上预先画好 |
| 工具调用次数 | 动态,LLM 觉得够了就停 | 固定,画了几个就几个 |
| 状态管理 | 代码定义 TypedDict,节点间共享 |
可视化变量传递 |
| 实现方式 | Python 代码 | 可视化拖拽画布 |
4.2 能力层面
| 能力 | LangGraph | Dify Workflow |
|---|---|---|
| 多工具动态调用 | 原生支持 | 需变通或使用 Agent 节点 |
| 链式推理(A 的结果决定 B 的输入) | 原生支持 | 不支持(纯 DAG 模式下) |
| 可视化编排 | 无内置 UI(可用 LangGraph Studio) | 核心能力,拖拽式画布 |
| 上手门槛 | 需要 Python 编程 | 零代码,适合非技术人员 |
| 确定性流程控制 | 可以做但偏重 | 天然适合 |
| Human-in-the-loop | 原生支持 | 有限支持 |
五、实战场景
5.1 多步骤动态推理
用户:”帮我看看公司销量最好的产品,查一下它的退货率高不高”
关键:第二步查什么取决于第一步的结果——设计时不知道”销量最好的产品”是哪个。

LangGraph 的处理(动态循环):
- Agent 第 1 轮:分析需求,先查销售数据 → 调用
query_sales_data() - Tools 返回”智能手表Pro 月销 500 台”
- Agent 第 2 轮(回到 Agent):拿到结果,决定查退货 → 调用
search_kb("智能手表Pro 退货") - Tools 返回退货政策内容
- Agent 第 3 轮(再回 Agent):整合两次结果,生成最终回复 → 不调工具 → END
第 2 次调用的参数 "智能手表Pro 退货" 是 LLM 根据第 1 次结果动态生成的。
Dify Workflow 的困境:
- 串联工具:知识库检索的关键词只能写死或用用户原始输入,没法用第一步的返回值来构造
- 穷举分支:N 个工具的排列组合 = N! 条路径,不现实
- Agent 节点:可行,但本质上就是在 DAG 里嵌了一个 Agent 循环
5.2 确定性业务流程
需求:用户上传 PDF,系统自动提取摘要 → 翻译成英文 → 发送邮件
路径完全确定:提取 → 翻译 → 发送,没有动态决策。
Dify Workflow 更合适:

拖几个节点连起来就行,直观、零代码。LangGraph 也能做,但用循环图跑线性流程没必要。
六、Dify 的 Agent 节点:DAG 里的循环
Dify 在较新版本中加入了 Agent 节点,可以嵌入 Workflow/Chatflow。
Agent 节点提供两种策略:
- Function Calling:利用模型原生的函数调用能力(GPT-4、Claude 等)
- ReAct:Thought → Action → Observation 循环(适合没有原生 Function Calling 的模型)
此外还可以从 Dify 插件市场安装更多 Agent 策略。
这其实是一种混合架构:

外层是 DAG,节点按预设顺序走;Agent 节点内部是循环,LLM 自己决定调什么工具、调几次。
这是个实用的折中——确定性流程交给 DAG,需要自主推理的环节交给 Agent 节点。不过相比 LangGraph 的原生循环图,Agent 节点作为”黑盒”嵌在 DAG 里,在状态透传、跨节点协作、细粒度控制方面还是有局限。
七、怎么选
7.1 选 Dify Workflow
- 流程确定,设计时就能画清楚
- 团队非技术背景,需要可视化零代码
- 快速搭原型
- 意图明确,一次只需调一个工具
7.2 选 LangGraph
- 需要多工具动态编排,LLM 根据上一步结果决定下一步
- 链式推理:工具 A 的输出是工具 B 的输入,且事先不可知
- 复杂 Agent:Human-in-the-loop、多 Agent 协作、自定义状态管理
- 生产级需求:精细的错误处理、重试、状态持久化
7.3 一句话
Dify 是人在设计时画好流程,LangGraph 是 LLM 在运行时自己走流程。
“先做 A,根据 A 的结果决定怎么做 B”——用 Agent(循环图)。”先做 A,再做 B,最后做 C”,路径固定——用 Workflow(DAG)。
实际项目中两者经常混着用:DAG 搭骨架,需要自主推理的地方嵌 Agent。