ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LangChain与LangGraph企业级Agent实战:从Demo到生产落地

LangChain与LangGraph企业级Agent实战:从Demo到生产落地 LangChain 1.0 LangGraph 1.0 企业级 Agent 实战从手搓 Demo 到安全可控生产级落地如果你最近一年做过 Agent 类项目大概率经历过这段心路历程Demo 阶段一切都很美好模型能准确调用工具、能流利输出 Markdown、能跟用户多轮对话看起来很聪明。可一旦想把这个 Demo 变成真正能上线跑业务的服务你很快就发现横在你面前的是一堵看不见的墙。这堵墙不是“模型不够聪明”而是工程问题多个任务串联时状态在哪里管理中途失败怎么办工具调用完全依赖模型的“临场发挥”怎么保证不越权、不乱调用户无意间触发了一个高权限操作系统能不能拦截线上 Agent 出了问题你能不能快速定位是哪一轮 Prompt 写错了还是哪个工具返回了脏数据每次升级 Prompt 或换模型如何灰度验证如何回滚换句话说Demo 阶段拼的是模型上限生产阶段拼的是工程下限。而 LangChain 1.0 和 LangGraph 1.0 的推出本质上就是把“工程下限”用一套标准框架托起来。本文不打算讲花哨的 Demo而是直接从企业级落地视角出发拆解以下四件事LangChain 1.0 和 LangGraph 1.0 到底是什么关系各自解决什么问题。如何用 LangGraph 构建一个带条件路由、子图、并行分支和人工审批的可控 Agent。如何通过 MCP 协议统一接入企业内外部工具告别一家一个 SDK。如何用 Langfuse 这类可观测工具把 Agent 的每一次调用链路、Token 消耗、成本和质量全部记录下来。1. 为什么企业级 Agent 不能靠手搓先看一个常见场景客服工单自动处理。你计划让 Agent 收到用户消息后先判断用户意图然后查知识库再调用 CRM 系统查询订单状态最后生成回复。如果用户要求退换货还需要进入审批流程。用最简单的“手搓”方式你会写成什么样很多人的第一版是这种范式在 Python 循环里让 LLM 反复调用工具。while True: response llm.invoke(messages tool_results) if response.tool_calls: for tool_call in response.tool_calls: tool_results.append(run_tool(tool_call)) continue break这段代码跑通一个“模型自己决定调用哪些工具”的流程并不难但它的问题非常致命没有显式状态。多轮对话的上下文、中间结果、分支状态全靠一个 messages 数组和外部变量硬撑。一旦流程复杂代码就变成意大利面条。没有边界控制。模型想调多少次工具就调多少次可能陷入死循环也可能在无人监督时执行了危险操作。没有恢复能力。某一步 API 超时或返回异常整个会话就废了想重试某一步、跳过某一步需要一个一个补 Case。没有可观测性。线上出问题时你根本不知道模型为什么做出这个决定异常发生前模型看到了什么、工具返回了什么全是黑盒。没有复用性。每个新场景都要复制一套 while 循环团队里每个人的写法还不一样代码质量全靠自觉。这些不是“代码写得差”的问题而是用通用编程范式硬建模 Agent 工作流时必然暴露的结构性缺陷。Agent 运行的本质不是一段顺序代码而是一个有状态、可分支、可循环、可中断、可恢复的状态机。你需要的不是手写 while 循环而是一个能编排状态机的框架。LangGraph 1.0 就是为此而生的。2. LangChain 1.0 与 LangGraph 1.0分工、定位与关系先说结论LangChain 和 LangGraph 不是同一个东西也不该把它们当成“同一个框架的旧版和新版”来选。两者是互补关系LangChain 管“零件”LangGraph 管“装配线”。很多初学者会把两者搞混因为 LangChain 生态里也在推 Agent 概念。但从 1.0 版本开始定位已经非常清晰维度LangChain 1.0LangGraph 1.0核心定位大模型应用开发工具链提供模型封装、Prompt 管理、输出解析、工具接口、Memory 抽象等“标准零件”有状态、可编排的 Agent 运行时基于图结构编排节点、边、状态、循环和恢复逻辑解决的核心痛点让开发者以统一方式接入不同模型、不同工具、不同向量库减少重复封装让复杂的 Agent 工作流变得可控、可调试、可恢复能跑进生产环境工作方式提供可组合的组件LLM、Retriever、Tool、Memory通过 StateGraph 定义节点与边编译成可执行的状态机最大价值生态标准降低集成成本架构控制保证流程可靠适合场景快速原型、简单 RAG、工具封装、模型切换多步骤任务编排、条件路由、循环控制、人工介入、并行执行运行时代应用层组件库独立的图执行引擎你可以在 LangGraph 的节点内部使用 LangChain 的模型封装、Retriever、Tool 对象也可以在 LangChain 的 AgentExecutor 之外用 LangGraph 完全接管编排逻辑。它们不是替代关系而是不同层次的协作关系。这里有必要解释一个常见的误读“LangChain 过时了吗大家都在说 LangGraph。”LangChain 1.0 在 2025 年已经发布了正式稳定版本核心价值在于依赖标准化和生态整合。你可以不用 LangChain自己写 OpenAI SDK 调用也可以自己在 LangGraph 里用原生 HTTP 请求调模型。但一旦项目需要接入多个模型厂商、多个向量库、多个工具源LangChain 的工具类封装能让你的代码省掉大量样板。而 LangGraph 1.0 则是把“LangChain 时代最粗糙的部分”——AgentExecutor 的循环执行逻辑——升级成了可编程的图执行引擎。它保留了 LangChain 的组件生态同时把控制权和可见性完全交还给开发者。用一张通俗的图来理解LangChain 是“工具箱”里面有各种螺丝刀、扳手、电钻。LangGraph 是“装配流水线”它不生产工具但告诉你哪一步加工、哪一步检测、哪一步回流、哪一步放行。MCP 是“设备统一接口标准”不管电钻是博世的还是得伟的插头都换成同一个标准。Langfuse 是“车间监控系统”全程记录每个工位的运行状态、耗材用量和异常事件。这四者组合起来才是一个能上生产线的完整方案。3. 企业级 Agent 架构的三个关键层次从工程架构看一个能上生产的企业级 Agent 至少有五个层次接入层对话 API、事件回调、Webhook。编排层LangGraph 状态机负责意图识别、任务分解、路由、循环、重试、人工审批。工具层通过 MCP 协议统一接入知识库检索、订单查询、工单创建、支付、邮件等业务能力。模型层支持多模型切换大模型、小模型甚至本地模型强调可替换。可观测与治理层链路追踪、日志、Token 用量统计、成本核算、告警、审计。如果你只是写一个 Demo前三层可以糊在一起。但企业落地时每一层都有关键问题需要单独回答。下面这张表汇总了每个层次的核心关注点层次核心问题工具选型常见踩坑编排层流程是否可控能否中断与恢复LangGraph 1.0把业务逻辑硬编码进节点导致无法复用工具层是否容易接入新工具权限边界如何管控MCP 协议每接一个工具写一套 Adapter维护成本高模型层能否低成本切换模型供应商LangChain 1.0直接在代码里调用 OpenAI SDK换台成本巨大可观测层能否定位某次回答为什么出错Langfuse / Prometheus只记录日志不记录调用链路与 Token 用量治理层谁有权限调用高敏感性工具RBAC 审批节点所有操作都由模型自动执行无人工兜底接下来我从实操角度把这几个层次串起来。4. 环境准备与前置条件本文示例以 Python 3.10 为基础操作系统不限Windows / macOS / Linux 均可。为了可复现建议使用虚拟环境。先创建项目目录并安装依赖mkdir langgraph-enterprise-agent cd langgraph-enterprise-agent python -m venv .venv source .venv/bin/activate # Windows 使用 .venv\Scripts\activate安装核心依赖pip install langchain1.0.0 langchain-openai1.0.0 langgraph1.0.0 pip install langfuse mcp版本说明本文写作时 LangChain 1.0 和 LangGraph 1.0 均已发布正式版但 API 仍在快速演进。如果你看到的接口略有差异以官方文档为准。本文的核心思路是通用的不会因为一两个参数名称变化而失效。接着配置环境变量。新建一个.env文件生产环境建议使用基础设施的密钥管理服务不要写入代码仓库OPENAI_API_KEYsk-xxxx # Langfuse 可观测平台配置 LANGFUSE_PUBLIC_KEYyour-public-key LANGFUSE_SECRET_KEYyour-secret-key LANGFUSE_HOSThttps://cloud.langfuse.com如果没有 Langfuse 账号也可以先用本地环境变量占位后面第 8 节会讲如何处理。5. 实战用 LangGraph 构建企业级客服工单 Agent本节的示例是一个“客服工单自动处理 Agent”。它的业务逻辑如下用户提交一个问题或工单请求。系统先判断意图是“查询订单”还是“提交退换货申请”还是“普通咨询”。根据意图走不同分支查询订单调用订单查询工具这里用模拟函数代替。退换货申请进入子图流程需要调用退款策略检查、人工审批节点。普通咨询直接检索知识库并生成回复。所有工具调用和模型调用都会走 Langfuse 可观测链路。5.1 定义 Agent 状态LangGraph 的核心抽象是 State。你定义一个 TypedDictLangGraph 会在每一步节点执行后自动更新它。# state.py from typing import Annotated, TypedDict from langgraph.graph import add_messages class AgentState(TypedDict): messages: Annotated[list, add_messages] # 对话消息自动追加 user_id: str # 用户标识 intent: str # 分类结果order_query / return_request / general order_info: dict # 订单查询结果 return_policy: dict # 退换货策略结果 needs_human_approval: bool # 是否需要人工审批 final_answer: str # 最终回复这里的Annotated[list, add_messages]是 LangGraph 的 Reducer 语法每次节点返回新的消息列表时不是覆盖而是追加。这种设计非常关键——它让 Agent 的多轮对话状态在不污染业务状态的前提下自然累积。5.2 定义工具节点为了演示我们直接用普通 Python 函数模拟内部系统。企业接真实 API 时只需要把函数体替换为 HTTP 调用即可。# tools.py def query_order_api(user_id: str, order_id: str) - dict: 模拟订单查询接口 return { order_id: order_id, status: 已发货, delivery_company: 顺丰速运, tracking_no: SF1234567890 } def check_return_policy(order_id: str) - dict: 模拟退换货策略校验 return { order_id: order_id, allow_return: True, return_window_days: 7, notes: 商品未拆封可申请七天无理由退货 }这种“先把业务函数写出来再接入 LangGraph 节点”的开发方式对团队非常友好业务同学可以完全不知道 LangGraph 的存在只负责提供能力和数据Agent 编排交给另一批人来设计。5.3 定义节点函数每个 LangGraph 节点就是一个接收 state 并返回部分更新的普通函数。# nodes.py from state import AgentState def classify_intent(state: AgentState): 意图分类节点根据最新消息判断用户意图 # 生产环境建议用一个较小的、便宜的模型做分类 # 或者直接用结构化输出不占用主对话模型额度。 last_message state[messages][-1].content if 订单 in last_message or 物流 in last_message: intent order_query elif 退货 in last_message or 退换 in last_message or 退款 in last_message: intent return_request else: intent general return {intent: intent} def query_order(state: AgentState): 查询订单意图处理节点 # 实际项目中从消息里解析 order_id这里为了演示写死 user_id state.get(user_id, unknown) order_info query_order_api(user_id, order_idA1001) return { order_info: order_info, final_answer: f您的订单 {order_info[order_id]} 当前状态为{order_info[status]}快递公司{order_info[delivery_company]}运单号{order_info[tracking_no]}。 } def check_return_policy_node(state: AgentState): 退换货策略校验节点 policy check_return_policy(order_idA1001) # 高风险操作需要人工审批 return { return_policy: policy, needs_human_approval: True } def general_consult(state: AgentState): 普通咨询节点用一个较小的 LLM 直接回答 from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-4o-mini, temperature0.3) response llm.invoke(state[messages][-1].content) return {final_answer: response.content}这里的设计有个值得注意的工程思路把“业务逻辑”和“模型调用”拆开。分类节点、订单函数、策略校验都不需要大模型只有普通咨询才调用 LLM。这样做的好处非常实际——大部分简单任务不需要昂贵的大模型成本可以降到原来的五分之一甚至更低。5.4 配置条件路由、子图与并行分支现在进入 LangGraph 真正的强项把上面的节点编排成一张图。这里面涉及几个关键概念条件路由conditional edge根据当前状态决定下一步走向哪个节点。子图subgraph把一个复杂的流程封装成独立子图主图按需调用。并行分支某些查询之间没有依赖关系可以并行执行。人工审批节点在进入高权限操作前暂停等待人工确认。我们先用条件路由构造主流程# graph.py from langgraph.graph import StateGraph, START, END from nodes import ( classify_intent, query_order, check_return_policy_node, general_consult, human_approval ) from state import AgentState builder StateGraph(AgentState) # 添加节点 builder.add_node(classify_intent, classify_intent) builder.add_node(query_order, query_order) builder.add_node(check_return_policy, check_return_policy_node) builder.add_node(general_consult, general_consult) builder.add_node(human_approval, human_approval) # 从入口开始先分类 builder.add_edge(START, classify_intent) # 条件路由 builder.add_conditional_edges( classify_intent, lambda state: state[intent], { order_query: query_order, return_request: check_return_policy, general: general_consult, } ) # 退换货流程校验策略后先过人工审批节点 builder.add_edge(check_return_policy, human_approval) builder.add_edge(human_approval, END) # 查询订单和普通咨询直接结束 builder.add_edge(query_order, END) builder.add_edge(general_consult, END) # 编译图 agent_graph builder.compile()这段代码的逻辑非常直观图从 START 进入意图分类节点分类节点根据 intent 字段走三条不同分支。退换货分支多了一个人工审批节点确保高权限操作不会由模型自动放行。5.5 人工审批节点的实现这里要重点讲讲人工审批。企业级 Agent 和 Demo 的区别很大程度体现在这里。LangGraph 1.0 提供了interrupt机制当图执行到某个节点时可以暂停等待外部输入。这个过程在源码层面等价于“图执行到一个断点把当前状态持久化返回给调用方等待外部系统恢复”。# nodes.py 新增 from langgraph.types import interrupt, Command def human_approval(state: AgentState): 人工审批节点高权限操作前暂停等待审批 policy state.get(return_policy, {}) decision interrupt({ type: return_approval, order_id: A1001, allow_return: policy.get(allow_return), message: 用户申请退换货请确认是否放行 }) if decision approved: return { final_answer: 您的退换货申请已通过我们将在 24 小时内发送退货地址。, needs_human_approval: False } else: return { final_answer: 抱歉您的退换货申请未通过审核。, needs_human_approval: False }调用这个图时第一次执行会返回一个interrupt信号而不是最终结果。外部系统比如客服后台收到信号后负责人点击“同意”或“拒绝”再把决策作为Command(resume...)塞回去图会从暂停位置继续执行。这种设计带来的价值是革命性的你不需要把“是否允许退款”这种决策交给模型的概率输出而是让真实业务负责人来做终审。模型只负责信息整理和流程推进风险决策由人来拍板。5.6 子图把复杂流程封装成独立单元如果退换货流程特别复杂——需要检查订单状态、检查库存、计算退款金额、通知仓库——建议把整个过程封装成一个子图而不是在主图里铺满十几个节点。# return_subgraph.py from langgraph.graph import StateGraph, START, END from state import AgentState def check_stock(state: AgentState): return {return_policy: {**state.get(return_policy, {}), stock_available: True}} def calculate_refund(state: AgentState): refund_amount 199.00 return {return_policy: {**state.get(return_policy, {}), refund_amount: refund_amount}} return_builder StateGraph(AgentState) return_builder.add_node(check_stock, check_stock) return_builder.add_node(calculate_refund, calculate_refund) return_builder.add_edge(START, check_stock) return_builder.add_edge(check_stock, calculate_refund) return_builder.add_edge(calculate_refund, END) return_subgraph return_builder.compile()然后在主图里把check_return_policy节点替换为这个子图builder.add_node(return_subgraph, return_subgraph)子图可以复用、可以单独测试、可以单独灰度。这就是产品化思维在代码层面的体现。5.7 并行分支再来看并行分支。用户查询订单时如果系统里有多个独立数据源订单系统、物流系统、售后系统它们之间没有依赖关系完全可以并行调用而不是串行等待。LangGraph 的SendAPI 就是为这种场景设计的。它允许图在运行时动态创建多个并行“副本”from langgraph.types import Send def spawn_query_nodes(state: AgentState): 并行调用多个查询 return [ Send(query_order, {messages: state[messages], user_id: state[user_id]}), Send(query_logistics, {messages: state[messages], user_id: state[user_id]}), ]每一个 Send 生成的子任务会独立执行最后通过 reducer 合并结果。这在“一次用户请求后端查询多个数据源”的场景里非常实用可以把整体响应时间从多个接口串行之和压缩到其中最长的一个性能收益非常明显。6. LangGraph 1.0 核心机制条件路由、循环检测与状态恢复很多刚上手 LangGraph 的人会觉得“这不就是个流程图框架吗”。实际上真正让它区别于普通工作流引擎的是几个容易被忽视的机制。6.1 条件路由条件路由conditional_edges在上面已经用到了。它的本质是节点执行完之后系统读取当前状态执行你提供的路由函数根据返回值决定下一步进入哪个节点。这里容易犯一个新手错误路由函数里做太多业务逻辑比如去查数据库、调外部 API。路由函数应该是纯函数输入 state输出一个分支标识。否则每次状态变化时路由不可预测调试成本会直线上升。6.2 循环检测与上限Agent 工作流里经常出现循环模型发现信息不够需要反复调用工具检索。如果没有循环控制一个 BUG 就能让 Agent 在无限循环里烧掉大量 Token。LangGraph 里推荐的做法是给循环节点设置递归上限或者在状态里维护一个step_count计数器class AgentState(TypedDict): messages: Annotated[list, add_messages] step_count: int # 记录当前执行步数 def route_after_tool_call(state: AgentState): if state.get(step_count, 0) 5: return final_answer # 触发最大步数强制收尾 return continue_process生产环境下建议在 Agent 启动配置里设置一个全局的执行步数上限避免因模型输出异常导致长时间空转。6.3 Checkpoint状态持久化与恢复LangGraph 1.0 最重要的生产级能力之一是 Checkpoint。它会把每一轮图执行的状态持久化到存储中内存、SQLite、PostgreSQL 或 Redis 都可以这样Agent 中途崩溃可以从最近一个 Checkpoint 恢复。人工审批中断后可以跨进程恢复执行。每一步执行都可以被回放、分析、审计。启用方式非常简单编译的时候传入一个检查点器from langgraph.checkpoint.sqlite import SqliteSaver with SqliteSaver.from_conn_string(checkpoints.db) as saver: agent_graph builder.compile(checkpointersaver)这意味着你不需要自己写“把中途状态存数据库”的逻辑框架已经帮你处理好了。对于故障恢复、审计追溯来说这是整个链路里非常关键的一个能力建议企业落地时优先使用外部持久化存储而不是默认内存。7. 用 MCP 统一接入企业工具前面所有工具都是用普通 Python 函数模拟的。真实企业环境里工具可能散落在不同团队、不同系统、不同技术栈中有的是内部 HTTP API有的是 Kafka 消息有的是 SQL 查询有的是第三方 SaaS。如果每个工具都自己写一套调用逻辑团队很快就会被“工具适配代码”淹没。这时候就需要 MCPModel Context Protocol出场。MCP 是一个开放的工具接入协议目标是统一“模型与外部工具之间的通信方式”。通俗地说它就像 USB-C 接口——无论你内部实现是什么对外都暴露同一套标准协议Agent 侧只需要实现一个 MCP 客户端就能接入所有 MCP Server。7.1 用 FastMCP 写一个极简工具服务下面用 Python 实现一个最简 MCP Server暴露“查询订单”功能# mcp_order_server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(order-service) mcp.tool() def query_order(order_id: str) - dict: 查询订单状态。order_id 为订单编号。 # 这里替换为真实 HTTP 调用 return { order_id: order_id, status: 已发货, delivery_company: 顺丰速运 } if __name__ __main__: mcp.run()运行python mcp_order_server.py这个 Server 启动后其他 Agent 应用可以通过 MCP 标准协议发现并调用这个工具。7.2 MCP 与 Skill 的区别了解 Agent 生态的读者可能会困惑MCP 和 Skill技能比如 Claude Agent Skill有什么不同简单区分MCP 是“工具接入协议”解决的是“Agent 怎么调用外部系统能力”的问题重点是标准化通信。Skill 是“能力包”通常包含一段 Prompt、示例代码、知识文档等解决的是“Agent 应该怎样完成某类任务”的问题重点是行为模板。两者不是竞争关系可以组合使用用 Skill 定义“如何执行退换货流程”用 MCP 定义“如何调用订单系统”。7.3 LangGraph 节点中调用 MCP Server在 LangGraph 节点里调用 MCP Server本质上就是写一个 MCP 客户端# mcp_client.py from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def call_order_tool_via_mcp(order_id: str): server_params StdioServerParameters( commandpython, args[mcp_order_server.py] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() result await session.call_tool(query_order, {order_id: order_id}) return result当然生产环境更推荐的方案是用 LangChain 的 MCP Adapters 把 MCP Server 自动转换成标准的 LangChain Tool然后直接作为工具绑定到 Agent 上。具体 API 每个版本略有差异接入时以官方文档为准核心思路不变MCP Server 标准化对外暴露工具Agent 侧统一消费。7.4 MCP 在企业落地中的架构意义如果你们公司的 Agent 项目已经接了 5 个工具、10 个工具你一定会遇到一个现实问题每个工具返回的数据格式不一样鉴权方式不一样错误处理逻辑不一样。MCP 解决的是这一层的“重复造轮子”。工具提供方只需要维护一个 MCP Server对外发布标准协议Agent 消费方只需要实现一次客户端逻辑。新增一个工具时不需要改 Agent 代码只需要新增一个 MCP Server。这对中大型团队的好处尤其明显工具接入从“项目定制开发”变成了“服务注册发布”。你甚至可以做一个内部工具市场每个团队把自己的能力发布成 MCP ServerAgent 按需发现和调用。8. 全链路可观测Langfuse 实操Agent 上生产最大的挑战之一是排障。传统后端的问题可以靠日志、链路追踪解决但 Agent 的“链路”里包含模型调用、Prompt 内容、Token 数量、工具返回、路由决策、人工审批状态等特殊信息普通日志系统很难覆盖。Langfuse 是目前 Agent 可观测性生态里非常主流的方案。它提供 Prompt 版本管理、链路追踪、Token 用量统计、成本核算、质量评分等功能。8.1 接入 Langfuse接入方式非常轻量。以 OpenAI 模型调用为例from langfuse.callback import CallbackHandler from langchain_openai import ChatOpenAI langfuse_handler CallbackHandler( public_keyyour-public-key, secret_keyyour-secret-key, hosthttps://cloud.langfuse.com ) llm ChatOpenAI( modelgpt-4o-mini, temperature0.3, callbacks[langfuse_handler] )当 LangGraph 的节点内部使用这个 LLM 时所有调用链路会被自动记录。如果想让 LangGraph 整张图的执行过程都纳入追踪可以在图编译后调用时传入回调config { callbacks: [langfuse_handler], configurable: {thread_id: thread-001} } result agent_graph.invoke( {messages: [{role: user, content: 帮我查一下订单 A1001 的状态}]}, configconfig )8.2 你能从 Langfuse 里看到什么接入后Langfuse 的 trace 视图会展示一张完整调用链用户输入进入了哪个节点。模型收到的是什么 Prompt模型返回了什么。模型调用消耗了多少 Token花了多少钱。工具调用返回了什么数据。哪个环节出现了超时、异常或安全拦截。这张图执行到哪个节点被 interrupt 暂停等待人工审批。有了这些数据你在线上排查问题时就可以做到“回放现场”而不是靠瞎猜。8.3 成本治理企业里模型调用成本是真实的支出。Langfuse 的 Cost 分析可以按用户、按会话、按功能模块统计 Token 消耗和费用帮助你回答类似问题“哪个 Agent 流程最烧钱是不是 Prompt 里塞了太多上下文”“哪个用户贡献了最高的 Token 消耗是不是有人在刷接口”“升级模型版本后同样请求的成本变化了多少”这些数据是优化系统的重要依据。没有可观测性你都不知道钱花在哪了更谈不上优化。9. 安全可控权限、限流、审批与审计企业级 Agent 与个人 Demo 最后、也是最重要的一道分水岭是安全可控。模型再强也不能在没有边界约束的情况下直接操作生产系统。这里有几个必须考虑的安全设计9.1 最小权限原则不要让 Agent 直接持有一堆系统的完整 API Key。推荐做法是为 Agent 创建一个独立的服务账号只授予它执行特定操作的最小权限。比如查订单的 Agent就不能同时有删除订单、修改价格的权限。MCP Server 本身也是一层很好的权限边界你可以让某个 MCP Server 只暴露查询接口不暴露写入接口。9.2 工具白名单与操作分类在 LangGraph 节点设计时建议把工具操作分为“只读操作”和“写操作”两类只读操作查询订单、查天气、搜文档可以由模型自动触发。写操作创建工单、退款、发送短信、修改配置必须走人工审批节点或者至少经过二次确认。LangGraph 的 interrupt 机制就是为这里设计的。它的价值不在于“多一道流程”而在于把风险决策权从模型手里交到真实业务负责人手里。9.3 限流与配额Agent 调用模型会消耗 Token调用业务 API 会打生产系统。如果没有限流一个异常循环可能瞬间烧掉大量资源和预算。建议在 Agent 接入层做两件事在 Agent 执行级别设置最大步数前面已经提过。在 LLM 调用和工具调用层设置配额和速率限制比如“单用户每分钟最多调用 20 次模型”“单会话最多消费 100 万 Token”。9.4 审计日志所有 Agent 的关键操作都应该记录审计日志包括用户请求内容。模型输出内容。工具调用参数和返回值。人工审批决定和审批人。执行链路 ID方便 Langfuse 回溯。审计日志不仅是合规要求也是故障排查的第一手材料。在 Agent 应用里“谁在什么时间让模型做了什么操作”必须完全可追溯。9.5 生产环境变更流程涉及生产系统时任何代码变更都应该走标准发布流程先在测试环境用模拟数据验证。再做灰度发布比如只放量 5% 的流量。观察 Langfuse 里的错误率和成本指标。确认无异常后再全量发布。任何时刻都要有回滚预案。这些规则听上去是老生常谈但在 Agent 项目里特别容易被忽略因为 Agent 的行为存在不确定性传统“单元测试过了就能上”的思路并不完全适用。10. 常见问题与排查思路问题现象可能原因排查方式解决方案Agent 陷入死循环连续调用工具不返回节点逻辑缺终止条件模型反复认为信息不足在 Langfuse trace 里看执行步数和节点调用顺序在状态中加入 step_count达到上限后强制走收尾节点模型调用了不该调的工具工具列表过宽权限控制不足查看链路中模型最终选择了哪个工具以及 Prompt 里工具描述按业务场景拆分工具集把“写操作”专用工具放到独立 Agent并加人工审批某个节点报错整个会话失败缺少异常恢复机制查看错误日志和 Langfuse trace 中报错节点为关键节点添加 try-except返回时附带错误信息启用 Checkpoint 以便恢复MCP Server 调用超时子进程启动耗时过长或网络不通先单独测试 MCP Server 是否可用再检查 Agent 侧客户端配置生产环境使用独立部署的 MCP ServerHTTP 模式不要用 stdio 模式人工审批节点没有正常暂停interrupt 用法不正确或调用时没有传 thread_id检查检查点配置是否启用确认 compile(checkpointer...) 已配置调用时传固定 thread_idToken 成本突然暴涨Prompt 里塞入了过多无关上下文或工具返回大量原始数据查看 Langfuse 的 Token 统计和 trace 详情对工具返回值做截断、清洗限制上下文窗口必要时用小模型做信息提取同一用户多次请求之间状态串了thread_id 使用不当多个会话共用了同一个 ID检查调用时传入的 configurable.thread_id每个会话生成独立 thread_id并按用户维度隔离11. 最佳实践与工程建议11.1 先画图再写代码LangGraph 项目的起点不是StateGraph代码而是一个节点关系图。建议先把业务流程转换成图结构有哪些节点哪些路径是并行的哪一步需要人工介入哪个环节可能循环循环上限是多少画清楚图再写代码效率会高很多。这其实是 LangGraph 带来的隐性价值——它逼着团队把模糊的业务流程显式化。11.2 模型分层使用不要让一个“大而全”的模型负责 Agent 的全部任务。推荐的分层策略是简单分类、信息提取用便宜的小模型。普通对话、知识问答用性价比高的中等模型。复杂推理、多步规划用最强的旗舰模型但频率要低。这样可以在保证质量的前提下把成本控制在合理区间。11.3 工具返回必须清洗工具返回的数据往往包含大量 Agent 不需要的字段。建议在工具层对返回值做“消息化”处理——只保留模型决策需要的关键信息其他一律丢弃。这能显著减少 Token 消耗也能降低模型被无关信息干扰的概率。11.4 Prompt 与代码分离Prompt 不要硬编码在 Python 文件里。Langfuse 等工具支持 Prompt 在线管理你可以把 Prompt 当作配置随时调整版本不用发版重新部署。这样运营人员和算法同学也能直接参与调优不需要改一次 Prompt 就找开发发布一次。11.5 每个 Agent 都应该是独立服务不要把多个业务 Agent 塞进一个服务进程。每个 Agent 独立部署、独立灰度、独立扩缩容是团队协作和稳定性保障的基础。11.6 从第一天就接入可观测可观测不是上了生产之后才做的事。从第一个 Demo 开始就接入 Langfuse养成看 trace 的习惯。这个习惯会在项目规模变大后产生巨大回报。12. 总结与后续学习方向如果只记住本文一句话企业级 Agent 的难点不在“模型多聪明”而在“工作流多可控”。LangChain 1.0 提供了标准化的组件生态LangGraph 1.0 提供了有状态、可恢复、可中断的编排运行时MCP 把工具接入变成标准化协议Langfuse 让每一次模型调用都有迹可循。这四者组合才是一条从 Demo 走向生产的最小可行路径。建议你直接拿一个真实业务场景练手可以是一个简单的工单机器人也可以是一个内部知识库问答助手。先用 LangGraph 画出流程接入两个 MCP 工具再接上 Langfuse然后尝试在某个高权限节点上加一个人工审批。跑通这条链路之后你对 Agent 生产级落地的理解会比看十篇文章都更扎实。后续值得深入研究的方向包括Checkpoint 持久化在 PostgreSQL/Redis 中的配置、Agent 的路由策略优化、基于反馈数据的 Prompt 自动迭代、多 Agent 协作框架的权限隔离以及模型评测与回归测试体系。每个方向都能单独写一篇长文也欢迎在评论区聊聊你们团队在 Agent 落地时遇到的具体问题。
返回列表