OpenAI 把在线存储从客户端库收成集中式服务;Pinterest 用量化与 SSD 压向量检索成本;PlanetScale Neki 让每个分片都是真 Postgres;火山引擎开源 Agent 上下文数据库 OpenViking
本期聚焦四条跨 9 月 10 至 12 日的进展:OpenAI 的 Habitat 存储平台从 Python 客户端库演进为跨近 40 个区域的集中式服务,Pinterest 用量化与 SSD 服务把向量索引从内存搬到盘上,PlanetScale 把分片路由收进 router 与 JSON 拓扑,火山引擎把 agent 的记忆与技能收进一层可寻址存储。
这四件事分属在线存储、向量检索、分布式 OLTP 与 agent 上下文四个方向,做法却指向同一处:把一项原本由每个使用方各自携带的能力,收拢到一个专门的层里统一提供。OpenAI 的 Habitat 原本是嵌在每个服务里的 Python 客户端库,改一次路由要在几十个服务间协调数天,如今收成独立服务,访问控制与审计也一并集中。Pinterest 的 Manas 把向量索引从必须全量驻留内存,改为按 I/O 预算直接从 SSD 服务,配合量化把索引体积压到几分之一。PlanetScale 的 Neki 把分片路由从应用代码收进 router 与一份 JSON 数据拓扑,每个分片仍是未经改动的 Postgres。火山引擎开源的 OpenViking 则把 agent 的记忆、知识与技能收进
viking://这层可寻址存储,用三层按需加载替代整段上下文灌入。收拢之后,这一层自己成了新的约束点:Habitat 变成必须扛住每秒七千万请求的唯一咽喉,SPANN 换来约 5% 的召回损失,Neki 的 router 得自己证明不会成为瓶颈,OpenViking 的目录摘要变成了新的维护对象。
OpenAI Habitat:从 Python 客户端库到支撑 500 PB 的集中式在线存储服务
事件概述
OpenAI 于 9 月 11 日发布系列文章第一篇,讲述其在线存储平台 Habitat 的演进。Habitat 最早在 2023 年的 DevDay 上为支撑 GPTs 而推出,当时只是一个连接单一数据库(Azure Cosmos DB)的 Python 客户端库。今天它已是一个跨近 40 个地理区域、服务超过 500 PB 数据、承载每秒七千万以上请求、面向每周超过十亿使用者的集中式分布式服务,并进一步从 Python 迁移到 Rust。
促成这次改造的是一次具体的运维失败。到 2025 年中,Habitat 作为客户端实现已经触顶。团队想把最关键的数据集迁到一组区域分布式的 Azure Cosmos DB 账户上,以降低单区域故障的影响,做法是在客户端里加入额外路由逻辑,用 feature flag 关着先全量发布到所有客户端,再打开开关。把变更推到几十个服务耗时数天,接着引入 shadowing 校验分片逻辑又花几天,发现并修复 bug 再花几天。等到准备打开开关时,某个团队因为无关原因把服务回滚到旧版客户端,反而引发了这次改造原本想避免的故障。OpenAI 的结论是:客户端库的变更需要在几十个服务之间做复杂协调,这个过程脆弱、低效且容易引发运维事故,于是把 Habitat 抽成独立服务。
技术解析
- 刻意做弱的 API:Habitat 提供受 TAO 启发的 NoSQL API,客户端预定义 object 与 edge 类型及其关系,但只支持查询某个对象的直接边,不支持典型图遍历查询。它不允许客户端构造任意 SQL,从而避免大表扫描与跨表 join;代价是复杂 join 与图遍历要由产品团队自己承担。原文把这一点写成了明确取舍——「the lack of a powerful API is an explicit tradeoff in Habitat’s design」。
- 分区与放置:图数据按对象分区,每个对象及其对应的边在存储层分区中共置,但不会在数据库层刻意共置边所指向的远端对象。这样做换来了水平扩展能力,代价是任意一跳都可能要跨两个不同区域的 Cosmos DB 账户取数,图遍历的效率就受制于此。
- 服务化的收益:部署、可观测性与平台增强收拢到单点,改动一次就能惠及所有产品。安全上它成为「single chokepoint」,集中执行 ACL 策略、审计日志与对底层存储的访问限制,防护对象覆盖外部、内部与 agent 三类行为体。
- 周边数据路径:缓存用 Valkey;在线存储的变更通过 CDC 以近实时方式流入隔离的 Rockset 实例,作为复杂查询的离线二级视图。每个客户团队需要自己扩展各自的 Rockset 实例,这一点被视作正确的权衡。
- Python 到 Rust:
asyncio有助于 I/O 并发,但不绕过 GIL、也不提供 CPU 并行。路由、压缩、加密、校验和、下游健康检查、request shadowing、hedging 都是 CPU 密集职责,asyncio 调度延迟在调优前主导了 p99 及更高的尾延迟——下游存储早已返回,请求却卡在等待协程被重新调度。团队明知 Python 在百倍规模下不可接受,仍把它当作战略性技术债先上,赌的是等到必须迁移时,代码模型能让迁移变得可行。
行业影响
这条演进路径对任何把存储访问封装成共享库的团队都不陌生:客户端库在早期是效率最高的形态,代价是协议变更的协调成本随服务数量线性上升,而且这个成本不由平台团队承担,由每个接入方各自承担。Habitat 把它变成服务,实质是把这份协调成本从组织层面移到了平台层面,平台团队此后必须自己扛住每秒七千万请求的可用性与尾延迟。
真正决定成败的是 OpenAI 对「弱 API」的坚持。在一个每秒产生数百次数据库调用的平均用户请求背后,限制表达力换来的可预测性比查询能力更值钱——昂贵查询对调用方显而易见, unbounded query 根本进不了系统。这与过去十年数据平台普遍扩张 SQL 表达力的方向相反,说明当规模到这个量级,约束本身成为产品特性。
需要留意本文是两篇系列的第一篇:一致性模型未作说明,Azure Cosmos DB 存储层的优化、多租户可靠性与读性能分层策略都留给了第二篇,Rust 迁移的过程与收益也未展开。
相关链接
- Rapidly scaling online storage to serve over 1 billion ChatGPT users
- Data Engineering Weekly #287(本期多条线索来源)
Pinterest Manas:量化、SSD 服务与多向量检索三线压向量成本
事件概述
Pinterest 工程团队在 9 月中旬撰文,讲述其自研分布式搜索平台 Manas 的向量检索栈如何演进。Manas 部署在 80 多个集群上,支撑 Home Feed、Search、Related Pins、Ads 与 Notifications 等主要产品面,目前已服务数十亿条 embedding,语料正朝数百亿条规模增长。
压力来自两侧。基础设施侧,HNSW 这类传统 ANN 算法要求整个索引驻留内存以维持低延迟,成本随语料规模线性增长。模型侧,经典的双塔检索范式把每个候选压缩成单个向量、用点积打分,无法表达依赖上下文的相似性。团队的应对分三条战线展开:量化、基于 SSD 的服务、多向量检索。
技术解析
- SQ 与 PQ 的取舍:在一亿条 GraphSage 数据集上,两种量化算法与 HNSW、IVF 两种 ANN 算法交叉评测。PQ 压缩率更高但召回明显下滑——HNSW 索引降 74%、IVF 索引降 93%,召回落在 70–80% 区间;SQ 压缩率略低但召回稳定在 90% 以上——HNSW 索引降 59%、IVF 索引降 75%。生产环境按用例做在线 A/B 实验选量化器,全量铺开后索引内存下降超过 50%,服务成本节省 20–30%。
- Linear Scaling SQ:量化到 8 位或 4 位不只是省内存,距离计算前通常需要一步解码,这会成为 CPU 瓶颈。团队实现的 Linear Scaling SQ 只做缩放、不做位移,从而消掉解码步骤,配合 SIMD intrinsics 让一条指令处理多个 8 位整数运算,在他们的用例中把每查询所需计算资源降低 10–15%。
- DiskANN 与 SPANN 的对决:在一亿条来自 Pinterest 搜索场景的语料上,SPANN 胜出。关键改动是对盘上 embedding 存储施加 PQ 量化,centroid 则保留全精度——这是相对原论文的一处微调,显著提升了准确率与吞吐。结果是 SPANN+PQ 比原生 SPANN 快 4.5 倍,QPS 达到 DiskANN 的 3 倍以上、延迟只有其三分之一,召回下降约 5%。
- SPANN 的落地细节:centroid 索引放内存并用 HNSW 构建,大规模 posting list 放盘;索引构建阶段采用层次平衡聚类挑选 centroid,使各簇规模均匀、posting list 长度接近,以此压低尾延迟。在一个索引超过 50 亿条 embedding 的 Pin 推荐场景初步评估中,SPANN 相比 HNSW 节省超过 40% 的 CPU 时间,召回下降不到 5%。
- 从双塔走向 late interaction:团队正把 ColBERT 这类 late interaction 模型引入检索阶段,用「Sum of MaxSim」取代单点积——分别计算每个 query token 与文档各 token 的最大相似度再求和。这要求 Manas 的查询解析器理解多 embedding 查询,并从一个查询并行发起多个 ANN 搜索。目前正与一个产品团队合作做 pilot。
- 后续方向:推进 SPANN 与 SPFresh 进一步压低 CPU 与内存成本,为一类多向量检索模型提供一等支持,并引入 SilverTorch、TIGER 这类 GPU 检索系统。
行业影响
向量检索的成本结构正在被重写。HNSW 之所以成为默认选择,是因为它把延迟问题转化成了内存问题,而内存一度比工程时间便宜;当语料从十亿走向百亿,这个兑换比例失效,「索引必须全在内存」这条默认假设就成了最贵的一条。Pinterest 的答案是接受一次约 5% 的召回损失,换 4.5 倍的吞吐与三分之一的延迟——这类交易在此前几乎不会被接受。
量化方案的选择逻辑更能说明问题:PQ 在纸面上压缩率明显更高(IVF 索引降 93% 对 SQ 的 75%),但召回掉到 70–80% 区间,最终在多数用例里输给了 SQ。这说明当检索质量直接影响用户参与度指标时,压缩率不是决策变量,召回底线才是。Pinterest 用在线 A/B 实验逐个用例定夺,而不是全局选一个量化器,也印证了这一点。
相关链接
PlanetScale Neki:分片 Postgres,但每个分片都是未经改动的 Postgres
事件概述
PlanetScale 于 9 月 10 日宣布 Neki 进入平台预览。Neki 是分片 Postgres 产品,应用通过标准 Postgres 线协议连接到 Neki router,现有驱动、ORM 与连接串无需改动;每个分片都是一个完整的 Postgres 集群,一主加至少两个副本,跨三个可用区部署,没有自研存储引擎。
产品动机来自 PlanetScale Postgres 上线一年半以来的观察:不少客户撞上了单机上限,买更大的机器只能买来时间,而当时的可选答案都要求用户放弃某些东西——应用层分片把路由逻辑推进业务代码,「Postgres 兼容」的分布式数据库则隐藏分片键、拿走扩展支持,并引入难以调试的复杂度与延迟。Neki 的原则被表述为:坚持 Postgres,不去绕过它、伪装它或背离它。
技术解析
- Router:持有完整的 Postgres 查询解析器、分布式查询规划器与查询缓冲。它解析查询、规划应该在哪些分片上执行、分派任务并合并结果流。router 可垂直与水平扩展,避免单个 router 成为瓶颈。
- 分片与分片组:分片组织成 shard group,不同表或不同负载可以落在不同的分片集合上。每个分片使用一份配置 profile,定义实例规格、副本数、存储、Postgres 参数与扩展,各组可针对自己的流量分别定尺寸。
- 连接池:每个 Postgres 实例旁跑 sidecar。由于 Neki 两端通吃——router 侧与 Postgres 侧都由它控制两端,连接池可以按实例真实能服务的量来定尺寸,而不是像外挂 PgBouncer 那样从进程外估算。
- 控制平面:跟踪每个节点的健康状态,执行计划内切换与非计划故障转移,并协调数据重分片、schema 变更与版本升级这些工作流。
- 数据拓扑:一份 JSON 配置把逻辑表映射到物理分片。shard indexes 指定路由列与哈希方式,shard groups 控制一组表铺开到多少分片、落在哪些分片上。router 缓存拓扑并在每次规划时查询它。
- 在线运维模型:通常需要申请维护窗口的操作都成了内置工作流——先置备目标节点、用复制追赶、通过
__nekimetafunction 切换流量、再退役旧节点,全过程走的是应用已经在用的那条psql连接。 - 可以先不分片:Neki 允许以单主加副本的形态运行,先享受改进的连接池、在线 DDL、零停机升级与健康监控,等超出单机后再对已有集群执行重分片工作流。
行业影响
Neki 把自己放在了两条主流路线之间的空档里。一边是应用层分片,路由逻辑写进业务代码,灵活但把分布式系统的复杂度交给了每个应用团队;另一边是 CockroachDB、YugabyteDB 这类「Postgres 兼容」的分布式数据库,提供透明扩展,代价是自研存储引擎带来的扩展缺失与行为差异。Neki 的赌注是:只要每个分片是真 Postgres,扩展生态、SQL 行为与性能特征就都能保持原样,透明性则交给 router 与那份 JSON 拓扑去实现。
这个赌注的代价也很清楚——跨分片事务与查询规划的正确性全部压在 router 上,而 router 本身成了一个必须水平扩展的新组件。官方博客没有给出任何基准数字,且明确写着平台预览期间不应运行生产负载,产品仍在变化且部分变更会是破坏性的。对正在评估的团队来说,值得关注的不是分片能力本身,而是那份 data topology 的表达力边界:分片键与表分组一旦写进 JSON,改动的成本就由这份配置的灵活性决定。
相关链接
火山引擎开源 OpenViking:把 Agent 的记忆与技能收进一层可寻址存储
事件概述
火山引擎开源的 OpenViking 近期登上 GitHub Trending,仓库 volcengine/OpenViking 星标数超过 3.7 万,许可为 AGPLv3(CLI 与示例为 Apache 2.0),最新版本 v0.4.19 发布于 9 月 8 日,Go SDK v0.0.2 发布于 9 月 10 日。项目定位是「AI Agent 的上下文数据库」,把原本分散在各类 agent 实现里的三类长期能力收敛到一个底座:跨会话记忆(Agent Memory)、知识检索(Knowledge RAG)与可调用技能(Skills)。
它的核心抽象是一个虚拟文件系统。上下文被组织在 viking:// 之下,agent 可以像操作文件一样用 ls、tree、read、write 浏览目录、读写内容,也可以在某个目录内检索;目录摘要支持按需加载。
技术解析
- 三层按需加载:L0(Abstract)是一句话摘要,用于快速判断相关性;L1(Overview)是核心信息与适用场景,用于规划;L2(Details)是完整原文,只在需要时读取。经过语义处理的目录会自带
.abstract.md与.overview.md,使 agent 能在读全文之前先判断该目录值不值得读。 - 目录结构即检索范围:
viking://下分为resources/(项目文档、仓库、网页等)与user/{user_id}/,后者按memories/、resources/、skills/、peers/组织。检索先在目录结构内用向量搜索定位候选目录,再探查其内容;find直接执行查询,search则可以结合会话上下文来规划检索路径。 - 会话转记忆:提交一个会话会归档对话并启动后台抽取。记忆策略控制保留什么,抽取出的候选会与已有记忆比较,决定创建、合并还是跳过。启用 VikingBot 后,
ov compile可以用一个 skill 把源材料组织成 wiki、知识图谱或报告。 - 官方基准(0.3.22 版本):在长对话用户记忆评测 LoCoMo 上,三类 agent 集成接入 OpenViking 后准确率落在 80–83%,而各自原生记忆为 24–57%——OpenClaw 从 24.20% 升至 82.08%,Hermes 从 33.38% 升至 82.86%,Claude Code 从 57.21% 升至 80.32%;输入 token 下降 34.3–91.0%,查询延迟下降 58.45–66.10%。在多轮 agent 任务 tau2-bench 上,经验记忆使任务成功率在零售场景提升 6.87 个百分点、航空场景提升 11.87 个百分点。评测使用 Doubao 2.0 Pro 作为 VLM、Doubao-embedding-vision-251215 作为嵌入模型。
行业影响
过去两年 agent 的记忆基本是各框架的内部实现问题——每个 agent 自己决定存什么、怎么索引、何时清理,结果是记忆无法跨框架迁移,换一个 agent 栈就全部作废。OpenViking 把它变成一层带 URI 的外部存储,试图让记忆像文件一样可寻址、可浏览、可被任何 agent 读写,这与数据库把应用内存里的状态外置成可查询实体的历史路径一致。
需要看清两个前提。第一,L0/L1 摘要不是免费的,它们本身是需要生成、随内容更新而失效、并占用存储的派生数据,等于用一份额外的写入与维护成本换读取时的 token 节省——输入 token 下降三到九成这个数字,必须和摘要维护的代价放在一起看。第二,上述基准绑定了特定的 VLM 与嵌入模型,换一组模型后绝对数字未必成立,可比的是相对提升幅度。还有一点值得注意:原生记忆越弱的 agent(OpenClaw 24.20%)提升越大,越强的(Claude Code 57.21%)提升越小,说明这类外部记忆层主要补的是「没有记忆实现」的短板,而不是全面超越已有实现。
相关链接
编者评
把四条放在一起看,会看到一个反复出现的动作:某项能力原本由每个使用方各自带一份,现在被收拢到一个专门的层里统一提供,而这个层随即成为新的约束点。
Habitat 把存储逻辑从几十个服务的客户端库收回服务端,协调成本从组织层面移到平台层面,平台则必须自己扛住每秒七千万请求与 p99 尾延迟,并接受一个刻意做弱的 API 作为代价。Manas 把索引从内存搬到 SSD,由平台统一决定量化方案与每请求的 I/O 预算,换来的是约 5% 的召回损失与一套必须持续调优的簇大小分布。Neki 把分片路由从应用代码收进 router 与那份 JSON 数据拓扑,跨分片正确性全部压在一个必须水平扩展的新组件上,而分片键一旦写定,改动成本就由拓扑的表达力决定。OpenViking 把 agent 的记忆与技能从各框架的内部实现收进 viking://,记忆得以跨栈迁移,代价是多出一份需要生成、更新与失效管理的摘要派生数据。
这四处的共同点不在于技术选型,而在于代价的位移方向:收拢之后代价没有变小,只是从「每个使用方各自承担、彼此不可见」变成了「一个层集中承担、且必须被显式度量」。Habitat 的 5% 召回、Neki 的 router 瓶颈、OpenViking 的摘要维护,都是这种位移留下的账单。判断这类改造是否值得,看的不是收拢本身,而是这一层有没有把代价变成可观测、可调优的旋钮——Pinterest 用在线 A/B 逐个用例选量化器、Neki 把分片键写进可版本化的 JSON,都是把账单摆到台面上的做法;而那些收拢之后代价仍然隐形的改造,通常会在下一个数量级上还回来。