超过60%的生产Agent事故源于状态管理问题而非模型质量,典型失败模式是并发写入导致静默覆盖,以及进程崩溃后无法恢复。
大多数针对失败 Agent 运行的事后分析,从一开始就找错了方向。有人会调出对话记录,看到模型在说某句话时出了问题,然后得出结论:模型糊涂了。有时候确实如此。但更多时候,模型在那个时刻的推理是正确的——只是它所基于的状态早在三步之前就已经被污染了。
LangChain 发布的《Agent 工程现状报告》显示,超过 60% 的生产环境 Agent 事故出在状态管理上,而非模型质量。这个数字重构了整个调试问题。如果大多数失败都是状态失败,那么真正重要的框架选择就不是调用哪个模型,而是你的系统如何存储和合并 Agent 至今所学到的东西。
两种失败模式占其中的大部分。
第一种是静默覆盖。workflow 中的两个节点同时向同一个字段写入,它们以非确定性顺序完成,最后写入的胜出。没有任何异常抛出。运行继续,但只收集到了一半的信息,输出看起来足够合理,以至于没人发现,直到客户发现了。
第二种是无法恢复的崩溃。运行进行到十二步中的第九步,进程挂了,而一 到八步没有任何可以从中恢复的记录。因此整个流程从零重新开始,消耗相同的 token 去重新发现相同的事实。对于一个长期的调研或迁移任务,这不是不便,而是任务能否完成与永远无法完成之间的差别。
这两种都不是 prompting 问题。你无法通过 prompt 来规避竞态条件。
链式抽象假设工作是线性的。真正的 Agent 工作不是线性的。它会分支,会循环直到某个条件满足,会等待人工介入,需要在某个步骤失败时有个落地之处。
LangGraph 将 workflow 建模为有向图,其中环和条件边是一等公民,而非后期加装。节点是读取状态并返回部分更新的计算单元。边既可以是固定转换,也可以是路由函数——检查状态并指定下一个节点。子图让你可以把整个图嵌套在另一个图中,拥有自己的内部状态和与父图的明确定义接口——这正是让团队级所有权成为可能、同时又不必让所有人争抢一个巨大状态对象的关键。
一个被低估的 primitive 是 interrupt gate。它在命名节点处暂停执行,检查点保存完整状态,然后等待外部输入。人工审批不再是你记得写的 if 语句,而成为 workflow 的结构性属性。
真正做实事的是两个机制。
Reducer 函数定义并发写入状态字段时如何合并。消息列表使用追加 reducer,这样并行分支会累积而非相互覆盖。这是对静默覆盖的直接修复,而且是按字段可选加入的,所以任何你跳过它的地方,都是在有意选择末位写入者胜出,而非意外。
Checkpointing 在每个步骤完成后捕获完整状态。这一单一机制同时给你三样东西:容错性,因为崩溃的运行可以从最后一个良好步骤恢复;长期运行的 workflow,可以跨会话和机器存活;以及时间旅行调试,可以倒回到任意检查点,编辑状态,然后从那里分叉出一条新的执行路径。
团队会做错的选择是后端。MemorySaver 是开发工具。PostgresSaver 才是生产环境需要的,因为它支持水平扩展、崩溃恢复和多进程访问。DynamoDBSaver 是给已经在 AWS 上的人用的。SQLiteSaver 存在,但它在多个进程访问的瞬间就是一个陷阱。选择这个,是整个技术栈中影响最大的基础设施决策之一,但通常在五分钟内就被搭完第一个原型的人决定了。
对天花板保持诚实,比推销框架更重要。
学习曲线确实很陡。类型化状态 schema、reducer 和图思维需要真正的时间来内化,而一个只想在本周做出一个可工作原型的团队,用 CrewAI 这类基于角色(role-based)的方案会更快——一个最小化 Agent 大约 35 行代码。生产部署本身就是一个项目,因为重试、降级、监控和 CI/CD 都位于框架之外。想替换某个组件时,与 LangChain 的紧耦合会变得受限。此外,大规模分布式 Agent 系统也不是 LangGraph 的强项,因为跨多节点调试状态同步需要大多数团队都没有的专业知识。
也有研究指出,外部编排框架可能会降低 LLM 在某些程序性任务上的表现。在你假设框架是免费的之前,值得了解一下。
如果你的 workflow 真的是线性的,不要用图。但如果它有分支、循环、需要为人暂停,或者运行足够长以至于崩溃代价高昂,那么状态层就是你的可靠性层,它值得你本来打算花在 prompt 调优上的设计注意力。
完整分析,包括四种多 Agent 协调模式、LangSmith 和部署平台的真实定价、企业生产案例,以及与 CrewAI、AutoGen 和 Hermes 的更完整对比,见:LangGraph: Complete Guide and Review