rag-titan 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.
- rag_titan-0.1.0/.gitignore +39 -0
- rag_titan-0.1.0/CHANGELOG.md +18 -0
- rag_titan-0.1.0/LICENSE +21 -0
- rag_titan-0.1.0/PKG-INFO +211 -0
- rag_titan-0.1.0/README.md +147 -0
- rag_titan-0.1.0/pyproject.toml +83 -0
- rag_titan-0.1.0/src/rag_titan/__init__.py +31 -0
- rag_titan-0.1.0/src/rag_titan/agents/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/agents/base_agent.py +81 -0
- rag_titan-0.1.0/src/rag_titan/agents/math_agent.py +29 -0
- rag_titan-0.1.0/src/rag_titan/agents/prompts.py +14 -0
- rag_titan-0.1.0/src/rag_titan/agents/tools/__init__.py +5 -0
- rag_titan-0.1.0/src/rag_titan/agents/tools/math_tools.py +55 -0
- rag_titan-0.1.0/src/rag_titan/app.py +60 -0
- rag_titan-0.1.0/src/rag_titan/chunking/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/chunking/base_chunker.py +36 -0
- rag_titan-0.1.0/src/rag_titan/chunking/word_chunker.py +40 -0
- rag_titan-0.1.0/src/rag_titan/cli.py +69 -0
- rag_titan-0.1.0/src/rag_titan/config.py +78 -0
- rag_titan-0.1.0/src/rag_titan/embeddings/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/embeddings/base_embedder.py +26 -0
- rag_titan-0.1.0/src/rag_titan/embeddings/ollama_embedder.py +53 -0
- rag_titan-0.1.0/src/rag_titan/factory.py +135 -0
- rag_titan-0.1.0/src/rag_titan/generation/__init__.py +7 -0
- rag_titan-0.1.0/src/rag_titan/generation/base_generator.py +30 -0
- rag_titan-0.1.0/src/rag_titan/generation/context_builder.py +20 -0
- rag_titan-0.1.0/src/rag_titan/generation/grounded_generator.py +27 -0
- rag_titan-0.1.0/src/rag_titan/llm/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/llm/base_llm.py +57 -0
- rag_titan-0.1.0/src/rag_titan/llm/ollama_llm.py +72 -0
- rag_titan-0.1.0/src/rag_titan/loaders/__init__.py +8 -0
- rag_titan-0.1.0/src/rag_titan/loaders/base_loader.py +40 -0
- rag_titan-0.1.0/src/rag_titan/loaders/docx_loader.py +17 -0
- rag_titan-0.1.0/src/rag_titan/loaders/loader_registry.py +36 -0
- rag_titan-0.1.0/src/rag_titan/loaders/pdf_loader.py +19 -0
- rag_titan-0.1.0/src/rag_titan/pipelines/__init__.py +5 -0
- rag_titan-0.1.0/src/rag_titan/pipelines/indexing_pipeline.py +72 -0
- rag_titan-0.1.0/src/rag_titan/prompts.py +70 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/adaptive/__init__.py +8 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/adaptive/adaptive_rag.py +95 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/adaptive/evidence_checker.py +26 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/adaptive/query_rewriter.py +20 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/adaptive/router.py +30 -0
- rag_titan-0.1.0/src/rag_titan/rag_types/simple_rag.py +47 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/__init__.py +5 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/rerankers/__init__.py +7 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/rerankers/base_reranker.py +37 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/rerankers/keyword_reranker.py +28 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/rerankers/no_reranker.py +11 -0
- rag_titan-0.1.0/src/rag_titan/retrieval/retriever.py +44 -0
- rag_titan-0.1.0/src/rag_titan/utils/__init__.py +5 -0
- rag_titan-0.1.0/src/rag_titan/utils/logger.py +54 -0
- rag_titan-0.1.0/src/rag_titan/vector_stores/__init__.py +6 -0
- rag_titan-0.1.0/src/rag_titan/vector_stores/base_store.py +28 -0
- rag_titan-0.1.0/src/rag_titan/vector_stores/memory_store.py +50 -0
- rag_titan-0.1.0/tests/conftest.py +87 -0
- rag_titan-0.1.0/tests/test_agent_and_config.py +56 -0
- rag_titan-0.1.0/tests/test_building_blocks.py +68 -0
- rag_titan-0.1.0/tests/test_rag_types.py +58 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Environments
|
|
7
|
+
.venv/
|
|
8
|
+
env/
|
|
9
|
+
venv/
|
|
10
|
+
.env
|
|
11
|
+
.env.*
|
|
12
|
+
!.env.example
|
|
13
|
+
|
|
14
|
+
# Vector databases / local storage
|
|
15
|
+
data/
|
|
16
|
+
*.sqlite3
|
|
17
|
+
*.db
|
|
18
|
+
chroma_db/
|
|
19
|
+
qdrant_storage/
|
|
20
|
+
|
|
21
|
+
# Observability / caches
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
.coverage
|
|
24
|
+
htmlcov/
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
.ruff_cache/
|
|
27
|
+
|
|
28
|
+
# OS / IDE
|
|
29
|
+
.DS_Store
|
|
30
|
+
.idea/
|
|
31
|
+
.vscode/
|
|
32
|
+
# Packaging / build output
|
|
33
|
+
build/
|
|
34
|
+
dist/
|
|
35
|
+
*.egg-info/
|
|
36
|
+
.eggs/
|
|
37
|
+
|
|
38
|
+
# Docs build output
|
|
39
|
+
site/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are written here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
5
|
+
and the project uses [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-11-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- First release of `rag-titan`.
|
|
11
|
+
- RAG types: `SimpleRAG` and `AdaptiveRAG`.
|
|
12
|
+
- `RAGTitan` class: index files and ask questions in two lines.
|
|
13
|
+
- `rag-titan` command line tool (`ask` and `chat`).
|
|
14
|
+
- Building blocks: PDF/DOCX loaders, word chunker, Ollama LLM and embedder,
|
|
15
|
+
in-memory vector store, keyword reranker, grounded generator.
|
|
16
|
+
- Tool-calling `BaseAgent` with an example `MathAgent`.
|
|
17
|
+
- Tests that run without Ollama, docs site, and PyPI publish workflow.
|
|
18
|
+
- Animated flow diagrams (SVG) for every capability, with worked examples.
|
rag_titan-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kumar Nishant
|
|
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.
|
rag_titan-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: rag-titan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Swiss Army knife for RAG: simple, adaptive and more RAG types in one beginner-friendly package.
|
|
5
|
+
Project-URL: Homepage, https://github.com/aion7891/rag-titan
|
|
6
|
+
Project-URL: Documentation, https://aion7891.github.io/rag-titan
|
|
7
|
+
Project-URL: Repository, https://github.com/aion7891/rag-titan
|
|
8
|
+
Project-URL: Issues, https://github.com/aion7891/rag-titan/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/aion7891/rag-titan/blob/main/CHANGELOG.md
|
|
10
|
+
Author: Kumar Nishant
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 Kumar Nishant
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: embeddings,llm,ollama,rag,retrieval-augmented-generation,vector-search
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: Intended Audience :: Education
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: OS Independent
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
46
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
47
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
48
|
+
Requires-Python: >=3.10
|
|
49
|
+
Requires-Dist: numpy>=1.24
|
|
50
|
+
Requires-Dist: ollama>=0.4.0
|
|
51
|
+
Requires-Dist: pypdf>=4.0
|
|
52
|
+
Requires-Dist: pytest>=8.4.2
|
|
53
|
+
Requires-Dist: python-docx>=1.1
|
|
54
|
+
Requires-Dist: python-dotenv>=1.0
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
58
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
59
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
60
|
+
Provides-Extra: docs
|
|
61
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
62
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
63
|
+
Description-Content-Type: text/markdown
|
|
64
|
+
|
|
65
|
+
# rag-titan
|
|
66
|
+
|
|
67
|
+
**A Swiss Army knife for RAG (Retrieval-Augmented Generation).**
|
|
68
|
+
|
|
69
|
+
`rag-titan` puts many types of RAG in one small, beginner-friendly Python
|
|
70
|
+
package. Every part (loader, chunker, embedder, vector store, reranker,
|
|
71
|
+
generator) is a small class you can read in a minute and replace with your own.
|
|
72
|
+
|
|
73
|
+
[](https://pypi.org/project/rag-titan/)
|
|
74
|
+
[](https://pypi.org/project/rag-titan/)
|
|
75
|
+
[](https://github.com/aion7891/rag-titan/blob/main/LICENSE)
|
|
76
|
+
|
|
77
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/overview.svg" alt="rag-titan overview: indexing and answering" width="100%"></p>
|
|
78
|
+
|
|
79
|
+
## Features
|
|
80
|
+
|
|
81
|
+
| RAG type | How it works |
|
|
82
|
+
|------------|---------------------------------------------------------------------|
|
|
83
|
+
| `simple` | Retrieve → Rerank → Generate |
|
|
84
|
+
| `adaptive` | Route the question → Retrieve → Check evidence → Rewrite and retry |
|
|
85
|
+
|
|
86
|
+
More RAG types (corrective, hybrid, multi-query, graph, agentic, ...) are
|
|
87
|
+
planned. See the [roadmap](https://github.com/aion7891/rag-titan/blob/main/docs/roadmap.md).
|
|
88
|
+
|
|
89
|
+
- Runs **100% locally** with [Ollama](https://ollama.com), so your data stays on your machine.
|
|
90
|
+
- Reads **PDF** and **DOCX** files.
|
|
91
|
+
- Answers are **grounded** in your documents and **cite** the chunks they used.
|
|
92
|
+
- Every part is swappable. You only need to inherit from one base class.
|
|
93
|
+
- Includes a `rag-titan` command line tool.
|
|
94
|
+
|
|
95
|
+
### Simple RAG
|
|
96
|
+
|
|
97
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/simple-rag.svg" alt="Simple RAG flow with example scores" width="100%"></p>
|
|
98
|
+
|
|
99
|
+
### Adaptive RAG
|
|
100
|
+
|
|
101
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/adaptive-rag.svg" alt="Adaptive RAG flow with routes and retries" width="100%"></p>
|
|
102
|
+
|
|
103
|
+
## Installation
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install rag-titan
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then install [Ollama](https://ollama.com/download) and pull the default models:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
ollama pull gemma3:4b # chat model
|
|
113
|
+
ollama pull nomic-embed-text # embedding model
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Quick start
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from rag_titan import RAGTitan
|
|
120
|
+
|
|
121
|
+
rag = RAGTitan(rag_type="simple") # or "adaptive"
|
|
122
|
+
rag.index(["handbook.pdf", "policy.docx"])
|
|
123
|
+
|
|
124
|
+
print(rag.ask("How many leave days do I get?"))
|
|
125
|
+
# You get 20 leave days every year [chunk_0].
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Change any setting in code:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
rag = RAGTitan(
|
|
132
|
+
rag_type="adaptive",
|
|
133
|
+
settings={"llm_model": "llama3.2", "chunk_size": 200, "reranker": "none"},
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Command line
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
rag-titan ask --files handbook.pdf --question "How many leave days?"
|
|
141
|
+
rag-titan chat --files handbook.pdf policy.docx --rag-type adaptive
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/cli.svg" alt="rag-titan command line demo" width="100%"></p>
|
|
145
|
+
|
|
146
|
+
## Configuration
|
|
147
|
+
|
|
148
|
+
Settings come from environment variables or a `.env` file. Copy
|
|
149
|
+
[`.env.example`](https://github.com/aion7891/rag-titan/blob/main/.env.example) to get started. Every setting has a default.
|
|
150
|
+
|
|
151
|
+
| Variable | Default | Meaning |
|
|
152
|
+
|-----------------|--------------------------|------------------------------|
|
|
153
|
+
| `LLM_MODEL` | `gemma3:4b` | Chat model used for answers |
|
|
154
|
+
| `EMBED_MODEL` | `nomic-embed-text` | Embedding model |
|
|
155
|
+
| `OLLAMA_HOST` | `http://localhost:11434` | Ollama server address |
|
|
156
|
+
| `CHUNK_SIZE` | `150` | Words per chunk |
|
|
157
|
+
| `CHUNK_OVERLAP` | `30` | Words shared between chunks |
|
|
158
|
+
| `RERANKER` | `keyword` | `keyword` or `none` |
|
|
159
|
+
|
|
160
|
+
See the [configuration docs](https://github.com/aion7891/rag-titan/blob/main/docs/configuration.md) for the full list.
|
|
161
|
+
|
|
162
|
+
## How it works
|
|
163
|
+
|
|
164
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/indexing.svg" alt="Indexing pipeline: load, chunk, embed, store" width="100%"></p>
|
|
165
|
+
|
|
166
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/architecture.svg" alt="Every building block is swappable" width="100%"></p>
|
|
167
|
+
|
|
168
|
+
## Agents
|
|
169
|
+
|
|
170
|
+
A small tool-calling agent loop is included. See the [agents docs](https://github.com/aion7891/rag-titan/blob/main/docs/agents.md).
|
|
171
|
+
|
|
172
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/agent.svg" alt="Agent loop with an example trace" width="100%"></p>
|
|
173
|
+
|
|
174
|
+
## Project layout
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
src/rag_titan/
|
|
178
|
+
├── app.py RAGTitan: the easy, all-in-one class
|
|
179
|
+
├── cli.py the `rag-titan` command
|
|
180
|
+
├── config.py settings from .env / environment
|
|
181
|
+
├── factory.py builds the right class for each setting
|
|
182
|
+
├── prompts.py every RAG prompt in one place
|
|
183
|
+
├── llm/ chat models (Ollama)
|
|
184
|
+
├── loaders/ PDF and DOCX readers
|
|
185
|
+
├── chunking/ split text into chunks
|
|
186
|
+
├── embeddings/ text -> vectors
|
|
187
|
+
├── vector_stores/ save and search vectors
|
|
188
|
+
├── retrieval/ retriever + rerankers
|
|
189
|
+
├── generation/ write the final answer
|
|
190
|
+
├── pipelines/ indexing pipeline
|
|
191
|
+
├── rag_types/ simple and adaptive RAG
|
|
192
|
+
├── agents/ tool-calling agents
|
|
193
|
+
└── utils/ logging
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Documentation
|
|
197
|
+
|
|
198
|
+
Full docs live in [`docs/`](https://github.com/aion7891/rag-titan/blob/main/docs/index.md). To view them locally:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
pip install -e ".[docs]"
|
|
202
|
+
mkdocs serve
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Contributing
|
|
206
|
+
|
|
207
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](https://github.com/aion7891/rag-titan/blob/main/CONTRIBUTING.md).
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
[MIT](https://github.com/aion7891/rag-titan/blob/main/LICENSE)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# rag-titan
|
|
2
|
+
|
|
3
|
+
**A Swiss Army knife for RAG (Retrieval-Augmented Generation).**
|
|
4
|
+
|
|
5
|
+
`rag-titan` puts many types of RAG in one small, beginner-friendly Python
|
|
6
|
+
package. Every part (loader, chunker, embedder, vector store, reranker,
|
|
7
|
+
generator) is a small class you can read in a minute and replace with your own.
|
|
8
|
+
|
|
9
|
+
[](https://pypi.org/project/rag-titan/)
|
|
10
|
+
[](https://pypi.org/project/rag-titan/)
|
|
11
|
+
[](https://github.com/aion7891/rag-titan/blob/main/LICENSE)
|
|
12
|
+
|
|
13
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/overview.svg" alt="rag-titan overview: indexing and answering" width="100%"></p>
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
| RAG type | How it works |
|
|
18
|
+
|------------|---------------------------------------------------------------------|
|
|
19
|
+
| `simple` | Retrieve → Rerank → Generate |
|
|
20
|
+
| `adaptive` | Route the question → Retrieve → Check evidence → Rewrite and retry |
|
|
21
|
+
|
|
22
|
+
More RAG types (corrective, hybrid, multi-query, graph, agentic, ...) are
|
|
23
|
+
planned. See the [roadmap](https://github.com/aion7891/rag-titan/blob/main/docs/roadmap.md).
|
|
24
|
+
|
|
25
|
+
- Runs **100% locally** with [Ollama](https://ollama.com), so your data stays on your machine.
|
|
26
|
+
- Reads **PDF** and **DOCX** files.
|
|
27
|
+
- Answers are **grounded** in your documents and **cite** the chunks they used.
|
|
28
|
+
- Every part is swappable. You only need to inherit from one base class.
|
|
29
|
+
- Includes a `rag-titan` command line tool.
|
|
30
|
+
|
|
31
|
+
### Simple RAG
|
|
32
|
+
|
|
33
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/simple-rag.svg" alt="Simple RAG flow with example scores" width="100%"></p>
|
|
34
|
+
|
|
35
|
+
### Adaptive RAG
|
|
36
|
+
|
|
37
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/adaptive-rag.svg" alt="Adaptive RAG flow with routes and retries" width="100%"></p>
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install rag-titan
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then install [Ollama](https://ollama.com/download) and pull the default models:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ollama pull gemma3:4b # chat model
|
|
49
|
+
ollama pull nomic-embed-text # embedding model
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from rag_titan import RAGTitan
|
|
56
|
+
|
|
57
|
+
rag = RAGTitan(rag_type="simple") # or "adaptive"
|
|
58
|
+
rag.index(["handbook.pdf", "policy.docx"])
|
|
59
|
+
|
|
60
|
+
print(rag.ask("How many leave days do I get?"))
|
|
61
|
+
# You get 20 leave days every year [chunk_0].
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Change any setting in code:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
rag = RAGTitan(
|
|
68
|
+
rag_type="adaptive",
|
|
69
|
+
settings={"llm_model": "llama3.2", "chunk_size": 200, "reranker": "none"},
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Command line
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
rag-titan ask --files handbook.pdf --question "How many leave days?"
|
|
77
|
+
rag-titan chat --files handbook.pdf policy.docx --rag-type adaptive
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/cli.svg" alt="rag-titan command line demo" width="100%"></p>
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
Settings come from environment variables or a `.env` file. Copy
|
|
85
|
+
[`.env.example`](https://github.com/aion7891/rag-titan/blob/main/.env.example) to get started. Every setting has a default.
|
|
86
|
+
|
|
87
|
+
| Variable | Default | Meaning |
|
|
88
|
+
|-----------------|--------------------------|------------------------------|
|
|
89
|
+
| `LLM_MODEL` | `gemma3:4b` | Chat model used for answers |
|
|
90
|
+
| `EMBED_MODEL` | `nomic-embed-text` | Embedding model |
|
|
91
|
+
| `OLLAMA_HOST` | `http://localhost:11434` | Ollama server address |
|
|
92
|
+
| `CHUNK_SIZE` | `150` | Words per chunk |
|
|
93
|
+
| `CHUNK_OVERLAP` | `30` | Words shared between chunks |
|
|
94
|
+
| `RERANKER` | `keyword` | `keyword` or `none` |
|
|
95
|
+
|
|
96
|
+
See the [configuration docs](https://github.com/aion7891/rag-titan/blob/main/docs/configuration.md) for the full list.
|
|
97
|
+
|
|
98
|
+
## How it works
|
|
99
|
+
|
|
100
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/indexing.svg" alt="Indexing pipeline: load, chunk, embed, store" width="100%"></p>
|
|
101
|
+
|
|
102
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/architecture.svg" alt="Every building block is swappable" width="100%"></p>
|
|
103
|
+
|
|
104
|
+
## Agents
|
|
105
|
+
|
|
106
|
+
A small tool-calling agent loop is included. See the [agents docs](https://github.com/aion7891/rag-titan/blob/main/docs/agents.md).
|
|
107
|
+
|
|
108
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/gh/aion7891/rag-titan@main/docs/assets/images/agent.svg" alt="Agent loop with an example trace" width="100%"></p>
|
|
109
|
+
|
|
110
|
+
## Project layout
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
src/rag_titan/
|
|
114
|
+
├── app.py RAGTitan: the easy, all-in-one class
|
|
115
|
+
├── cli.py the `rag-titan` command
|
|
116
|
+
├── config.py settings from .env / environment
|
|
117
|
+
├── factory.py builds the right class for each setting
|
|
118
|
+
├── prompts.py every RAG prompt in one place
|
|
119
|
+
├── llm/ chat models (Ollama)
|
|
120
|
+
├── loaders/ PDF and DOCX readers
|
|
121
|
+
├── chunking/ split text into chunks
|
|
122
|
+
├── embeddings/ text -> vectors
|
|
123
|
+
├── vector_stores/ save and search vectors
|
|
124
|
+
├── retrieval/ retriever + rerankers
|
|
125
|
+
├── generation/ write the final answer
|
|
126
|
+
├── pipelines/ indexing pipeline
|
|
127
|
+
├── rag_types/ simple and adaptive RAG
|
|
128
|
+
├── agents/ tool-calling agents
|
|
129
|
+
└── utils/ logging
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Documentation
|
|
133
|
+
|
|
134
|
+
Full docs live in [`docs/`](https://github.com/aion7891/rag-titan/blob/main/docs/index.md). To view them locally:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pip install -e ".[docs]"
|
|
138
|
+
mkdocs serve
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](https://github.com/aion7891/rag-titan/blob/main/CONTRIBUTING.md).
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
[MIT](https://github.com/aion7891/rag-titan/blob/main/LICENSE)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Packaging settings for rag-titan.
|
|
2
|
+
# Build: python -m build
|
|
3
|
+
# Publish: twine upload dist/* (or the GitHub "Publish" workflow)
|
|
4
|
+
|
|
5
|
+
[build-system]
|
|
6
|
+
requires = ["hatchling>=1.24"]
|
|
7
|
+
build-backend = "hatchling.build"
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
name = "rag-titan"
|
|
11
|
+
dynamic = ["version"]
|
|
12
|
+
description = "A Swiss Army knife for RAG: simple, adaptive and more RAG types in one beginner-friendly package."
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
license = { file = "LICENSE" }
|
|
16
|
+
authors = [{ name = "Kumar Nishant" }]
|
|
17
|
+
keywords = ["rag", "retrieval-augmented-generation", "llm", "ollama", "embeddings", "vector-search"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Intended Audience :: Education",
|
|
22
|
+
"License :: OSI Approved :: MIT License",
|
|
23
|
+
"Operating System :: OS Independent",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
32
|
+
"Topic :: Text Processing :: Indexing",
|
|
33
|
+
]
|
|
34
|
+
dependencies = [
|
|
35
|
+
"numpy>=1.24",
|
|
36
|
+
"ollama>=0.4.0",
|
|
37
|
+
"pypdf>=4.0",
|
|
38
|
+
"pytest>=8.4.2",
|
|
39
|
+
"python-docx>=1.1",
|
|
40
|
+
"python-dotenv>=1.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
dev = [
|
|
45
|
+
"pytest>=8.0",
|
|
46
|
+
"ruff>=0.6",
|
|
47
|
+
"build>=1.2",
|
|
48
|
+
"twine>=5.0",
|
|
49
|
+
]
|
|
50
|
+
docs = [
|
|
51
|
+
"mkdocs-material>=9.5",
|
|
52
|
+
"mkdocstrings[python]>=0.25",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/aion7891/rag-titan"
|
|
57
|
+
Documentation = "https://aion7891.github.io/rag-titan"
|
|
58
|
+
Repository = "https://github.com/aion7891/rag-titan"
|
|
59
|
+
Issues = "https://github.com/aion7891/rag-titan/issues"
|
|
60
|
+
Changelog = "https://github.com/aion7891/rag-titan/blob/main/CHANGELOG.md"
|
|
61
|
+
|
|
62
|
+
[project.scripts]
|
|
63
|
+
rag-titan = "rag_titan.cli:main"
|
|
64
|
+
|
|
65
|
+
# the version lives in one place: src/rag_titan/__init__.py
|
|
66
|
+
[tool.hatch.version]
|
|
67
|
+
path = "src/rag_titan/__init__.py"
|
|
68
|
+
|
|
69
|
+
[tool.hatch.build.targets.wheel]
|
|
70
|
+
packages = ["src/rag_titan"]
|
|
71
|
+
|
|
72
|
+
[tool.hatch.build.targets.sdist]
|
|
73
|
+
include = ["src/rag_titan", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
|
|
74
|
+
|
|
75
|
+
[tool.pytest.ini_options]
|
|
76
|
+
testpaths = ["tests"]
|
|
77
|
+
|
|
78
|
+
[tool.ruff]
|
|
79
|
+
line-length = 100
|
|
80
|
+
target-version = "py310"
|
|
81
|
+
|
|
82
|
+
[tool.ruff.lint]
|
|
83
|
+
select = ["E", "F", "W", "I"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
rag-titan: a Swiss Army knife for Retrieval-Augmented Generation (RAG).
|
|
3
|
+
|
|
4
|
+
Quick start:
|
|
5
|
+
from rag_titan import RAGTitan
|
|
6
|
+
|
|
7
|
+
rag = RAGTitan(rag_type="simple")
|
|
8
|
+
rag.index(["handbook.pdf"])
|
|
9
|
+
print(rag.ask("How many leave days do I get?"))
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from rag_titan.app import RAGTitan
|
|
13
|
+
from rag_titan.config import get_settings
|
|
14
|
+
from rag_titan.factory import RAG_TYPES, build_rag, build_rag_parts
|
|
15
|
+
from rag_titan.rag_types.adaptive.adaptive_rag import AdaptiveRAG
|
|
16
|
+
from rag_titan.rag_types.simple_rag import SimpleRAG
|
|
17
|
+
from rag_titan.utils.logger import setup_logging
|
|
18
|
+
|
|
19
|
+
__version__ = "0.1.0"
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"RAGTitan",
|
|
23
|
+
"SimpleRAG",
|
|
24
|
+
"AdaptiveRAG",
|
|
25
|
+
"RAG_TYPES",
|
|
26
|
+
"build_rag",
|
|
27
|
+
"build_rag_parts",
|
|
28
|
+
"get_settings",
|
|
29
|
+
"setup_logging",
|
|
30
|
+
"__version__",
|
|
31
|
+
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class for every tool-calling agent.
|
|
3
|
+
|
|
4
|
+
The loop:
|
|
5
|
+
think (LLM) -> call tools -> send results back -> repeat
|
|
6
|
+
until the LLM answers without calling a tool, or max_steps is reached.
|
|
7
|
+
|
|
8
|
+
To build a new agent, inherit from BaseAgent and pass a prompt and tools.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from rag_titan.utils.logger import get_logger
|
|
12
|
+
|
|
13
|
+
logger = get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseAgent:
|
|
17
|
+
"""
|
|
18
|
+
A simple agent that lets an LLM call Python functions.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
llm: any BaseLLM that supports tool calling.
|
|
22
|
+
system_prompt: instructions that describe the agent's job.
|
|
23
|
+
tools: list of plain Python functions the LLM may call.
|
|
24
|
+
max_steps: stop after this many think/tool rounds.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, llm, system_prompt, tools, max_steps=5):
|
|
28
|
+
self.llm = llm
|
|
29
|
+
self.system_prompt = system_prompt
|
|
30
|
+
self.tools = tools
|
|
31
|
+
self.tools_by_name = {tool.__name__: tool for tool in tools}
|
|
32
|
+
self.max_steps = max_steps
|
|
33
|
+
self.reset()
|
|
34
|
+
|
|
35
|
+
def reset(self):
|
|
36
|
+
"""Forget the conversation and start fresh."""
|
|
37
|
+
self.messages = [{"role": "system", "content": self.system_prompt}]
|
|
38
|
+
|
|
39
|
+
def run(self, query):
|
|
40
|
+
"""
|
|
41
|
+
Answer one user message, calling tools as needed.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
query: the user's message.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The agent's final answer text.
|
|
48
|
+
"""
|
|
49
|
+
self.messages.append({"role": "user", "content": query})
|
|
50
|
+
|
|
51
|
+
for step in range(1, self.max_steps + 1):
|
|
52
|
+
logger.info("Agent step %d: thinking...", step)
|
|
53
|
+
response = self.llm.chat(self.messages, tools=self.tools)
|
|
54
|
+
self.messages.append(response["message"])
|
|
55
|
+
|
|
56
|
+
# no tool calls means the LLM has given its final answer
|
|
57
|
+
if not response["tool_calls"]:
|
|
58
|
+
return response["content"]
|
|
59
|
+
|
|
60
|
+
for tool_call in response["tool_calls"]:
|
|
61
|
+
result = self._run_tool(tool_call)
|
|
62
|
+
self.messages.append(self.llm.tool_result_message(tool_call, result))
|
|
63
|
+
|
|
64
|
+
return "Maximum steps reached without a final answer."
|
|
65
|
+
|
|
66
|
+
def _run_tool(self, tool_call):
|
|
67
|
+
"""Run one tool safely. Errors are returned as text to the LLM."""
|
|
68
|
+
name = tool_call["name"]
|
|
69
|
+
arguments = tool_call["arguments"]
|
|
70
|
+
tool = self.tools_by_name.get(name)
|
|
71
|
+
|
|
72
|
+
if tool is None:
|
|
73
|
+
result = f"Error: unknown tool '{name}'"
|
|
74
|
+
else:
|
|
75
|
+
try:
|
|
76
|
+
result = tool(**arguments)
|
|
77
|
+
except Exception as error:
|
|
78
|
+
result = f"Error while running {name}: {error}"
|
|
79
|
+
|
|
80
|
+
logger.info("Tool %s(%s) = %s", name, arguments, result)
|
|
81
|
+
return result
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A small example agent that solves math with tools.
|
|
3
|
+
|
|
4
|
+
from rag_titan.agents import MathAgent
|
|
5
|
+
agent = MathAgent(llm)
|
|
6
|
+
print(agent.run("What is (12 + 8) * 3?"))
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from rag_titan.agents.base_agent import BaseAgent
|
|
10
|
+
from rag_titan.agents.prompts import MATH_AGENT_PROMPT
|
|
11
|
+
from rag_titan.agents.tools.math_tools import MATH_TOOLS
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MathAgent(BaseAgent):
|
|
15
|
+
"""
|
|
16
|
+
Agent that uses add, subtract, multiply and divide tools.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
llm: a BaseLLM whose model supports tool calling.
|
|
20
|
+
max_steps: stop after this many think/tool rounds.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, llm, max_steps=5):
|
|
24
|
+
super().__init__(
|
|
25
|
+
llm=llm,
|
|
26
|
+
system_prompt=MATH_AGENT_PROMPT,
|
|
27
|
+
tools=MATH_TOOLS,
|
|
28
|
+
max_steps=max_steps,
|
|
29
|
+
)
|