- 人工智能
- RAG
- 大模型
【免费下载链接】llama_index
LlamaIndex is the document processing platform for AI
本篇技术指南围绕 LlamaIndex 仓库中的llama_index.storage.index_store.gel模块(API 参考页见 docs/api_reference/api_reference/storage/index_store/gel.md),系统讲解如何以 Gel(EdgeDB 的新一代开源图关系数据库)为后端持久化索引结构。读完本文,你将掌握GelIndexStore的完整类结构、底层GelKVStore的实现原理、Gel 数据模型与迁移步骤,以及同步/异步两种 API 的实际用法。
一、GelIndexStore 在 LlamaIndex 存储体系中的定位
LlamaIndex 将索引构建信息封装为IndexStruct(索引结构),需要一套持久化机制在构建完成后保存"索引本身长什么样",这套机制就是Index Store。它区别于存放文档切片的 DocStore 与存放原始向量的 Vector Store,只关心索引结构的元数据。
GelIndexStore正是 Index Store 的一个具体实现,它把索引结构存储在Gel数据库中。从继承关系看(见 test_storage_index_store_gel.py),GelIndexStore直接继承自核心包的KVIndexStore:
GelIndexStore → KVIndexStore → BaseIndexStore这意味着它本质上是一个"KV(键值)型 Index Store",所有索引结构都被序列化为键值对写入底层 KV 存储。同时,测试文件 test_gel.py 演示了它与GelKVStore的组合使用方式。
二、GelIndexStore 类定义与构造参数
GelIndexStore的定义十分精简(见 base.py),全部业务逻辑复用自父类,自身只负责"绑定 Gel KV 后端":
from typing import Optional from llama_index.core.storage.index_store.keyval_index_store import KVIndexStore from llama_index.storage.kvstore.gel import GelKVStore class GelIndexStore(KVIndexStore): """ Gel Index store. Args: gel_kvstore (GelKVStore): Gel key-value store namespace (str): namespace for the index store """ def __init__( self, gel_kvstore: GelKVStore, namespace: Optional[str] = None, collection_suffix: Optional[str] = None, ) -> None: """Init a GelIndexStore.""" super().__init__( gel_kvstore, namespace=namespace, collection_suffix=collection_suffix )三个构造参数的含义如下:
| 参数 | 类型 | 说明 |
|---|---|---|
gel_kvstore | GelKVStore | 必填,底层的 Gel 键值存储实例 |
namespace | Optional[str] | 索引存储的命名空间,默认为"index_store" |
collection_suffix | Optional[str] | 集合名后缀,默认为"/data" |
其中namespace与collection_suffix的默认值定义在父类 keyval_index_store.py 顶部:
DEFAULT_NAMESPACE = "index_store" DEFAULT_COLLECTION_SUFFIX = "/data"实际存储时,Gel 中的"集合名"由两者拼接而成:f"{self._namespace}{self._collection_suffix}",即默认的"index_store/data"。这个集合名会作为底层 KV 记录的namespace字段写入 Gel。
三、继承而来的完整 Index Store 能力
虽然GelIndexStore自身只有构造逻辑,但通过继承KVIndexStore(keyval_index_store.py),它完整具备了BaseIndexStore抽象基类(types.py)定义的全部接口。核心方法及其底层行为如下:
| 方法 | 同步/异步 | 底层 KV 调用 |
|---|---|---|
add_index_struct(index_struct)/async_add_index_struct | 同步/异步 | 以index_struct.index_id为 key,序列化后put写入 |
get_index_struct(struct_id)/aget_index_struct | 同步/异步 | 按 keyget;struct_id=None时若只有一条记录则直接返回 |
delete_index_struct(key)/adelete_index_struct | 同步/异步 | 按 keydelete |
index_structs()/async_index_structs | 同步/异步 | get_all后逐个反序列化为IndexStruct |
序列化由 utils.py 中的index_struct_to_json/json_to_index_struct完成,因此任意IndexStruct子类(如IndexGraph)都可以被 Gel 持久化。这一点在测试 test_gel.py 中得到了直接验证:
def test_gel_index_store(gel_indexstore: GelIndexStore) -> None: index_struct = IndexGraph() index_store = gel_indexstore index_store.add_index_struct(index_struct) assert index_store.get_index_struct(struct_id=index_struct.index_id) == index_struct测试还展示了完整的生命周期管理:通过 fixture 在测试结束后遍历kvstore.get_all().keys()并逐个delete,避免残留数据影响后续断言。
四、底层存储原理:GelKVStore 与 EdgeQL 实现
GelIndexStore的存储能力完全委托给GelKVStore,后者实现了核心包中的BaseKVStore接口(types.py),并定义了DEFAULT_COLLECTION = "data"与DEFAULT_BATCH_SIZE = 1。
GelKVStore的实现位于 kvstore-gel/base.py,其核心设计如下。
4.1 数据模型:单一 Record 类型
集成依赖 Gel 中一个自定义对象类型Record,schema 定义在 dbschema/default.gel:
module default { type Record { required key: str; required namespace: str; value: json; constraint exclusive on ((.key, .namespace)); } }字段语义:
key:必填字符串,即 KV 的键(对 Index Store 而言是IndexStruct.index_id);namespace:必填字符串,对应GelKVStore.put/get中的collection参数(对 Index Store 而言是拼接后的集合名);value:json类型,存储序列化后的索引结构数据;constraint exclusive on ((.key, .namespace)):约束(key, namespace)二元组全局唯一,保证同一命名空间内键不冲突。
4.2 核心 EdgeQL 查询
GelKVStore将全部操作翻译为原生 EdgeQL 查询,key/namespace/value均以参数化方式传入:
- 写入/覆盖(
PUT_QUERY):采用insert ... unless conflict on (.key, .namespace) else (update ...)的 upsert 语义——键不存在则插入,存在则仅更新value,天然幂等; - 批量写入(
PUT_ALL_QUERY):借助json_array_unpack解包 JSON 数组,配合for item in ... union (...)在一个查询内完成多条 upsert,并按batch_size(默认 1)分批执行; - 单键读取(
GET_QUERY):按key与namespace过滤后select record.value; - 全量读取(
GET_ALL_QUERY):按namespace过滤,返回{key, value}集合,随后在 Python 侧组装为字典; - 删除(
DELETE_QUERY):delete Record filter .key = ... and .namespace = ...,返回值非空表示确有删除。
4.3 客户端管理与错误提示
GelKVStore内部同时维护同步与异步两套 Gel 客户端(gel.create_client()/gel.create_async_client()),并且做了互斥保护:若同一实例先被异步使用过,再调用同步方法会抛出RuntimeError,反之亦然,避免混用 IO 模式(源码中有明确提示"please create a new instance instead")。
初始化时会执行两次防御性检查:
ensure_connected():连接失败(ClientConnectionError)时提示"Gel 项目可能尚未初始化",见 kvstore-gel/base.py 中的NO_PROJECT_MESSAGE;select {record_type}:若InvalidReferenceError,说明 schema 中缺少Record类型,日志会给出完整的dbschema/default.gel补全模板与迁移命令(MISSING_RECORD_TYPE_TEMPLATE)。
五、安装与 Gel 环境准备
5.1 安装集成包
集成包的元数据见 pyproject.toml,发布名为llama-index-storage-index-store-gel:
pip install llama-index-storage-index-store-gel其依赖为:
llama-index-storage-kvstore-gel>=0.2.0,<0.3(提供GelKVStore)llama-index-core>=0.13.0,<0.15(提供KVIndexStore、BaseKVStore等核心抽象)- Python 版本要求
>=3.10,<4.0
底层还需要 Gel 的 Python 驱动,源码在导入阶段即强制检查(try: import gel,失败则抛出提示 "Please install it using 'pip install gel'"):
pip install gel5.2 初始化 Gel 项目与数据库
GelKVStore通过gel.create_client()连接数据库,连接信息来自 Gel CLI 的项目级配置。首次使用需在当前目录初始化项目并启动实例:
# 初始化 Gel 项目(test 代码中使用的正是该命令) gel project init --non-interactive随后创建并应用迁移,以保证 schema 中存在Record类型。迁移目录见 dbschema/migrations,其中 00001-m1qleqa.edgeql 就是创建default::Record类型的初始迁移。手动补 schema 后的迁移命令为:
gel migration create gel migrate注意:集成包目录下的 gel.toml 声明了server-version = "6.4",说明该集成对应的 Gel 服务端版本为 6.4,使用其他大版本时建议参考其兼容性。
5.3 环境限制说明
测试用例 test_gel.py 与 test_storage_kvstore_gel.py 均带有两重跳过逻辑:gel包未安装时跳过;环境变量CI存在时跳过(避免在 CI 中拉起数据库)。这意味着集成验证需要本地的 Gel 运行环境。
六、完整使用示例
6.1 构建索引并持久化到 Gel
将GelIndexStore接入 LlamaIndex 索引构建流程,核心步骤只有三步:创建GelKVStore→ 用它构造GelIndexStore→ 在构建索引时传入:
from llama_index.core import VectorStoreIndex from llama_index.core.schema import Document from llama_index.storage.kvstore.gel import GelKVStore from llama_index.storage.index_store.gel import GelIndexStore # 1. 创建 Gel KV 后端与 Index Store kvstore = GelKVStore() index_store = GelIndexStore(gel_kvstore=kvstore) # 2. 构建索引并将 index_store 传入 documents = [Document(text="LlamaIndex 的 GelIndexStore 实战示例")] index = VectorStoreIndex.from_documents( documents, index_store=index_store, # 索引结构写入 Gel # 这里还可按需传入 docstore / vector_store ) # 3. 验证读取 struct = index_store.get_index_struct(struct_id=index.index_id) print(struct) # IndexGraph 等具体结构 # 4. 清理 index_store.delete_index_struct(index.index_id)6.2 直接操作 Index Store 的增删查
也可以不经过索引构建,直接以 KV 语义操作索引结构:
from llama_index.core.data_structs.data_structs import IndexGraph from llama_index.storage.kvstore.gel import GelKVStore from llama_index.storage.index_store.gel import GelIndexStore store = GelIndexStore(gel_kvstore=GelKVStore()) graph = IndexGraph() store.add_index_struct(graph) # 写入 assert store.get_index_struct(graph.index_id) == graph # 读取 assert len(store.index_structs()) >= 1 # 全量列举 # 异步版本 # await store.async_add_index_struct(graph) # assert await store.aget_index_struct(graph.index_id) == graph # await store.adelete_index_struct(graph.index_id)6.3 自定义命名空间隔离多套索引
通过namespace与collection_suffix参数可以为不同业务隔离索引数据(对应 Gel 中不同的namespace记录):
store_a = GelIndexStore(gel_kvstore=GelKVStore(), namespace="tenant_a") store_b = GelIndexStore(gel_kvstore=GelKVStore(), namespace="tenant_b")两者互不干扰,即使 key 相同也不会冲突——这正是Record上exclusive on ((.key, .namespace))约束的意义所在。
七、实现要点小结
- 职责单一:
GelIndexStore只做"绑定 Gel KV 后端",全部索引语义来自KVIndexStore,因此天然支持同步与异步全套接口,且序列化协议与其余 KV 型 Index Store 完全一致; - 幂等写入:Gel 层的 upsert 查询使重复写入同一
index_id不会产生重复记录,适合索引重建、增量更新等场景; - 防御性检查:
GelKVStore在首次连接时即校验项目初始化与 schema 完整性,错误信息直接给出修复命令,降低了环境排查成本; - 同步/异步互斥:同一
GelKVStore实例不可混用同步与异步调用,需要两种模式时应分别创建实例。
如需进一步深入,可阅读以下仓库路径:GelIndexStore实现见 llama-index-integrations/storage/index_store/llama-index-storage-index-store-gel/llama_index/storage/index_store/gel/base.py;父类KVIndexStore见 llama-index-core/llama_index/core/storage/index_store/keyval_index_store.py;底层GelKVStore见 llama-index-integrations/storage/kvstore/llama-index-storage-kvstore-gel/llama_index/storage/kvstore/gel/base.py;数据模型与迁移见 dbschema/default.gel 与 dbschema/migrations;验证用例见 tests/test_gel.py。
- 人工智能
- RAG
- 大模型
【免费下载链接】llama_index
LlamaIndex is the document processing platform for AI
相关推荐
LlamaIndex GelChatStore 详解:用 Gel 数据库持久化聊天记忆存储(Chat Store)
LlamaIndex GelChatStore 详解:用 Gel 数据库持久化聊天记忆存储(Chat Store) 本文围绕 LlamaIndex 的 llam
人工智能RAG大模型LlamaIndex PostgresKVStore 实战指南:基于 PostgreSQL 的键值存储集成解析
LlamaIndex PostgresKVStore 实战指南:基于 PostgreSQL 的键值存储集成解析 PostgresKVStore 是 LlamaI
人工智能RAG大模型LlamaIndex RedisIndexStore 完全指南:基于 Redis 的索引结构持久化存储
LlamaIndex RedisIndexStore 完全指南:基于 Redis 的索引结构持久化存储 在 LlamaIndex 的持久化体系里,一个常被忽视却
人工智能RAG大模型
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考