AI Infra:用文件系统约束Agent,一种可治理的上下文存储思路
Chatbot 等 C 端 AI Agent,在大规模用户使用的情况下,上下文的 I/O 处理是个值得注意的工程问题。本文的思路是:以块存储为基础,通过高性能本地文件系统(XFS)+ 哈希分桶目录结构 + 每个用户独立SQLite文件一、思路说明
关键不在于文件系统本身,而在于如何把“用户上下文”拆解为适合块设备顺序与随机访问特性的对象,再用文件系统语义去约束 agent 的读写行为。
1.1 从块存储起步
C 端 agent 的上下文呈现出几个稳定特征:用户数量巨大、单用户上下文规模可控、读多写少、访问集中在最近时间窗口。
块存储在低延迟、稳定 IOPS、可控成本上有优势,尤其适合承载高频随机读。文件系统层可以把这些块组织成对 agent 友好的逻辑单元,从而避免直接把复杂语义压到模型侧。
1.2 上下文的数据拆分方式
将“一个用户的上下文”拆成三类文件,让 agent 的 I/O 行为高度可预测,避免无边界读取:
- 第一类是 session context 文件
这类文件对应短期对话窗口,采用 append only 的方式写入。文件通常很小,适合放在连续块中,便于快速顺序读取。agent 每次推理只需要 mmap 最近几个 session 文件即可。 - 第二类是 memory shard 文件
长期记忆被切分成多个 shard,每个 shard 覆盖一个主题或时间段。每个 shard 是独立文件,对应固定大小的块区间。检索时通过轻量级索引文件定位需要读取的 shard,再做局部扫描。 - 第三类是 metadata 与索引文件
包括时间戳、embedding offset、权限标记、可信度等。这些文件体积小、访问频繁,建议常驻缓存或单独的高性能块区。
1.3 文件系统层的设计点
这里的文件系统并非通用 POSIX 实现,而是带有明确语义约束的“agent-aware FS”。
1.3.1 命名即隔离
目录结构天然表达租户与权限,例如
/users/{uid}/sessions/
/users/{uid}/memory/
/users/{uid}/meta/
agent 只能被授予某一子树的访问能力,权限在 FS 层就被裁断。
1.3.2 写入路径被严格限制
session 文件允许顺序追加。memory shard 只允许通过 compaction 任务重写。agent 进程不具备任意覆盖写权限,从根上避免上下文污染。
1.3.3 版本化与快照
块存储天然支持快照。文件系统层可以把“某次 agent 决策所见的上下文”冻结成一个只读视图,用于回溯与审计。
1.3.4 预读与局部 mmap
基于块地址与访问历史做简单预读策略,把最近 N 个 session 文件和高命中 shard 映射进内存。相比向量数据库的 RPC,这种方式在单机延迟上更稳定。
1.4 与 agent runtime 的配合方式
agent 不直接“理解文件系统”,而是通过一个极薄的 context runtime,这个 runtime 做三件事:
- 根据当前意图决定需要读取哪些文件
- 执行 mmap 或顺序读,把结果拼成 prompt 或中间表示
- 负责把新上下文写入 append 区域,并发出异步 compaction 事件
模型看到的是结构化上下文,存储系统看到的是受控的块 I/O。
1.5 扩展到大规模用户的方式
单机可以支撑数十万活跃用户的热上下文。再往上扩展时,按 uid 做一致性哈希,把用户目录分布到不同节点即可。块存储层保持简单,文件系统负责 locality。冷用户的 memory shard 可以被下沉到更便宜的块设备或对象存储,通过 lazy mount 的方式拉回。
以向量数据库更适合作为检索加速层,而不是上下文的唯一真源。对象存储更适合归档和离线分析。这里的块存储文件系统承担的是“在线工作集”的角色,服务 agent 的高频 I/O。
二、具体方案
以块存储为基础,通过高性能本地文件系统(XFS)+ 哈希分桶目录结构 + 每个用户独立SQLite文件,可能是目前性价比最高、延迟最低的方案,优势来自成熟组件的叠加,而不是单点技术突破。
2.1 潜在的风险
- 文件数量。百万级用户意味着百万个 SQLite 文件,inode、fd 管理、备份与迁移都会成为运维问题
- 写放大与 fsync 策略。如果 agent 写入过于频繁,WAL checkpoint 与 fsync 会抬高尾延迟
- 冷热不分。把长期冷 memory 与热 session 混在一个文件里,会拖累 cache 命中率
- 跨机扩展。一旦需要频繁迁移用户目录,本地文件系统的优势会被削弱
2.2 可能的工程优化
- 将 session 与 long-term memory 分成不同的 SQLite 文件,甚至不同挂载点
- 强制 agent 走批量写入,限制每次交互的事务次数
- 设置合理的 WAL checkpoint 阈值,避免高峰期抖动
- 对冷用户目录做 lazy mount 或打包迁移,减少常驻 inode 压力
- 通过一致性哈希固定用户到节点,避免频繁跨机访问
总之,我对 SQLite 或者 DuckDB 这种数据库有一点个人偏好,但又确实在工程上解决很大的问题,尤其是在加强了向量能力之后