easy-knowledge-retriever 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.
- easy_knowledge_retriever-0.1.0/LICENSE +18 -0
- easy_knowledge_retriever-0.1.0/MANIFEST.in +3 -0
- easy_knowledge_retriever-0.1.0/PKG-INFO +255 -0
- easy_knowledge_retriever-0.1.0/README.md +210 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/__init__.py +4 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/constants.py +97 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/base.py +826 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/concurrency.py +1025 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/exceptions.py +136 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/json_doc_status_impl.py +409 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/json_kv_impl.py +306 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/milvus_impl.py +1375 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/namespace.py +28 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/nano_vector_db_impl.py +473 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/neo4j_impl.py +1808 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/networkx_impl.py +572 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/postgres_impl.py +5111 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/registry.py +104 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/services.py +143 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/shared_memory.py +360 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/shared_storage.py +55 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/state.py +45 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/types.py +27 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/utils.py +68 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/kg/utils_graph.py +1734 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/client.py +82 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/exceptions.py +4 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/openai.py +645 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/options.py +495 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/prompts.py +762 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/service.py +139 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/types.py +5 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/llm/utils.py +331 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/chunking.py +208 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/extraction.py +657 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/graph_ops.py +1943 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/image_processing.py +83 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/mineru_parser.py +165 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/mineru_tool.py +20 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/query.py +2029 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/operations/summarization.py +202 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/pipeline/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/reranker/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/reranker/generic.py +174 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/reranker/openai.py +51 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/reranker/utils.py +156 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/retriever.py +4164 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/__init__.py +0 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/async_utils.py +528 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/common_utils.py +339 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/file_utils.py +106 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/hashing.py +76 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/logger.py +229 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/text_utils.py +475 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/token_tracker.py +71 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/tokenizer.py +103 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever/utils/vector_utils.py +738 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever.egg-info/PKG-INFO +255 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever.egg-info/SOURCES.txt +66 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever.egg-info/dependency_links.txt +1 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever.egg-info/requires.txt +20 -0
- easy_knowledge_retriever-0.1.0/easy_knowledge_retriever.egg-info/top_level.txt +1 -0
- easy_knowledge_retriever-0.1.0/requirements.txt +33 -0
- easy_knowledge_retriever-0.1.0/setup.cfg +4 -0
- easy_knowledge_retriever-0.1.0/setup.py +37 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Easy Knowledge Retriever — License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Thomas Martinet
|
|
4
|
+
|
|
5
|
+
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).
|
|
6
|
+
|
|
7
|
+
You are free to share and adapt the material under the following terms:
|
|
8
|
+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
9
|
+
- NonCommercial — You may not use the material for commercial purposes.
|
|
10
|
+
- ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
|
11
|
+
|
|
12
|
+
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
|
13
|
+
|
|
14
|
+
Full license text:
|
|
15
|
+
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
|
16
|
+
|
|
17
|
+
Plain‑language summary (EN):
|
|
18
|
+
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: easy-knowledge-retriever
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple and efficient RAG (Retrieval-Augmented Generation) library with Knowledge Graph support.
|
|
5
|
+
Author: Thomas Martinet
|
|
6
|
+
Author-email: your.email@example.com
|
|
7
|
+
License: CC BY-NC-SA 4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: Free for non-commercial use
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: asyncpg<1.0.0,>=0.29.0
|
|
16
|
+
Requires-Dist: httpx
|
|
17
|
+
Requires-Dist: networkx
|
|
18
|
+
Requires-Dist: numpy
|
|
19
|
+
Requires-Dist: tenacity
|
|
20
|
+
Requires-Dist: tiktoken
|
|
21
|
+
Requires-Dist: openai<3.0.0,>=2.0.0
|
|
22
|
+
Requires-Dist: neo4j<7.0.0,>=5.0.0
|
|
23
|
+
Requires-Dist: pymilvus>=2.6.2
|
|
24
|
+
Requires-Dist: nano-vectordb
|
|
25
|
+
Requires-Dist: pypdf
|
|
26
|
+
Requires-Dist: mineru
|
|
27
|
+
Requires-Dist: doclayout_yolo
|
|
28
|
+
Requires-Dist: ultralytics
|
|
29
|
+
Requires-Dist: ftfy
|
|
30
|
+
Requires-Dist: shapely
|
|
31
|
+
Requires-Dist: pyclipper
|
|
32
|
+
Requires-Dist: omegaconf
|
|
33
|
+
Requires-Dist: pypinyin
|
|
34
|
+
Requires-Dist: dill
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: author-email
|
|
37
|
+
Dynamic: classifier
|
|
38
|
+
Dynamic: description
|
|
39
|
+
Dynamic: description-content-type
|
|
40
|
+
Dynamic: license
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
Dynamic: requires-dist
|
|
43
|
+
Dynamic: requires-python
|
|
44
|
+
Dynamic: summary
|
|
45
|
+
|
|
46
|
+
<div align="center">
|
|
47
|
+
<img src="docs/logo.png" alt="EKR Logo" width="400">
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div align="center">
|
|
51
|
+
<h1>Easy Knowledge Retriever - The easiest RAG lib ever</h1>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
[](https://pypi.org/project/easy-knowledge-retriever/) [](https://pypi.org/project/easy-knowledge-retriever/) [](https://creativecommons.org/licenses/by-nc-sa/4.0/) [](https://<YOUR_GITHUB_USERNAME>.github.io/EasyKnowledgeRetrieval/)
|
|
55
|
+
|
|
56
|
+
**Easy Knowledge Retriever** is a powerful and flexible library for building Retrieval-Augmented Generation (RAG) systems with integrated Knowledge Graph support. It allows you to easily ingest documents, build a structured knowledge base (combining vector embeddings and graph relations), and perform advanced queries using Large Language Models (LLMs).
|
|
57
|
+
|
|
58
|
+
Full documentation (GitHub Pages): https://hankerspace.github.io/EasyKnowledgeRetrieval/
|
|
59
|
+
|
|
60
|
+
## Features~~~~
|
|
61
|
+
|
|
62
|
+
- **Hybrid Retrieval**: Combines vector similarity search with knowledge graph exploration for more context-aware answers.
|
|
63
|
+
- **Knowledge Graph Integration**: Automatically extracts entities and relationships from your text documents.
|
|
64
|
+
- **Modular Storage**: Supports various backends for Key-Value pairs, Vector Stores, and Graph Storage (e.g., JSON, NanoVectorDB, NetworkX, Neo4j, Milvus).
|
|
65
|
+
- **LLM Agnostic**: Designed to work with OpenAI-compatible LLM APIs (OpenAI, Gemini via OpenAI adapter, etc.).
|
|
66
|
+
- **Async Support**: built with `asyncio` for high-performance ingestion and retrieval.
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
You can install the library via pip:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install easy-knowledge-retriever
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
This guide will show you how to build a database from PDF documents and then query it.
|
|
79
|
+
|
|
80
|
+
### 1. Build the Database (Ingestion)
|
|
81
|
+
|
|
82
|
+
During this step, documents are processed, chunked, embedded, and entities/relations are extracted to build the Knowledge Graph options.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import asyncio
|
|
86
|
+
import os
|
|
87
|
+
from easy_knowledge_retriever import EasyKnowledgeRetriever
|
|
88
|
+
from easy_knowledge_retriever.llm.service import OpenAILLMService, OpenAIEmbeddingService
|
|
89
|
+
from easy_knowledge_retriever.kg.json_kv_impl import JsonKVStorage
|
|
90
|
+
from easy_knowledge_retriever.kg.nano_vector_db_impl import NanoVectorDBStorage
|
|
91
|
+
from easy_knowledge_retriever.kg.networkx_impl import NetworkXStorage
|
|
92
|
+
from easy_knowledge_retriever.kg.json_doc_status_impl import JsonDocStatusStorage
|
|
93
|
+
|
|
94
|
+
async def build_database():
|
|
95
|
+
# 1. Configure Services
|
|
96
|
+
# Replace with your actual API keys and endpoints
|
|
97
|
+
embedding_service = OpenAIEmbeddingService(
|
|
98
|
+
api_key="your-embedding-api-key",
|
|
99
|
+
base_url="https://api.openai.com/v1", # or compatible
|
|
100
|
+
model="text-embedding-3-small",
|
|
101
|
+
embedding_dim=1536
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
llm_service = OpenAILLMService(
|
|
105
|
+
model="gpt-4o",
|
|
106
|
+
api_key="your-llm-api-key",
|
|
107
|
+
base_url="https://api.openai.com/v1"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# 2. Initialize Retriever with specific storage backends
|
|
111
|
+
working_dir = "./rag_data"
|
|
112
|
+
rag = EasyKnowledgeRetriever(
|
|
113
|
+
working_dir=working_dir,
|
|
114
|
+
llm_service=llm_service,
|
|
115
|
+
embedding_service=embedding_service,
|
|
116
|
+
kv_storage=JsonKVStorage(),
|
|
117
|
+
vector_storage=NanoVectorDBStorage(cosine_better_than_threshold=0.2),
|
|
118
|
+
graph_storage=NetworkXStorage(),
|
|
119
|
+
doc_status_storage=JsonDocStatusStorage(),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
await rag.initialize_storages()
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
# 3. Ingest Documents
|
|
126
|
+
pdf_path = "./documents/example.pdf"
|
|
127
|
+
if os.path.exists(pdf_path):
|
|
128
|
+
print(f"Ingesting {pdf_path}...")
|
|
129
|
+
await rag.ingest(pdf_path)
|
|
130
|
+
print("Ingestion complete.")
|
|
131
|
+
else:
|
|
132
|
+
print("Please provide a valid PDF path.")
|
|
133
|
+
|
|
134
|
+
finally:
|
|
135
|
+
# Always finalize to save state
|
|
136
|
+
await rag.finalize_storages()
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
asyncio.run(build_database())
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2. Retrieve Information (Querying)
|
|
143
|
+
|
|
144
|
+
Once the database is built, you can query it.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
import asyncio
|
|
148
|
+
from easy_knowledge_retriever import EasyKnowledgeRetriever, QueryParam
|
|
149
|
+
from easy_knowledge_retriever.llm.service import OpenAILLMService, OpenAIEmbeddingService
|
|
150
|
+
from easy_knowledge_retriever.kg.json_kv_impl import JsonKVStorage
|
|
151
|
+
from easy_knowledge_retriever.kg.nano_vector_db_impl import NanoVectorDBStorage
|
|
152
|
+
from easy_knowledge_retriever.kg.networkx_impl import NetworkXStorage
|
|
153
|
+
from easy_knowledge_retriever.kg.json_doc_status_impl import JsonDocStatusStorage
|
|
154
|
+
|
|
155
|
+
async def query_knowledge_base():
|
|
156
|
+
# 1. Re-initialize Services (same config as build)
|
|
157
|
+
embedding_service = OpenAIEmbeddingService(
|
|
158
|
+
api_key="your-embedding-api-key",
|
|
159
|
+
base_url="https://api.openai.com/v1",
|
|
160
|
+
model="text-embedding-3-small",
|
|
161
|
+
embedding_dim=1536
|
|
162
|
+
)
|
|
163
|
+
llm_service = OpenAILLMService(
|
|
164
|
+
model="gpt-4o",
|
|
165
|
+
api_key="your-llm-api-key",
|
|
166
|
+
base_url="https://api.openai.com/v1"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# 2. Load the existing Retriever
|
|
170
|
+
working_dir = "./rag_data"
|
|
171
|
+
rag = EasyKnowledgeRetriever(
|
|
172
|
+
working_dir=working_dir,
|
|
173
|
+
llm_service=llm_service,
|
|
174
|
+
embedding_service=embedding_service,
|
|
175
|
+
kv_storage=JsonKVStorage(),
|
|
176
|
+
vector_storage=NanoVectorDBStorage(cosine_better_than_threshold=0.2),
|
|
177
|
+
graph_storage=NetworkXStorage(),
|
|
178
|
+
doc_status_storage=JsonDocStatusStorage(),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
await rag.initialize_storages()
|
|
182
|
+
|
|
183
|
+
try:
|
|
184
|
+
# 3. Perform a Query
|
|
185
|
+
query_text = "What does the document say about forest fires?"
|
|
186
|
+
|
|
187
|
+
# 'mix' mode uses both vector search and knowledge graph
|
|
188
|
+
param = QueryParam(mode="mix")
|
|
189
|
+
|
|
190
|
+
print(f"Querying: {query_text}")
|
|
191
|
+
result = await rag.aquery(query_text, param=param)
|
|
192
|
+
|
|
193
|
+
print("\nAnswer:")
|
|
194
|
+
print(result)
|
|
195
|
+
|
|
196
|
+
finally:
|
|
197
|
+
await rag.finalize_storages()
|
|
198
|
+
|
|
199
|
+
if __name__ == "__main__":
|
|
200
|
+
asyncio.run(query_knowledge_base())
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Advanced Configuration
|
|
204
|
+
|
|
205
|
+
### Storage Options
|
|
206
|
+
|
|
207
|
+
You can swap out storage implementations by creating instances of different classes from `easy_knowledge_retriever.kg.*`:
|
|
208
|
+
|
|
209
|
+
* **Vector Storage**: `NanoVectorDBStorage` (local, lightweight), `MilvusStorage` (scalable).
|
|
210
|
+
* **Graph Storage**: `NetworkXStorage` (in-memory/json, simple), `Neo4jStorage` (robust graph DB).
|
|
211
|
+
* **KV Storage**: `JsonKVStorage`, `RedisKVStorage` (if available), etc.
|
|
212
|
+
|
|
213
|
+
Example for Neo4j:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from easy_knowledge_retriever.kg.neo4j_impl import Neo4jStorage
|
|
217
|
+
|
|
218
|
+
graph_storage = Neo4jStorage(
|
|
219
|
+
uri="bolt://localhost:7687",
|
|
220
|
+
user="neo4j",
|
|
221
|
+
password="password"
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Service & Configuration Catalog
|
|
226
|
+
|
|
227
|
+
For a complete, up-to-date list of all services (LLM, Vector/KV/Graph/Doc Status) and their configuration options, see:
|
|
228
|
+
|
|
229
|
+
- docs/ServiceCatalog.md
|
|
230
|
+
|
|
231
|
+
## Development
|
|
232
|
+
|
|
233
|
+
To set up the project for development:
|
|
234
|
+
|
|
235
|
+
1. Clone the repository.
|
|
236
|
+
2. Install dependencies: `pip install -r requirements.txt`.
|
|
237
|
+
3. Install the package in editable mode: `pip install -e .`.
|
|
238
|
+
|
|
239
|
+
### Running Tests
|
|
240
|
+
|
|
241
|
+
(Instructions for running tests if applicable)
|
|
242
|
+
```bash
|
|
243
|
+
pytest
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
This project is licensed under the Creative Commons Attribution–NonCommercial–ShareAlike 4.0 International (CC BY‑NC‑SA 4.0).
|
|
249
|
+
|
|
250
|
+
- You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
251
|
+
- You may not use the material for commercial purposes.
|
|
252
|
+
- If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
|
253
|
+
|
|
254
|
+
Full legal text: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
|
255
|
+
Summary (EN): https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="docs/logo.png" alt="EKR Logo" width="400">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
<h1>Easy Knowledge Retriever - The easiest RAG lib ever</h1>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
[](https://pypi.org/project/easy-knowledge-retriever/) [](https://pypi.org/project/easy-knowledge-retriever/) [](https://creativecommons.org/licenses/by-nc-sa/4.0/) [](https://<YOUR_GITHUB_USERNAME>.github.io/EasyKnowledgeRetrieval/)
|
|
10
|
+
|
|
11
|
+
**Easy Knowledge Retriever** is a powerful and flexible library for building Retrieval-Augmented Generation (RAG) systems with integrated Knowledge Graph support. It allows you to easily ingest documents, build a structured knowledge base (combining vector embeddings and graph relations), and perform advanced queries using Large Language Models (LLMs).
|
|
12
|
+
|
|
13
|
+
Full documentation (GitHub Pages): https://hankerspace.github.io/EasyKnowledgeRetrieval/
|
|
14
|
+
|
|
15
|
+
## Features~~~~
|
|
16
|
+
|
|
17
|
+
- **Hybrid Retrieval**: Combines vector similarity search with knowledge graph exploration for more context-aware answers.
|
|
18
|
+
- **Knowledge Graph Integration**: Automatically extracts entities and relationships from your text documents.
|
|
19
|
+
- **Modular Storage**: Supports various backends for Key-Value pairs, Vector Stores, and Graph Storage (e.g., JSON, NanoVectorDB, NetworkX, Neo4j, Milvus).
|
|
20
|
+
- **LLM Agnostic**: Designed to work with OpenAI-compatible LLM APIs (OpenAI, Gemini via OpenAI adapter, etc.).
|
|
21
|
+
- **Async Support**: built with `asyncio` for high-performance ingestion and retrieval.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
You can install the library via pip:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install easy-knowledge-retriever
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
This guide will show you how to build a database from PDF documents and then query it.
|
|
34
|
+
|
|
35
|
+
### 1. Build the Database (Ingestion)
|
|
36
|
+
|
|
37
|
+
During this step, documents are processed, chunked, embedded, and entities/relations are extracted to build the Knowledge Graph options.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
import os
|
|
42
|
+
from easy_knowledge_retriever import EasyKnowledgeRetriever
|
|
43
|
+
from easy_knowledge_retriever.llm.service import OpenAILLMService, OpenAIEmbeddingService
|
|
44
|
+
from easy_knowledge_retriever.kg.json_kv_impl import JsonKVStorage
|
|
45
|
+
from easy_knowledge_retriever.kg.nano_vector_db_impl import NanoVectorDBStorage
|
|
46
|
+
from easy_knowledge_retriever.kg.networkx_impl import NetworkXStorage
|
|
47
|
+
from easy_knowledge_retriever.kg.json_doc_status_impl import JsonDocStatusStorage
|
|
48
|
+
|
|
49
|
+
async def build_database():
|
|
50
|
+
# 1. Configure Services
|
|
51
|
+
# Replace with your actual API keys and endpoints
|
|
52
|
+
embedding_service = OpenAIEmbeddingService(
|
|
53
|
+
api_key="your-embedding-api-key",
|
|
54
|
+
base_url="https://api.openai.com/v1", # or compatible
|
|
55
|
+
model="text-embedding-3-small",
|
|
56
|
+
embedding_dim=1536
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
llm_service = OpenAILLMService(
|
|
60
|
+
model="gpt-4o",
|
|
61
|
+
api_key="your-llm-api-key",
|
|
62
|
+
base_url="https://api.openai.com/v1"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 2. Initialize Retriever with specific storage backends
|
|
66
|
+
working_dir = "./rag_data"
|
|
67
|
+
rag = EasyKnowledgeRetriever(
|
|
68
|
+
working_dir=working_dir,
|
|
69
|
+
llm_service=llm_service,
|
|
70
|
+
embedding_service=embedding_service,
|
|
71
|
+
kv_storage=JsonKVStorage(),
|
|
72
|
+
vector_storage=NanoVectorDBStorage(cosine_better_than_threshold=0.2),
|
|
73
|
+
graph_storage=NetworkXStorage(),
|
|
74
|
+
doc_status_storage=JsonDocStatusStorage(),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
await rag.initialize_storages()
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
# 3. Ingest Documents
|
|
81
|
+
pdf_path = "./documents/example.pdf"
|
|
82
|
+
if os.path.exists(pdf_path):
|
|
83
|
+
print(f"Ingesting {pdf_path}...")
|
|
84
|
+
await rag.ingest(pdf_path)
|
|
85
|
+
print("Ingestion complete.")
|
|
86
|
+
else:
|
|
87
|
+
print("Please provide a valid PDF path.")
|
|
88
|
+
|
|
89
|
+
finally:
|
|
90
|
+
# Always finalize to save state
|
|
91
|
+
await rag.finalize_storages()
|
|
92
|
+
|
|
93
|
+
if __name__ == "__main__":
|
|
94
|
+
asyncio.run(build_database())
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 2. Retrieve Information (Querying)
|
|
98
|
+
|
|
99
|
+
Once the database is built, you can query it.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import asyncio
|
|
103
|
+
from easy_knowledge_retriever import EasyKnowledgeRetriever, QueryParam
|
|
104
|
+
from easy_knowledge_retriever.llm.service import OpenAILLMService, OpenAIEmbeddingService
|
|
105
|
+
from easy_knowledge_retriever.kg.json_kv_impl import JsonKVStorage
|
|
106
|
+
from easy_knowledge_retriever.kg.nano_vector_db_impl import NanoVectorDBStorage
|
|
107
|
+
from easy_knowledge_retriever.kg.networkx_impl import NetworkXStorage
|
|
108
|
+
from easy_knowledge_retriever.kg.json_doc_status_impl import JsonDocStatusStorage
|
|
109
|
+
|
|
110
|
+
async def query_knowledge_base():
|
|
111
|
+
# 1. Re-initialize Services (same config as build)
|
|
112
|
+
embedding_service = OpenAIEmbeddingService(
|
|
113
|
+
api_key="your-embedding-api-key",
|
|
114
|
+
base_url="https://api.openai.com/v1",
|
|
115
|
+
model="text-embedding-3-small",
|
|
116
|
+
embedding_dim=1536
|
|
117
|
+
)
|
|
118
|
+
llm_service = OpenAILLMService(
|
|
119
|
+
model="gpt-4o",
|
|
120
|
+
api_key="your-llm-api-key",
|
|
121
|
+
base_url="https://api.openai.com/v1"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# 2. Load the existing Retriever
|
|
125
|
+
working_dir = "./rag_data"
|
|
126
|
+
rag = EasyKnowledgeRetriever(
|
|
127
|
+
working_dir=working_dir,
|
|
128
|
+
llm_service=llm_service,
|
|
129
|
+
embedding_service=embedding_service,
|
|
130
|
+
kv_storage=JsonKVStorage(),
|
|
131
|
+
vector_storage=NanoVectorDBStorage(cosine_better_than_threshold=0.2),
|
|
132
|
+
graph_storage=NetworkXStorage(),
|
|
133
|
+
doc_status_storage=JsonDocStatusStorage(),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
await rag.initialize_storages()
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
# 3. Perform a Query
|
|
140
|
+
query_text = "What does the document say about forest fires?"
|
|
141
|
+
|
|
142
|
+
# 'mix' mode uses both vector search and knowledge graph
|
|
143
|
+
param = QueryParam(mode="mix")
|
|
144
|
+
|
|
145
|
+
print(f"Querying: {query_text}")
|
|
146
|
+
result = await rag.aquery(query_text, param=param)
|
|
147
|
+
|
|
148
|
+
print("\nAnswer:")
|
|
149
|
+
print(result)
|
|
150
|
+
|
|
151
|
+
finally:
|
|
152
|
+
await rag.finalize_storages()
|
|
153
|
+
|
|
154
|
+
if __name__ == "__main__":
|
|
155
|
+
asyncio.run(query_knowledge_base())
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Advanced Configuration
|
|
159
|
+
|
|
160
|
+
### Storage Options
|
|
161
|
+
|
|
162
|
+
You can swap out storage implementations by creating instances of different classes from `easy_knowledge_retriever.kg.*`:
|
|
163
|
+
|
|
164
|
+
* **Vector Storage**: `NanoVectorDBStorage` (local, lightweight), `MilvusStorage` (scalable).
|
|
165
|
+
* **Graph Storage**: `NetworkXStorage` (in-memory/json, simple), `Neo4jStorage` (robust graph DB).
|
|
166
|
+
* **KV Storage**: `JsonKVStorage`, `RedisKVStorage` (if available), etc.
|
|
167
|
+
|
|
168
|
+
Example for Neo4j:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from easy_knowledge_retriever.kg.neo4j_impl import Neo4jStorage
|
|
172
|
+
|
|
173
|
+
graph_storage = Neo4jStorage(
|
|
174
|
+
uri="bolt://localhost:7687",
|
|
175
|
+
user="neo4j",
|
|
176
|
+
password="password"
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Service & Configuration Catalog
|
|
181
|
+
|
|
182
|
+
For a complete, up-to-date list of all services (LLM, Vector/KV/Graph/Doc Status) and their configuration options, see:
|
|
183
|
+
|
|
184
|
+
- docs/ServiceCatalog.md
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
To set up the project for development:
|
|
189
|
+
|
|
190
|
+
1. Clone the repository.
|
|
191
|
+
2. Install dependencies: `pip install -r requirements.txt`.
|
|
192
|
+
3. Install the package in editable mode: `pip install -e .`.
|
|
193
|
+
|
|
194
|
+
### Running Tests
|
|
195
|
+
|
|
196
|
+
(Instructions for running tests if applicable)
|
|
197
|
+
```bash
|
|
198
|
+
pytest
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
This project is licensed under the Creative Commons Attribution–NonCommercial–ShareAlike 4.0 International (CC BY‑NC‑SA 4.0).
|
|
204
|
+
|
|
205
|
+
- You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
206
|
+
- You may not use the material for commercial purposes.
|
|
207
|
+
- If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
|
208
|
+
|
|
209
|
+
Full legal text: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
|
210
|
+
Summary (EN): https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Centralized configuration constants for EasyKnowledgeRetriever.
|
|
3
|
+
|
|
4
|
+
This module defines default values for configuration constants used across
|
|
5
|
+
different parts of the EasyKnowledgeRetriever system. Centralizing these values ensures
|
|
6
|
+
consistency and makes maintenance easier.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Default values for server settings
|
|
10
|
+
DEFAULT_MAX_GRAPH_NODES = 1000
|
|
11
|
+
|
|
12
|
+
# Default values for extraction settings
|
|
13
|
+
DEFAULT_SUMMARY_LANGUAGE = "French" # Default language for document processing
|
|
14
|
+
DEFAULT_MAX_GLEANING = 1
|
|
15
|
+
DEFAULT_ENTITY_NAME_MAX_LENGTH = 256
|
|
16
|
+
|
|
17
|
+
# Number of description fragments to trigger LLM summary
|
|
18
|
+
DEFAULT_FORCE_LLM_SUMMARY_ON_MERGE = 8
|
|
19
|
+
# Max description token size to trigger LLM summary
|
|
20
|
+
DEFAULT_SUMMARY_MAX_TOKENS = 1200
|
|
21
|
+
# Recommended LLM summary output length in tokens
|
|
22
|
+
DEFAULT_SUMMARY_LENGTH_RECOMMENDED = 600
|
|
23
|
+
# Maximum token size sent to LLM for summary
|
|
24
|
+
DEFAULT_SUMMARY_CONTEXT_SIZE = 12000
|
|
25
|
+
# Default entities to extract if ENTITY_TYPES is not specified in .env
|
|
26
|
+
DEFAULT_ENTITY_TYPES = [
|
|
27
|
+
"Person",
|
|
28
|
+
"Creature",
|
|
29
|
+
"Organization",
|
|
30
|
+
"Location",
|
|
31
|
+
"Event",
|
|
32
|
+
"Concept",
|
|
33
|
+
"Method",
|
|
34
|
+
"Content",
|
|
35
|
+
"Data",
|
|
36
|
+
"Artifact",
|
|
37
|
+
"NaturalObject",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# Separator for: description, source_id and relation-key fields(Can not be changed after data inserted)
|
|
41
|
+
GRAPH_FIELD_SEP = "<SEP>"
|
|
42
|
+
|
|
43
|
+
# Query and retrieval configuration defaults
|
|
44
|
+
DEFAULT_TOP_K = 40
|
|
45
|
+
DEFAULT_CHUNK_TOP_K = 20
|
|
46
|
+
DEFAULT_MAX_ENTITY_TOKENS = 6000
|
|
47
|
+
DEFAULT_MAX_RELATION_TOKENS = 8000
|
|
48
|
+
DEFAULT_MAX_TOTAL_TOKENS = 30000
|
|
49
|
+
DEFAULT_COSINE_THRESHOLD = 0.2
|
|
50
|
+
DEFAULT_RELATED_CHUNK_NUMBER = 5
|
|
51
|
+
DEFAULT_KG_CHUNK_PICK_METHOD = "VECTOR"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Rerank configuration defaults
|
|
55
|
+
# Default source ids limit in meta data for entity and relation
|
|
56
|
+
DEFAULT_MAX_SOURCE_IDS_PER_ENTITY = 300
|
|
57
|
+
DEFAULT_MAX_SOURCE_IDS_PER_RELATION = 300
|
|
58
|
+
### control chunk_ids limitation method: FIFO, FIFO
|
|
59
|
+
### FIFO: First in first out
|
|
60
|
+
### KEEP: Keep oldest (less merge action and faster)
|
|
61
|
+
SOURCE_IDS_LIMIT_METHOD_KEEP = "KEEP"
|
|
62
|
+
SOURCE_IDS_LIMIT_METHOD_FIFO = "FIFO"
|
|
63
|
+
DEFAULT_SOURCE_IDS_LIMIT_METHOD = SOURCE_IDS_LIMIT_METHOD_FIFO
|
|
64
|
+
VALID_SOURCE_IDS_LIMIT_METHODS = {
|
|
65
|
+
SOURCE_IDS_LIMIT_METHOD_KEEP,
|
|
66
|
+
SOURCE_IDS_LIMIT_METHOD_FIFO,
|
|
67
|
+
}
|
|
68
|
+
# Maximum number of file paths stored in entity/relation file_path field (For displayed only, does not affect query performance)
|
|
69
|
+
DEFAULT_MAX_FILE_PATHS = 100
|
|
70
|
+
|
|
71
|
+
# Field length of file_path in Milvus Schema for entity and relation (Should not be changed)
|
|
72
|
+
# file_path must store all file paths up to the DEFAULT_MAX_FILE_PATHS limit within the metadata.
|
|
73
|
+
DEFAULT_MAX_FILE_PATH_LENGTH = 32768
|
|
74
|
+
# Placeholder for more file paths in meta data for entity and relation (Should not be changed)
|
|
75
|
+
DEFAULT_FILE_PATH_MORE_PLACEHOLDER = "truncated"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# Default maximum parallel insert operations
|
|
79
|
+
DEFAULT_MAX_PARALLEL_INSERT = 1
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Logging configuration defaults
|
|
83
|
+
DEFAULT_LOG_MAX_BYTES = 10485760 # Default 10MB
|
|
84
|
+
DEFAULT_LOG_BACKUP_COUNT = 5 # Default 5 backups
|
|
85
|
+
DEFAULT_LOG_FILENAME = "easy_knowledge_retriever.log" # Default log filename
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# LLM execution defaults
|
|
90
|
+
DEFAULT_TEMPERATURE = 1.0
|
|
91
|
+
DEFAULT_MAX_ASYNC = 1
|
|
92
|
+
DEFAULT_LLM_TIMEOUT = 1000000
|
|
93
|
+
|
|
94
|
+
# Embedding execution defaults
|
|
95
|
+
DEFAULT_EMBEDDING_BATCH_NUM = 1
|
|
96
|
+
DEFAULT_EMBEDDING_FUNC_MAX_ASYNC = 1
|
|
97
|
+
DEFAULT_EMBEDDING_TIMEOUT = 1000000
|
|
File without changes
|