pirag 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.
- pirag-0.1.0/LICENSE +21 -0
- pirag-0.1.0/PKG-INFO +132 -0
- pirag-0.1.0/README.md +113 -0
- pirag-0.1.0/app/main.py +80 -0
- pirag-0.1.0/app/rag/agent.py +64 -0
- pirag-0.1.0/app/rag/config.py +159 -0
- pirag-0.1.0/app/requirements.txt +11 -0
- pirag-0.1.0/app/setup.py +28 -0
- pirag-0.1.0/pirag.egg-info/PKG-INFO +132 -0
- pirag-0.1.0/pirag.egg-info/SOURCES.txt +14 -0
- pirag-0.1.0/pirag.egg-info/dependency_links.txt +1 -0
- pirag-0.1.0/pirag.egg-info/entry_points.txt +2 -0
- pirag-0.1.0/pirag.egg-info/requires.txt +6 -0
- pirag-0.1.0/pirag.egg-info/top_level.txt +1 -0
- pirag-0.1.0/pyproject.toml +39 -0
- pirag-0.1.0/setup.cfg +4 -0
pirag-0.1.0/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 jyje with studio.r4iny
|
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.
|
pirag-0.1.0/PKG-INFO
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: pirag
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: CLI Projects of On-Premise RAG. You can use your own LLM and vector DB. Or just add remote LLM servers and vector DB.
|
5
|
+
Author-email: semir4in <semir4in@gmail.com>, jyje <jyjeon@outlook.com>
|
6
|
+
Project-URL: Homepage, https://github.com/jyje/pilot-onpremise-rag
|
7
|
+
Project-URL: Repository, https://github.com/jyje/pilot-onpremise-rag
|
8
|
+
Project-URL: Issue, https://github.com/jyje/pilot-onpremise-rag/issues
|
9
|
+
Requires-Python: >=3.9
|
10
|
+
Description-Content-Type: text/markdown
|
11
|
+
License-File: LICENSE
|
12
|
+
Requires-Dist: python-dotenv<1.2
|
13
|
+
Requires-Dist: loguru<0.8
|
14
|
+
Requires-Dist: pytest<8.4
|
15
|
+
Requires-Dist: black<25.2
|
16
|
+
Requires-Dist: ragas<0.3
|
17
|
+
Requires-Dist: pymilvus<2.6
|
18
|
+
Dynamic: license-file
|
19
|
+
|
20
|
+
<div align="center">
|
21
|
+
|
22
|
+
# pirag: pilot-onpremise-rag
|
23
|
+
|
24
|
+
<!-- <img alt="RAG Logo" src="docs/rag-logo.jpg" width="450" style="object-fit: contain; max-width: 100%; aspect-ratio: 16 / 9;"> -->
|
25
|
+
|
26
|
+
๐ฑ LLM+RAG CLI project operating in On-Premise environment
|
27
|
+
|
28
|
+
[](https://typer.tiangolo.com/)
|
29
|
+
[](https://typer.tiangolo.com/)
|
30
|
+
[](https://openai.com)
|
31
|
+
[](https://langchain.com)
|
32
|
+
[](https://milvus.io/)
|
33
|
+
[](https://min.io/)
|
34
|
+
<!-- [](https://docker.com) -->
|
35
|
+
|
36
|
+
</div>
|
37
|
+
|
38
|
+
## ๐ Introduction
|
39
|
+
|
40
|
+
**pilot-onpremise-rag** is a CLI tool that implements a knowledge-based RAG (Retrieval-Augmented Generation) system with LLM. It provides powerful document retrieval and generation capabilities while ensuring data privacy.
|
41
|
+
|
42
|
+
## ๐ง Setup
|
43
|
+
|
44
|
+
### (Optional) Setup External Dependencies
|
45
|
+
```bash
|
46
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
47
|
+
cd pilot-onpremise-rag
|
48
|
+
|
49
|
+
docker compose -f docker/compose.yaml up -d
|
50
|
+
```
|
51
|
+
|
52
|
+
### Install pirag
|
53
|
+
```bash
|
54
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
55
|
+
cd pilot-onpremise-rag
|
56
|
+
|
57
|
+
pip install --upgrade -e ./app
|
58
|
+
```
|
59
|
+
|
60
|
+
## ๐ Usage
|
61
|
+
|
62
|
+
### Basic Commands
|
63
|
+
|
64
|
+
```
|
65
|
+
# View help
|
66
|
+
pirag --help
|
67
|
+
|
68
|
+
# Train documents
|
69
|
+
pirag train --source ./documents
|
70
|
+
|
71
|
+
# Ask a question
|
72
|
+
pirag ask "Give me a joke for Cat-holic."
|
73
|
+
```
|
74
|
+
|
75
|
+
## ๐๏ธ Project Structure
|
76
|
+
|
77
|
+
```
|
78
|
+
pilot-onpremise-rag/
|
79
|
+
โโโ app/ # Main application directory
|
80
|
+
โ โโโ main.py # CLI main entry point
|
81
|
+
โ โโโ setup.py # Package setup configuration
|
82
|
+
โ โโโ pyproject.toml # PEP 517/518 build configuration
|
83
|
+
โ โโโ requirements.txt # Dependencies
|
84
|
+
โ โโโ logs/ # Application logs
|
85
|
+
โ โโโ rag/ # RAG implementation
|
86
|
+
โ โโโ config.py # Configuration settings
|
87
|
+
โ โโโ agent.py # Agent implementation
|
88
|
+
โ โโโ ask/ # Query handling module
|
89
|
+
โ โโโ train/ # Document training module
|
90
|
+
โ โโโ test/ # Testing module
|
91
|
+
โ โโโ doctor/ # Diagnostic tools
|
92
|
+
โโโ VERSION # Project version
|
93
|
+
โโโ docker/ # Docker configuration
|
94
|
+
โโโ assets/ # Static assets (Files are not included)
|
95
|
+
โโโ LICENSE # License information
|
96
|
+
```
|
97
|
+
|
98
|
+
## ๐ How It Works
|
99
|
+
|
100
|
+
1. **Document Training**: Process local documents and store in vector database
|
101
|
+
2. **Search Engine**: Find document chunks related to user queries
|
102
|
+
3. **Context Generation**: Create LLM prompts from retrieved documents
|
103
|
+
4. **Response Generation**: Provide accurate responses via local LLM
|
104
|
+
|
105
|
+
## ๐ก Key Features
|
106
|
+
|
107
|
+
- **Privacy Guaranteed**: All data and processing occurs locally
|
108
|
+
- **Multiple Document Support**: Support for PDF, Markdown, TXT, DOCX, and other formats
|
109
|
+
- **Custom LLM**: Compatible with various local LLM models
|
110
|
+
- **Vector Database**: Vector DB integration for efficient document retrieval
|
111
|
+
|
112
|
+
## ๐งช Performance Optimization
|
113
|
+
|
114
|
+
| Configuration | Memory Usage | Response Speed | Suitable Use Cases |
|
115
|
+
|--------------|-------------|---------------|-------------------|
|
116
|
+
| Light Model | 4-6GB | Fast | Simple queries, low-spec hardware |
|
117
|
+
| Medium Model | 8-12GB | Medium | General use, most queries |
|
118
|
+
| Large Model | 16GB+ | Slow | Complex document analysis, expert answers |
|
119
|
+
|
120
|
+
## ๐ References
|
121
|
+
|
122
|
+
- [LangChain Documentation](https://python.langchain.com/docs/get_started/introduction)
|
123
|
+
- [LLM Optimization Techniques](https://huggingface.co/docs/optimum/index)
|
124
|
+
- [RAG Paper](https://arxiv.org/abs/2005.11401)
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
|
128
|
+
Any contributions are welcome!
|
129
|
+
|
130
|
+
### Current Maintainers
|
131
|
+
- [Studio R4iny](https://github.com/studior4iny)
|
132
|
+
- [jyje](https://github.com/jyje), [semir4in](https://github.com/semir4in) (Same person)
|
pirag-0.1.0/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
<div align="center">
|
2
|
+
|
3
|
+
# pirag: pilot-onpremise-rag
|
4
|
+
|
5
|
+
<!-- <img alt="RAG Logo" src="docs/rag-logo.jpg" width="450" style="object-fit: contain; max-width: 100%; aspect-ratio: 16 / 9;"> -->
|
6
|
+
|
7
|
+
๐ฑ LLM+RAG CLI project operating in On-Premise environment
|
8
|
+
|
9
|
+
[](https://typer.tiangolo.com/)
|
10
|
+
[](https://typer.tiangolo.com/)
|
11
|
+
[](https://openai.com)
|
12
|
+
[](https://langchain.com)
|
13
|
+
[](https://milvus.io/)
|
14
|
+
[](https://min.io/)
|
15
|
+
<!-- [](https://docker.com) -->
|
16
|
+
|
17
|
+
</div>
|
18
|
+
|
19
|
+
## ๐ Introduction
|
20
|
+
|
21
|
+
**pilot-onpremise-rag** is a CLI tool that implements a knowledge-based RAG (Retrieval-Augmented Generation) system with LLM. It provides powerful document retrieval and generation capabilities while ensuring data privacy.
|
22
|
+
|
23
|
+
## ๐ง Setup
|
24
|
+
|
25
|
+
### (Optional) Setup External Dependencies
|
26
|
+
```bash
|
27
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
28
|
+
cd pilot-onpremise-rag
|
29
|
+
|
30
|
+
docker compose -f docker/compose.yaml up -d
|
31
|
+
```
|
32
|
+
|
33
|
+
### Install pirag
|
34
|
+
```bash
|
35
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
36
|
+
cd pilot-onpremise-rag
|
37
|
+
|
38
|
+
pip install --upgrade -e ./app
|
39
|
+
```
|
40
|
+
|
41
|
+
## ๐ Usage
|
42
|
+
|
43
|
+
### Basic Commands
|
44
|
+
|
45
|
+
```
|
46
|
+
# View help
|
47
|
+
pirag --help
|
48
|
+
|
49
|
+
# Train documents
|
50
|
+
pirag train --source ./documents
|
51
|
+
|
52
|
+
# Ask a question
|
53
|
+
pirag ask "Give me a joke for Cat-holic."
|
54
|
+
```
|
55
|
+
|
56
|
+
## ๐๏ธ Project Structure
|
57
|
+
|
58
|
+
```
|
59
|
+
pilot-onpremise-rag/
|
60
|
+
โโโ app/ # Main application directory
|
61
|
+
โ โโโ main.py # CLI main entry point
|
62
|
+
โ โโโ setup.py # Package setup configuration
|
63
|
+
โ โโโ pyproject.toml # PEP 517/518 build configuration
|
64
|
+
โ โโโ requirements.txt # Dependencies
|
65
|
+
โ โโโ logs/ # Application logs
|
66
|
+
โ โโโ rag/ # RAG implementation
|
67
|
+
โ โโโ config.py # Configuration settings
|
68
|
+
โ โโโ agent.py # Agent implementation
|
69
|
+
โ โโโ ask/ # Query handling module
|
70
|
+
โ โโโ train/ # Document training module
|
71
|
+
โ โโโ test/ # Testing module
|
72
|
+
โ โโโ doctor/ # Diagnostic tools
|
73
|
+
โโโ VERSION # Project version
|
74
|
+
โโโ docker/ # Docker configuration
|
75
|
+
โโโ assets/ # Static assets (Files are not included)
|
76
|
+
โโโ LICENSE # License information
|
77
|
+
```
|
78
|
+
|
79
|
+
## ๐ How It Works
|
80
|
+
|
81
|
+
1. **Document Training**: Process local documents and store in vector database
|
82
|
+
2. **Search Engine**: Find document chunks related to user queries
|
83
|
+
3. **Context Generation**: Create LLM prompts from retrieved documents
|
84
|
+
4. **Response Generation**: Provide accurate responses via local LLM
|
85
|
+
|
86
|
+
## ๐ก Key Features
|
87
|
+
|
88
|
+
- **Privacy Guaranteed**: All data and processing occurs locally
|
89
|
+
- **Multiple Document Support**: Support for PDF, Markdown, TXT, DOCX, and other formats
|
90
|
+
- **Custom LLM**: Compatible with various local LLM models
|
91
|
+
- **Vector Database**: Vector DB integration for efficient document retrieval
|
92
|
+
|
93
|
+
## ๐งช Performance Optimization
|
94
|
+
|
95
|
+
| Configuration | Memory Usage | Response Speed | Suitable Use Cases |
|
96
|
+
|--------------|-------------|---------------|-------------------|
|
97
|
+
| Light Model | 4-6GB | Fast | Simple queries, low-spec hardware |
|
98
|
+
| Medium Model | 8-12GB | Medium | General use, most queries |
|
99
|
+
| Large Model | 16GB+ | Slow | Complex document analysis, expert answers |
|
100
|
+
|
101
|
+
## ๐ References
|
102
|
+
|
103
|
+
- [LangChain Documentation](https://python.langchain.com/docs/get_started/introduction)
|
104
|
+
- [LLM Optimization Techniques](https://huggingface.co/docs/optimum/index)
|
105
|
+
- [RAG Paper](https://arxiv.org/abs/2005.11401)
|
106
|
+
|
107
|
+
## Contributing
|
108
|
+
|
109
|
+
Any contributions are welcome!
|
110
|
+
|
111
|
+
### Current Maintainers
|
112
|
+
- [Studio R4iny](https://github.com/studior4iny)
|
113
|
+
- [jyje](https://github.com/jyje), [semir4in](https://github.com/semir4in) (Same person)
|
pirag-0.1.0/app/main.py
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
import argparse, os
|
2
|
+
from dotenv import load_dotenv
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
load_dotenv(dotenv_path=os.environ.get('ENV_FILE', '.env'), override=True)
|
6
|
+
|
7
|
+
from app.rag.config import top_parser, common_parser, setup_logger
|
8
|
+
from app.rag.doctor import help as doctor_help, parser as doctor_parser, route as doctor_route
|
9
|
+
from app.rag.train import help as train_help, parser as train_parser, route as train_route
|
10
|
+
from app.rag.ask import help as ask_help, parser as ask_parser, route as ask_route
|
11
|
+
from app.rag.test import help as test_help, parser as test_parser, route as test_route
|
12
|
+
|
13
|
+
# Main parser
|
14
|
+
parser = argparse.ArgumentParser(
|
15
|
+
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
|
16
|
+
description = 'Pilot of On-Premise RAG',
|
17
|
+
parents = [top_parser],
|
18
|
+
add_help = False,
|
19
|
+
)
|
20
|
+
|
21
|
+
# Commands
|
22
|
+
subparsers = parser.add_subparsers(
|
23
|
+
title = 'commands',
|
24
|
+
dest = 'command',
|
25
|
+
)
|
26
|
+
|
27
|
+
subparsers.add_parser(
|
28
|
+
'doctor',
|
29
|
+
help = doctor_help,
|
30
|
+
description = doctor_parser.description,
|
31
|
+
parents = [top_parser, common_parser, doctor_parser],
|
32
|
+
add_help = False,
|
33
|
+
)
|
34
|
+
|
35
|
+
subparsers.add_parser(
|
36
|
+
'train',
|
37
|
+
help = train_help,
|
38
|
+
description = train_parser.description,
|
39
|
+
parents = [top_parser, common_parser, train_parser],
|
40
|
+
add_help = False,
|
41
|
+
)
|
42
|
+
|
43
|
+
subparsers.add_parser(
|
44
|
+
'test',
|
45
|
+
help = test_help,
|
46
|
+
description = test_parser.description,
|
47
|
+
parents = [top_parser, common_parser, test_parser],
|
48
|
+
add_help = False,
|
49
|
+
)
|
50
|
+
|
51
|
+
subparsers.add_parser(
|
52
|
+
'ask',
|
53
|
+
help = ask_help,
|
54
|
+
description = ask_parser.description,
|
55
|
+
parents = [top_parser, common_parser, ask_parser],
|
56
|
+
add_help = False,
|
57
|
+
)
|
58
|
+
|
59
|
+
def main():
|
60
|
+
args = parser.parse_args()
|
61
|
+
|
62
|
+
command_message = f"with command: {args.command}" if args.command else ""
|
63
|
+
logger.info(f"RAG Started {command_message}")
|
64
|
+
|
65
|
+
setup_logger(args.log_level)
|
66
|
+
logger.debug(f"Parsed arguments: {args}")
|
67
|
+
|
68
|
+
if args.command == 'doctor':
|
69
|
+
doctor_route(args)
|
70
|
+
elif args.command == 'ask':
|
71
|
+
ask_route(args)
|
72
|
+
elif args.command == 'train':
|
73
|
+
train_route(args)
|
74
|
+
elif args.command == 'test':
|
75
|
+
test_route(args)
|
76
|
+
else:
|
77
|
+
parser.print_help()
|
78
|
+
|
79
|
+
if __name__ == '__main__':
|
80
|
+
main()
|
@@ -0,0 +1,64 @@
|
|
1
|
+
from langchain_openai.llms import OpenAI
|
2
|
+
from langchain_openai.embeddings import OpenAIEmbeddings
|
3
|
+
from pymilvus import MilvusClient
|
4
|
+
|
5
|
+
class Agent():
|
6
|
+
def __init__(
|
7
|
+
self,
|
8
|
+
llm_base_url: str,
|
9
|
+
llm_api_key: str,
|
10
|
+
llm_model: str,
|
11
|
+
embedding_base_url: str,
|
12
|
+
embedding_api_key: str,
|
13
|
+
embedding_model: str,
|
14
|
+
milvus_host: str,
|
15
|
+
milvus_database: str,
|
16
|
+
milvus_collection: str,
|
17
|
+
):
|
18
|
+
self.llm_base_url = llm_base_url
|
19
|
+
self.llm_api_key = llm_api_key
|
20
|
+
self.llm_model = llm_model
|
21
|
+
self.embedding_base_url = embedding_base_url
|
22
|
+
self.embedding_api_key = embedding_api_key
|
23
|
+
self.embedding_model = embedding_model
|
24
|
+
self.milvus_host = milvus_host
|
25
|
+
self.milvus_database = milvus_database
|
26
|
+
self.milvus_collection = milvus_collection
|
27
|
+
|
28
|
+
self._llm_client: OpenAI = None
|
29
|
+
self._embedding_client: OpenAIEmbeddings = None
|
30
|
+
self._milvus_client: MilvusClient = None
|
31
|
+
|
32
|
+
def retrieve_knowledge_base(self, query: str) -> str:
|
33
|
+
llm_client = self._get_llm_client()
|
34
|
+
embedding_client = self._get_embedding_client()
|
35
|
+
milvus_client = self._get_milvus_client()
|
36
|
+
|
37
|
+
|
38
|
+
def _get_llm_client(self) -> OpenAI:
|
39
|
+
if self._llm_client is None:
|
40
|
+
self._llm_client = OpenAI(
|
41
|
+
base_url=self.llm_base_url,
|
42
|
+
api_key=self.llm_api_key,
|
43
|
+
model=self.llm_model,
|
44
|
+
)
|
45
|
+
return self._llm_client
|
46
|
+
|
47
|
+
|
48
|
+
def _get_embedding_client(self) -> OpenAIEmbeddings:
|
49
|
+
if self._embedding_client is None:
|
50
|
+
self._embedding_client = OpenAIEmbeddings(
|
51
|
+
base_url=self.embedding_base_url,
|
52
|
+
api_key=self.embedding_api_key,
|
53
|
+
model=self.embedding_model,
|
54
|
+
)
|
55
|
+
return self._embedding_client
|
56
|
+
|
57
|
+
def _get_milvus_client(self) -> MilvusClient:
|
58
|
+
if self._milvus_client is None:
|
59
|
+
self._milvus_client = MilvusClient(
|
60
|
+
host=self.milvus_host,
|
61
|
+
database=self.milvus_database,
|
62
|
+
collection=self.milvus_collection,
|
63
|
+
)
|
64
|
+
return self._milvus_client
|
@@ -0,0 +1,159 @@
|
|
1
|
+
import argparse, os, sys
|
2
|
+
from pathlib import Path
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
# Logger format constants
|
6
|
+
TIME_FORMAT = "{time:YYYY-MM-DD HH:mm:ss.SSS!UTC}Z"
|
7
|
+
FILE_FORMAT = f"{TIME_FORMAT} | {{level: <8}} | {{name}}:{{function}}:{{line}} - {{message}}"
|
8
|
+
CONSOLE_FORMAT_FULL = f"<green>{TIME_FORMAT}</green> | <level>{{level: <8}}</level> | <cyan>{{name}}</cyan>:<cyan>{{function}}</cyan>:<cyan>{{line}}</cyan> - <level>{{message}}</level>\n"
|
9
|
+
CONSOLE_FORMAT_SIMPLE = f"<green>{TIME_FORMAT}</green> | <level>{{level: <8}}</level> | <level>{{message}}</level>\n"
|
10
|
+
|
11
|
+
# Initial logger setup before setup_logger()
|
12
|
+
logger.remove()
|
13
|
+
logger.add(
|
14
|
+
sink = sys.stderr,
|
15
|
+
level = "INFO",
|
16
|
+
format = lambda record: CONSOLE_FORMAT_SIMPLE if record["level"].name == "INFO" else CONSOLE_FORMAT_FULL,
|
17
|
+
colorize = True
|
18
|
+
)
|
19
|
+
|
20
|
+
def setup_logger(log_level: str):
|
21
|
+
"""Configure logger with specified level and outputs"""
|
22
|
+
|
23
|
+
logger.remove()
|
24
|
+
|
25
|
+
log_dir = Path("app/logs")
|
26
|
+
log_dir.mkdir(exist_ok=True, parents=True)
|
27
|
+
|
28
|
+
# File handler
|
29
|
+
logger.add(
|
30
|
+
sink = log_dir / "app.log",
|
31
|
+
level = log_level,
|
32
|
+
rotation = "500 MB",
|
33
|
+
format = FILE_FORMAT,
|
34
|
+
serialize = False,
|
35
|
+
enqueue = True,
|
36
|
+
backtrace = True,
|
37
|
+
diagnose = True,
|
38
|
+
catch = True
|
39
|
+
)
|
40
|
+
|
41
|
+
# Console handler
|
42
|
+
logger.add(
|
43
|
+
sink = sys.stderr,
|
44
|
+
level = log_level,
|
45
|
+
format = lambda record: CONSOLE_FORMAT_SIMPLE if record["level"].name == "INFO" else CONSOLE_FORMAT_FULL,
|
46
|
+
colorize = True
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
class EnvDefault(argparse.Action):
|
51
|
+
"""Custom argparse action that uses environment variables as defaults.
|
52
|
+
|
53
|
+
This action extends the standard argparse.Action to support reading default values
|
54
|
+
from environment variables. If the specified environment variable exists, its value
|
55
|
+
will be used as the default value for the argument.
|
56
|
+
|
57
|
+
For boolean flags (store_true/store_false), the environment variable is interpreted
|
58
|
+
as a boolean value where 'true', '1', 'yes', or 'on' (case-insensitive) are
|
59
|
+
considered True.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
envvar (str): Name of the environment variable to use as default
|
63
|
+
required (bool, optional): Whether the argument is required. Defaults to True.
|
64
|
+
Note: If a default value is found in environment variables, required is set to False.
|
65
|
+
default (Any, optional): Default value if environment variable is not set. Defaults to None.
|
66
|
+
**kwargs: Additional arguments passed to argparse.Action
|
67
|
+
|
68
|
+
Example:
|
69
|
+
```python
|
70
|
+
parser.add_argument(
|
71
|
+
'--log-level',
|
72
|
+
envvar='LOG_LEVEL',
|
73
|
+
help='Logging level',
|
74
|
+
default='INFO',
|
75
|
+
action=EnvDefault
|
76
|
+
)
|
77
|
+
```
|
78
|
+
|
79
|
+
Note:
|
80
|
+
The help text is automatically updated to include the environment variable name.
|
81
|
+
"""
|
82
|
+
def __init__(self, envvar, required=True, default=None, **kwargs):
|
83
|
+
if envvar and envvar in os.environ:
|
84
|
+
env_value = os.environ[envvar]
|
85
|
+
# Convert string environment variable to boolean
|
86
|
+
if kwargs.get('nargs') is None and kwargs.get('const') is not None: # store_true/store_false case
|
87
|
+
default = env_value.lower() in ('true', '1', 'yes', 'on')
|
88
|
+
else:
|
89
|
+
default = env_value
|
90
|
+
logger.debug(f"Using {envvar}={default} from environment")
|
91
|
+
|
92
|
+
if envvar:
|
93
|
+
kwargs["help"] += f" (envvar: {envvar})"
|
94
|
+
|
95
|
+
if required and default:
|
96
|
+
required = False
|
97
|
+
|
98
|
+
super(EnvDefault, self).__init__(default=default, required=required, **kwargs)
|
99
|
+
self.envvar = envvar
|
100
|
+
|
101
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
102
|
+
setattr(namespace, self.dest, values if values is not None else self.default)
|
103
|
+
|
104
|
+
|
105
|
+
# Top-level parser with common options
|
106
|
+
top_parser = argparse.ArgumentParser(add_help=False)
|
107
|
+
|
108
|
+
top_parser.add_argument(
|
109
|
+
'-h', '--help',
|
110
|
+
help = 'Show help message and exit',
|
111
|
+
default = argparse.SUPPRESS,
|
112
|
+
action = 'help',
|
113
|
+
)
|
114
|
+
|
115
|
+
top_parser.add_argument(
|
116
|
+
'--env-file',
|
117
|
+
envvar = 'ENV_FILE',
|
118
|
+
help = 'Path to environment file',
|
119
|
+
default = '.env',
|
120
|
+
type = str,
|
121
|
+
action = EnvDefault,
|
122
|
+
)
|
123
|
+
|
124
|
+
top_parser.add_argument(
|
125
|
+
'--log-level',
|
126
|
+
envvar = 'LOG_LEVEL',
|
127
|
+
help = 'Logging level',
|
128
|
+
default = 'INFO',
|
129
|
+
type = lambda x: x.upper(),
|
130
|
+
choices = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
|
131
|
+
required = False,
|
132
|
+
action = EnvDefault,
|
133
|
+
)
|
134
|
+
|
135
|
+
top_parser.add_argument(
|
136
|
+
'--log-path',
|
137
|
+
envvar = 'LOG_PATH',
|
138
|
+
help = 'Path to log file',
|
139
|
+
default = '.logs',
|
140
|
+
type = str,
|
141
|
+
required = False,
|
142
|
+
action = EnvDefault,
|
143
|
+
)
|
144
|
+
|
145
|
+
top_parser.add_argument(
|
146
|
+
'--log-save',
|
147
|
+
envvar = 'LOG_SAVE',
|
148
|
+
help = 'Save log to file. If this flag is set, the log will be saved to the file specified in the `--log-path`.',
|
149
|
+
default = False,
|
150
|
+
const = True,
|
151
|
+
nargs = 0,
|
152
|
+
type = bool,
|
153
|
+
required = False,
|
154
|
+
action = EnvDefault,
|
155
|
+
)
|
156
|
+
|
157
|
+
common_parser = argparse.ArgumentParser(
|
158
|
+
add_help = False,
|
159
|
+
)
|
pirag-0.1.0/app/setup.py
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
from setuptools import setup, find_packages
|
2
|
+
import os, sys
|
3
|
+
import tomli
|
4
|
+
|
5
|
+
# Load requirements
|
6
|
+
with open(os.path.join(os.path.dirname(__file__), 'requirements.txt'), 'r') as f:
|
7
|
+
requirements = [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
8
|
+
|
9
|
+
# Get version from pyproject.toml
|
10
|
+
with open(os.path.join(os.path.dirname(__file__), '../pyproject.toml'), 'rb') as f:
|
11
|
+
pyproject = tomli.load(f)
|
12
|
+
version = pyproject["project"]["version"]
|
13
|
+
|
14
|
+
APP_NAME = "pirag"
|
15
|
+
|
16
|
+
setup(
|
17
|
+
name = APP_NAME,
|
18
|
+
version = version,
|
19
|
+
packages = [".", "rag"],
|
20
|
+
package_dir = {"": ".", "rag": "rag"},
|
21
|
+
include_package_data = True,
|
22
|
+
install_requires = requirements,
|
23
|
+
entry_points = {
|
24
|
+
"console_scripts": [
|
25
|
+
f"{APP_NAME}=main:main",
|
26
|
+
],
|
27
|
+
},
|
28
|
+
)
|
@@ -0,0 +1,132 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: pirag
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: CLI Projects of On-Premise RAG. You can use your own LLM and vector DB. Or just add remote LLM servers and vector DB.
|
5
|
+
Author-email: semir4in <semir4in@gmail.com>, jyje <jyjeon@outlook.com>
|
6
|
+
Project-URL: Homepage, https://github.com/jyje/pilot-onpremise-rag
|
7
|
+
Project-URL: Repository, https://github.com/jyje/pilot-onpremise-rag
|
8
|
+
Project-URL: Issue, https://github.com/jyje/pilot-onpremise-rag/issues
|
9
|
+
Requires-Python: >=3.9
|
10
|
+
Description-Content-Type: text/markdown
|
11
|
+
License-File: LICENSE
|
12
|
+
Requires-Dist: python-dotenv<1.2
|
13
|
+
Requires-Dist: loguru<0.8
|
14
|
+
Requires-Dist: pytest<8.4
|
15
|
+
Requires-Dist: black<25.2
|
16
|
+
Requires-Dist: ragas<0.3
|
17
|
+
Requires-Dist: pymilvus<2.6
|
18
|
+
Dynamic: license-file
|
19
|
+
|
20
|
+
<div align="center">
|
21
|
+
|
22
|
+
# pirag: pilot-onpremise-rag
|
23
|
+
|
24
|
+
<!-- <img alt="RAG Logo" src="docs/rag-logo.jpg" width="450" style="object-fit: contain; max-width: 100%; aspect-ratio: 16 / 9;"> -->
|
25
|
+
|
26
|
+
๐ฑ LLM+RAG CLI project operating in On-Premise environment
|
27
|
+
|
28
|
+
[](https://typer.tiangolo.com/)
|
29
|
+
[](https://typer.tiangolo.com/)
|
30
|
+
[](https://openai.com)
|
31
|
+
[](https://langchain.com)
|
32
|
+
[](https://milvus.io/)
|
33
|
+
[](https://min.io/)
|
34
|
+
<!-- [](https://docker.com) -->
|
35
|
+
|
36
|
+
</div>
|
37
|
+
|
38
|
+
## ๐ Introduction
|
39
|
+
|
40
|
+
**pilot-onpremise-rag** is a CLI tool that implements a knowledge-based RAG (Retrieval-Augmented Generation) system with LLM. It provides powerful document retrieval and generation capabilities while ensuring data privacy.
|
41
|
+
|
42
|
+
## ๐ง Setup
|
43
|
+
|
44
|
+
### (Optional) Setup External Dependencies
|
45
|
+
```bash
|
46
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
47
|
+
cd pilot-onpremise-rag
|
48
|
+
|
49
|
+
docker compose -f docker/compose.yaml up -d
|
50
|
+
```
|
51
|
+
|
52
|
+
### Install pirag
|
53
|
+
```bash
|
54
|
+
git clone https://github.com/jyje/pilot-onpremise-rag
|
55
|
+
cd pilot-onpremise-rag
|
56
|
+
|
57
|
+
pip install --upgrade -e ./app
|
58
|
+
```
|
59
|
+
|
60
|
+
## ๐ Usage
|
61
|
+
|
62
|
+
### Basic Commands
|
63
|
+
|
64
|
+
```
|
65
|
+
# View help
|
66
|
+
pirag --help
|
67
|
+
|
68
|
+
# Train documents
|
69
|
+
pirag train --source ./documents
|
70
|
+
|
71
|
+
# Ask a question
|
72
|
+
pirag ask "Give me a joke for Cat-holic."
|
73
|
+
```
|
74
|
+
|
75
|
+
## ๐๏ธ Project Structure
|
76
|
+
|
77
|
+
```
|
78
|
+
pilot-onpremise-rag/
|
79
|
+
โโโ app/ # Main application directory
|
80
|
+
โ โโโ main.py # CLI main entry point
|
81
|
+
โ โโโ setup.py # Package setup configuration
|
82
|
+
โ โโโ pyproject.toml # PEP 517/518 build configuration
|
83
|
+
โ โโโ requirements.txt # Dependencies
|
84
|
+
โ โโโ logs/ # Application logs
|
85
|
+
โ โโโ rag/ # RAG implementation
|
86
|
+
โ โโโ config.py # Configuration settings
|
87
|
+
โ โโโ agent.py # Agent implementation
|
88
|
+
โ โโโ ask/ # Query handling module
|
89
|
+
โ โโโ train/ # Document training module
|
90
|
+
โ โโโ test/ # Testing module
|
91
|
+
โ โโโ doctor/ # Diagnostic tools
|
92
|
+
โโโ VERSION # Project version
|
93
|
+
โโโ docker/ # Docker configuration
|
94
|
+
โโโ assets/ # Static assets (Files are not included)
|
95
|
+
โโโ LICENSE # License information
|
96
|
+
```
|
97
|
+
|
98
|
+
## ๐ How It Works
|
99
|
+
|
100
|
+
1. **Document Training**: Process local documents and store in vector database
|
101
|
+
2. **Search Engine**: Find document chunks related to user queries
|
102
|
+
3. **Context Generation**: Create LLM prompts from retrieved documents
|
103
|
+
4. **Response Generation**: Provide accurate responses via local LLM
|
104
|
+
|
105
|
+
## ๐ก Key Features
|
106
|
+
|
107
|
+
- **Privacy Guaranteed**: All data and processing occurs locally
|
108
|
+
- **Multiple Document Support**: Support for PDF, Markdown, TXT, DOCX, and other formats
|
109
|
+
- **Custom LLM**: Compatible with various local LLM models
|
110
|
+
- **Vector Database**: Vector DB integration for efficient document retrieval
|
111
|
+
|
112
|
+
## ๐งช Performance Optimization
|
113
|
+
|
114
|
+
| Configuration | Memory Usage | Response Speed | Suitable Use Cases |
|
115
|
+
|--------------|-------------|---------------|-------------------|
|
116
|
+
| Light Model | 4-6GB | Fast | Simple queries, low-spec hardware |
|
117
|
+
| Medium Model | 8-12GB | Medium | General use, most queries |
|
118
|
+
| Large Model | 16GB+ | Slow | Complex document analysis, expert answers |
|
119
|
+
|
120
|
+
## ๐ References
|
121
|
+
|
122
|
+
- [LangChain Documentation](https://python.langchain.com/docs/get_started/introduction)
|
123
|
+
- [LLM Optimization Techniques](https://huggingface.co/docs/optimum/index)
|
124
|
+
- [RAG Paper](https://arxiv.org/abs/2005.11401)
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
|
128
|
+
Any contributions are welcome!
|
129
|
+
|
130
|
+
### Current Maintainers
|
131
|
+
- [Studio R4iny](https://github.com/studior4iny)
|
132
|
+
- [jyje](https://github.com/jyje), [semir4in](https://github.com/semir4in) (Same person)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
LICENSE
|
2
|
+
README.md
|
3
|
+
pyproject.toml
|
4
|
+
app/main.py
|
5
|
+
app/requirements.txt
|
6
|
+
app/setup.py
|
7
|
+
app/rag/agent.py
|
8
|
+
app/rag/config.py
|
9
|
+
pirag.egg-info/PKG-INFO
|
10
|
+
pirag.egg-info/SOURCES.txt
|
11
|
+
pirag.egg-info/dependency_links.txt
|
12
|
+
pirag.egg-info/entry_points.txt
|
13
|
+
pirag.egg-info/requires.txt
|
14
|
+
pirag.egg-info/top_level.txt
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
app
|
@@ -0,0 +1,39 @@
|
|
1
|
+
[project]
|
2
|
+
name = "pirag"
|
3
|
+
version = "0.1.0"
|
4
|
+
description = "CLI Projects of On-Premise RAG. You can use your own LLM and vector DB. Or just add remote LLM servers and vector DB."
|
5
|
+
authors = [
|
6
|
+
{ name="semir4in", email="semir4in@gmail.com" },
|
7
|
+
{ name="jyje", email="jyjeon@outlook.com" }
|
8
|
+
]
|
9
|
+
readme = "README.md"
|
10
|
+
requires-python = ">=3.9"
|
11
|
+
dynamic = ["dependencies"]
|
12
|
+
|
13
|
+
[project.urls]
|
14
|
+
Homepage = "https://github.com/jyje/pilot-onpremise-rag"
|
15
|
+
Repository = "https://github.com/jyje/pilot-onpremise-rag"
|
16
|
+
Issue = "https://github.com/jyje/pilot-onpremise-rag/issues"
|
17
|
+
|
18
|
+
[project.scripts]
|
19
|
+
pirag = "app.main:main"
|
20
|
+
|
21
|
+
[build-system]
|
22
|
+
requires = [
|
23
|
+
"setuptools>=61.0",
|
24
|
+
"wheel<0.46",
|
25
|
+
"build>=1.0.3",
|
26
|
+
"pip>=23.0",
|
27
|
+
"tomli<2.1",
|
28
|
+
]
|
29
|
+
build-backend = "setuptools.build_meta"
|
30
|
+
|
31
|
+
[tool.setuptools]
|
32
|
+
packages = ["app", "app.rag"]
|
33
|
+
|
34
|
+
[tool.setuptools.package-dir]
|
35
|
+
app = "app"
|
36
|
+
"app.rag" = "app/rag"
|
37
|
+
|
38
|
+
[tool.setuptools.dynamic]
|
39
|
+
dependencies = {file = ["app/requirements.txt"]}
|
pirag-0.1.0/setup.cfg
ADDED