
LangGraph、n8n、Dify这三个词放到一起的时候很多人第一反应是“我到底该学哪个”“哪个能取代哪个”。我做了两年多AI Agent相关项目从最早手写状态机到后来用LangGraph做复杂编排再到帮业务团队搭Dify知识库、用n8n拉通内部系统可以明确告诉你它们根本不是一个赛道的东西硬要比个高下没有意义真正有价值的是搞懂各自边界再根据实际场景做选型甚至组合使用。这篇就一次性拆清楚。1. 选型前先搞清楚LangGraph、n8n、Dify到底是谁1.1 三条路线的定位差异先说结论化的定位后面再逐个展开LangGraph是LangChain团队推出的Agent编排框架本质是一个Python/JS库不是平台。核心是状态图StateGraph用节点和边的形式把Agent的执行流程画出来然后在图上跑状态流转。程序员拿它写代码自由度极高。n8n是far taller出品的开源自动化工作流工具本质是iPaaS集成平台即服务用来打通不同系统之间的数据流。它后来加入了LangChain节点和AI Agent节点但它最擅长的依然是系统集成、定时任务、Webhook触发这类自动化场景。Dify是一个完整的LLM应用开发平台开箱即用。它有知识库RAG、Agent、工作流、模型管理、可观测性这些功能讲得直白一点就是一个把AI应用从“写代码”变成“配界面”的平台。用一个生活化类比LangGraph是给你一堆乐高零件和图纸自己拼n8n是给你一个插线板把现成的电器插上去接通Dify是给你一台功能完整的电器面板上按按钮就行。这三者的核心差异是“逻辑写在哪里”LangGraph的逻辑在代码里n8n的逻辑在节点连线里Dify的逻辑在可视化编排界面里。1.2 为什么会出现三分天下的局面AI Agent开发落到工程层面本质只有一件事编排。LLM调用、工具调用、循环、条件分支、记忆管理、数据检索这些东西谁来决定执行顺序、谁来决定何时终止、谁来决定下一步调什么这就是Agent框架的全部核心。三条路线分别从三个不同维度切入LangGraph从“代码控制”切入。适合需要精细控制、复杂分支、动态路由、子图嵌套的场景也是目前做生产级Agent的主流选择。n8n从“集成自动化”切入。它解决的痛点是“AI怎么接入现有系统”比如Webhook触发、数据库查询、发邮件、发企业微信消息、调用内部API这些事n8n做得极其顺手代码量几乎为零。Dify从“完整产品闭环”切入。它解决的是“业务怎么用上AI”的问题不需要团队里有懂LangChain的人把文档丢进去做知识库配一个Agent应用前端通过API接入一个可用的AI产品就出来了。所以要我说LangGraph、n8n和Dify之间存在的是互补关系而不是替代关系。Dify做不了很复杂的条件路由n8n不适合写高并发状态机LangGraph则不适合让非技术同事去维护。各管一段才是常态。1.3 LangGraph和LangChain的关系为什么很多初学者卡住搜索热词里出现频率很高的是“LangGraph和LangChain的区别”这个问题不搞清楚LangGraph教程看十遍也容易懵。LangChain是一个面向LLM应用的工具链提供了模型调用封装、Prompt模板、输出解析、文档加载、向量存储封装等基础能力。LangGraph则是建立在LangChain或独立使用之上的执行引擎专门处理有状态、有分支、有循环的Agent流程。我的理解是LangChain解决的是“模型怎么调、数据怎么取”LangGraph解决的是“整个流程怎么走、状态怎么流转、出错了怎么回退”。初学者的典型误区是还在用“链式思维”写LangGraph。LangChain的链是一串顺序执行上一轮输出给下一轮LangGraph是图节点之间可以有条件跳转、可以循环、可以并行。用链式思维写Graph的典型症状是写出来的图是一条直线完全没发挥状态机的作用还觉得LangGraph比LangChain还难用。2. LangGraph核心机制实战状态、节点、条件路由与子图2.1 State设计整个图的“全局变量”LangGraph里的State是贯穿全流程的数据结构你可以理解为一个全局共享对象每个节点函数接收当前state处理后返回要更新的部分。官方推荐用TypedDict定义。from typing import TypedDict, Annotated from langgraph.graph.message import add_messages class AgentState(TypedDict): messages: Annotated[list, add_messages] # 消息列表多个节点写入时自动追加 next_step: str # 当前执行到哪个步骤 risk_level: int # 自定义标记例如日志风险等级 logs: list # 从ES查询到的日志结果这里最关键的是Annotated[list, add_messages]这个reducer。LangGraph默认情况下每个节点返回的state是覆盖前值加上add_messages之后多个节点写入的消息会追加而不是覆盖。这就是LangGraph里控制状态“合并策略”的核心语法。注意State设计决定了你的Agent能跑多复杂。如果State里全是覆盖字段节点一多就容易丢数据如果全是追加字段内存膨胀很快。建议高频更新的状态字段如消息列表用追加流程标记字段如当前步骤用覆盖。2.2 节点函数如何改变State状态值节点函数接收state返回一个部分更新的dict。返回什么LangGraph就按reducer规则更新什么。一个标准的日志分析Agent节点可以这样写from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph def fetch_logs_from_es(state: AgentState): # 模拟从Elasticsearch获取error日志 query {size: 20, query: {term: {level: error}}} response es_client.search(indexapp-logs-*, bodyquery) log_list [hit[_source] for hit in response[hits][hits]] risk_level len(log_list) return { logs: log_list, risk_level: risk_level, next_step: analyze if risk_level 0 else end, }节点里做一些事查ES接口、整理数据、把结果写入State然后通过返回值更新状态。这里有个我踩过的坑不要在节点函数内部直接修改外部变量或全局dict所有状态变更都通过返回值完成。原因很简单LangGraph的state更新是有执行上下文管理的直接改外部变量会导致状态回放、并发执行时出现脏数据。2.3 条件路由、循环检测、子图与并行分支LangGraph的看家本领是conditional_edge。它实现的就是“根据当前状态走不同的边”def route_by_risk(state: AgentState): if state[risk_level] 10: return alert # 风险高走告警分支 elif state[risk_level] 0: return analyze # 有日志走分析分支 else: return end # 无异常结束流程 graph.add_conditional_edges( fetch, route_by_risk, { alert: send_alert, analyze: analyze_logs, end: finish, } )这里我重点说三个实战细节循环检测。LangGraph的图是允许存在环的一个节点通过条件边可以绕回自身这是做Agent多轮工具调用最核心的机制。但环不设上限就是灾难尤其在LLM接口出错时可能进入死循环。我常用的方案是在State里加一个计数器字段路由函数里判断如果超过最大轮数就直接走结束边。这就是实战里说的“循环检测”不是图自动检测而是你自己限定执行轮次。子图Subgraph。当一个图的规模变大之后把一部分逻辑抽成子图是保持可维护性的关键。LangGraph的子图用法就是把一个编译好的graph当作另一个graph里的节点。比如我可以做一个“日志分析子图”包含查询、分类、告警三个节点然后在主图里直接调用它。子图的好处是隔离复杂度而且可以单独调试。并行分支。一些节点之间没有依赖关系可以用fan-out/fan-in结构并行执行。LangGraph里可以在一个节点返回后分裂成多个并行路径最后汇聚到同一个节点。我自己用下来这个功能做“多数据源同时采集”特别合适。3. n8n实战从零搭一个可落地的AI Agent工作流3.1 n8n安装与初始化n8n上手最舒服的一点是部署足够简单有Docker环境的话直接跑容器docker run -it --rm \ --name n8n \ -p 5678:5678 \ -v n8n_data:/home/node/.n8n \ -e GENERIC_TIMEZONEAsia/Shanghai \ -e TZAsia/Shanghai \ n8nio/n8n这里有几个配置细节-v n8n_data:/home/node/.n8n持久化数据卷工作流和Credentials都存这里容器删了数据不能丢。-e GENERIC_TIMEZONEAsia/Shanghai时区必须设置否则定时触发器Schedule Trigger会按UTC时间执行早上8点变成下午4点。端口默认5678浏览器访问http://localhost:5678进入工作流界面。如果你要部署到服务器供团队使用建议走官方推荐的Docker Compose方案至少考虑三件事数据库用PostgreSQL而非默认的SQLite并发更强、配置N8N_ENCRYPTION_KEY防止重启后Credentials无法解密、通过反向代理加HTTPS。n8n的企业级部署方案里分布式执行器和工作队列是另一个话题中小团队先用Compose把SQLite换掉就够用了。3.2 Credentials配置是新手第一道坎n8n里把MCP、LangChain、HTTP请求需要的密钥都叫Credentials。很多新手在HTTP Request节点里直接写Header比如直接在Authorization里填Bearer xxx这么做虽然能跑通但极其不优雅——工作流导出分享时密钥直接泄露。正确的打开方式左侧菜单进入Credentials点Add Credential。选择类型。调用OpenAI是OpenAI类型调用内部接口选HTTP Header Auth类型或Basic Auth。在HTTP Header Auth里填写Header名称比如X-API-Key和值。保存后回到HTTP Request节点在Credential下拉框里选择刚才创建的凭据即可。n8n里针对LangChain相关节点还有单独的Chat Model Credential管理规则是一样的不要在工作流里写死密钥。我见过太多人把API Key直接放在Webhook响应体里这个必须避免。3.3 一个案例日志异常检测到企业微信告警的完整链路n8n里搭一条AI Agent工作流典型场景是Webhook接收系统上报的数据 - LLM判断是否异常 - 异常则发送企业微信通知。步骤拆开Webhook节点生成一个测试URL用来接收外部系统的POST请求。比如让日志系统把错误日志POST到这个地址。Code节点把Webhook传入的数据做预处理提取message字段、时间戳、来源系统。LangChain节点或AI Agent节点把预处理后的日志信息交给LLM提示词是“你是运维专家判断以下日志是否需要告警只返回json{needsAlert: bool, reason: string, level: string}”。IF节点判断LLM返回的needsAlert是否为true。企业微信节点条件为真时调用企业微信机器人Webhook发送告警内容。这条工作流全程不用写代码除了Code节点里的几行预处理而且每步执行日志都可以在n8n的Executions里看到排查问题很直观。这里说一个n8n里的关键语法坑表达式。n8n的节点之间传数据靠$json。上一个节点的输出如果是个数组引用时要写成{{ $json[message] }}如果在IF节点判断字段字段名要参考节点输出面板里的实际结构。遇到取不到值的情况最快的办法是在Code节点里console.log($json)打印完整结构。3.4 n8n的常见痛点Webhook地址在本地无法被外网访问。n8n有tunnel转发n8n tunnel命令但免费限制比较多。做开发联调时建议用ngrok之类做临时映射生产环境一定要有公网HTTPS地址。执行历史里报401。几乎都是Credentials没配好或Header名不对。用Postman先手测一下接口确认Header格式再去n8n里配。循环遍历数据集合速度慢。n8n的Loop Over Items节点是串行执行数据量大时性能很差。能用Split Out 并行执行的场景尽量别用循环。4. Dify本地部署与知识库流水线业务侧搭Agent的正确姿势4.1 本地部署与初始化Dify社区版是目前主流的开源LLM应用平台本地部署的好处是数据不出内网、模型Key统一管理、流程可控。部署过程不复杂Dify官方提供了docker-compose文件。核心步骤git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env # 按需修改.env中的关键项 docker compose up -d.env文件里必改的几个配置项是SECRET_KEY生成一个随机字符串用于会话加密。不更换默认值会有安全风险。APP_WEB_URL改成你的实际访问域名否则分享链接和部分回调不对。POSTGRES_USER、POSTGRES_PASSWORD默认密码要改掉。如果你要基于容器部署多租户Dify社区版1.10开始支持多租户能力的配置需要检查ENABLE_ORGANIZATION这类开关。启动后浏览器访问http://localhost/install创建管理员账号就能进入工作台。注意Dify的在线升级在Windows环境偶尔会遇到容器卷权限问题。我的做法是升级前先docker compose down再拉新镜像同时备份docker目录下的volumes避免升级失败导致知识库索引丢失。4.2 知识库流水线搭建从文档到可检索的五个环节Dify被用得最多的功能就是知识库RAG。很多人以为建知识库就是上传文档点一下“完成”其实一个完整知识库流水线包含五个环节文档加载Dify支持PDF、Word、Markdown、TXT、HTML等格式也支持从Notion同步。分段把长文档切分为小块。切分粒度直接影响检索效果Dify里可以设置分段长度Token数和重叠长度。我的经验是默认500-800 Token一段够用但如果文档结构强如产品手册的章节建议用“自定义分段标识符”切分避免把一个操作步骤从中间截断。Embedding把文本段转化为向量。在Dify的模型供应商里配置Embedding模型推荐用text-embedding-3-small或BGE系列。Embedding模型的选择要和检索效果一起评估不同模型对中文的语义理解差异很大。索引构建Dify会为每个分段生成向量索引同时支持关键词索引。检索与重排应用侧可以选择检索模式。默认的“向量检索”只算相似度“全文检索”基于关键词“混合检索”两者结合。我最推荐的是混合检索 Rerank重排。Rerank模型会对初筛结果做二次排序明显提升准确率代价是增加一点延迟。我实际经验里最大的坑是“分段不合理”。之前把一份企业制度文档按固定长度硬切结果上下文被切碎检索到的片段语义完全不对。改成按“标题层级段落”切分后效果立刻改善。4.3 Agent模式与工作流模式怎么选Dify里有两类核心应用Agent模式和Workflow工作流模式。Agent模式更适合开放式对话和工具调用。你把一堆工具自定义API、知识库检索、模型能力挂给Agent然后让LLM自己决定调用顺序。比如“日志分析Assistant”就是把ES的REST API封装成自定义工具然后让Agent在对话中按需查询。Workflow模式更适合固定流程。比如“日报生成”流程是固定的获取数据 - 总结 - 发送。用工作流编排每一步清晰可见非技术同事也能改。这里有个实用建议Dify的Agent里可以嵌套调用工作流工作流节点里也可以调用Agent。我做复杂问答系统的时候通常外层是Workflow来控制顺序先查知识库再做情绪判断内层用Agent处理开放问题这样兼顾稳定性和灵活度。4.4 Dify通过ES REST API做日志分析的实践结合热词里那条“AI Agent通过ES REST API智能分析日志”说一个我在Dify里比较成功的方案。Dify的自定义工具本质上就是OpenAPI Schema描述的一组HTTP请求。做法是在插件/工具里创建一个OpenAPI工具把ES的_search接口包进来paths: /es_log_search: get: operationId: searchLogs summary: 查询ES日志 parameters: - name: index in: query required: true schema: type: string - name: q in: query required: true schema: type: string responses: 200: content: application/json: schema: type: object然后在Agent提示词里写清楚“当用户询问错误日志时调用searchLogs工具索引填app-logs-*关键词从用户问题提取”。这样Agent就能自主完成ES日志查询和分析。我踩过的坑ES返回的JSON结构比较深hits.hits._sourceLLM有时解析不准。解决办法是在工具的输出描述里显式注明“返回结构为hits.hits下每个元素的_source字段包含message、timestamp、level字段”并且把返回结果用Code节点Dify内置代码工具做一层扁平化再交给LLM。一次性查询准确率从七成提升到九成以上。5. 三套方案核心对比与选型建议维度LangGraphn8nDify产品定位代码级Agent编排框架自动化工作流平台LLM应用开发平台目标用户程序员、算法工程师运维、业务开发、自动化爱好者产品、业务、算法团队状态管理原生State灵活但需代码维护JSON字段传递靠节点连线管理上下文变量可视化维护条件分支最强支持任意图结构用IF/Switch节点实现够用有分支节点但复杂逻辑有限循环与递归原生支持可自循环、子图支持Loop串行性能一般有限支持复杂循环不推荐RAG/知识库需要自己组装检索链路有向量存储节点但工程能力弱开箱即用体验最完善可观测性需要自己接日志和追踪有Execution历史和调试面板完整日志、标注、复盘面板部署方式作为代码库集成到现有项目Docker/云版可私有化Docker/云版社区版可私有化上手门槛高需要Python/图论思维中可视化拖拽低业务人员也能上手典型场景复杂对话Agent、多工具编排系统间数据同步、定时任务、告警知识问答、RAG应用、内部AI助手选型建议很直接如果你是个写代码的人核心诉求是自由度和可控性选LangGraph。它不会限制你任何结构代价是所有可视化能力都需要自己搭。如果你的核心诉求是把现有系统串起来比如CRM、数据库、邮件、IM机器人之间的自动化选n8n。它做的是事件驱动集成不是AI编排。如果你的核心诉求是快速交付一个AI应用给业务用比如内部知识库问答、文档摘要、客服机器人选Dify。如果你的团队都想要那也不用纠结Dify做前端应用和知识库LangGraph做底层复杂Agent服务n8n做周边自动化连接三者各司其职是目前大型项目里很常见的技术组合。6. 常见问题与排查技巧实录问题现象根本原因排查思路与解决方案LangGraph图执行不终止图里存在循环但没有上限在State中增加计数器路由函数判断最大值后走ENDLangGraph节点返回值不是预期值多个节点写同一字段被覆盖用Annotated[list, add_messages]合并策略或改用不同字段名LangGraph子图内状态不共享子图State和父图State未合并子图构造时需要显式声明StateSchema与父图字段兼容n8n HTTP请求报401Credential未配置或Header名错误先用Postman测通接口再创建Credential并在节点关联n8n表达式取到undefined节点输出结构不是预期对象在Code节点里打印$json逐层确认字段路径n8n定时任务时间不对容器时区未设置设置TZAsia/Shanghai环境变量后重建容器Dify知识库检索结果不准分段粒度不合理或未加Rerank按文档结构自定义分段检索方式改为混合检索RerankDify升级后登录异常SECRET_KEY或数据库不匹配升级前备份volumes确认.env的SECRET_KEY不变Agent调用ES工具返回解析失败返回结构嵌套过深在Dify里用代码节点做数据扁平化再交给LLMDify多租户相关选项不生效版本旧或环境变量未开启升级到社区版1.10检查对应环境变量与安装文档这里特别提醒一点任何Agent框架日志和追踪都极其重要。LangGraph里我习惯给每个节点做输入输出日志n8n已经内置了Execution历史Dify自带完整日志。排查问题的时候先看数据在哪一步断了再去看Prompt对不对最后才是看代码逻辑。7. 从选型思维到Agent开发进阶路径如果你是一个想入行AI Agent开发的人我建议的进阶路线是先学会LangChain的基本概念模型调用、工具定义、记忆再学LangGraph的状态图和条件路由然后掌握RAG知识库的基本方法最后选一个业务场景从头到尾做一个完整Agent。这些基础打牢之后再来用Dify或n8n会觉得它们只是“把繁琐的部分封装成了界面”。实际开发中一个经常被忽略的点Agent的质量上限取决于工具定义和数据质量。模型再强如果ES返回的数据是脏的、字段含义不清晰Agent也分析不出什么有价值的结果。所以我在日志分析类项目里花了大量精力在写工具的OpenAPI描述和返回字段注释Prompt反而只用了几行。这一点很值得后来者借鉴。另外“AI Agent 2026发展趋势”这类话题在社群一直很热但作为工程师我觉得与其追概念不如把已经成熟的能力吃透条件路由、循环控制、子图复用、RAG检索优化、多工具协同。这些技术点不会因为框架更新而过时。这三套工具里LangGraph、n8n、Dify各解决一块问题。我自己实际项目里的体会是它们不是对手而是不同工种之间的协作工具——Dify让业务侧能自助搭AI应用n8n把AI和现有系统之间的数据管道拉通LangGraph在底层支撑着真正复杂的Agent大脑。搞清楚“谁在执行、谁在维护、谁在改逻辑”这三个问题选型自然就清晰了。希望这篇对你有用。