openai-simple-vectorstore 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. openai_simple_vectorstore-0.1.0/LICENSE +21 -0
  2. openai_simple_vectorstore-0.1.0/PKG-INFO +317 -0
  3. openai_simple_vectorstore-0.1.0/README.md +271 -0
  4. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/__init__.py +60 -0
  5. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/base.py +769 -0
  6. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/__init__.py +15 -0
  7. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/elasticsearch_vectorstore.py +475 -0
  8. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/milvus_lite_vectorstore.py +480 -0
  9. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/milvus_vectorstore.py +533 -0
  10. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/pgvector_vectorstore.py +504 -0
  11. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/redis_vectorstore.py +366 -0
  12. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/engines/sqlite_vec_vectorstore.py +507 -0
  13. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/registry.py +167 -0
  14. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/schemas.py +21 -0
  15. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/settings.py +252 -0
  16. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/utils.py +32 -0
  17. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore/version.py +4 -0
  18. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/PKG-INFO +317 -0
  19. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/SOURCES.txt +23 -0
  20. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/dependency_links.txt +1 -0
  21. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/entry_points.txt +7 -0
  22. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/requires.txt +34 -0
  23. openai_simple_vectorstore-0.1.0/openai_simple_vectorstore.egg-info/top_level.txt +1 -0
  24. openai_simple_vectorstore-0.1.0/pyproject.toml +88 -0
  25. openai_simple_vectorstore-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rRR0VrFP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,317 @@
