做h网站怎么才能安全,微信引流主动被加软件,我怎么自己创建微信公众号,html代码翻译器在大模型#xff08;LLM#xff09;从“聊天玩具”迈向“生产力引擎”的进程中#xff0c;如何可靠地指挥 AI 完成多步骤、多工具、带反馈的复杂任务#xff0c;已成为构建下一代智能系统的核心挑战。早期的 Prompt 工程和单轮调用已显乏力#xff0c;而真正的智能体…在大模型LLM从“聊天玩具”迈向“生产力引擎”的进程中如何可靠地指挥 AI 完成多步骤、多工具、带反馈的复杂任务已成为构建下一代智能系统的核心挑战。早期的 Prompt 工程和单轮调用已显乏力而真正的智能体Agent需要具备规划、执行、反思与协作的能力——这催生了对可编程、可调试、可扩展的 Agent 编排框架的迫切需求。在此背景下LangGraph 应运而生。作为 LangChain[上一篇文章已经介绍过] 生态中面向状态化、循环化工作流的官方解决方案LangGraph 以有向图State Graph 为核心抽象赋予开发者对 Agent 控制流的精细掌控力尤其适合构建具备记忆、分支与回溯能力的复杂智能体。与此同时低代码可视化平台如 n8n 和 Dify 也迅速崛起它们通过拖拽式界面大幅降低 AI 自动化门槛让非技术人员也能参与智能流程的设计。然而图形化是否意味着“一切皆可拖拽”当 Agent 逻辑日益复杂可视化工作流在灵活性、可观测性与工程化方面是否面临天花板本文将系统介绍 LangGraph 的核心概念与基本用法对比分析 n8n 与 Dify 在 AI Agent 场景中的能力边界并客观探讨可视化低代码范式在构建生产级智能体时所面临的挑战与权衡——旨在帮助开发者在“效率”与“控制力”之间找到属于自己的平衡点。一、LangGraphLangGraph is alow-level orchestration frameworkand runtime for building, managing, and deploying long-running, stateful agents。LangGraph中最重要的两个概念是Node和StateNode通过edge链接形成一个可执行的workflowState是整个workflow的Context上下文这是一个典型的Procedure Context上下文设计模式。基本所有的框架都会使用使用上下文模式因为处理信息需要上下文而且这些信息需要在不同Node之间传递。接下来我们以一个自动处理用户邮件的AI Agent为例来演示LangGraph的使用和主要概念需求是要借助AI的能力智能处理用户的email其主要处理流程如下阅读收到的客户邮件根据紧急程度和主题进行分类搜索相关文档以回答问题起草适当的回复将复杂问题升级给人工客服处理处理完成后存档用户请求基于LangGraph构建应用首先我们要对问题进行结构化分解把每一个处理单元作为一个节点同时想清楚需要在不同Node之间共享数据的State。于以上分析本应用的功能实现代码如下import functoolsfrom typing import TypedDict, Literalimport psycopgfrom langgraph.checkpoint.postgres import PostgresSaverfrom langgraph.store.postgres import PostgresStorefrom mermaid_image import generate_mermaid_image_advanced# Define the structure for email classification# This is using output format for Classification purposeclass EmailClassification(TypedDict): intent: Literal[question, bug, billing, feature, complex] urgency: Literal[low, medium, high, critical] topic: str summary: strclass EmailAgentState(TypedDict): # Raw email data email_content: str sender_email: str email_id: str # Classification result classification: EmailClassification | None # Raw search/API results search_results: list[str] | None # List of raw document chunks customer_history: dict | None # Raw customer data from CRM # Generated content draft_response: str | None messages: list[str] | Nonefrom typing import Literalfrom langgraph.graph import StateGraph, START, ENDfrom langgraph.types import interrupt, Commandfrom langchain.messages import HumanMessagefrom deepseek_model import llmdef read_email(state: EmailAgentState) - dict: Extract and parse email content # In production, this would connect to your email service return { messages: [HumanMessage(contentfProcessing email: {state[email_content]})] }def classify_intent(state: EmailAgentState) - Command[ Literal[search_documentation, human_review, bug_tracking]]: Use LLM to classify email intent and urgency, then route accordingly # Create structured LLM that returns EmailClassification dict structured_llm llm.with_structured_output(EmailClassification) # Format the prompt on-demand, not stored in state classification_prompt f Analyze this customer email and classify it: Email: {state[email_content]} From: {state[sender_email]} Provide classification including intent, urgency, topic, and summary. # Get structured response directly as dict classification structured_llm.invoke(classification_prompt) # Determine next node based on classification if classification[intent] billing or classification[urgency] critical: goto human_review elif classification[intent] in [question, feature]: goto search_documentation elif classification[intent] bug: goto bug_tracking else: goto draft_response # Store classification as a single dict in state return Command( update{classification: classification}, gotogoto )def search_documentation(state: EmailAgentState) - Command[Literal[draft_response]]: Search knowledge base for relevant information # Build search query from classification classification state.get(classification, {}) query f{classification.get(intent, )} {classification.get(topic, )} try: # Implement your search logic here # Store raw search results, not formatted text search_results [ Reset password via Settings Security Change Password, Password must be at least 12 characters, Include uppercase, lowercase, numbers, and symbols ] except Exception as e: # For recoverable search errors, store error and continue search_results [fSearch temporarily unavailable: {str(e)}] return Command( update{search_results: search_results}, # Store raw results or error gotodraft_response )def bug_tracking(state: EmailAgentState) - Command[Literal[draft_response]]: Create or update bug tracking ticket # Create ticket in your bug tracking system ticket_id BUG-12345 # Would be created via API return Command( update{ search_results: [fBug ticket {ticket_id} created], current_step: bug_tracked }, gotodraft_response )def draft_response(state: EmailAgentState) - Command[Literal[human_review, send_reply]]: Generate response using context and route based on quality classification state.get(classification, {}) # Format context from raw state data on-demand context_sections [] if state.get(search_results): # Format search results for the prompt formatted_docs \n.join([f- {doc} for doc in state[search_results]]) context_sections.append(fRelevant documentation:\n{formatted_docs}) if state.get(customer_history): # Format customer data for the prompt context_sections.append(fCustomer tier: {state[customer_history].get(tier, standard)}) # Build the prompt with formatted context draft_prompt f Draft a response to this customer email: {state[email_content]} Email intent: {classification.get(intent, unknown)} Urgency level: {classification.get(urgency, medium)} {chr(10).join(context_sections)} Guidelines: - Be professional and helpful - Address their specific concern - Use the provided documentation when relevant response llm.invoke(draft_prompt) # Determine if human review needed based on urgency and intent needs_review ( classification.get(urgency) in [high, critical] or classification.get(intent) complex ) # Route to appropriate next node goto human_review if needs_review else send_reply print(fDraft response: {response.content}) return Command( update{draft_response: response.content}, # Store only the raw response gotogoto )def human_review(state: EmailAgentState) - Command[Literal[send_reply, END]]: Pause for human review using interrupt and route based on decision classification state.get(classification, {}) # interrupt() must come first - any code before it will re-run on resume human_decision interrupt({ email_id: state.get(email_id, ), original_email: state.get(email_content, ), draft_response: state.get(draft_response, ), urgency: classification.get(urgency), intent: classification.get(intent), action: Please review and approve/edit this response }) # Now process the humans decision if human_decision.get(approved): return Command( update{draft_response: human_decision.get(edited_response, state.get(draft_response, ))}, gotosend_reply ) else: # Rejection means human will handle directly return Command(update{}, gotoEND)def send_reply(state: EmailAgentState) - Command[Literal[save_user_request]]: Send the email response # Integrate with email service print(fSending reply: {state[draft_response][:100]}...) return Command( gotosave_user_request )def save_user_request(state: EmailAgentState, store: PostgresStore) - dict: # 从state中获取email_id和classification数据 email_id state.get(email_id) classification_data state.get(classification) # 检查必要数据是否存在 if email_id and classification_data: try: # 使用store的put方法保存数据 # 将email_id作为键classification_data作为值 store.put((user_requests,), email_id, classification_data) print(f成功保存用户请求邮件ID: {email_id}, 分类信息: {classification_data}) except Exception as e: # 捕获并打印可能发生的异常 print(f保存用户请求时出错: {e}) else: # 如果缺少必要数据打印警告信息 print(f无法保存请求缺少email_id或classification数据。State: {state}) # 返回原始state或者根据需要返回修改后的state return {}from langgraph.types import RetryPolicyDB_URI postgresql://postgres:1314520localhost:5432/Test?sslmodedisablewith ( PostgresStore.from_conn_string(DB_URI) as store, PostgresSaver.from_conn_string(DB_URI) as checkpointer,): store.setup() checkpointer.setup() # Create the graph workflow StateGraph(EmailAgentState) # Add nodes with appropriate error handling workflow.add_node(read_email, read_email) workflow.add_node(classify_intent, classify_intent) # Add retry policy for nodes that might have transient failures workflow.add_node( search_documentation, search_documentation, retry_policyRetryPolicy(max_attempts3) ) workflow.add_node(bug_tracking, bug_tracking) workflow.add_node(draft_response, draft_response) workflow.add_node(human_review, human_review) workflow.add_node(send_reply, send_reply) workflow.add_node(save_user_request, functools.partial(save_user_request, storestore)) # Add only the essential edges workflow.add_edge(START, read_email) workflow.add_edge(read_email, classify_intent) workflow.add_edge(send_reply, save_user_request) workflow.add_edge(save_user_request, END) app workflow.compile(checkpointercheckpointer, storestore) # generate graph generate_mermaid_image_advanced(app.get_graph().draw_mermaid()) # Test with an urgent billing issue initial_state { email_content: i want to return the computer i bought last month, this is urgent, sender_email: customerexample.com, email_id: email_123, messages: [] } # Run with a thread_id for persistence config {configurable: {thread_id: customer_345}} result app.invoke(initial_state, config) # The graph will pause at human_review print(fhuman review interrupt:{result[__interrupt__]}) # When ready, provide human input to resume from langgraph.types import Command human_response Command( resume{ approved: True, } ) # Resume execution final_result app.invoke(human_response, config) print(fEmail sent successfully!)二、Persistence关于持久化我在langchain中已经介绍过了我们常用的持久化有内存InMemorySaver数据库PostgresSaverRedis等在本示例中我们使用的是Postgres数据库相关代码是with ( PostgresStore.from_conn_string(DB_URI) as store, PostgresSaver.from_conn_string(DB_URI) as checkpointer,): store.setup() checkpointer.setup() #... app workflow.compile(checkpointercheckpointer, storestore)三、CheckpointThe checkpointer usesthread_idas the primary key for storing and retrieving checkpoints. Checkpoints are persisted and can be used to restore the state of a thread at a later time.在运行过我们的demo之后我们会看到如下的数据库记录记录了每个node在执行后产生的state数据变化也就是snapshot以及checkpoint相关的metadata。Checkpoint使得人工介入interrupt或者失败重试成为可能当我们需要从一个已知的checkpoint继续我们未完成的task时我们可以用下面的方式# 从当前状态继续执行 config_with_checkpoint { configurable: { thread_id: test-1, # 任务唯一标识 checkpoint_id: 1f0da204-f949-664a-bfff-3c4d4c4acfd1 # 需要断点继续的checkpointId } } # 继续执行 result await app.ainvoke( None, # 不需要输入从检查点继续 configconfig_with_checkpoint )然而天下没有免费的午餐高级功能的背后必有代价如果我们查看第二步classify_intent的Checkpoint的内容你会看到如下信息{ v: 4, id: 1f0da205-29f1-672c-8002-d2a1d71bd4ae, ts: 2025-12-16T01:41:20.84518800:00, versions_seen: { __input__: {}, __start__: { __start__: 00000000000000000000000000000001.0.8181195432664937 }, read_email: { branch:to:read_email: 00000000000000000000000000000002.0.9889639973936442 }, classify_intent: { branch:to:classify_intent: 00000000000000000000000000000003.0.10211870765000752 } }, channel_values: { email_id: email_123, sender_email: customerexample.com, email_content: i want to return the computer i bought last month, this is urgent, branch:to:bug_tracking: null }, channel_versions: { email_id: 00000000000000000000000000000002.0.9889639973936442, messages: 00000000000000000000000000000003.0.10211870765000752, __start__: 00000000000000000000000000000002.0.9889639973936442, sender_email: 00000000000000000000000000000002.0.9889639973936442, email_content: 00000000000000000000000000000002.0.9889639973936442, classification: 00000000000000000000000000000004.0.4645694893583696, branch:to:read_email: 00000000000000000000000000000003.0.10211870765000752, branch:to:bug_tracking: 00000000000000000000000000000004.0.4645694893583696, branch:to:classify_intent: 00000000000000000000000000000004.0.4645694893583696 }, updated_channels: [ branch:to:bug_tracking, classification ]}LangGraph为了保证工作流的可恢复可中断使用了版本控制信息确保确定性重放和避免重复计算。实现这些“需求”给系统添加了很大的复杂度我第一眼看到这些versions信息时是一头雾水不知所云。另外每一个node执行都会产生如此多的数据规模大了数据存储也将是个不小的问题。四、InterruptInterrupt主要用于人工介入的场景比如我们示例中的human_review节点就是典型的人工介入场景当interrupt( )被掉用的时候整个workflow会暂定执行直到接受到新的指令Command才能决定下一步的动作。其相关代码如下def human_review(state: EmailAgentState) - Command[Literal[send_reply, END]]: Pause for human review using interrupt and route based on decision classification state.get(classification, {}) # interrupt() invokedworkflow will pause herewaiting for humans decision Command human_decision interrupt({ email_id: state.get(email_id, ), original_email: state.get(email_content, ), draft_response: state.get(draft_response, ), urgency: classification.get(urgency), intent: classification.get(intent), action: Please review and approve/edit this response }) # resume to process the humans decision if human_decision.get(approved): return Command( update{draft_response: human_decision.get(edited_response, state.get(draft_response, ))}, gotosend_reply ) else: # Rejection means human will handle directly return Command(update{}, gotoEND)在human_review这个节点中整个工作流会在human_decision之后暂停在执行下面代码之后。config {configurable: {thread_id: customer_345}} human_response Command( resume{ approved: True, } ) # Resume execution final_result app.invoke(human_response, config)相当于给human_decision添加了新的变量approved: True这样workflow会按照命令走到send_reply否则就直接结束了。以上就是LangGraph的基本使用和核心概念的解释对于这个简单的应用还有一种更容易的实现方式就是使用可视化的低代码平台。五、可视化工作流随着AI兴起可用于 AI Agent 可视化工作流编排 的工具正在快速发展这些工具帮助开发者以图形化方式设计、调试和部署基于大语言模型LLM的智能体Agent支持 多步推理、工具调用、记忆、条件分支、循环 等能力。可视化的低代码工作流编排工具、平台有很多不管是通用的低代码的自动化工作流编排工具n8n发音 “n-eight-n”还是面向 AI 应用开发的低代码平台专注于构建、部署和运营基于大语言模型LLM的 AI 应用的Dify。它们的形态都是大同小异就是通过UI界面拖拖拽拽搞出一个Agent应用来。对于我们客户邮件支持系统示例如果要用n8n实现的话我们可以在其UI界面上通过选择不同的节点连线形成一个如下的workflow其实现的功能和我们通过一堆基于LangGraph代码实现的功能类似。实际上低代码也好工作流也好并不是什么新鲜玩意。“工作流” 本是上世纪 BPM业务流程管理的旧题。在AI兴起之前为了提升“研发效率”业界早就进行了无数次尝试只是鲜有成功案例而已其原因就在于这玩意也只能搞搞demo一旦遇到复杂的生产场景就会碰到Low Code Ceiling问题一不小心就会陷进万劫不复的深渊。关于这一点想一下阿里的中台就明白了。适用场景推荐使用不适用场景慎用或需结合代码快速构建 PoC / MVP高性能、低延迟的生产系统规则明确的线性/分支流程复杂动态逻辑如强化学习式决策AI SaaS 工具集成邮件、CRM、数据库需深度定制 LLM 推理逻辑团队协作、非技术成员参与设计需要严格测试覆盖和审计中低频任务如客服、内部工具高并发、关键业务系统如金融交易六、太阳底下无新事“太阳底下无新事”——无论是 LangGraph 的状态图、n8n 的节点连线还是 Dify 的可视化编排本质上都是对控制流与数据流这一古老计算范式的现代封装。它们以更友好的界面、更高的抽象层级降低了构建 AI Agent 的初始门槛让“人人皆可造智能体”成为可能。这无疑是进步也是普惠。然而抽象总有代价。当工作流从演示走向真实业务从日均百次调用迈向高并发、低延迟、强一致性的生产环境低代码的“甜蜜外衣”之下便显露出其结构性局限难以调试的黑盒逻辑、脆弱的错误传播链、缺失的工程化能力如灰度发布、性能压测、SLO 监控以及最关键的——无法突破的“low-code ceiling”。你无法用拖拽解决 Token 爆炸、无法用图形节点实现高效的并发工具调用更难在可视化界面中注入细粒度的安全审计或容灾回滚机制。因此作为公司的决策者特别是架构师或工程师请清醒地认识到低代码是探索的起点而非生产的终点。对于核心业务系统、关键客户交互、或任何对可靠性与可维护性有严苛要求的场景真正的答案仍藏在代码之中——通过 LangGraph 这类可编程框架结合严谨的软件工程实践才能构建出既智能又健壮的下一代 Agent 系统。毕竟再美的流程图也替代不了一个经过压力测试、日志完备、可被团队集体维护的代码库。如何学习大模型 AI 由于新岗位的生产效率要优于被取代岗位的生产效率所以实际上整个社会的生产效率是提升的。但是具体到个人只能说是“最先掌握AI的人将会比较晚掌握AI的人有竞争优势”。这句话放在计算机、互联网、移动互联网的开局时期都是一样的道理。我在一线互联网企业工作十余年里指导过不少同行后辈。帮助很多人得到了学习和成长。我意识到有很多经验和知识值得分享给大家也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限很多互联网行业朋友无法获得正确的资料得到学习提升故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。第一阶段10天初阶应用该阶段让大家对大模型 AI有一个最前沿的认识对大模型 AI 的理解超过 95% 的人可以在相关讨论时发表高级、不跟风、又接地气的见解别人只会和 AI 聊天而你能调教 AI并能用代码将大模型和业务衔接。大模型 AI 能干什么大模型是怎样获得「智能」的用好 AI 的核心心法大模型应用业务架构大模型应用技术架构代码示例向 GPT-3.5 灌入新知识提示工程的意义和核心思想Prompt 典型构成指令调优方法论思维链和思维树Prompt 攻击和防范…第二阶段30天高阶应用该阶段我们正式进入大模型 AI 进阶实战学习学会构造私有知识库扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架抓住最新的技术进展适合 Python 和 JavaScript 程序员。为什么要做 RAG搭建一个简单的 ChatPDF检索的基础概念什么是向量表示Embeddings向量数据库与向量检索基于向量检索的 RAG搭建 RAG 系统的扩展知识混合检索与 RAG-Fusion 简介向量模型本地部署…第三阶段30天模型训练恭喜你如果学到这里你基本可以找到一份大模型 AI相关的工作自己也能训练 GPT 了通过微调训练自己的垂直大模型能独立训练开源多模态大模型掌握更多技术方案。到此为止大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗为什么要做 RAG什么是模型什么是模型训练求解器 损失函数简介小实验2手写一个简单的神经网络并训练它什么是训练/预训练/微调/轻量化微调Transformer结构简介轻量化微调实验数据集的构建…第四阶段20天商业闭环对全球大模型从性能、吞吐量、成本等方面有一定的认知可以在云端和本地等多种环境下部署大模型找到适合自己的项目/创业方向做一名被 AI 武装的产品经理。硬件选型带你了解全球大模型使用国产大模型服务搭建 OpenAI 代理热身基于阿里云 PAI 部署 Stable Diffusion在本地计算机运行大模型大模型的私有化部署基于 vLLM 部署大模型案例如何优雅地在阿里云私有部署开源大模型部署一套开源 LLM 项目内容安全互联网信息服务算法备案…学习是一个过程只要学习就会有挑战。天道酬勤你越努力就会成为越优秀的自己。如果你能在15天内完成所有的任务那你堪称天才。然而如果你能完成 60-70% 的内容你就已经开始具备成为一名大模型 AI 的正确特征了。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】