有状态 vs. 无状态 AI 功能:决定一切下游走向的架构抉择
当一个购物助手向一位两年前曾提及怀孕的用户推荐婴儿产品时,系统没有抛出任何异常。它完全按照设计运行。LLM 返回了一个充满信心的 HTTP 200 响应。问题出在数据上——一段从未被清除的过期记忆——而且它完全隐形,直到一位用户投诉才被发现。这就是潜伏在有状态 AI 系统中的幽灵,其行为与你习惯调试的 Bug 截然不同。
有状态与无状态 AI 功能之间的抉择,表面上看起来异常简单。但在实践中,这是你在构建 AI 产品时最早做出的架构决策之一,其影响会贯穿存储层、调试工具链、安全态势和运营成本。大多数团队是在不经意间做出这个决定的——盲目沿用某种模式,却未仔细审视其权衡取舍。本文旨在帮助你做出有意识的选择。
"无状态"对 LLM 究竟意味着什么
有必要在此厘清概念,因为 LLM 通常被描述为无状态,但这一说法使用得相当宽泛。
在模型层面,每个 LLM 在设计上都是无状态的。每次推理调用接收一个上下文窗口并产生输出,零延续。模型对十分钟前说了什么一无所知,除非你将其明确包含在当前提示词中。这不是限制——正是这一特性使 LLM 能够横向扩展、可复现,且可并行化。
无状态 AI 功能将这一特性延伸到整个技术栈。输入进来,输出出去,什么都不持久化。每个请求都是自包含的。极端情况是单次补全:提示词 → 模型 → 响应,完毕。
有状态 AI 功能则打破了这一链条。在推理调用之前,需要从外部存储读取状态并注入提示词,响应后再写回。每次调用至少需要额外两次 I/O 操作,加上所有分布式系统复杂性的附带影响:
无状态:用户请求 → [构建提示词] → LLM → 响应
有状态:用户请求 → [读取状态] → [构建提示词] → LLM → 响应
↓
[写入更新后的状态]
有状态版本在每次推理调用中增加了读写操作,以及维护、版本化和偶尔清除存储状态的复杂性。
今天部署的 AI 工具中,大约 95% 是无状态的——将每个查询孤立处理。这不是因为有状态不好,而是因为有状态很难构建正确。
有状态值得付出这些代价的情况
坦率地说:通常在早期不值得,只有当用户会察觉到缺乏连续性时才值得。
以下情况值得承担有状态的复杂性:
- 交互本质上是多轮的,且用户期望连续性——客户支持、个人助手、长时间运行的编程智能体、心理咨询机器人
- 用户历史能够显著改善输出质量——个性化、自适应学习、偏好感知推荐
- 任务是一个工作流,智能体必须记住它上次停在哪里——跨会话执行多小时任务的自主智能体
- 用户会将"遗忘"视为产品缺陷,而非怪癖
以下情况保持无状态:
- 任务是单轮或有边界的:分类、对固定文档的问答、翻译、垃圾邮件检测、代码解释
- 隐私合规(GDPR、HIPAA)要求最小化数据保留
- 你需要最大的可扩展性——无状态工作负载无需协调即可横向扩展
- 你需要可复现、可审计的输出——给定相同提示词,无状态调用是确定性的
- 你处于早期阶段,发货速度比个性化更重要
关键诊断问题是:用户是 否将"遗忘"体验为 Bug。如果用户两次运行相同的分类任务得到相同的答案,这是预期行为。如果用户与支持机器人进行了三轮对话,机器人在第三轮忘记了第一轮说的话,这是一个坏掉的产品——即使系统在技术上按设计工作。
从无状态到有状态的跨越不是线性的。你从单个 API 调用转变为一个带有会话存储、每次请求的读写操作、状态同步、TTL 管理、缓存失效以及部分写入错误处理的分布式系统。预计运营成本是等效无状态系统的 2–3 倍。
在生产中真正有效的存储与检索模式
假设你已经决定有状态是必要的,下一个决策是存储什么、存储在哪里以及如何检索。
该领域已经收敛到四层内存层次结构:
工作内存(上下文内): 当前对话、活动任务状态和推理草稿。存在于上下文窗口中。读取免费,消耗 token。生命周期:一个请求。
会话内存: 活跃会话中的对话历史。Redis 或内存 KV 存储。亚毫秒读取。生命周期:会话 TTL,通常为数小时。
情节记忆: 近期会话中的关键事实、摘要交流、实体关系。PostgreSQL 或 MongoDB。1–10ms 读取。生命周期:数天到数月。
语义/档案记忆: 精炼的用户偏好、长期知识、过去决策。向量数据库加 KV 存储。甚至在进行 LLM 调用之前就需要 200–500ms 的检索时间。生命周期:无限期。
朴素的有状态方法是将所有历史记录塞入上下文 窗口。这是正确的,但对于长会话来说会失败,因为 token 成本随上下文长度线性增长——即使硬件可以处理,长上下文的模型注意力也会下降。在规模上,每次请求注入 3,000 个对话历史 token,以每百万输入 token 3 美元的价格计算,一个每天处理 100 万次请求的服务每天需要花费约 9,000 美元。
成熟的方法是带有选择性检索的分层外部内存。逐字的近期对话(最后 N 次交流的滑动窗口)、摘要的旧对话、语义检索的长期事实——每一层都有不同的新鲜度要求和不同的检索成本。
关于选择存储后端:向量数据库在文档超过 10 万个或需要跨任意主题进行语义检索时才有意义。对于查询次数在几百次以内的较短历史,一个带有前缀搜索的简单键值存储,当你考虑到 200–500ms 的检索延迟加上嵌入模型调用加上重排序时,始终优于向量数据库。不要首先选用最强大的存储层。
闹鬼的系统:为什么有状态 Bug 与众不同
以下是调试有状态 AI 系统的实际情景:你的助手开始给出微妙的错误答案。没有抛出错误。LLM 返回了 HTTP 200。你查看最新的请求,提示词看起来没问题。问题是六个会话之前,用户随口说的一句话被错误地提取到了长期内存中,现在每个响应都锚定在一个错误的信念上。你不知道是什么时候发生的,也没有堆栈跟踪。
- https://tacnode.io/post/stateful-vs-stateless-ai-agents-practical-architecture-guide-for-developers
- https://ark-labs.cloud/blog/stateful-vs-stateless-llms/
- https://redis.io/blog/ai-agent-memory-stateful-systems/
- https://www.letta.com/blog/stateful-agents
- https://arize.com/blog/memory-and-state-in-llm-applications/
- https://serokell.io/blog/design-patterns-for-long-term-memory-in-llm-powered-architectures
- https://mem0.ai/blog/llm-chat-history-summarization-guide-2025
- https://www.getmaxim.ai/articles/context-window-management-strategies-for-long-context-ai-agents-and-chatbots/
- https://cookbook.openai.com/examples/agents_sdk/session_memory
- https://openai.com/index/memory-and-new-controls-for-chatgpt/
- https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool
- https://arxiv.org/html/2312.05516v1
- https://www.devx.com/enterprise-zone/why-stateful-services-trigger-latency-cliffs/
- https://medium.com/@alexzanfir/context-poisoning-how-shared-memory-kills-multi-agent-intelligence-8bf32712834f
- https://christian-schneider.net/blog/persistent-memory-poisoning-in-ai-agents/
- https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/
- https://insights.daffodilsw.com/blog/stateful-vs-stateless-ai-agents-when-to-choose-each-pattern
- https://memorilabs.ai/blog/rag-vs-memory-for-ai-agents/
- https://www.letta.com/blog/agent-memory
- https://venturebeat.com/ai/anthropic-adds-memory-to-claude-team-and-enterprise-incognito-for-all
- https://medium.com/@sahin.samia/engineering-challenges-and-failure-modes-in-agentic-ai-systems-a-practical-guide-f9c43aa0ae3f
- https://swarmsignal.net/ai-agent-security-2026/
