Agent / 工程
SmithDB 如何为对象存储设计倒排索引以实现全文检索
SmithDB 是 LangChain 旗下 LangSmith 平台的底层数据库,专门用于存储和查询 Agent 运行追踪数据。这些追踪数据以深度嵌套的大型 JSON 文档形式存储于对象存储中,单条记录的 inputs 和 outputs 字段往往超过 1 MB,部分甚至达到数百 MB。面对如此庞大且结构复杂的数据,SmithDB 需要支持路径存在性查询、键值匹配查询和自由文本全文检索三种查询模式,同时还要应对对象存储每次请求数十至数百毫秒延迟的挑战。LangChain 工程团队没有直接采用 Lucene 或 Tantivy 等现有方案,而是从第一性原理出发,针对 Agent 追踪数据的独特特征重新设计了倒排索引的存储布局与查询执行策略,最终实现了中位延迟 400 毫秒的检索性能。
SmithDB 面临的核心挑战在于 Agent 追踪数据的特殊性。与传统日志引擎索引数十亿条小文档不同,SmithDB 索引的是数十亿条巨型文档。LangSmith 中每条事件记录的绝大部分字节都集中在 inputs 和 outputs 字段,这两个内容列比身份标识、时间戳等元数据列大出几个数量级。随着 LLM 上下文窗口不断扩大、Agent 运行时间持续延长,这些追踪数据的体量还在持续增长。实测数据显示,Agent 追踪的原始数据与索引数据之比约为 1:1.9,远高于传统日志场景的 1:1.25。
数据体量的倒置带来了三个直接后果。首先,没有索引的内容过滤代价极高——若要扫描候选范围内的所有 payload 来查找某个关键词,可能需要读取数 GB 数据才能返回寥寥几行结果。其次,词频分布遵循 Zipf 定律:少数高频词(如 agents、import、role、type 等)几乎出现在每一条文档中,而大量长尾词只出现一两次,索引必须在一个文件内跨越多个数量级的词频范围保持紧凑且可裁剪。第三,用户的查询模式多样,涵盖路径存在性、键值匹配和自由文本三种形态,倒排索引必须同时高效支持这三类查询。
对象存储的特性进一步加剧了设计难度。SmithDB 将所有持久化数据存放在对象存储中,以实现计算节点的无状态化和水平扩展。然而对象存储的每次请求延迟高达数十至数百毫秒,单次请求的吞吐量也相对有限。这意味着查询成本大致正比于请求次数与每次读取字节数的乘积。如果在确认需要某条 posting list 之前就盲目拉取,延迟将被放大到不可接受的程度。因此,SmithDB 倒排索引的存储布局和查询执行的每一个细节都必须围绕这一约束进行设计。
SmithDB 的查询接口抽象为三种谓词族。第一种是路径存在性查询(json_key),用于判断文档是否包含某个键路径,支持 LIKE 语法匹配前缀、后缀或中间片段。第二种是键值查询(json_key_search),在指定路径下匹配特定值,支持单词元和多词元短语,短语查询还要求词元在文档中连续出现。第三种是全文检索(search),在文本列或 JSON 所有值中搜索任意词元,不限定路径。这三种查询模式覆盖了用户在调试和分析 Agent 运行时的主要需求场景。
倒排索引的核心数据结构由词项(term)、posting list 和位置列表(positions)三部分构成。词项是索引的基本单元,可以是 JSON 路径、键值对或文本词元;posting list 是包含该词项的文档 ID 的有序集合;位置列表记录词项在文档中出现的具体位置,是实现短语查询的关键。以五条追踪文档为例,查询 search("deep agents") 时,系统分别取出 deep 和 agents 的 posting list 并求交集,再通过位置列表验证两个词元是否相邻,从而精确定位匹配文档,整个过程无需扫描任何原始 payload。
SmithDB 的这套设计思路体现了在特定约束下从第一性原理出发解决工程问题的价值。Lucene 和 Tantivy 等成熟方案针对的是通用场景,而 Agent 追踪数据在文档体量、词频分布和查询模式上的独特性,使得直接套用现有方案会带来显著的性能损耗。通过针对对象存储延迟特性优化存储布局、针对 Zipf 分布设计可裁剪的索引结构,SmithDB 最终在不依赖本地磁盘的纯对象存储架构上实现了 P50 延迟 400 毫秒的全文检索,为构建大规模 Agent 可观测性平台提供了重要的工程参考。
要点
- Agent 追踪数据的原始数据与索引数据之比约为 1:1.9,远高于传统日志场景,倒排索引对于避免全量 payload 扫描至关重要。
- 对象存储每次请求的高延迟要求索引的存储布局和查询执行必须最小化请求次数与读取字节数,不能盲目预取 posting list。
- SmithDB 支持路径存在性、键值匹配、自由文本三种查询谓词,倒排索引通过词项、posting list 和位置列表的组合统一支撑这三类查询。
- 词频的 Zipf 分布要求索引在单个文件内跨越多个数量级的词频范围保持紧凑且可裁剪,这是大型 JSON 文档场景下索引设计的核心难点。
- LangChain 选择从第一性原理重新设计而非直接采用 Lucene 或 Tantivy,验证了在特定数据特征和基础设施约束下定制化工程方案的必要性。
原始标题:Full Text Search in SmithDB: Designing an Inverted Index for Object Storage
本文由 DataHub 基于公开来源整理,用于信息发现与摘要阅读;具体事实、数据和后续更新以原始来源为准。