upd docker prepare script
This commit is contained in:
parent
5b6d7728ce
commit
0d681ea2ba
Binary file not shown.
122
Backend/arch.py
Normal file
122
Backend/arch.py
Normal file
@ -0,0 +1,122 @@
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches
|
||||
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE, MSO_CONNECTOR
|
||||
|
||||
# Vytvorenie novej prezentácie
|
||||
prs = Presentation()
|
||||
slide_layout = prs.slide_layouts[5] # Prázdny slide
|
||||
slide = prs.slides.add_slide(slide_layout)
|
||||
|
||||
# Definícia základných rozmerov a pozícií
|
||||
left_margin = Inches(0.5)
|
||||
top_margin = Inches(0.5)
|
||||
block_width = Inches(3)
|
||||
block_height = Inches(0.7)
|
||||
vertical_gap = Inches(0.3)
|
||||
horizontal_gap = Inches(0.5)
|
||||
|
||||
# Blok 1: Používateľský dotaz & Chat history
|
||||
box1 = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_margin, top_margin, block_width, block_height)
|
||||
box1.text = "Používateľský dotaz\n& Chat history"
|
||||
|
||||
# Blok 2: ConversationalAgent (pod box1)
|
||||
box2_top = top_margin + block_height + vertical_gap
|
||||
box2 = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_margin, box2_top, block_width, block_height)
|
||||
box2.text = "ConversationalAgent"
|
||||
|
||||
# Blok 3: Klasifikácia dotazu (pod box2)
|
||||
box3_top = box2_top + block_height + vertical_gap
|
||||
box3 = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_margin, box3_top, block_width, block_height)
|
||||
box3.text = "Klasifikácia dotazu"
|
||||
|
||||
# Vetvenie: Pozície pre dve vetvy
|
||||
branch_top = box3_top + block_height + vertical_gap
|
||||
|
||||
# Ľavá vetva ("Vyhladavanie")
|
||||
left_branch_left = left_margin - Inches(0.2)
|
||||
box4A = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_branch_left, branch_top, block_width, block_height)
|
||||
box4A.text = "ElasticsearchStore\nvyhľadávanie"
|
||||
|
||||
box5A_top = branch_top + block_height + vertical_gap
|
||||
box5A = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_branch_left, box5A_top, block_width, block_height)
|
||||
box5A.text = "Generovanie\ndynamického promptu"
|
||||
|
||||
box6A_top = box5A_top + block_height + vertical_gap
|
||||
box6A = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_branch_left, box6A_top, block_width, block_height)
|
||||
box6A.text = "Generovanie\nodpovede"
|
||||
|
||||
box7A_top = box6A_top + block_height + vertical_gap
|
||||
box7A = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_branch_left, box7A_top, block_width, block_height)
|
||||
box7A.text = "Finalizácia\nodpovede"
|
||||
|
||||
# Pravá vetva ("Upresnenie")
|
||||
right_branch_left = left_margin + block_width + horizontal_gap
|
||||
box4B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, branch_top, block_width, block_height)
|
||||
box4B.text = "Kombinovanie\ndotazov"
|
||||
|
||||
box5B_top = branch_top + block_height + vertical_gap
|
||||
box5B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, box5B_top, block_width, block_height)
|
||||
box5B.text = "ElasticsearchStore\nvyhľadávanie"
|
||||
|
||||
box6B_top = box5B_top + block_height + vertical_gap
|
||||
box6B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, box6B_top, block_width, block_height)
|
||||
box6B.text = "Generovanie\ndynamického promptu"
|
||||
|
||||
box7B_top = box6B_top + block_height + vertical_gap
|
||||
box7B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, box7B_top, block_width, block_height)
|
||||
box7B.text = "Generovanie\nodpovedí (2 modely)"
|
||||
|
||||
box8B_top = box7B_top + block_height + vertical_gap
|
||||
box8B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, box8B_top, block_width, block_height)
|
||||
box8B.text = "Validácia a\nhodnotenie odpovedí"
|
||||
|
||||
box9B_top = box8B_top + block_height + vertical_gap
|
||||
box9B = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, right_branch_left, box9B_top, block_width, block_height)
|
||||
box9B.text = "Finalizácia\nodpovede"
|
||||
|
||||
# Finálny blok: Výstup (zlúčenie vetiev)
|
||||
final_box_top = max(box7A_top, box9B_top) + block_height + vertical_gap
|
||||
final_box = slide.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.RECTANGLE, left_margin, final_box_top, block_width, block_height)
|
||||
final_box.text = "Výstup"
|
||||
|
||||
# Funkcia na pridanie šípok medzi blokmi
|
||||
def add_connector(slide, start_shape, end_shape):
|
||||
start_x = start_shape.left + start_shape.width / 2
|
||||
start_y = start_shape.top + start_shape.height
|
||||
end_x = end_shape.left + end_shape.width / 2
|
||||
end_y = end_shape.top
|
||||
connector = slide.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, start_x, start_y, end_x, end_y)
|
||||
# Aktuálna verzia python-pptx nepodporuje nastavenie šípky, preto tento riadok odstraňte alebo zakomentujte:
|
||||
# connector.line.end_arrowhead.style = 1
|
||||
return connector
|
||||
|
||||
# Prepojenie blokov
|
||||
add_connector(slide, box1, box2)
|
||||
add_connector(slide, box2, box3)
|
||||
|
||||
# Vetvenie z Box3 do oboch vetiev
|
||||
mid_point = box3.left + box3.width / 2
|
||||
branch_mid_y = box3.top + box3.height + vertical_gap/2
|
||||
# Do ľavej vetvy:
|
||||
connector_left = slide.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, mid_point, box3.top + box3.height, left_branch_left + block_width/2, branch_mid_y)
|
||||
# Do pravej vetvy:
|
||||
connector_right = slide.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, mid_point, box3.top + box3.height, right_branch_left + block_width/2, branch_mid_y)
|
||||
|
||||
# Prepojenie blokov v ľavej vetve
|
||||
add_connector(slide, box4A, box5A)
|
||||
add_connector(slide, box5A, box6A)
|
||||
add_connector(slide, box6A, box7A)
|
||||
|
||||
# Prepojenie blokov v pravej vetve
|
||||
add_connector(slide, box4B, box5B)
|
||||
add_connector(slide, box5B, box6B)
|
||||
add_connector(slide, box6B, box7B)
|
||||
add_connector(slide, box7B, box8B)
|
||||
add_connector(slide, box8B, box9B)
|
||||
|
||||
# Spojenie oboch vetiev s finálnym blokom "Výstup"
|
||||
add_connector(slide, box7A, final_box)
|
||||
add_connector(slide, box9B, final_box)
|
||||
|
||||
# Uloženie prezentácie
|
||||
prs.save("architecture_diagram.pptx")
|
@ -14,7 +14,6 @@ from psycopg2.extras import RealDictCursor
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
config_file_path = "config.json"
|
||||
with open(config_file_path, 'r') as config_file:
|
||||
config = json.load(config_file)
|
||||
@ -23,15 +22,18 @@ mistral_api_key = "hXDC4RBJk1qy5pOlrgr01GtOlmyCBaNs"
|
||||
if not mistral_api_key:
|
||||
raise ValueError("Mistral API key not found in configuration.")
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Simple functions for translation (stub)
|
||||
###############################################################################
|
||||
def translate_to_slovak(text: str) -> str:
|
||||
return text
|
||||
|
||||
|
||||
def translate_preserving_medicine_names(text: str) -> str:
|
||||
return text
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function for evaluating the completeness of the answer
|
||||
###############################################################################
|
||||
@ -53,6 +55,7 @@ def evaluate_complete_answer(query: str, answer: str) -> dict:
|
||||
score = 0.0
|
||||
return {"rating": round(score, 2), "explanation": "Evaluation based on required criteria."}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function for validating the response logic
|
||||
###############################################################################
|
||||
@ -73,6 +76,7 @@ def validate_answer_logic(query: str, answer: str) -> str:
|
||||
logger.error(f"Error during answer validation: {e}")
|
||||
return answer
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function for creating a dynamic prompt with information from documents
|
||||
###############################################################################
|
||||
@ -91,6 +95,7 @@ def build_dynamic_prompt(query: str, documents: list) -> str:
|
||||
)
|
||||
return prompt
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function to get user data from the database via endpoint /api/get_user_data
|
||||
###############################################################################
|
||||
@ -106,6 +111,7 @@ def get_user_data_from_db(chat_id: str) -> str:
|
||||
logger.error(f"Error retrieving user_data from DB: {e}", exc_info=True)
|
||||
return ""
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Class for calling Mistral LLM
|
||||
###############################################################################
|
||||
@ -147,6 +153,21 @@ class CustomMistralLLM:
|
||||
raise ex
|
||||
raise Exception("Reached maximum number of retries for API request")
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function for generating a detailed evaluation description
|
||||
###############################################################################
|
||||
# def detailed_evaluation_description(query: str, answer: str, rating: float) -> str:
|
||||
# prompt = (
|
||||
# f"Podrobne opíš, prečo odpoveď: '{answer}' na otázku: '{query}' dosiahla hodnotenie {rating} zo 10. "
|
||||
# "Uveď relevantné aspekty, ktoré ovplyvnili toto hodnotenie, vrátane úplnosti, presnosti a kvality vysvetlenia."
|
||||
# )
|
||||
# description = llm_small.generate_text(prompt=prompt, max_tokens=150, temperature=0.5)
|
||||
# return description.strip()
|
||||
#
|
||||
# Ak chcete vidieť podrobné hodnotenie, odkomentujte funkciu detailed_evaluation_description a príslušné časti kódu.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Initialisation of Embeddings and Elasticsearch
|
||||
###############################################################################
|
||||
@ -188,6 +209,7 @@ llm_large = CustomMistralLLM(
|
||||
model_name="mistral-large-latest"
|
||||
)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Request classification function: vyhladavanie vs. upresnenie
|
||||
###############################################################################
|
||||
@ -213,6 +235,7 @@ def classify_query(query: str, chat_history: str = "") -> str:
|
||||
return "upresnenie"
|
||||
return "vyhladavanie"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Template for upresnenie dopytu
|
||||
###############################################################################
|
||||
@ -237,6 +260,7 @@ Upresňujúca otázka od používateľa:
|
||||
"""
|
||||
return prompt
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Function for retrieving the last vyhladavacieho dopytu z histórie
|
||||
###############################################################################
|
||||
@ -249,6 +273,7 @@ def extract_last_vyhladavacie_query(chat_history: str) -> str:
|
||||
break
|
||||
return last_query
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Agent class for data storage: vek, anamneza, predpis, user_data, search_query
|
||||
###############################################################################
|
||||
@ -308,15 +333,16 @@ class ConversationalAgent:
|
||||
def ask_follow_up(self, missing_info: dict) -> str:
|
||||
return " ".join(missing_info.values())
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Main function process_query_with_mistral with updated logic
|
||||
###############################################################################
|
||||
CHAT_HISTORY_ENDPOINT = "http://localhost:5000/api/chat_history_detail"
|
||||
|
||||
|
||||
def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10):
|
||||
logger.info("Processing query started.")
|
||||
|
||||
|
||||
chat_history = ""
|
||||
if chat_context:
|
||||
chat_history = chat_context
|
||||
@ -337,23 +363,18 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
except Exception as e:
|
||||
logger.error(f"Chyba pri načítaní histórie: {e}")
|
||||
|
||||
|
||||
agent = ConversationalAgent()
|
||||
if chat_history:
|
||||
agent.load_memory_from_history(chat_history)
|
||||
|
||||
|
||||
existing_user_data = ""
|
||||
if chat_id:
|
||||
existing_user_data = get_user_data_from_db(chat_id)
|
||||
|
||||
|
||||
agent.parse_user_info(query)
|
||||
missing_info = agent.analyze_input(query)
|
||||
|
||||
|
||||
if not existing_user_data:
|
||||
|
||||
if "Prosím, uveďte vek pacienta" in chat_history:
|
||||
if chat_id:
|
||||
update_payload = {"chatId": chat_id, "userData": query}
|
||||
@ -388,19 +409,16 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
"patient_data": query
|
||||
}
|
||||
|
||||
|
||||
qtype = classify_query(query, chat_history)
|
||||
logger.info(f"Typ dopytu: {qtype}")
|
||||
logger.info(f"Chat context (snippet): {chat_history[:200]}...")
|
||||
|
||||
|
||||
if qtype == "vyhladavanie":
|
||||
user_data_db = get_user_data_from_db(chat_id)
|
||||
if user_data_db:
|
||||
query = query + " Udaje cloveka: " + user_data_db
|
||||
agent.long_term_memory["search_query"] = query
|
||||
|
||||
|
||||
if qtype == "upresnenie":
|
||||
original_search = agent.long_term_memory.get("search_query")
|
||||
if not original_search:
|
||||
@ -442,7 +460,8 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
f"Otázka: {combined_query}\n\n"
|
||||
"Na základe týchto informácií:\n"
|
||||
f"{joined_docs}\n\n"
|
||||
"Vygeneruj odporúčanie liekov alebo vysvetlenie, ak je to relevantné."
|
||||
"Vygeneruj odporúčanie liekov alebo vysvetlenie, ak je to relevantné.\n"
|
||||
"Prosím, odpovedaj stručne a dostatočne, bez nadmernej dĺžky."
|
||||
)
|
||||
ans_small = llm_small.generate_text(final_prompt, max_tokens=1200, temperature=0.7)
|
||||
ans_large = llm_large.generate_text(final_prompt, max_tokens=1200, temperature=0.7)
|
||||
@ -454,8 +473,32 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
{"summary": val_small, "eval": eval_small, "model": "Mistral Small"},
|
||||
{"summary": val_large, "eval": eval_large, "model": "Mistral Large"},
|
||||
]
|
||||
|
||||
#
|
||||
# for candidate in candidates:
|
||||
# detailed_desc = detailed_evaluation_description(combined_query, candidate["summary"], candidate["eval"]["rating"])
|
||||
# candidate["eval"]["detailed_description"] = detailed_desc
|
||||
#
|
||||
|
||||
|
||||
best = max(candidates, key=lambda x: x["eval"]["rating"])
|
||||
logger.info(f"Odpoveď od modelu {best['model']} má rating: {best['eval']['rating']}/10")
|
||||
|
||||
|
||||
evaluation_table = "=== Výsledky hodnotenia odpovedí ===\n"
|
||||
evaluation_table += "{:<15} | {:<6} | {:<60}\n".format("Model", "Rating", "Evaluated Text")
|
||||
evaluation_table += "-" * 100 + "\n"
|
||||
for candidate in candidates:
|
||||
model_name = candidate["model"]
|
||||
rating = candidate["eval"]["rating"]
|
||||
evaluated_text = candidate["summary"].replace("\n", " ")
|
||||
evaluation_table += "{:<15} | {:<6} | {:<60}\n".format(model_name, rating, evaluated_text)
|
||||
evaluation_table += "=" * 100 + "\n"
|
||||
|
||||
# with open("evaluation.txt", "w", encoding="utf-8") as f:
|
||||
# f.write(evaluation_table)
|
||||
# logger.info("Evaluation table записана в evaluation.txt")
|
||||
|
||||
final_answer = translate_preserving_medicine_names(best["summary"])
|
||||
memory_json = json.dumps(agent.long_term_memory)
|
||||
memory_block = f"[MEMORY]{memory_json}[/MEMORY]"
|
||||
@ -467,7 +510,6 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
"explanation": best["eval"]["explanation"]
|
||||
}
|
||||
|
||||
|
||||
vector_results = vectorstore.similarity_search(query, k=k)
|
||||
max_docs = 5
|
||||
max_len = 1000
|
||||
@ -484,7 +526,8 @@ def process_query_with_mistral(query: str, chat_id: str, chat_context: str, k=10
|
||||
f"Otázka: {query}\n\n"
|
||||
"Na základe týchto informácií:\n"
|
||||
f"{joined_docs}\n\n"
|
||||
"Vygeneruj odporúčanie liekov alebo vysvetlenie, ak je to relevantné."
|
||||
"Vygeneruj odporúčanie liekov alebo vysvetlenie, ak je to relevantné.\n"
|
||||
"Prosím, odpovedaj stručne a dostatočne, bez nadmernej dĺžky."
|
||||
)
|
||||
answer = llm_small.generate_text(final_prompt, max_tokens=1200, temperature=0.7)
|
||||
memory_json = json.dumps(agent.long_term_memory)
|
||||
|
56
Backend/tablepresent.py
Normal file
56
Backend/tablepresent.py
Normal file
@ -0,0 +1,56 @@
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches
|
||||
|
||||
# Создание новой презентации
|
||||
prs = Presentation()
|
||||
|
||||
# Добавляем пустой слайд (layout с индексом 5 обычно является пустым)
|
||||
slide_layout = prs.slide_layouts[5]
|
||||
slide = prs.slides.add_slide(slide_layout)
|
||||
|
||||
# Определяем позицию и размер таблицы
|
||||
left = Inches(0.5)
|
||||
top = Inches(1.5)
|
||||
width = Inches(9)
|
||||
height = Inches(3)
|
||||
|
||||
# Количество строк: 1 заголовок + 2 строки с данными
|
||||
rows = 3
|
||||
cols = 4
|
||||
|
||||
# Добавляем таблицу на слайд
|
||||
table = slide.shapes.add_table(rows, cols, left, top, width, height).table
|
||||
|
||||
# Устанавливаем ширину столбцов (при необходимости можно настроить отдельно)
|
||||
table.columns[0].width = Inches(1.5) # Модель
|
||||
table.columns[1].width = Inches(1) # Оценка
|
||||
table.columns[2].width = Inches(4) # Текст
|
||||
table.columns[3].width = Inches(2.5) # Описание
|
||||
|
||||
# Заполняем заголовки
|
||||
table.cell(0, 0).text = "Модель"
|
||||
table.cell(0, 1).text = "Оценка"
|
||||
table.cell(0, 2).text = "Текст"
|
||||
table.cell(0, 3).text = "Описание"
|
||||
|
||||
# Данные для первого кандидата
|
||||
table.cell(1, 0).text = "Mistral Small"
|
||||
table.cell(1, 1).text = "9.0"
|
||||
table.cell(1, 2).text = (
|
||||
"Nevolnosť môže byť spôsobená rôznymi príčinami, ako sú napríklad gastrointestinálne problémy, infekcie, alebo vedľajšie účinky liekov. "
|
||||
"Pre ľudí, ktorí hľadajú voľnopredajný liek na nevolnosť, sú dostupné niekoľko možností: 1. Dimedrol (Dramin) – Antihistaminikum; "
|
||||
"2. Bismut subsalicylát (Pepto-Bismol); 3. Ginger (Zázvor); 4. Meclizin (Bonine). Pred použitím lieku je dôležité konzultovať s lekárom."
|
||||
)
|
||||
table.cell(1, 3).text = "Evaluation based on required criteria."
|
||||
|
||||
# Данные для второго кандидата
|
||||
table.cell(2, 0).text = "Mistral Large"
|
||||
table.cell(2, 1).text = "8.0"
|
||||
table.cell(2, 2).text = (
|
||||
"Pre nevolnosť sa dajú použiť niektoré voľne predávané lieky, ale dôležité je poradiť sa s lekárom, najmä ak má pacient 20 rokov. "
|
||||
"Medzi bežné voľne predávané lieky patria: 1. Dimenhydrinát; 2. Meclozín. Tieto lieky môžu spôsobiť spánkovosť a dávkovanie je nutné konzultovať."
|
||||
)
|
||||
table.cell(2, 3).text = "Evaluation based on required criteria."
|
||||
|
||||
# Сохраняем презентацию в файл
|
||||
prs.save("evaluation_table.pptx")
|
@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
echo "Подготовка окружения: сборка Docker образов..."
|
||||
docker-compose build
|
||||
echo "Подготовка завершена."
|
||||
echo "Prepearing Docker images..."
|
||||
docker-compose up --build
|
||||
|
||||
echo "Preparation ended."
|
||||
|
Loading…
Reference in New Issue
Block a user