先讲一个我自己踩过的坑。去年年中,我们团队在做一个面向企业客户的AI客服Agent,早期架构很“天真”:用户聊天记录、长期记忆、知识分块,全都往S3桶里扔,觉得存储就是“容量的事”。结果用户量跑到几万之后,问题开始一个接一个冒出来:恢复一个用户最近20轮上下文,得先到数据库里查消息Key列表,再逐个把对象读回来,最后还要自己拼装、排序、召回,高峰期LLM调用还没成为瓶颈,存储拼接层先崩了。后来我们花了两周时间梳理方案,逐步切到一个叫Agent Bucket的新存储模型,才真正把这块理顺。
写这篇文章前,我自己完整走了一遍从S3迁移到Agent Bucket的流程。标题里说“30分钟构建百万级用户应用”,指的是接入主链路的速度,不是包含所有历史数据清洗的排期。这篇文章的价值在于:第一,讲清楚为什么AI Agent应用不能继续沿用传统对象存储的思路;第二,把Agent Bucket的存储模型拆开看,给一份可以直接参考的落地指南;第三,分享一些百万级用户规模下、我在生产环境里真正踩过的性能与账单陷阱。适合正在做AI Agent应用选型、准备把Demo推上生产、或者被存储架构折磨过的开发者阅读。
1. AI Agent场景里,传统S3到底卡在哪
1.1 把文件扔进桶里的思路,从来不是为了“记忆”而设计的
S3这类对象存储的设计目标非常明确:提供一个海量、持久、便宜的文件仓库。你上传一张图片、一份PDF、一段日志,给它一个唯一的Key,存进去,以后需要了再取出来。这套模型在传统Web应用里无可挑剔,它解决的问题是“把静态的字节可靠地存住”。
但AI Agent消费数据的方式完全不是这样。Agent处理的是会话、上下文、用户偏好、知识片段,这些数据的核心特征是流动性和关联性。一段对话不是写完就不动的文件,它会和用户历史行为关联,会被新信息覆盖,会过期作废,还会在某个时刻因为语义相似而被召回。你把一条消息存成一个对象,就像把河流里的水一瓢一瓢装进密封罐:物理上能存,逻辑上却失去了河流本来的流动关系。
S3引以为傲的几个特性,在Agent场景下反而成了负担:
- Key是无结构的字符串,没人在Key里维护“这是哪个用户第几个会话的第几条消息”这种语义。
- 没有原生的数据过期机制,对象存进去之后要自己写定时任务清理。
- 不支持“按相关性排序”的查询,只能做前缀匹配和列表扫描。
- 权限是基于桶或前缀的,做不到“这个Agent能读属于自己的记忆块,看不到别人的”。
这些不是S3的缺陷,而是它的适用边界。对象存储适合做备份、归档、文件源,但它天然不适合成为Agent记忆的主力存储。很多团队绕来绕去,最后做出一个“S3+关系型数据库+向量数据库+定时任务”的缝合方案,代码越来越厚,脏数据越来越多,这就是没有意识到S3定位局限的代价。
1.2 Agent会生成四种数据,普通对象存储一种都伺候不好
我在生产环境里给AI Agent应用做了数据盘点,最后归成四类,每一类和S3的“文件思维”都有冲突。
第一类是会话流水。 一个用户在一个session内会产生很多条消息,这些消息按时间顺序追加,同时需要支持“拉取最近N条”“按主题找某一段聊天”“找到某个用户上周说过的话”等操作。把每条消息作为一个对象存S3,最大的麻烦是会话恢复时要批量读取,每一轮对话都产生几十次GET请求,而且这种读和写是高频的,不像文件归档一年可能只读一两次。会话流的本质是一条动态增长的队列,对象存储没有原生的“游标分页”能力,你得在外部维护索引,这不叫省事,叫把简单问题复杂化。
第二类是长期记忆和知识块。 这类数据可能是用户画像、产品知识、FAQ片段,也可能是Agent从一次对话里提炼出来的偏好。比如一个用户说“以后预订酒店尽量选高层”,这句话如果只是存成日志,下一次对话根本不会被想起来。它需要被切片、向量化、按语义召回,还要处理“用户改主意了”的更新和“这条记忆过时了”的遗忘。S3对这样的数据完全无感,它只会安静地帮你保存,至于这个片段和另一个片段之间的语义关系,它既不理解也不关心。
第三类是任务状态和工具调用结果。 Agent在执行任务时,会产生中间状态:一个查询是否成功、外部API返回了什么、哪个步骤重试过。这些数据生命周期短,更新频繁,需要版本控制,有时还需要在链路中断后恢复。如果存放不当,很容易堆积成海量垃圾对象。
第四类是带格式的源文件。 PDF、表格、图片、录音,这些文件本身需要被Agent阅读、解析、切片。你不能只保存原始二进制,还需要生成对应的文本块、embedding向量、引用关系。纯对象存储能放文件,但文件和它的语义索引之间缺少关联能力。
可以看出,这四类数据的共性是:它们需要一套理解“会话”“记忆”“租户”“关系”的存储能力。传统对象存储给不了,所以我们必须换一种存储组织方式。
1.3 根本矛盾不是容量,而是百万级用户下的关系面压力
很多人问我:“百万级用户一天产生多少数据?S3扛不住吗?”实际上,如果只算容量,S3完全可以扛。假设100万日活用户,每人每天产生20条消息,平均一条文本2KB,一天新增也就是40GB,对象存储的容量和带宽都毫无压力。
真正的问题出在每次请求需要跨越多少层才能把数据拼回来。我拆过一条典型的Agent对话恢复链路,原来长这样:
- Agent收到一个用户消息,需要恢复该用户最近20轮上下文。
- 程序先查PostgreSQL里的消息索引表,找到最近20轮的消息Key,顺便按user_id过滤。
- 拿到Key后,逐个调用S3的GET,把每条消息内容拉回来。
- 如果要加入长期记忆,还要再查向量数据库,把这几天沉淀的记忆碎片召回。
- 最后合并排序,截断到上下文窗口,再调用LLM。
这个链路的故障点太多了:PostgreSQL在百万级消息量下,按session分页查询需要正确的联合索引;S3的GET延迟在高并发时会抖动;向量库和PG之间还会出现数据不一致。用户可能感觉不到存储容量有问题,但他们会觉得Agent变笨了、反应变慢了、偶尔还会“失忆”。
Agent类应用对存储的诉求,从来不是“能不能放下”,而是“一次对话开始前,能不能快速找到与这个话题相关的所有信息”。当场景从几万用户放大到百万级,这个“找到”的动作会无限放大存储模型的缺陷。S3提供了文件级访问能力,Agent需要的却是基于时间、用户、会话、语义的关联检索能力。想通这一点,后面接受Agent Bucket的模型就顺理成章了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Agent Bucket的存储模型:把桶升级成“语义加工厂”
2.1 它不是又一个数据库,而是带语义层的存储服务
Agent Bucket这个命名其实很讲究。它保留了S3里“Bucket”
