Agent长期运行可靠性:从Demo到生产的分布式状态机设计

发布时间:2026/10/17 9:21:13
Agent长期运行可靠性:从Demo到生产的分布式状态机设计 1. 从跑个Demo到跑三个月Agent可靠性问题的真实起点大多数人对 Agent 的第一次认知都停留在跑通一个 Demo的阶段。你写一个 ReAct 循环接上几个工具让它帮你查天气、搜网页、写文件跑起来那一刻确实很爽。但只要你把它放到生产环境里让它连续运行几天甚至几周问题就会像潮水一样涌出来上下文窗口爆了、工具调用超时了、状态丢失了、重复执行了、内存泄漏了、某个外部 API 挂了导致整个流程卡死……这些问题的本质其实不是Agent 不够聪明而是我们把一个本质上属于分布式系统的问题当成了一个单机脚本问题来处理。我在过去一年里陆续参与过几个长期运行的 Agent 项目有做自动化运维巡检的有做持续数据采集与分析的也有做多 Agent 协作内容生产的。踩过的坑足够写一本书。今天这篇我想把Agent 作为长期运行的分布式状态机这个视角彻底讲透——为什么这个视角重要、它带来了哪些具体的设计约束、以及在真实项目里怎么落地。如果你正在做 Agent 开发或者正准备把 Agent 从 Demo 推向生产这篇文章应该能帮你少走至少半年的弯路。如果你还在学习 Agent 基础也可以先收藏等真正遇到跑久了就崩的问题时再回来对照。先说一个反直觉的结论Agent 的可靠性问题90% 不是模型能力问题而是状态管理问题。模型再强如果状态丢了、状态错了、状态重复了整个系统就是不可靠的。这也是为什么我把标题定为分布式状态机——因为一旦你接受这个视角很多设计决策会瞬间变得清晰。2. 为什么状态机是理解 Agent 最准确的隐喻2.1 从 ReAct 循环看 Agent 的本质结构我们先回到最基础的 ReAct 循环。一个典型的 Agent 执行流程是这样的接收输入用户消息或系统事件组装上下文历史消息 工具定义 系统提示调用 LLM 推理解析输出判断是直接回答还是调用工具如果调用工具执行工具把结果追加到上下文回到步骤 2直到满足终止条件如果你把这段伪代码画成状态转移图会发现它和经典的有限状态机FSM几乎一模一样有明确的状态上下文、待执行动作、执行结果、有明确的转移条件LLM 输出类型、有明确的终止状态最终回答或错误退出。区别只在于传统 FSM 的状态转移是确定性的而 Agent 的状态转移由 LLM 的概率输出决定。但这不改变它状态机的本质只是增加了一个非确定性转移函数。2.2 长期运行带来的三个质变一旦 Agent 从单次请求变成长期运行三个质变会同时发生第一状态从内存变成持久化需求。单次请求时上下文放在内存里请求结束就释放。但长期运行的 Agent 必须把状态写到磁盘或数据库否则进程一重启几个小时的积累就没了。第二执行从单进程变成多进程/多节点。为了高可用和负载均衡你不可能只跑一个 Agent 实例。多个实例同时操作同一份状态就引入了并发控制问题。第三故障从偶发变成必然。单次请求跑 10 秒遇到故障的概率很低。但长期运行意味着你要面对网络抖动、外部 API 限流、磁盘写满、进程被 OOM Kill 等各种故障。在分布式系统里故障不是异常而是常态。这三个质变叠加起来就是为什么我说Agent 可靠性本质是分布式系统问题。你用写脚本的思路去写长期运行的 Agent一定会崩。2.3 一个具体的对比脚本思维 vs 状态机思维我拿一个真实场景对比一下。假设你要做一个每天定时巡检服务器并生成报告的 Agent。脚本思维的写法是写一个 while 循环每次巡检完 sleep 24 小时状态全放内存。问题在于进程挂了怎么办巡检到一半挂了重启后是从头开始还是继续如果两台机器同时跑会不会重复巡检状态机思维的写法是把巡检任务建模成一个有状态实体每个任务有明确的阶段待执行、执行中、已完成、失败状态持久化到数据库用乐观锁或租约机制保证同一任务只有一个执行者失败时根据阶段决定是重试还是回滚。后者明显更复杂但它是唯一能支撑长期运行的方案。复杂度不是被引入的而是被显式化的——脚本思维把这些复杂度藏在了假设不会出问题里状态机思维把它们摆到台面上处理。3. 长期运行 Agent 的状态分层设计3.1 四层状态模型会话、任务、执行、记忆在真实项目里我习惯把 Agent 的状态分成四层每层的生命周期和存储策略都不同状态层级生命周期存储位置典型内容会话状态分钟到小时Redis / 内存当前对话上下文、临时变量任务状态小时到天关系数据库任务阶段、重试次数、依赖关系执行状态秒到分钟内存 日志当前工具调用、中间结果长期记忆天到永久向量库 / 对象存储历史经验、知识沉淀这个分层不是拍脑袋定的而是根据状态变化的频率和状态的重要性两个维度切出来的。会话状态变化最频繁但最不重要丢了可以重建长期记忆变化最慢但最重要丢了就是灾难。3.2 会话状态为什么不能只放内存很多人做 Agent 时会话状态直接放在进程内存里。单实例跑没问题但一旦你要做水平扩展或者进程需要重启会话就丢了。我的做法是会话状态放 Redis但设置合理的 TTL。TTL 的设定有个技巧——不要设成固定值而是根据会话活跃度动态调整。活跃会话 TTL 长一点比如 2 小时不活跃的短一点比如 15 分钟。这样既能保证用户体验又不会让 Redis 被僵尸会话撑爆。另外一个细节会话状态要区分可重建和不可重建两部分。历史消息是可重建的从数据库读但一些临时计算结果比如用户刚上传的文件解析结果是不可重建的后者要优先保证持久化。3.3 任务状态幂等性是第一原则任务状态是长期运行 Agent 的核心。这里最重要的原则是幂等性——同一个任务执行多次结果应该和执行一次一样。为什么幂等性这么重要因为在分布式环境里至少执行一次是你能保证的最强语义。网络超时、进程崩溃、消息重投都会导致任务被重复触发。如果你的任务不幂等重复执行就会产生副作用比如重复发邮件、重复扣款、重复写数据。实现幂等性的常见手段有三种唯一键约束给每个任务分配唯一 ID执行前先检查是否已执行状态机守卫只有处于特定状态的任务才能执行执行后立即转移状态去重表记录已执行的操作指纹执行前查表我一般会组合使用任务表加唯一键约束执行前用SELECT ... FOR UPDATE加行锁执行后更新状态。这样即使多个实例同时抢同一个任务也只有一个能成功。3.4 长期记忆写入容易检索难长期记忆这块很多人只关注怎么存忽略了怎么取。存进去一万条经验检索时召回不准等于没存。我的经验是长期记忆的写入要克制检索要激进。写入时做严格的质量过滤只存真正有价值的经验比如成功解决过的问题、用户明确反馈有用的回答。检索时用多路召回向量相似度 关键词 时间衰减宁可多召回一些再重排也不要漏掉关键信息。还有一个坑长期记忆会污染上下文。如果你把检索到的记忆无脑塞进 prompt很容易把上下文撑爆或者引入不相关的信息干扰推理。我的做法是给记忆加一个相关性阈值低于阈值的直接丢弃高于阈值的按相关性排序只取 top-k。4. 分布式执行下的并发与一致性难题4.1 多实例部署时的状态竞争当你把 Agent 部署成多个实例时第一个遇到的问题就是状态竞争。两个实例同时读到同一个任务都认为该自己执行结果就是重复执行。解决这个问题的经典方案是分布式锁。但分布式锁本身也有很多坑锁的粒度锁整个任务表还是锁单行粒度太粗影响并发太细容易死锁锁的超时设太短任务没跑完锁就释放了设太长故障时恢复慢锁的续期长任务需要定期续期续期失败要能感知我一般用 Redis 的SET NX EX实现简单的分布式锁配合一个后台线程定期续期。对于特别关键的任务会用数据库的行锁SELECT ... FOR UPDATE虽然性能差一点但一致性更强。4.2 工具调用的超时与重试策略Agent 调用外部工具时超时和重试是必须处理的。但重试有个陷阱不是所有操作都能安全重试。读操作查询、搜索可以随便重试写操作发消息、改数据重试要小心。我的分类策略是幂等读操作直接重试指数退避幂等写操作重试前先查状态确认没成功再重试非幂等写操作不自动重试记录到待人工处理队列超时时间也要分层设置。LLM 调用通常 30-60 秒工具调用根据类型 5-30 秒数据库操作 1-5 秒。超时时间要小于上游的超时时间否则会出现上游已经放弃下游还在跑的浪费。4.3 状态一致性最终一致还是强一致这是个架构层面的选择。强一致比如用分布式事务实现复杂、性能差但语义清晰。最终一致实现简单、性能好但需要处理中间状态。我的建议是核心状态用强一致辅助状态用最终一致。比如任务的执行中/已完成状态必须强一致否则会重复执行但任务的统计计数可以用最终一致晚几秒更新没关系。具体实现上核心状态用数据库事务保证辅助状态用消息队列异步更新。这样既保证了正确性又保证了性能。5. 故障恢复Agent 挂了之后怎么接着跑5.1 检查点机制把执行过程切成可恢复的段长期运行的 Agent 必须支持检查点Checkpoint。所谓检查点就是在执行过程中定期把状态快照保存下来故障恢复时从最近的检查点继续而不是从头开始。检查点的粒度是个权衡太粗比如整个任务只存一次恢复代价大太细每步都存性能开销大。我的经验是按不可逆操作划分检查点——在执行不可逆操作比如发送消息、写入外部系统之前必须先保存检查点。5.2 幂等重放恢复时如何避免重复副作用从检查点恢复时会重放检查点之后的步骤。如果这些步骤里有副作用操作就会重复执行。所以检查点之后的步骤必须是幂等的或者检查点必须精确到副作用操作之前。我踩过的一个坑有一次检查点设在调用支付接口之后结果恢复时又调了一次支付。后来改成检查点设在支付之前支付成功后立即更新状态恢复时先检查状态再决定是否支付。5.3 死信队列处理那些反复失败的任务有些任务会反复失败比如依赖的外部服务长期不可用。这种任务如果一直重试会占用资源、污染日志。我的做法是设置最大重试次数超过后把任务移到死信队列等待人工介入或定时重扫。死信队列不是垃圾桶要配套监控和告警。我一般会设置一个阈值死信队列超过 N 条就告警避免问题被埋没。6. 可观测性看不见的 Agent 等于不可靠的 Agent6.1 日志、指标、追踪三件套Agent 的可观测性和普通服务不太一样因为它有推理这个黑盒环节。我的做法是三件套齐全日志记录每一步的输入输出包括 prompt、LLM 响应、工具调用参数和结果指标QPS、延迟、成功率、Token 消耗、工具调用次数追踪用 Trace ID 串起一次完整执行方便定位问题日志这块有个技巧prompt 和响应要脱敏后再存避免敏感信息泄露。同时要控制日志量全量存 prompt 会很快撑爆存储我一般只存摘要 关键字段需要时再按 Trace ID 查详情。6.2 关键指标怎么判断 Agent 是否健康判断 Agent 健康与否不能只看有没有报错。我关注这几个指标任务完成率成功完成的任务占比低于 95% 就要排查平均执行步数步数突然增加往往意味着模型在绕圈工具调用失败率某个工具失败率飙升可能是外部服务出问题Token 消耗趋势消耗突然增加可能是上下文管理出了问题状态转移异常率非法状态转移的次数反映状态机设计是否有漏洞这些指标要配告警但告警阈值不能拍脑袋定要基于历史数据统计。我一般用 P95 或 P99 作为基线超过基线 2 倍才告警避免告警疲劳。6.3 回放能力出问题时如何复现Agent 的问题往往难以复现因为 LLM 的输出有随机性。所以回放能力非常重要——能根据历史日志把某次执行完整重放一遍。实现回放的关键是记录所有非确定性输入LLM 的原始响应、工具调用的原始结果、时间戳、随机种子。有了这些就能在离线环境复现问题。我一般会保留最近 7 天的完整执行记录超过 7 天的只保留摘要。这样既能支持问题排查又不会占用太多存储。7. 我在真实项目里踩过的五个坑7.1 坑一上下文无限增长导致 OOM早期做的一个 Agent上下文只追加不清理跑了两天后上下文涨到几十万 Token直接把内存撑爆。后来改成滑动窗口 摘要压缩保留最近 N 轮完整对话更早的用 LLM 压缩成摘要。这样上下文能稳定在可控范围。7.2 坑二工具调用没有超时导致线程池耗尽有个 Agent 调用外部 API 时没设超时外部服务卡住后Agent 的线程池很快被占满整个服务不可用。后来给所有外部调用加了超时并且用独立的线程池隔离不同类型的调用避免一个慢调用拖垮全局。7.3 坑三状态更新和副作用操作不在一个事务里有一次 Agent 先调用了外部接口副作用再更新数据库状态。结果外部接口成功了数据库更新失败了恢复时又调了一次外部接口。后来改成先更新状态为执行中再调外部接口成功后更新为已完成配合幂等检查问题解决。7.4 坑四多实例部署时用了本地缓存有个项目为了性能把一些配置缓存在本地内存。单实例没问题多实例部署后配置更新不同步导致不同实例行为不一致。后来改成用 Redis 做集中缓存配合发布订阅做失效通知。7.5 坑五日志里存了完整 prompt 导致存储爆炸早期为了排查方便把完整 prompt 和响应都存进日志。结果一天产生几百 GB 日志存储成本飙升。后来改成只存摘要和关键字段需要详情时按 Trace ID 从对象存储拉取。8. 从 Demo 到生产一份可落地的检查清单如果你正准备把 Agent 推向生产可以对照这份清单自查状态管理会话状态是否持久化TTL 是否合理任务状态是否有明确的状态机定义状态转移是否有守卫条件长期记忆的写入和检索策略是否清晰并发控制多实例部署时如何避免重复执行分布式锁的粒度和超时是否合理关键操作是否幂等故障恢复是否有检查点机制恢复时如何避免重复副作用是否有死信队列处理反复失败的任务可观测性日志、指标、追踪是否齐全关键指标是否有告警是否支持执行回放安全与合规敏感信息是否脱敏权限控制是否到位是否有审计日志这份清单不是一次性的而是应该定期回顾。Agent 系统会随着业务演进而变化今天合理的设计半年后可能就不适用了。最后分享一个我个人的体会做长期运行的 Agent最重要的不是把功能做多而是把边界做清楚。什么情况下该重试、什么情况下该放弃、什么情况下该告警这些边界定义清楚了系统才真正可靠。功能可以慢慢加但可靠性一旦欠债后面要还的利息会非常高。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询