Spaces:
Sleeping
Sleeping
Commit
·
1eaf3d8
1
Parent(s):
a50849a
fixed open ai problem + simplified work
Browse files- app.py +5 -2
- scripts/config.py +85 -51
- scripts/rag_engine.py +4 -2
app.py
CHANGED
@@ -25,13 +25,16 @@ def initialize_system():
|
|
25 |
global query_engine
|
26 |
query_engine = None
|
27 |
|
28 |
-
#
|
|
|
|
|
|
|
|
|
29 |
if os.path.exists(os.path.join(RAG_FILES_DIR, 'faiss_index.index')):
|
30 |
try:
|
31 |
print("Found existing RAG system files, loading...")
|
32 |
query_engine = load_rag_system()
|
33 |
if query_engine is not None:
|
34 |
-
# Count chunks from existing system
|
35 |
chunk_count = 0
|
36 |
if os.path.exists(PROCESSED_DATA_FILE):
|
37 |
processed_chunks = load_processed_chunks(PROCESSED_DATA_FILE)
|
|
|
25 |
global query_engine
|
26 |
query_engine = None
|
27 |
|
28 |
+
# IMPORTANT: Setup LLM settings at the very beginning
|
29 |
+
from scripts.config import setup_llm_settings
|
30 |
+
setup_llm_settings()
|
31 |
+
|
32 |
+
# Rest of your existing code...
|
33 |
if os.path.exists(os.path.join(RAG_FILES_DIR, 'faiss_index.index')):
|
34 |
try:
|
35 |
print("Found existing RAG system files, loading...")
|
36 |
query_engine = load_rag_system()
|
37 |
if query_engine is not None:
|
|
|
38 |
chunk_count = 0
|
39 |
if os.path.exists(PROCESSED_DATA_FILE):
|
40 |
processed_chunks = load_processed_chunks(PROCESSED_DATA_FILE)
|
scripts/config.py
CHANGED
@@ -6,8 +6,7 @@ from llama_index.core import Settings
|
|
6 |
from llama_index.core.llms import ChatMessage, MessageRole
|
7 |
import os
|
8 |
|
9 |
-
|
10 |
-
|
11 |
EMBEDDING_MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
|
12 |
RETRIEVER_TOP_K = 10
|
13 |
RETRIEVER_SIMILARITY_CUTOFF = 0.7
|
@@ -15,78 +14,113 @@ RAG_FILES_DIR = "processed_data"
|
|
15 |
PROCESSED_DATA_FILE = "processed_data/processed_chunks.csv"
|
16 |
|
17 |
UPLOAD_FOLDER = "UPLOADED_DOCUMENTS"
|
18 |
-
PROCESSED_DATA_FILE = "processed_data/processed_chunks.csv"
|
19 |
INDEX_STATE_FILE = "processed_data/index_store.json"
|
20 |
-
RAG_FILES_DIR = "processed_data"
|
21 |
|
22 |
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY', "AIzaSyDemsCp7JIdRNDRyP6DkYdMox1DLZwPcPE")
|
23 |
LLM_MODEL = "gemini-2.0-flash"
|
24 |
|
25 |
-
|
26 |
CHUNK_SIZE = 1024
|
27 |
CHUNK_OVERLAP = 256
|
28 |
MAX_CHUNK_SIZE = 2048
|
29 |
MIN_CHUNK_SIZE = 750
|
30 |
SIMILARITY_THRESHOLD = 0.7
|
31 |
|
32 |
-
|
33 |
-
RETRIEVER_TOP_K = 15
|
34 |
-
RETRIEVER_SIMILARITY_CUTOFF = 0.7
|
35 |
-
|
36 |
-
|
37 |
def setup_llm_settings():
|
38 |
-
|
39 |
-
|
|
|
|
|
40 |
|
41 |
-
#
|
|
|
|
|
|
|
|
|
42 |
if GOOGLE_API_KEY:
|
43 |
try:
|
44 |
llm = GoogleGenAI(model=LLM_MODEL, api_key=GOOGLE_API_KEY)
|
45 |
Settings.llm = llm
|
46 |
-
|
47 |
-
if hasattr(llm, 'system_prompt'):
|
48 |
-
llm.system_prompt = CUSTOM_PROMPT
|
49 |
except Exception as e:
|
50 |
print(f"Warning: Could not initialize Google GenAI LLM: {e}")
|
51 |
-
|
|
|
|
|
52 |
else:
|
53 |
-
print("Warning: GOOGLE_API_KEY not found.
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
CUSTOM_PROMPT = """
|
58 |
-
You are a highly specialized Document Analysis Assistant (AIEXP). Your purpose is to provide precise, accurate, and contextually relevant answers by analyzing a set of normal regulatory documents (НД). Your responses must be entirely based on the provided context, without any external knowledge or assumptions.
|
59 |
-
|
60 |
-
Core Tasks:
|
61 |
-
Based on the user's query, perform one of the following tasks:
|
62 |
-
- Information Retrieval: Find and present specific information.
|
63 |
-
- Summarization: Provide a concise summary of a document or a section.
|
64 |
-
- Semantic Analysis: Compare a provided text against the requirements of the ND.
|
65 |
-
- Action Planning: Create a step-by-step plan based on ND requirements.
|
66 |
|
67 |
-
Strict Rules for Response Generation:
|
68 |
-
1. Source Attribution is Mandatory: Every answer must explicitly cite its source from the provided context. Use one of the following formats:
|
69 |
-
- For content from a specific section/subsection:
|
70 |
-
Согласно разделу [X] и подразделу [X.X]: [Ваш ответ]
|
71 |
-
- For content that is not part of a specific subsection (e.g., from a general section, table, or figure):
|
72 |
-
Согласно [Название документа] - [Номер и наименование пункта/таблицы/изображения]: [Ваш ответ]
|
73 |
-
- If the source chunk has metadata for both section and subsection, always include both.
|
74 |
-
- If the source chunk has only a section, use the format Согласно разделу [X]: [Ваш ответ].
|
75 |
|
76 |
-
2. No Hallucinations: If the requested information is not explicitly found within the provided context, you must state that the information is not available. Do not attempt to infer, guess, or create a response. The correct response in this case is:
|
77 |
-
Информация по вашему запросу не была найдена в нормативной документации.
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
"""
|
91 |
|
92 |
|
|
|
6 |
from llama_index.core.llms import ChatMessage, MessageRole
|
7 |
import os
|
8 |
|
9 |
+
# Configuration
|
|
|
10 |
EMBEDDING_MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
|
11 |
RETRIEVER_TOP_K = 10
|
12 |
RETRIEVER_SIMILARITY_CUTOFF = 0.7
|
|
|
14 |
PROCESSED_DATA_FILE = "processed_data/processed_chunks.csv"
|
15 |
|
16 |
UPLOAD_FOLDER = "UPLOADED_DOCUMENTS"
|
|
|
17 |
INDEX_STATE_FILE = "processed_data/index_store.json"
|
|
|
18 |
|
19 |
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY', "AIzaSyDemsCp7JIdRNDRyP6DkYdMox1DLZwPcPE")
|
20 |
LLM_MODEL = "gemini-2.0-flash"
|
21 |
|
|
|
22 |
CHUNK_SIZE = 1024
|
23 |
CHUNK_OVERLAP = 256
|
24 |
MAX_CHUNK_SIZE = 2048
|
25 |
MIN_CHUNK_SIZE = 750
|
26 |
SIMILARITY_THRESHOLD = 0.7
|
27 |
|
|
|
|
|
|
|
|
|
|
|
28 |
def setup_llm_settings():
|
29 |
+
"""Setup embedding and LLM models"""
|
30 |
+
# Configure Google API
|
31 |
+
if GOOGLE_API_KEY:
|
32 |
+
genai.configure(api_key=GOOGLE_API_KEY)
|
33 |
|
34 |
+
# Set embedding model
|
35 |
+
embed_model = HuggingFaceEmbedding(model_name=EMBEDDING_MODEL)
|
36 |
+
Settings.embed_model = embed_model
|
37 |
+
|
38 |
+
# Set LLM - IMPORTANT: This prevents OpenAI default
|
39 |
if GOOGLE_API_KEY:
|
40 |
try:
|
41 |
llm = GoogleGenAI(model=LLM_MODEL, api_key=GOOGLE_API_KEY)
|
42 |
Settings.llm = llm
|
43 |
+
print("Google GenAI LLM initialized successfully")
|
|
|
|
|
44 |
except Exception as e:
|
45 |
print(f"Warning: Could not initialize Google GenAI LLM: {e}")
|
46 |
+
# Set a dummy LLM to prevent OpenAI default
|
47 |
+
from llama_index.core.llms.mock import MockLLM
|
48 |
+
Settings.llm = MockLLM()
|
49 |
else:
|
50 |
+
print("Warning: GOOGLE_API_KEY not found. Using MockLLM.")
|
51 |
+
from llama_index.core.llms.mock import MockLLM
|
52 |
+
Settings.llm = MockLLM()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
|
|
|
|
55 |
|
56 |
+
CUSTOM_PROMPT = """
|
57 |
+
Вы являетесь высокоспециализированным Ассистентом для анализа документов (AIEXP). Ваша цель - предоставлять точные, корректные и контекстно релевантные ответы на основе анализа нормативной документации (НД). Все ваши ответы до��жны основываться исключительно на предоставленном контексте без использования внешних знаний или предположений.
|
58 |
+
|
59 |
+
ОПРЕДЕЛЕНИЕ ТИПА ЗАДАЧИ:
|
60 |
+
Проанализируйте запрос пользователя и определите тип задачи:
|
61 |
+
|
62 |
+
1. КРАТКОЕ САММАРИ (ключевые слова: "кратко", "суммировать", "резюме", "основные моменты", "в двух словах"):
|
63 |
+
- Предоставьте структурированное резюме запрашиваемого раздела/пункта
|
64 |
+
- Выделите ключевые требования, процедуры или положения
|
65 |
+
- Используйте нумерованный список для лучшей читаемости
|
66 |
+
- Сохраняйте терминологию НД
|
67 |
+
|
68 |
+
2. ПОИСК ДОКУМЕНТА И ПУНКТА (ключевые слова: "найти", "где", "какой документ", "в каком разделе", "ссылка"):
|
69 |
+
- Укажите конкретный документ и его структурное расположение
|
70 |
+
- Предоставьте точные номера разделов/подразделов/пунктов
|
71 |
+
- Процитируйте релевантные фрагменты
|
72 |
+
- Если найдено несколько документов, перечислите все с указанием специфики каждого
|
73 |
+
|
74 |
+
3. ПРОВЕРКА КОРРЕКТНОСТИ (ключевые слова: "правильно ли", "соответствует ли", "проверить", "корректно", "нарушение"):
|
75 |
+
- Сопоставьте предоставленную информацию с требованиями НД
|
76 |
+
- Четко укажите: "СООТВЕТСТВУЕТ" или "НЕ СООТВЕТСТВУЕТ"
|
77 |
+
- Перечислите конкретные требования НД
|
78 |
+
- Укажите выявленные расхождения или подтвердите соответствие
|
79 |
+
- Процитируйте релевантные пункты НД
|
80 |
+
|
81 |
+
4. ПЛАН ДЕЙСТВИЙ (ключевые слова: "план", "алгоритм", "последовательность", "как действовать", "пошагово"):
|
82 |
+
- Создайте пронумерованный пошаговый план
|
83 |
+
- Каждый шаг должен содержать ссылку на соответствующий пункт НД
|
84 |
+
- Укажите необходимые документы или формы
|
85 |
+
- Добавьте временные рамки, если они указаны в НД
|
86 |
+
- Выделите критические требования или ограничения
|
87 |
+
|
88 |
+
ПРАВИЛА ФОРМИРОВАНИЯ ОТВЕТОВ:
|
89 |
+
|
90 |
+
1. ОБЯЗАТЕЛЬНОЕ УКАЗАНИЕ ИСТОЧНИКОВ:
|
91 |
+
- Для контента из конкретного раздела/подраздела:
|
92 |
+
"Согласно разделу [X] и подразделу [X.X]: [Ваш ответ]"
|
93 |
+
- Для контента вне подразделов (таблицы, рисунки, общие разделы):
|
94 |
+
"Согласно [Название документа] - [Номер и наименование пункта/таблицы/рисунка]: [Ваш ответ]"
|
95 |
+
- При наличии метаданных о разделе и подразделе - включайте оба
|
96 |
+
- При наличии только раздела: "Согласно разделу [X]: [Ваш ответ]"
|
97 |
+
|
98 |
+
2. СТРОГОЕ СЛЕДОВАНИЕ КОНТЕКСТУ:
|
99 |
+
- Если информация не найдена: "Информация по вашему запросу не была найдена в нормативной документации."
|
100 |
+
- Не делайте предположений или выводов за пределами предоставленного контекста
|
101 |
+
- Не используйте общие знания
|
102 |
+
|
103 |
+
3. ИСПОЛЬЗОВАНИЕ ТЕРМИНОЛОГИИ НД:
|
104 |
+
- Применяйте официальную терминологию из документов
|
105 |
+
- Сохраняйте оригинальные формулировки ключевых требований
|
106 |
+
- При необходимости разъясняйте специальные термины на основе НД
|
107 |
+
|
108 |
+
4. СТРУКТУРИРОВАНИЕ ОТВЕТОВ:
|
109 |
+
- Для саммари: используйте маркированные или нумерованные списки
|
110 |
+
- Для проверки: четкая структура "Требование → Соответствие/Несоответствие"
|
111 |
+
- Для планов: пронумерованные шаги с подзадачами при необходимости
|
112 |
+
- Для поиска: указание иерархии документа
|
113 |
+
|
114 |
+
5. ДОПОЛНИТЕЛЬНЫЕ РЕКОМЕНДАЦИИ:
|
115 |
+
- При множественных релевантных источниках - укажите все
|
116 |
+
- Выделяйте критически важные требования
|
117 |
+
- Указывайте альтернативные процедуры, если они предусмотрены НД
|
118 |
+
|
119 |
+
Контекст: {context_str}
|
120 |
+
|
121 |
+
Вопрос: {query_str}
|
122 |
+
|
123 |
+
Ответ:
|
124 |
"""
|
125 |
|
126 |
|
scripts/rag_engine.py
CHANGED
@@ -17,17 +17,19 @@ def setup_llm_settings():
|
|
17 |
Settings.embed_model = embed_model
|
18 |
|
19 |
def create_vector_index_with_faiss(documents):
|
|
|
20 |
setup_llm_settings()
|
21 |
|
22 |
-
d = 384
|
23 |
faiss_index = faiss.IndexFlatIP(d)
|
24 |
vector_store = FaissVectorStore(faiss_index=faiss_index)
|
25 |
storage_context = StorageContext.from_defaults(vector_store=vector_store)
|
26 |
|
|
|
27 |
index = VectorStoreIndex.from_documents(
|
28 |
documents,
|
29 |
storage_context=storage_context,
|
30 |
-
embed_model
|
31 |
)
|
32 |
|
33 |
return index, faiss_index
|
|
|
17 |
Settings.embed_model = embed_model
|
18 |
|
19 |
def create_vector_index_with_faiss(documents):
|
20 |
+
# Setup settings FIRST before creating any objects
|
21 |
setup_llm_settings()
|
22 |
|
23 |
+
d = 384 # Dimension for the embedding model
|
24 |
faiss_index = faiss.IndexFlatIP(d)
|
25 |
vector_store = FaissVectorStore(faiss_index=faiss_index)
|
26 |
storage_context = StorageContext.from_defaults(vector_store=vector_store)
|
27 |
|
28 |
+
# Use the embedding model from Settings
|
29 |
index = VectorStoreIndex.from_documents(
|
30 |
documents,
|
31 |
storage_context=storage_context,
|
32 |
+
embed_model=Settings.embed_model # Use Settings instead of string
|
33 |
)
|
34 |
|
35 |
return index, faiss_index
|