LangGraph 生产环境跑了三个月,我的真实感受

我们团队从去年底开始在生产环境用 LangGraph 做 Agent 开发,到现在稳定运行了三个月。不吹不黑,聊聊实际体验。

为什么选 LangGraph

Agent 框架我们对比过 AutoGen、CrewAI,最终选了 LangGraph。不是它最好,而是最匹配我们的场景。

LangGraph 的核心优势是有状态、可编排,能可视化地管理复杂流程。我们的业务里有一个典型场景:用户下单后需要跑一串校验,状态流转必须稳定可靠。

python

python 复制代码
from typing import TypedDict, Annotated
from langchain_core.messages import BaseMessage
import operator

class OrderState(TypedDict):
    order_id: str
    user_id: str
    messages: Annotated[list[BaseMessage], operator.add]
    validation_results: dict
    current_step: str

如果你的需求只是简单问答,不建议用 LangGraph,太重了。

实际案例:一个客服 Agent 的完整链路

我们搭建的客服 Agent 大致流程:

text

复制代码
用户下单 → 验证库存 → 检查地址 → 计算运费 → 更新库存 → 发送通知

每一步都可能出错,一旦出错需要回滚到上一步。用 LangGraph 来实现非常自然:

python

python 复制代码
def validate_inventory(state: OrderState) -> OrderState:
    """检查库存"""
    order_id = state["order_id"]
    stock = check_stock(order_id)

    if stock < state["quantity"]:
        return {
            **state,
            "current_step": "insufficient_stock",
            "validation_results": {"inventory": False}
        }

    return {
        **state,
        "validation_results": {"inventory": True},
        "current_step": "check_address"
    }

def handle_insufficient_stock(state: OrderState) -> OrderState:
    """处理库存不足,回滚并通知用户"""
    notify_user(state["user_id"], "库存不足")
    return {
        **state,
        "messages": state["messages"] + [
            AIMessage(content="很抱歉,库存不足,请减少购买数量")
        ]
    }

流程图示意:

text

css 复制代码
[validate_inventory] → [check_address] → [calc_shipping]
      ↓                                       ↓
[handle_insufficient_stock] ← [rollback]

用图来管理流程比一堆 if-else 清晰太多了,这也是 LangGraph 最打动我们的地方。

工具调用的经验与坑

工具调用我们用了不少,但也踩过坑:

python

ini 复制代码
from langchain_community.tools import DuckDuckGoSearchRun

search = DuckDuckGoSearchRun()

常见问题:AI 会重复调用同一个工具,于是我们加了一个去重逻辑:

python

ini 复制代码
def deduplicate_tools(tools_called: list[str]) -> list[str]:
    seen = set()
    result = []
    for tool in tools_called:
        if tool not in seen:
            seen.add(tool)
            result.append(tool)
    return result

另外,工具描述(tool description)写得不够清晰时,AI 很容易乱调,这块需要在 Prompt 上调教到位。

生产环境踩过的三个坑

  1. 长对话导致内存持续上涨

    运行几天后发现内存一直涨,排查发现是 messages 没做截断。加了一个长度限制:

    python

    python 复制代码
    def trim_messages(messages: list[BaseMessage], max_len: int = 20) -> list[BaseMessage]:
        if len(messages) > max_len:
            return messages[-max_len:]
        return messages
  2. 并行执行几乎跑崩

    有一次让 AI 同时调用 5 个工具,结果两个超时、两个报错,AI 开始循环重试,差点把系统打崩。后面我们为所有工具调用都加了最大重试次数限制。

  3. K8s 多 Pod 间状态丢失

    在 Kubernetes 上跑的时候,不同 Pod 之间状态不共享。某个请求的后续调用被调度到另一个 Pod 上,状态直接丢了。后来改用 Redis 做状态持久化:

    python

    python 复制代码
    from redis import Redis
    import json
    
    redis_client = Redis(host='redis', port=6379)
    
    def save_state(session_id: str, state: OrderState):
        redis_client.setex(
            f"order_state:{session_id}",
            3600,  # 1 小时过期
            json.dumps(state)
        )

生产环境的三个建议

从三个月实战里浓缩出三条最重要的经验:

1. 监控必须上

LangGraph 没有内置监控,我们自己加上了 Prometheus 指标:

python

ini 复制代码
from prometheus_client import Counter, Histogram

tool_calls = Counter('agent_tool_calls_total', 'Total tool calls', ['tool_name'])
execution_time = Histogram('agent_execution_seconds', 'Agent execution time')

2. 异常兜底要全面

不要相信 AI 一定按你的流程走,必须给它兜底:

python

python 复制代码
try:
    result = graph.invoke(state)
except Exception as e:
    logger.error(f"Graph execution failed: {e}")
    route_to_human(state)  # 降级为人工处理

3. 日志要足够细

AI 的行为很难排查,日志不够详细的话,问题出现时只能干瞪眼。

到底适不适合你?

不是所有场景都需要 LangGraph,可以按复杂度对号入座:

  • 简单场景:对话机器人、FAQ 问答 → 用 RAG 就够了
  • 中等复杂度 :多步骤执行、需要状态管理 → LangGraph 正合适
  • 高复杂度:多 Agent 协作、复杂回滚逻辑 → AutoGen 或自研

我们的场景恰好卡在中等复杂度,使用 LangGraph 刚好够用。如果你也在类似的业务里,它值得一试。


如果还有任何问题,欢迎在评论区交流。

相关推荐
Rust语言中文社区1 小时前
【Rust日报】2026-04-28 Pacquet:pnpm 的 Rust 重写版本
开发语言·后端·rust
胡马北风Norstead1 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 7)
后端
fliter2 小时前
Cloudflare 防火墙规则背后的工程实践
后端
JarvanMo2 小时前
搞懂这 5 个 AI 术语,你就超过了 90% 的人
前端·后端
IT_陈寒2 小时前
Vite的HMR怎么突然失效了?原来是我太年轻
前端·人工智能·后端
胖纳特2 小时前
Nextcloud 文件预览困局与破局:集成 BaseMetas Fileview 实现全格式在线预览
前端·后端
lczllx2 小时前
MIT 6.824-lab3A(实现思路)
后端
派星2 小时前
AOP实践:公共字段自动填充
后端
用户0510122572962 小时前
从 malloc 到 DMA-BUF:嵌入式边缘设备上 mmap 的缓存一致性真相
后端