四种方案的本质差异
选择工作流框架要匹配执行模型、工程成本、团队能力,不是找最好的那个。
javascript
方案 工作流定义 状态持久化 执行引擎
─────────────────────────────────────────────────────────────────
Prompt-based Markdown + YAML 手写 JSON 文件 LLM(A 层)
LangGraph Python 代码(图结构) 内置 State Schema Python 代码(确定性)
Temporal Python/TypeScript 内置(数据库) 代码(确定性)
n8n 可视化 + JSON 内置 代码(确定性)
前三种支持语义判断(confidence >= 0.95),n8n 基本只支持布尔表达式。LangGraph 和 Temporal 的执行引擎是确定性代码,Prompt-based 的执行引擎是 LLM 本身。
Prompt-based(你的方案)
工作流定义: Markdown + YAML 文件
markdown
# workflow.md
## Phase 3:根因分析
执行子 Agent:rnd-automotive-issue-analyzer
Context:{{ phases.phase2.log_dir }}
路由:
- confidence >= 0.95 → Phase 4
- 0.6 <= confidence < 0.95 → Gate A
- confidence < 0.6 且重试次数 < 3 → 重试 Phase 3
- confidence < 0.6 且重试次数 >= 3 → 人工升级
优势:
- 工作流定义可以被非工程师读懂和修改
- 改 Markdown 比改代码快,适合频繁迭代
- LLM 执行路由逻辑,无需硬编码所有边界条件
- 启动成本低,适合 POC 和快速验证
劣势:
- 路由逻辑由 LLM 执行,有不确定性(同一个输入可能有不同路由结果)
- 缺少代码级的类型系统和测试工具支持
- 可观测性需要手动接 Langfuse,不是开箱即用
- 规模增大后,Markdown 文件维护难度上升
适合:
- 工作流经常变,改 Markdown 比改代码快的场景
- 团队没有专职工程师,或非技术人员需要能读懂工作流定义
- 快速验证 POC,3 天内跑通一个 MVP
LangGraph
工作流定义: Python 代码(图结构)
python
from langgraph.graph import StateGraph, END
from typing import TypedDict
class WorkflowState(TypedDict):
jira_key: str
bug_info: dict # Phase 1 输出
analysis: dict # Phase 3 输出
fix_result: dict # Phase 4 输出
def analyze_node(state: WorkflowState) -> dict:
result = call_skill("rnd-automotive-issue-analyzer", state["bug_info"])
return {"analysis": result}
def route_after_analyze(state: WorkflowState) -> str:
confidence = state["analysis"]["confidence"]
retries = state.get("analyze_retries", 0)
if confidence >= 0.95:
return "fix_and_verify"
elif retries < 3:
return "analyze" # 重试
else:
return "human_gate_A"
graph = StateGraph(WorkflowState)
graph.add_node("analyze", analyze_node)
graph.add_conditional_edges("analyze", route_after_analyze, {
"fix_and_verify": "fix_and_verify",
"analyze": "analyze",
"human_gate_A": "human_gate_A"
})
LangGraph 概念与 Prompt-based 的对应关系:
arduino
LangGraph 概念 Prompt-based 对应
──────────────────────────────────────────────────────
WorkflowState(TypedDict) workflow_state.json 的结构
Node 函数 每个 Phase 的执行逻辑
Edge / conditional_edges workflow.md 里的路由条件
checkpointer workflow_state.json 本身
interrupt(human-in-loop) 确认门
理解了这个映射,两种方案之间的转换是有规律的,不是从头重写。
优势:
- 路由逻辑是纯 Python 函数,确定性强,可以写单元测试
- TypedDict 的 State Schema 提供类型检查,字段缺失编译期就能发现
- 内置 LangSmith 集成,Trace 开箱即用
- 支持复杂的嵌套子图(subgraph),适合复杂状态机
劣势:
- 工作流定义是代码,非工程师无法直接读懂和修改
- 改动需要走代码 review,迭代比 Markdown 慢
- 学习成本:需要理解图结构和 StateGraph API
适合:
- 工作流逻辑复杂,需要精确控制状态机
- 团队熟悉 Python,工作流相对稳定(不是天天改)
- 需要代码级别的类型检查和测试覆盖
Temporal
工作流定义: Python 或 TypeScript 代码
python
from temporalio import workflow, activity
from datetime import timedelta
@activity.defn
async def analyze_bug(bug_info: dict) -> dict:
return await call_skill("rnd-automotive-issue-analyzer", bug_info)
@workflow.defn
class BugFixWorkflow:
@workflow.run
async def run(self, jira_key: str) -> dict:
bug_info = await workflow.execute_activity(
fetch_jira_ticket,
jira_key,
start_to_close_timeout=timedelta(minutes=5)
)
analysis = await workflow.execute_activity(
analyze_bug,
bug_info,
start_to_close_timeout=timedelta(minutes=30),
retry_policy=RetryPolicy(maximum_attempts=3)
)
# ...
优势:
- 真正的 Durable Execution:代码层保证崩溃恢复,不需要手写状态文件
- 天然支持长时间运行(天/周级别),适合有 SLA 的企业流程
- 内置的可视化 UI 和工作流历史追踪
- 活动(Activity)和工作流(Workflow)的分离是严格的
劣势:
- 部署复杂:需要运行 Temporal Server
- 学习成本高:Temporal 的编程模型与常规 async 代码有本质区别
- 对于 AI Agent Workflow,Temporal 的 Activity 超时和重试模型与 LLM 调用不完全匹配
适合:
- 工作流运行时间超长(> 1 小时),涉及人工审批等长等待操作
- 企业级场景,需要强一致性保证
- 有专职后端工程师维护基础设施
n8n
工作流定义: 可视化画布 + JSON
css
[HTTP Request] → [AI Agent] → [条件判断] → [Jira 写评论]
↓
[发送邮件]
优势:
- 可视化,非技术人员可以搭建和理解
- 大量内置集成节点(Jira、GitHub、Slack、数据库等)
- 自托管,数据不出域
劣势:
- 条件分支基本只支持布尔表达式,语义路由需要外挂 LLM 节点
- 复杂的状态管理(如重试计数、候选结果汇总)在可视化界面里很笨拙
- 版本控制:JSON 文件 diff 不友好,合并冲突难处理
- LLM Agent 节点的功能受限,无法实现 Orchestrator-Subagents 模式
适合:
- 主要是 API 集成场景,AI 只是其中一个节点
- 需要向非技术用户展示工作流
- 任务简单,不需要复杂的状态管理
选型决策树
工作流经常变,需要非工程师能维护?
→ Prompt-based(Markdown)
工作流逻辑复杂,需要代码级测试,团队会 Python?
→ LangGraph
运行时间超过 1 小时,企业级 SLA,有专职后端团队?
→ Temporal
主要是 API 集成,AI 只是其中一步,需要可视化?
→ n8n
混合使用: 这四种方案不是互斥的。一个实际系统里可能是:n8n 负责触发条件和通知集成(监听 Jira 新工单 → 发飞书通知),LangGraph 或 Prompt-based 负责核心的 AI Agent 工作流逻辑。
从 Prompt-based 迁移到 LangGraph
理解了对应关系,迁移有规律可循:
Step 1:把 workflow.md 的结构转为 WorkflowState
python
# workflow.md 的 context 结构 → TypedDict
class WfBugE2EState(TypedDict):
jira_key: str
bug_info: dict | None # Phase 1 输出
log_dir: str | None # Phase 2 输出
analysis: dict | None # Phase 3 输出
fix_results: list[dict] # Phase 4 并发候选结果
selected_fix: dict | None # Phase 4 Fan-in 结果
commit_result: dict | None # Phase 5 输出
analyze_retries: int # 重试计数器
Step 2:把每个 Phase 的 template 转为 Node 函数
python
def phase3_analyze_node(state: WfBugE2EState) -> dict:
result = spawn_subagent(
template="templates/analyze.md",
context={"bug_info": state["bug_info"], "log_dir": state["log_dir"]}
)
return {
"analysis": result,
"analyze_retries": state["analyze_retries"] + 1
}
Step 3:把 workflow.md 的路由条件转为 conditional_edges
python
def route_after_analyze(state: WfBugE2EState) -> str:
conf = state["analysis"]["confidence"]
retries = state["analyze_retries"]
if conf >= 0.95: return "phase_4_fix"
if conf >= 0.6: return "gate_A"
if retries < 3: return "phase_3_analyze" # 重试
return "human_escalation"
迁移的主要工作不是重写逻辑,而是把"隐含在 LLM 里的路由判断"改为"显式的 Python 函数"。两种方案的核心设计(Phase 结构、Context 传递、确认门)是共通的。
总结
- 没有最好的框架,只有最匹配的框架:Prompt-based 适合快速迭代、非技术维护;LangGraph 适合复杂状态机、代码级测试;Temporal 适合长时间运行的企业流程;n8n 适合 API 集成和可视化展示
- LangGraph 和 Prompt-based 可以互相转换:WorkflowState = workflow_state.json,Node = Phase/Step,conditional_edges = 路由条件,概念一一对应,理解了结构就能迁移
- 框架选型不影响核心设计:Context 传递模式、确认门、幂等性、版本绑定这些工程原则,不管用什么框架都需要
欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。
更多实用知识和有趣产品,欢迎访问我的个人主页