openai-simple-vectorstore
可扩展的多向量数据库接入库,内置 redis-search、milvus、milvus-lite、 pgvector、elasticsearch、sqlite-vec 与 qdrant 等后端,并提供统一的 embeddings / rerank 二阶段召回、插入、删除、刷新等管理接口。
- redis-search 后端与 openai-redis-vectorstore 行为 100% 兼容(相同的 uid 规则、relevance score、索引 schema)。
- 通过工厂 + 注册表机制可低成本扩展其它向量数据库后端。
安装
作为业务方使用时,从 PyPI 安装本库并选择所需后端:
# 默认后端(redis-search)
pip3 install openai-simple-vectorstore
# 仅 redis-search 后端
pip3 install "openai-simple-vectorstore[redis]"
# 仅 milvus 后端(依赖 pymilvus)
pip3 install "openai-simple-vectorstore[milvus]"
# 仅 milvus-lite 后端(嵌入式 milvus,无需单独部署,适合本地开发/测试)
pip3 install "openai-simple-vectorstore[milvus-lite]"
# 仅 pgvector 后端(依赖 psycopg2-binary)
pip3 install "openai-simple-vectorstore[pgvector]"
# 仅 elasticsearch 后端
pip3 install "openai-simple-vectorstore[elasticsearch]"
# 仅 sqlite-vec 后端(嵌入式 SQLite,无需单独部署)
pip3 install "openai-simple-vectorstore[sqlite-vec]"
# 仅 qdrant 后端(依赖 qdrant-client)
pip3 install "openai-simple-vectorstore[qdrant]"
# 全部后端
pip3 install "openai-simple-vectorstore[all]"
在仓库源码目录内本地开发时使用
pip3 install -e ".[all]";离线安装本库自身依赖时, 使用pip3 install --no-index --find-links wheelhouse/ -r requirements.txt。
快速开始
选择 redis-search 后端(默认)
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store() # 默认后端由 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB 决定
# 插入
uid = vs.insert("今天天气很好", kb_id="kb1", doc_id="doc1", page_id="p1")
# 二阶段召回(向量检索 + rerank 重排)
docs = vs.similarity_search_and_rerank(
query="今天天气怎么样",
index_name="default",
k=3,
)
for doc in docs:
print(doc.vs_page_content, doc.vs_embeddings_score, doc.vs_rerank_score)
# 删除 / 刷新
vs.delete(uid)
vs.flush("default")
选择 milvus 后端
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store( # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus
vector_db="milvus"
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
选择 milvus-lite 后端(嵌入式,本地开发/测试)
milvus-lite 与 milvus 使用相同的 MilvusClient API,仅连接方式不同:milvus 通过
http://host:19530 连接服务端,milvus-lite 通过本地文件路径启动进程内嵌入式数据库,
无需部署 milvus 服务。
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store(
vector_db="milvus-lite", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus-lite
milvus_lite_uri="./milvus_lite.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
选择 sqlite-vec 后端(嵌入式,本地开发/测试)
sqlite-vec 是 SQLite 的向量搜索扩展,所有数据存在本地文件中,无需单独部署服务。 注意:需要 sqlite3 支持 loadable-extension(多数发行版 CPython 均支持)。
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store(
vector_db="sqlite-vec", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=sqlite-vec
sqlite_vec_uri="./sqlite_vec.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
选择 pgvector 后端(PostgreSQL 扩展)
需要 PostgreSQL 已安装 pgvector 扩展(程序启动时会尝试 CREATE EXTENSION IF NOT EXISTS vector):
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store(
vector_db="pgvector", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=pgvector
pgvector_url="postgresql://user:pass@localhost:5432/postgres", # 默认 OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
选择 elasticsearch 后端
需要 Elasticsearch 8.x(dense_vector + HNSW):
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store(
vector_db="elasticsearch", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=elasticsearch
es_url="http://localhost:9200",
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
选择 qdrant 后端
需要部署 Qdrant 服务(或使用 Qdrant Cloud)。使用原生 payload 过滤,无需像 milvus / sqlite-vec 那样对候选集做放大:
from openai_simple_vectorstore import create_vector_store
vs = create_vector_store(
vector_db="qdrant", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=qdrant
qdrant_url="http://localhost:6333", # 默认 OPENAI_SIMPLE_VECTORSTORE_QDRANT_URL
qdrant_api_key=None, # 默认 OPENAI_SIMPLE_VECTORSTORE_QDRANT_API_KEY
# qdrant_prefer_grpc=True, # 默认 OPENAI_SIMPLE_VECTORSTORE_QDRANT_PREFER_GRPC
# qdrant_on_disk=False, # 默认 OPENAI_SIMPLE_VECTORSTORE_QDRANT_ON_DISK(True)
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
qdrant_on_disk(默认 True)同时作用于向量、HNSW 图和 payload 索引:
向量与 HNSW 图均落盘(mmap),避免整张图常驻内存;代价是检索时的随机读会变慢,
建议搭配 NVMe SSD,并在高召回(大 m)场景下评估延迟。
本地快速启动(podman):
podman run -d --name qdrant -p 6333:6333 -p 6334:6334 docker.io/qdrant/qdrant:latest
直接实例化(不依赖全局配置)
from openai_simple_vectorstore import RedisVectorStore
from openai_simple_vectorstore.base import Connection
from openai_simple_vectorstore.utils import YamlSerializer
vs = RedisVectorStore(
redis_stack_url="redis://localhost:6379/0",
embeddings_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
rerank_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
embeddings_model="bge-m3",
rerank_model="bge-reranker-v2-m3",
metadata_serializer=YamlSerializer(),
)
环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB |
redis |
后端:redis / redis-search / milvus / milvus-lite / pgvector / elasticsearch / sqlite-vec / qdrant |
OPENAI_SIMPLE_VECTORSTORE_REDIS_STACK_URL |
redis://localhost:6379/0 |
redis-stack 地址(redis 后端) |
OPENAI_SIMPLE_VECTORSTORE_MILVUS_URI |
http://localhost:19530 |
milvus 地址 |
OPENAI_SIMPLE_VECTORSTORE_MILVUS_TOKEN |
空 | milvus 鉴权 token |
OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI |
./milvus_lite.db |
milvus-lite 本地数据库文件路径 |
OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL |
postgresql://localhost:5432/postgres |
pgvector 连接串(pgvector 后端) |
OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_URL |
http://localhost:9200 |
elasticsearch 地址 |
OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_API_KEY |
空 | elasticsearch API key(优先于账号密码) |
OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_USERNAME |
空 | elasticsearch 用户名 |
OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_PASSWORD |
空 | elasticsearch 密码 |
OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_VERIFY_CERTS |
True |
是否校验证书(自签 HTTPS 集群可设 false) |
OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI |
./sqlite_vec.db |
sqlite-vec 本地数据库文件路径 |
OPENAI_SIMPLE_VECTORSTORE_QDRANT_URL |
http://localhost:6333 |
qdrant 服务地址(别名 QDRANT_URL) |
OPENAI_SIMPLE_VECTORSTORE_QDRANT_API_KEY |
空 | qdrant API key(别名 QDRANT_API_KEY) |
OPENAI_SIMPLE_VECTORSTORE_QDRANT_PREFER_GRPC |
False |
是否优先使用 gRPC(别名 QDRANT_PREFER_GRPC) |
OPENAI_SIMPLE_VECTORSTORE_QDRANT_ON_DISK |
True |
向量与 payload 索引是否落盘存储(别名 QDRANT_ON_DISK) |
OPENAI_BASE_URL |
http://localhost/v1 |
OpenAI 兼容服务基础地址 |
OPENAI_API_KEY |
空 | OpenAI 兼容服务密钥 |
OPENAI_EMBEDDINGS_MODEL |
bge-m3 |
embeddings 模型名 |
OPENAI_RERANK_MODEL |
bge-reranker-v2-m3 |
rerank 模型名 |
兼容
openai-redis-vectorstore:OPENAI_REDIS_VECTORSTORE_REDIS_STACK_URL、OPENAI_EMBEDDINGS_*、OPENAI_RERANK_*、OPENAI_BASE_URL、OPENAI_API_KEY等变量可直接使用。
扩展新的向量数据库后端
继承共享抽象基类 VectorStore 并实现以下方法,再注册到工厂即可:
- 实现
get_cached_vectorstore(引擎的获取与缓存) - 实现
_search_index,返回[(page_id, distance, item), ...] - 实现
get_item/delete/delete_many/flush
from openai_simple_vectorstore.base import VectorStore, IndexField
from openai_simple_vectorstore.registry import register_vector_store, create_vector_store
class MyStore(VectorStore):
def get_cached_vectorstore(self, **kwargs): ...
def _search_index(self, engine, query_embedding, index_name,
filters, filter_expression, k): ...
def get_item(self, uid): ...
def delete(self, uid): ...
def delete_many(self, uids): ...
def flush(self, index_name=None): ...
# 可选的统一字段模型 / 能力矩阵 / schema 查询契约
def _capabilities(self): ...
def _describe_index(self, index_name): ...
def _ensure_index_created(self, index_name, fields): ...
register_vector_store("mydb", MyStore)
vs = create_vector_store(vector_db="mydb")
base 会统一处理 embeddings 生成、rerank、过滤、去重、排序、relevance_score 与
Document 组装,后端只需专注各自的检索实现。
字段模型与过滤语义
各引擎通过统一的字段声明 / 能力矩阵 / schema 查询接口,向业务暴露"哪些扩展字段可过滤、索引现状如何":
IndexField:声明字段类型,支持tag/tag_multi/numeric/text/vector; 向量字段必须给出dims,并与引擎配置的embeddings_dims一致。capabilities():返回能力矩阵(Capabilities)——indexed_types表示后端建成 原生可过滤列的类型(如 redis、elasticsearch),meta_filter_types表示在元数据上做 Python/表达式侧兜底过滤的类型(如 milvus / sqlite-vec / pgvector 的部分类型)。describe_index(index_name):返回归一化的IndexSchemaInfo——exists=False表示 索引尚未创建(此时fields返回声明/期望字段,方便业务预创建),否则返回线上真实字段。create_index(index_name, fields):按声明的IndexField列表构建索引(显式传入的fields优先于实例构造时的declared_fields);已存在时仅补齐可增量添加的部分 (redisFT.ALTER/ elasticsearchput_mapping/ qdrant payload 索引),不会重建。compare_index_schema(index_name)/rebuild_index(index_name, force=...):只读检测 线上 schema 与期望是否漂移;重建一律是破坏性的(删除并重新索引、丢失该索引下的数据), 只能显式调用rebuild_index(force=True无条件重建,force=False仅在检测到漂移时 重建),不会在创建 / ensure 索引时自动触发。
过滤统一使用 Filter 对象(tag 精确、tag_multi 多值命中、numeric 区间 via op="range");
base 把归一化后的 filters 传入各后端的 engine/search。后端只需实现
_build_filter_expression(filters, filter_expression) 把归一化过滤器组装为原生过滤表达式。
概念说明
- uid:
<index_name>:<page_id>,用于唯一定位一条记录。 - relevance_score:
1 - distance,取值[0, 1],越大越相关。 - 二阶段召回:
similarity_search_and_rerank先用向量检索取k * scale条候选, 再经 rerank 重排取前k条。
开发与测试
python3 -m pytest -q
跑 pytest 时的覆盖率门槛在 pytest.ini 中(--cov-fail-under=90);
.coveragerc 的 fail_under=80 只作用于单独执行 coverage report 的场合。
测试分两类:
- 单元测试(
test_unit.py/test_engines_*.py):全部基于内存 fake,离线可跑。 - 真实嵌入式/外部服务集成测试(
test_engines_integration.py):优先使用真实数据库 跑完整链路(本地 OpenAI 兼容 HTTP stub 提供 embeddings/rerank,覆盖 base 真实 HTTP 路径):-
milvus-lite:进程内嵌入,直接运行; -
sqlite-vec:需要 sqlite3 支持 loadable-extension,否则自动跳过 (本机 python.org 构建默认不支持,可用支持扩展的 Homebrew python3 执行); -
pgvector:外部服务,通过OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL指定连接串, 连接可达才执行。例如:podman run -d --name pgvector-pg17 -p 55432:5432 \ -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \ docker.io/pgvector/pgvector:pg17 OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL='postgresql://postgres:postgres@localhost:55432/postgres' \ python3 -m pytest test_engines_integration.py -q
-
qdrant:外部服务,安装qdrant-client且通过OPENAI_SIMPLE_VECTORSTORE_QDRANT_URL指定的服务可达才执行。例如:podman run -d --name qdrant -p 6333:6333 -p 6334:6334 docker.io/qdrant/qdrant:latest OPENAI_SIMPLE_VECTORSTORE_QDRANT_URL='http://localhost:6333' \ python3 -m pytest test_engines_integration.py -q
未安装
qdrant-client时,test_engines_qdrant.py会注入内存 fake 客户端, 离线即可完整覆盖 qdrant 引擎逻辑。
-
# 真实嵌入式/外部后端(milvus-lite / sqlite-vec / pgvector / qdrant,按运行时能力自动启用)
python3 -m pytest test_engines_integration.py -q
版本记录
0.3.0(2026-09-24)
- 新增 qdrant 后端(原生 payload 过滤、
uuid5point id 映射、可配置on_disk, 同时作用于向量、HNSW 图与 payload 索引),并补齐capabilities/describe_index/create_index/ 漂移检测与重建。 create_index(index_name, fields=...)语义统一:显式传入的fields优先于实例构造时的declared_fields,redis / elasticsearch / qdrant 均生效;已存在索引时按可增量方式补齐 字段(redisFT.ALTER ... SCHEMA ADD、elasticsearchput_mapping、qdrant payload 索引)。- 索引重建收敛为显式调用:
rebuild_index不再在创建 / ensure 时自动触发;新增只读的compare_index_schema漂移检测(force=False仅在漂移时重建)。 - 修复 redis 索引 schema 漂移误报:
FT.INFO向量参数兼容dims=/DIM键值对两种格式, 字段类型与向量维度 / 距离度量归一化后比对。 - 移除未被调用的死钩子
_prepare_engine(milvus / milvus-lite / pgvector / elasticsearch / sqlite-vec)。 - 包元数据完善:描述列出全部后端并补充 embeddings / rerank 关键词。
0.2.0(2026-09-08)
- 演进为完整字段模型:新增
IndexField声明(tag/tag_multi/numeric/text/vector)、capabilities()能力矩阵、describe_index()归一化 schema 查询、create_index()schema 声明建索引。 - 过滤 DSL 升级为统一的
Filter(含numeric区间op="range")并新增validate_filters; 各引擎_search_index收敛为(engine, query_embedding, index_name, filters, filter_expression, k), 移除旧的kb_ids/categories参数(内部经Filter适配为vs_kb_id/vs_category字段)。 - redis / elasticsearch / milvus / milvus-lite / pgvector / sqlite-vec 全部适配新签名,
并补齐
capabilities/describe_index/_ensure_index_created。 Document新增vs_metadata字段:检索结果携带业务自定义元数据(如声明IndexField的可过滤标量vs_score),非标准vs_*模型字段在_extract_custom_metadata中聚拢。- milvus(独立部署)insert / delete 不再显式
flush():写入后检索可见依赖服务端自动落盘 (cacheFlushInterval,默认约 3s),有短暂写后读不一致窗口;集成测试据此改为有界轮询收敛。 - 覆盖率提升至 97%(阈值 90%)。
0.1.0(2026-09-08)
- 首个正式版本:在 redis-search 与 milvus 基础上新增 pgvector、elasticsearch、 sqlite-vec 三个后端(factory + registry 注册,支持 extras 选择性安装)。
- 统一 embeddings / rerank 二阶段召回、插入 / 删除 / 更新(upsert)/ 查询 / 刷新等接口。
- 新增 kb / category 元数据过滤语义:各引擎在向量候选上按元数据过滤。
- milvus(独立部署)与 milvus-lite 支持同 page_id 更新(upsert)与删除后立即可见。
- elasticsearch 显式声明 kb / doc / category 等 keyword 映射以支持过滤,并自动迁移旧 schema。
- 新增对 pgvector / elasticsearch / sqlite-vec / milvus 真实外部服务的端到端测试
(
test_engines_integration.py),覆盖率 96%(阈值 90%)。
License
Metadata
Release files for openai-simple-vectorstore 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openai_simple_vectorstore-0.3.0.tar.gz | 56.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openai_simple_vectorstore-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 124.6 kB
Release files / openai_simple_vectorstore-0.3.0.tar.gz
| Download URL | openai_simple_vectorstore-0.3.0.tar.gz |
|---|---|
| Size | 56.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
842bb82ca8cd6a39bd1e8dc980940a777e7fa043f7065aa53b380f2065f04c44
|
|
BLAKE2b-256 checksum How to use checksums |
662b7838127de8037854d1cdc2cd6c4f372b56c1c52e07dc44d50d0c1eb394fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / openai_simple_vectorstore-0.3.0-py3-none-any.whl
| Download URL | openai_simple_vectorstore-0.3.0-py3-none-any.whl |
|---|---|
| Size | 68.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a5aa6c6743a772b0c7eaae48e692dfb220f39532cbbbcd7cb475e18b1cc1d1e4
|
|
BLAKE2b-256 checksum How to use checksums |
906dea579598bd627159e1bb326cf2e1a43f5d412cc8be77de39f18d918e74b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|