AI编程生活评测

Agent vs Workflow:LangGraph 循环图与 Dify DAG 的区别

编程笔记 / 2026-05-13 / 8 min

构建 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——一个以共享状态驱动的有向图。

LangGraph 有向循环图架构

图的三要素:

要素 说明 示例
State(状态) 节点间共享的数据结构,常用 TypedDict 定义 messages: listuser_info: dict
Node(节点) Python 函数,接收 state 并返回状态更新 call_model()tool_node()
Edge(边) 连接节点,分为固定边和条件边 add_edge("tools", "agent")

2.2 ReAct 模式:Agent 循环的核心

LangGraph 中最典型的 Agent 模式是 ReAct(Reasoning + Acting),本质是一个双节点循环

ReAct 模式循环

每轮循环三个阶段:

  1. Thought:LLM 分析当前状态,决定下一步
  2. Action:调用工具
  3. 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 画布——拖拽连线定义数据流和控制流。节点的连接关系在设计时确定,运行时不变。

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 的处理(动态循环)

  1. Agent 第 1 轮:分析需求,先查销售数据 → 调用 query_sales_data()
  2. Tools 返回”智能手表Pro 月销 500 台”
  3. Agent 第 2 轮(回到 Agent):拿到结果,决定查退货 → 调用 search_kb("智能手表Pro 退货")
  4. Tools 返回退货政策内容
  5. 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 策略。

这其实是一种混合架构

hybrid-arch

外层是 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。


参考资料

点击刷新