1
+ Metadata-Version: 2.4
2
+ Name: openai-simple-vectorstore
3
+ Version: 0.1.0
4
+ Summary: 可扩展的多向量数据库(redis-search / milvus 等),集成embeddings和rerank模型,支持二阶段召回,支持添加和删除等管理功能。
5
+ Author: rRR0VrFP
6
+ Maintainer: rRR0VrFP
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://gitee.com/rRR0VrFP/openai-simple-vectorstore
9
+ Keywords: openai-simple-vectorstore,vectorstore,redis-search,milvus,milvus-lite,pgvector,elasticsearch,sqlite-vec
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: PyYAML
19
+ Requires-Dist: httpx
20
+ Requires-Dist: pydantic
21
+ Requires-Dist: python-environment-settings
22
+ Requires-Dist: zenutils
23
+ Provides-Extra: redis
24
+ Requires-Dist: redis; extra == "redis"
25
+ Requires-Dist: redisvl>=0.27.1; extra == "redis"
26
+ Provides-Extra: milvus
27
+ Requires-Dist: pymilvus>=2.3; extra == "milvus"
28
+ Provides-Extra: milvus-lite
29
+ Requires-Dist: pymilvus>=2.3; extra == "milvus-lite"
30
+ Requires-Dist: milvus-lite; extra == "milvus-lite"
31
+ Provides-Extra: pgvector
32
+ Requires-Dist: psycopg2-binary; extra == "pgvector"
33
+ Provides-Extra: elasticsearch
34
+ Requires-Dist: elasticsearch>=8.0; extra == "elasticsearch"
35
+ Provides-Extra: sqlite-vec
36
+ Requires-Dist: sqlite-vec; extra == "sqlite-vec"
37
+ Provides-Extra: all
38
+ Requires-Dist: redis; extra == "all"
39
+ Requires-Dist: redisvl>=0.27.1; extra == "all"
40
+ Requires-Dist: pymilvus>=2.3; extra == "all"
41
+ Requires-Dist: milvus-lite; extra == "all"
42
+ Requires-Dist: psycopg2-binary; extra == "all"
43
+ Requires-Dist: elasticsearch>=8.0; extra == "all"
44
+ Requires-Dist: sqlite-vec; extra == "all"
45
+ Dynamic: license-file
46
+
47
+ # openai-simple-vectorstore
48
+
49
+ 可扩展的多向量数据库接入库,内置 **redis-search**、**milvus**、**pgvector**、
50
+ **elasticsearch** 与 **sqlite-vec** 等后端,并提供统一的 embeddings / rerank
51
+ 二阶段召回、插入、删除、刷新等管理接口。
52
+
53
+ - redis-search 后端与 [openai-redis-vectorstore](https://gitee.com/rRR0VrFP/openai-redis-vectorstore)
54
+ 行为 100% 兼容(相同的 uid 规则、relevance score、索引 schema)。
55
+ - 通过工厂 + 注册表机制可低成本扩展其它向量数据库后端。
56
+
57
+ ## 安装
58
+
59
+ 作为业务方使用时,从 PyPI 安装本库并选择所需后端:
60
+
61
+ ```bash
62
+ # 默认后端(redis-search)
63
+ pip3 install openai-simple-vectorstore
64
+
65
+ # 仅 redis-search 后端
66
+ pip3 install "openai-simple-vectorstore[redis]"
67
+
68
+ # 仅 milvus 后端(依赖 pymilvus)
69
+ pip3 install "openai-simple-vectorstore[milvus]"
70
+
71
+ # 仅 milvus-lite 后端(嵌入式 milvus,无需单独部署,适合本地开发/测试)
72
+ pip3 install "openai-simple-vectorstore[milvus-lite]"
73
+
74
+ # 仅 pgvector 后端(依赖 psycopg2-binary)
75
+ pip3 install "openai-simple-vectorstore[pgvector]"
76
+
77
+ # 仅 elasticsearch 后端
78
+ pip3 install "openai-simple-vectorstore[elasticsearch]"
79
+
80
+ # 仅 sqlite-vec 后端(嵌入式 SQLite,无需单独部署)
81
+ pip3 install "openai-simple-vectorstore[sqlite-vec]"
82
+
83
+ # 全部后端
84
+ pip3 install "openai-simple-vectorstore[all]"
85
+ ```
86
+
87
+ > 在仓库源码目录内本地开发时使用 `pip3 install -e ".[all]"`;离线安装本库自身依赖时,
88
+ > 使用 `pip3 install --no-index --find-links wheelhouse/ -r requirements.txt`。
89
+
90
+ ## 快速开始
91
+
92
+ ### 选择 redis-search 后端(默认)
93
+
94
+ ```python
95
+ from openai_simple_vectorstore import create_vector_store
96
+
97
+ vs = create_vector_store() # 默认后端由 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB 决定
98
+
99
+ # 插入
100
+ uid = vs.insert("今天天气很好", kb_id="kb1", doc_id="doc1", page_id="p1")
101
+
102
+ # 二阶段召回(向量检索 + rerank 重排)
103
+ docs = vs.similarity_search_and_rerank(
104
+ query="今天天气怎么样",
105
+ index_name="default",
106
+ k=3,
107
+ )
108
+ for doc in docs:
109
+ print(doc.vs_page_content, doc.vs_embeddings_score, doc.vs_rerank_score)
110
+
111
+ # 删除 / 刷新
112
+ vs.delete(uid)
113
+ vs.flush("default")
114
+ ```
115
+
116
+ ### 选择 milvus 后端
117
+
118
+ ```python
119
+ from openai_simple_vectorstore import create_vector_store
120
+
121
+ vs = create_vector_store( # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus
122
+ vector_db="milvus"
123
+ )
124
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
125
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
126
+ ```
127
+
128
+ ### 选择 milvus-lite 后端(嵌入式,本地开发/测试)
129
+
130
+ milvus-lite 与 milvus 使用相同的 `MilvusClient` API,仅连接方式不同:milvus 通过
131
+ `http://host:19530` 连接服务端,milvus-lite 通过本地文件路径启动进程内嵌入式数据库,
132
+ 无需部署 milvus 服务。
133
+
134
+ ```python
135
+ from openai_simple_vectorstore import create_vector_store
136
+
137
+ vs = create_vector_store(
138
+ vector_db="milvus-lite", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus-lite
139
+ milvus_lite_uri="./milvus_lite.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI
140
+ )
141
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
142
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
143
+ ```
144
+
145
+
146
+ ### 选择 sqlite-vec 后端(嵌入式,本地开发/测试)
147
+
148
+ sqlite-vec 是 SQLite 的向量搜索扩展,所有数据存在本地文件中,无需单独部署服务。
149
+ 注意:需要 sqlite3 支持 loadable-extension(多数发行版 CPython 均支持)。
150
+
151
+ ```python
152
+ from openai_simple_vectorstore import create_vector_store
153
+
154
+ vs = create_vector_store(
155
+ vector_db="sqlite-vec", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=sqlite-vec
156
+ sqlite_vec_uri="./sqlite_vec.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI
157
+ )
158
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
159
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
160
+ ```
161
+
162
+ ### 选择 pgvector 后端(PostgreSQL 扩展)
163
+
164
+ 需要 PostgreSQL 已安装 pgvector 扩展(程序启动时会尝试 ``CREATE EXTENSION IF NOT EXISTS vector``):
165
+
166
+ ```python
167
+ from openai_simple_vectorstore import create_vector_store
168
+
169
+ vs = create_vector_store(
170
+ vector_db="pgvector", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=pgvector
171
+ pgvector_url="postgresql://user:pass@localhost:5432/postgres", # 默认 OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL
172
+ )
173
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
174
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
175
+ ```
176
+
177
+ ### 选择 elasticsearch 后端
178
+
179
+ 需要 Elasticsearch 8.x(dense_vector + HNSW):
180
+
181
+ ```python
182
+ from openai_simple_vectorstore import create_vector_store
183
+
184
+ vs = create_vector_store(
185
+ vector_db="elasticsearch", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=elasticsearch
186
+ es_url="http://localhost:9200",
187
+ )
188
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
189
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
190
+ ```
191
+
192
+ ### 直接实例化(不依赖全局配置)
193
+
194
+ ```python
195
+ from openai_simple_vectorstore import RedisVectorStore
196
+ from openai_simple_vectorstore.base import Connection
197
+ from openai_simple_vectorstore.utils import YamlSerializer
198
+
199
+ vs = RedisVectorStore(
200
+ redis_stack_url="redis://localhost:6379/0",
201
+ embeddings_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
202
+ rerank_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
203
+ embeddings_model="bge-m3",
204
+ rerank_model="bge-reranker-v2-m3",
205
+ metadata_serializer=YamlSerializer(),
206
+ )
207
+ ```
208
+
209
+ ## 环境变量
210
+
211
+ | 变量 | 默认值 | 说明 |
212
+ | --- | --- | --- |
213
+ | `OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB` | `redis` | 后端:`redis` / `redis-search` / `milvus` / `milvus-lite` / `pgvector` / `elasticsearch` / `sqlite-vec` |
214
+ | `OPENAI_SIMPLE_VECTORSTORE_REDIS_STACK_URL` | `redis://localhost:6379/0` | redis-stack 地址(redis 后端) |
215
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_URI` | `http://localhost:19530` | milvus 地址 |
216
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_TOKEN` | 空 | milvus 鉴权 token |
217
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI` | `./milvus_lite.db` | milvus-lite 本地数据库文件路径 |
218
+ | `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` | `postgresql://localhost:5432/postgres` | pgvector 连接串(pgvector 后端) |
219
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_URL` | `http://localhost:9200` | elasticsearch 地址 |
220
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_API_KEY` | 空 | elasticsearch API key(优先于账号密码) |
221
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_USERNAME` | 空 | elasticsearch 用户名 |
222
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_PASSWORD` | 空 | elasticsearch 密码 |
223
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_VERIFY_CERTS` | `True` | 是否校验证书(自签 HTTPS 集群可设 `false`) |
224
+ | `OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI` | `./sqlite_vec.db` | sqlite-vec 本地数据库文件路径 |
225
+ | `OPENAI_BASE_URL` | `http://localhost/v1` | OpenAI 兼容服务基础地址 |
226
+ | `OPENAI_API_KEY` | 空 | OpenAI 兼容服务密钥 |
227
+ | `OPENAI_EMBEDDINGS_MODEL` | `bge-m3` | embeddings 模型名 |
228
+ | `OPENAI_RERANK_MODEL` | `bge-reranker-v2-m3` | rerank 模型名 |
229
+
230
+ > 兼容 `openai-redis-vectorstore`:`OPENAI_REDIS_VECTORSTORE_REDIS_STACK_URL`、
231
+ > `OPENAI_EMBEDDINGS_*`、`OPENAI_RERANK_*`、`OPENAI_BASE_URL`、`OPENAI_API_KEY` 等变量可直接使用。
232
+
233
+ ## 扩展新的向量数据库后端
234
+
235
+ 继承共享抽象基类 `VectorStore` 并实现以下方法,再注册到工厂即可:
236
+
237
+ 1. 实现 `get_cached_vectorstore`(引擎的获取与缓存)
238
+ 2. 实现 `_search_index`,返回 `[(page_id, distance, item), ...]`
239
+ 3. 实现 `get_item` / `delete` / `delete_many` / `flush`
240
+
241
+ ```python
242
+ from openai_simple_vectorstore.base import VectorStore
243
+ from openai_simple_vectorstore.registry import register_vector_store, create_vector_store
244
+
245
+ class MyStore(VectorStore):
246
+ def get_cached_vectorstore(self, **kwargs): ...
247
+ def _search_index(self, engine, query_embedding, index_name,
248
+ kb_ids, categories, filter_expression, k): ...
249
+ def get_item(self, uid): ...
250
+ def delete(self, uid): ...
251
+ def delete_many(self, uids): ...
252
+ def flush(self, index_name=None): ...
253
+
254
+ register_vector_store("mydb", MyStore)
255
+ vs = create_vector_store(vector_db="mydb")
256
+ ```
257
+
258
+ `base` 会统一处理 embeddings 生成、rerank、过滤、去重、排序、`relevance_score` 与
259
+ `Document` 组装,后端只需专注各自的检索实现。
260
+
261
+ ## 概念说明
262
+
263
+ - **uid**:`<index_name>:<page_id>`,用于唯一定位一条记录。
264
+ - **relevance_score**:`1 - distance`,取值 `[0, 1]`,越大越相关。
265
+ - **二阶段召回**:`similarity_search_and_rerank` 先用向量检索取 `k * scale` 条候选,
266
+ 再经 rerank 重排取前 `k` 条。
267
+
268
+ ## 开发与测试
269
+
270
+ ```bash
271
+ python3 -m pytest -q
272
+ ```
273
+
274
+ 跑 `pytest` 时的覆盖率门槛在 `pytest.ini` 中(`--cov-fail-under=90`);
275
+ `.coveragerc` 的 `fail_under=80` 只作用于单独执行 `coverage report` 的场合。
276
+
277
+ 测试分两类:
278
+
279
+ - **单元测试**(`test_unit.py` / `test_engines_*.py`):全部基于内存 fake,离线可跑。
280
+ - **真实嵌入式/外部服务集成测试**(`test_engines_integration.py`):优先使用真实数据库
281
+ 跑完整链路(本地 OpenAI 兼容 HTTP stub 提供 embeddings/rerank,覆盖 base 真实 HTTP 路径):
282
+ - `milvus-lite`:进程内嵌入,直接运行;
283
+ - `sqlite-vec`:需要 sqlite3 支持 loadable-extension,否则自动跳过
284
+ (本机 python.org 构建默认不支持,可用支持扩展的 Homebrew python3 执行);
285
+ - `pgvector`:外部服务,通过 `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` 指定连接串,
286
+ 连接可达才执行。例如:
287
+
288
+ ```bash
289
+ podman run -d --name pgvector-pg17 -p 55432:5432 \
290
+ -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
291
+ docker.io/pgvector/pgvector:pg17
292
+
293
+ OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL='postgresql://postgres:postgres@localhost:55432/postgres' \
294
+ python3 -m pytest test_engines_integration.py -q
295
+ ```
296
+
297
+ ```bash
298
+ # 真实嵌入式/外部后端(milvus-lite / sqlite-vec / pgvector,按运行时能力自动启用)
299
+ python3 -m pytest test_engines_integration.py -q
300
+ ```
301
+
302
+ ## 版本记录
303
+
304
+ ### 0.1.0(2026-09-08)
305
+
306
+ - 首个正式版本:在 redis-search 与 milvus 基础上新增 **pgvector**、**elasticsearch**、
307
+ **sqlite-vec** 三个后端(factory + registry 注册,支持 extras 选择性安装)。
308
+ - 统一 embeddings / rerank 二阶段召回、插入 / 删除 / 更新(upsert)/ 查询 / 刷新等接口。
309
+ - 新增 kb / category 元数据过滤语义:各引擎在向量候选上按元数据过滤。
310
+ - milvus(独立部署)与 milvus-lite 支持同 page_id 更新(upsert)与删除后立即可见。
311
+ - elasticsearch 显式声明 kb / doc / category 等 keyword 映射以支持过滤,并自动迁移旧 schema。
312
+ - 新增对 pgvector / elasticsearch / sqlite-vec / milvus 真实外部服务的端到端测试
313
+ (`test_engines_integration.py`),覆盖率 96%(阈值 90%)。
314
+
315
+ ## License
316
+
317
+ [MIT](LICENSE)
@@ -0,0 +1,271 @@
1
+ # openai-simple-vectorstore
2
+
3
+ 可扩展的多向量数据库接入库,内置 **redis-search**、**milvus**、**pgvector**、
4
+ **elasticsearch** 与 **sqlite-vec** 等后端,并提供统一的 embeddings / rerank
5
+ 二阶段召回、插入、删除、刷新等管理接口。
6
+
7
+ - redis-search 后端与 [openai-redis-vectorstore](https://gitee.com/rRR0VrFP/openai-redis-vectorstore)
8
+ 行为 100% 兼容(相同的 uid 规则、relevance score、索引 schema)。
9
+ - 通过工厂 + 注册表机制可低成本扩展其它向量数据库后端。
10
+
11
+ ## 安装
12
+
13
+ 作为业务方使用时,从 PyPI 安装本库并选择所需后端:
14
+
15
+ ```bash
16
+ # 默认后端(redis-search)
17
+ pip3 install openai-simple-vectorstore
18
+
19
+ # 仅 redis-search 后端
20
+ pip3 install "openai-simple-vectorstore[redis]"
21
+
22
+ # 仅 milvus 后端(依赖 pymilvus)
23
+ pip3 install "openai-simple-vectorstore[milvus]"
24
+
25
+ # 仅 milvus-lite 后端(嵌入式 milvus,无需单独部署,适合本地开发/测试)
26
+ pip3 install "openai-simple-vectorstore[milvus-lite]"
27
+
28
+ # 仅 pgvector 后端(依赖 psycopg2-binary)
29
+ pip3 install "openai-simple-vectorstore[pgvector]"
30
+
31
+ # 仅 elasticsearch 后端
32
+ pip3 install "openai-simple-vectorstore[elasticsearch]"
33
+
34
+ # 仅 sqlite-vec 后端(嵌入式 SQLite,无需单独部署)
35
+ pip3 install "openai-simple-vectorstore[sqlite-vec]"
36
+
37
+ # 全部后端
38
+ pip3 install "openai-simple-vectorstore[all]"
39
+ ```
40
+
41
+ > 在仓库源码目录内本地开发时使用 `pip3 install -e ".[all]"`;离线安装本库自身依赖时,
42
+ > 使用 `pip3 install --no-index --find-links wheelhouse/ -r requirements.txt`。
43
+
44
+ ## 快速开始
45
+
46
+ ### 选择 redis-search 后端(默认)
47
+
48
+ ```python
49
+ from openai_simple_vectorstore import create_vector_store
50
+
51
+ vs = create_vector_store() # 默认后端由 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB 决定
52
+
53
+ # 插入
54
+ uid = vs.insert("今天天气很好", kb_id="kb1", doc_id="doc1", page_id="p1")
55
+
56
+ # 二阶段召回(向量检索 + rerank 重排)
57
+ docs = vs.similarity_search_and_rerank(
58
+ query="今天天气怎么样",
59
+ index_name="default",
60
+ k=3,
61
+ )
62
+ for doc in docs:
63
+ print(doc.vs_page_content, doc.vs_embeddings_score, doc.vs_rerank_score)
64
+
65
+ # 删除 / 刷新
66
+ vs.delete(uid)
67
+ vs.flush("default")
68
+ ```
69
+
70
+ ### 选择 milvus 后端
71
+
72
+ ```python
73
+ from openai_simple_vectorstore import create_vector_store
74
+
75
+ vs = create_vector_store( # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus
76
+ vector_db="milvus"
77
+ )
78
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
79
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
80
+ ```
81
+
82
+ ### 选择 milvus-lite 后端(嵌入式,本地开发/测试)
83
+
84
+ milvus-lite 与 milvus 使用相同的 `MilvusClient` API,仅连接方式不同:milvus 通过
85
+ `http://host:19530` 连接服务端,milvus-lite 通过本地文件路径启动进程内嵌入式数据库,
86
+ 无需部署 milvus 服务。
87
+
88
+ ```python
89
+ from openai_simple_vectorstore import create_vector_store
90
+
91
+ vs = create_vector_store(
92
+ vector_db="milvus-lite", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus-lite
93
+ milvus_lite_uri="./milvus_lite.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI
94
+ )
95
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
96
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
97
+ ```
98
+
99
+
100
+ ### 选择 sqlite-vec 后端(嵌入式,本地开发/测试)
101
+
102
+ sqlite-vec 是 SQLite 的向量搜索扩展,所有数据存在本地文件中,无需单独部署服务。
103
+ 注意:需要 sqlite3 支持 loadable-extension(多数发行版 CPython 均支持)。
104
+
105
+ ```python
106
+ from openai_simple_vectorstore import create_vector_store
107
+
108
+ vs = create_vector_store(
109
+ vector_db="sqlite-vec", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=sqlite-vec
110
+ sqlite_vec_uri="./sqlite_vec.db", # 默认 OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI
111
+ )
112
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
113
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
114
+ ```
115
+
116
+ ### 选择 pgvector 后端(PostgreSQL 扩展)
117
+
118
+ 需要 PostgreSQL 已安装 pgvector 扩展(程序启动时会尝试 ``CREATE EXTENSION IF NOT EXISTS vector``):
119
+
120
+ ```python
121
+ from openai_simple_vectorstore import create_vector_store
122
+
123
+ vs = create_vector_store(
124
+ vector_db="pgvector", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=pgvector
125
+ pgvector_url="postgresql://user:pass@localhost:5432/postgres", # 默认 OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL
126
+ )
127
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
128
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
129
+ ```
130
+
131
+ ### 选择 elasticsearch 后端
132
+
133
+ 需要 Elasticsearch 8.x(dense_vector + HNSW):
134
+
135
+ ```python
136
+ from openai_simple_vectorstore import create_vector_store
137
+
138
+ vs = create_vector_store(
139
+ vector_db="elasticsearch", # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=elasticsearch
140
+ es_url="http://localhost:9200",
141
+ )
142
+ vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
143
+ docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
144
+ ```
145
+
146
+ ### 直接实例化(不依赖全局配置)
147
+
148
+ ```python
149
+ from openai_simple_vectorstore import RedisVectorStore
150
+ from openai_simple_vectorstore.base import Connection
151
+ from openai_simple_vectorstore.utils import YamlSerializer
152
+
153
+ vs = RedisVectorStore(
154
+ redis_stack_url="redis://localhost:6379/0",
155
+ embeddings_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
156
+ rerank_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
157
+ embeddings_model="bge-m3",
158
+ rerank_model="bge-reranker-v2-m3",
159
+ metadata_serializer=YamlSerializer(),
160
+ )
161
+ ```
162
+
163
+ ## 环境变量
164
+
165
+ | 变量 | 默认值 | 说明 |
166
+ | --- | --- | --- |
167
+ | `OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB` | `redis` | 后端:`redis` / `redis-search` / `milvus` / `milvus-lite` / `pgvector` / `elasticsearch` / `sqlite-vec` |
168
+ | `OPENAI_SIMPLE_VECTORSTORE_REDIS_STACK_URL` | `redis://localhost:6379/0` | redis-stack 地址(redis 后端) |
169
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_URI` | `http://localhost:19530` | milvus 地址 |
170
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_TOKEN` | 空 | milvus 鉴权 token |
171
+ | `OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI` | `./milvus_lite.db` | milvus-lite 本地数据库文件路径 |
172
+ | `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` | `postgresql://localhost:5432/postgres` | pgvector 连接串(pgvector 后端) |
173
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_URL` | `http://localhost:9200` | elasticsearch 地址 |
174
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_API_KEY` | 空 | elasticsearch API key(优先于账号密码) |
175
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_USERNAME` | 空 | elasticsearch 用户名 |
176
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_PASSWORD` | 空 | elasticsearch 密码 |
177
+ | `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_VERIFY_CERTS` | `True` | 是否校验证书(自签 HTTPS 集群可设 `false`) |
178
+ | `OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI` | `./sqlite_vec.db` | sqlite-vec 本地数据库文件路径 |
179
+ | `OPENAI_BASE_URL` | `http://localhost/v1` | OpenAI 兼容服务基础地址 |
180
+ | `OPENAI_API_KEY` | 空 | OpenAI 兼容服务密钥 |
181
+ | `OPENAI_EMBEDDINGS_MODEL` | `bge-m3` | embeddings 模型名 |
182
+ | `OPENAI_RERANK_MODEL` | `bge-reranker-v2-m3` | rerank 模型名 |
183
+
184
+ > 兼容 `openai-redis-vectorstore`:`OPENAI_REDIS_VECTORSTORE_REDIS_STACK_URL`、
185
+ > `OPENAI_EMBEDDINGS_*`、`OPENAI_RERANK_*`、`OPENAI_BASE_URL`、`OPENAI_API_KEY` 等变量可直接使用。
186
+
187
+ ## 扩展新的向量数据库后端
188
+
189
+ 继承共享抽象基类 `VectorStore` 并实现以下方法,再注册到工厂即可:
190
+
191
+ 1. 实现 `get_cached_vectorstore`(引擎的获取与缓存)
192
+ 2. 实现 `_search_index`,返回 `[(page_id, distance, item), ...]`
193
+ 3. 实现 `get_item` / `delete` / `delete_many` / `flush`
194
+
195
+ ```python
196
+ from openai_simple_vectorstore.base import VectorStore
197
+ from openai_simple_vectorstore.registry import register_vector_store, create_vector_store
198
+
199
+ class MyStore(VectorStore):
200
+ def get_cached_vectorstore(self, **kwargs): ...
201
+ def _search_index(self, engine, query_embedding, index_name,
202
+ kb_ids, categories, filter_expression, k): ...
203
+ def get_item(self, uid): ...
204
+ def delete(self, uid): ...
205
+ def delete_many(self, uids): ...
206
+ def flush(self, index_name=None): ...
207
+
208
+ register_vector_store("mydb", MyStore)
209
+ vs = create_vector_store(vector_db="mydb")
210
+ ```
211
+
212
+ `base` 会统一处理 embeddings 生成、rerank、过滤、去重、排序、`relevance_score` 与
213
+ `Document` 组装,后端只需专注各自的检索实现。
214
+
215
+ ## 概念说明
216
+
217
+ - **uid**:`<index_name>:<page_id>`,用于唯一定位一条记录。
218
+ - **relevance_score**:`1 - distance`,取值 `[0, 1]`,越大越相关。
219
+ - **二阶段召回**:`similarity_search_and_rerank` 先用向量检索取 `k * scale` 条候选,
220
+ 再经 rerank 重排取前 `k` 条。
221
+
222
+ ## 开发与测试
223
+
224
+ ```bash
225
+ python3 -m pytest -q
226
+ ```
227
+
228
+ 跑 `pytest` 时的覆盖率门槛在 `pytest.ini` 中(`--cov-fail-under=90`);
229
+ `.coveragerc` 的 `fail_under=80` 只作用于单独执行 `coverage report` 的场合。
230
+
231
+ 测试分两类:
232
+
233
+ - **单元测试**(`test_unit.py` / `test_engines_*.py`):全部基于内存 fake,离线可跑。
234
+ - **真实嵌入式/外部服务集成测试**(`test_engines_integration.py`):优先使用真实数据库
235
+ 跑完整链路(本地 OpenAI 兼容 HTTP stub 提供 embeddings/rerank,覆盖 base 真实 HTTP 路径):
236
+ - `milvus-lite`:进程内嵌入,直接运行;
237
+ - `sqlite-vec`:需要 sqlite3 支持 loadable-extension,否则自动跳过
238
+ (本机 python.org 构建默认不支持,可用支持扩展的 Homebrew python3 执行);
239
+ - `pgvector`:外部服务,通过 `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` 指定连接串,
240
+ 连接可达才执行。例如:
241
+
242
+ ```bash
243
+ podman run -d --name pgvector-pg17 -p 55432:5432 \
244
+ -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
245
+ docker.io/pgvector/pgvector:pg17
246
+
247
+ OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL='postgresql://postgres:postgres@localhost:55432/postgres' \
248
+ python3 -m pytest test_engines_integration.py -q
249
+ ```
250
+
251
+ ```bash
252
+ # 真实嵌入式/外部后端(milvus-lite / sqlite-vec / pgvector,按运行时能力自动启用)
253
+ python3 -m pytest test_engines_integration.py -q
254
+ ```
255
+
256
+ ## 版本记录
257
+
258
+ ### 0.1.0(2026-09-08)
259
+
260
+ - 首个正式版本:在 redis-search 与 milvus 基础上新增 **pgvector**、**elasticsearch**、
261
+ **sqlite-vec** 三个后端(factory + registry 注册,支持 extras 选择性安装)。
262
+ - 统一 embeddings / rerank 二阶段召回、插入 / 删除 / 更新(upsert)/ 查询 / 刷新等接口。
263
+ - 新增 kb / category 元数据过滤语义:各引擎在向量候选上按元数据过滤。
264
+ - milvus(独立部署)与 milvus-lite 支持同 page_id 更新(upsert)与删除后立即可见。
265
+ - elasticsearch 显式声明 kb / doc / category 等 keyword 映射以支持过滤,并自动迁移旧 schema。
266
+ - 新增对 pgvector / elasticsearch / sqlite-vec / milvus 真实外部服务的端到端测试
267
+ (`test_engines_integration.py`),覆盖率 96%(阈值 90%)。
268
+
269
+ ## License
270
+
271
+ [MIT](LICENSE)
@@ -0,0 +1,60 @@
1
+ from .base import *
2
+ from .schemas import *
3
+ from .settings import *
4
+ from .utils import *
5
+ from .version import *
6
+
7
+
8
+ def __getattr__(name):
9
+ # 顶层便捷导出:RedisVectorStore / MilvusVectorStore / RedisVLEngine / MilvusEngine
10
+ # 及其它类型。backend 相关模块在首次访问时才被导入,避免强制依赖未安装的驱动。
11
+ if name in ("RedisVLEngine", "RedisVectorStore"):
12
+ from .engines import redis_vectorstore as _m
13
+ return getattr(_m, name)
14
+ if name in ("MilvusEngine", "MilvusVectorStore"):
15
+ from .engines import milvus_vectorstore as _m
16
+ return getattr(_m, name)
17
+ if name in ("MilvusLiteEngine", "MilvusLiteVectorStore"):
18
+ from .engines import milvus_lite_vectorstore as _m
19
+ return getattr(_m, name)
20
+ if name in ("PgVectorEngine", "PgVectorVectorStore"):
21
+ from .engines import pgvector_vectorstore as _m
22
+ return getattr(_m, name)
23
+ if name in ("ElasticsearchEngine", "ElasticsearchVectorStore"):
24
+ from .engines import elasticsearch_vectorstore as _m
25
+ return getattr(_m, name)
26
+ if name in ("SqliteVecEngine", "SqliteVecVectorStore"):
27
+ from .engines import sqlite_vec_vectorstore as _m
28
+ return getattr(_m, name)
29
+ if name in ("create_vector_store", "get_vector_store_class", "register_vector_store"):
30
+ from .registry import _FACTORY_FUNCTIONS
31
+ return _FACTORY_FUNCTIONS[name]
32
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
33
+
34
+
35
+ def _load_default_registry():
36
+ from .registry import register_vector_store
37
+
38
+ def _try_register(name, module_name, attr_name):
39
+ try:
40
+ module = __import__(
41
+ "openai_simple_vectorstore.engines." + module_name,
42
+ fromlist=[attr_name],
43
+ )
44
+ cls = getattr(module, attr_name)
45
+ register_vector_store(name, cls)
46
+ except Exception as exc: # pragma: no cover - 取决于环境
47
+ import logging
48
+ logging.getLogger(__name__).debug(
49
+ "vector store %r not registered: %s", name, exc
50
+ )
51
+
52
+ _try_register("redis", "redis_vectorstore", "RedisVectorStore")
53
+ _try_register("milvus", "milvus_vectorstore", "MilvusVectorStore")
54
+ _try_register("milvus-lite", "milvus_lite_vectorstore", "MilvusLiteVectorStore")
55
+ _try_register("pgvector", "pgvector_vectorstore", "PgVectorVectorStore")
56
+ _try_register("elasticsearch", "elasticsearch_vectorstore", "ElasticsearchVectorStore")
57
+ _try_register("sqlite-vec", "sqlite_vec_vectorstore", "SqliteVecVectorStore")
58
+
59
+
60
+ _load_default_registry()