From 3dbba3f2d66375f1648d7639190d4a4772a2341b Mon Sep 17 00:00:00 2001 From: "l.gabrysiak" Date: Fri, 28 Feb 2025 11:44:28 +0100 Subject: [PATCH] code ready to deploy + prompty --- ollama_service.py | 89 +++++++++++++++++++++++---------------- prompts/prompt_answer.txt | 1 + prompts/prompt_data.txt | 1 + prompts/prompt_seach.txt | 15 +++++++ prompts/prompt_system.txt | 25 +++++++++++ 5 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 prompts/prompt_answer.txt create mode 100644 prompts/prompt_data.txt create mode 100644 prompts/prompt_seach.txt create mode 100644 prompts/prompt_system.txt diff --git a/ollama_service.py b/ollama_service.py index d045cfc..79fce8d 100644 --- a/ollama_service.py +++ b/ollama_service.py @@ -11,11 +11,13 @@ import uvicorn import httpx from typing import List, Optional import asyncio +import os app = FastAPI() OLLAMA_BASE_URL = "http://ollama:11434" WEAVIATE_URL = "http://weaviate:8080" +PROMPT_DIR_PATCH = "./prompts" # Inicjalizacja klientów ollama_client = ollama.Client(host=OLLAMA_BASE_URL) @@ -31,7 +33,7 @@ weaviate_client = weaviate.WeaviateClient( ) weaviate_client.connect() collection = weaviate_client.collections.get("Document") - +files_content = None class Message(BaseModel): role: str content: str @@ -54,28 +56,30 @@ class ChatResponse(BaseModel): eval_count: int eval_duration: int -prompt = """ -Jesteś precyzyjnym narzędziem do generowania słów kluczowych z zakresu BHP i prawa pracy. Twoje zadanie to podanie WYŁĄCZNIE najistotniejszych słów do wyszukiwania w bazie dokumentów prawnych. +def read_text_files_from_directory(directory_path): + files_dict = {} + + # Iterowanie przez wszystkie pliki w katalogu + for filename in os.listdir(directory_path): + # Sprawdzanie, czy plik ma rozszerzenie .txt + if filename.endswith('.txt'): + file_path = os.path.join(directory_path, filename) + try: + # Odczytywanie zawartości pliku + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + # Dodawanie do słownika z nazwą pliku bez rozszerzenia jako kluczem + file_name_without_extension = os.path.splitext(filename)[0] + files_dict[file_name_without_extension] = content + except Exception as e: + print(f"Błąd przy odczycie pliku {filename}: {e}") + + return files_dict -Ścisłe zasady: -1. Jeśli zapytanie dotyczy konkretnego artykułu: - - Podaj TYLKO numer artykułu i nazwę kodeksu (np. "Art. 154, Kodeks pracy"). - - NIE dodawaj żadnych innych słów. -2. Jeśli zapytanie nie dotyczy konkretnego artykułu: - - Podaj maksymalnie 3 najbardziej specyficzne terminy związane z zapytaniem. - - Unikaj ogólnych słów jak "praca", "pracownik", "pracodawca", chyba że są częścią specjalistycznego terminu. -3. Używaj wyłącznie terminów, które z pewnością występują w dokumentach prawnych lub specjalistycznych opracowaniach. -4. NIE dodawaj własnych interpretacji ani rozszerzeń zapytania. - -Odpowiedz TYLKO listą słów kluczowych oddzielonych przecinkami, bez żadnych dodatkowych wyjaśnień czy komentarzy. - -Zapytanie: '{query}' -""" - -def analyze_query(query): +def analyze_query(content): analysis = ollama_client.chat( model="gemma2:2b", - messages=[{"role": "user", "content": prompt.format(query=query)}] + messages=[{"role": "user", "content": content}] ) keywords = [word.strip() for word in analysis['message']['content'].split(',') if word.strip()] print("Słowa kluczowe:", keywords) @@ -103,7 +107,7 @@ def extract_relevant_fragment(content, query, context_size=100): return f"...{content[start:end]}..." return content[:200] + "..." -def hybrid_search(keywords, limit=5, alpha=0.5): +def hybrid_search(keywords, limit=100, alpha=0.5): if isinstance(keywords, str): keywords = [keywords] @@ -182,27 +186,38 @@ async def stream_chat(model, messages, options): @app.post("/api/chat") async def chat_endpoint(request: ChatRequest): try: + files_content = read_text_files_from_directory(PROMPT_DIR_PATCH) + if files_content is None: + raise KeyError(f"Nie wczytano promptów!!!") + + prompt_seach = files_content.get("prompt_seach") + if prompt_seach is None: + raise KeyError(f"Nie znaleziono promptu o nazwie '{prompt_seach}'.") + + prompt_system = files_content.get("prompt_system") + if prompt_system is None: + raise KeyError(f"Nie znaleziono promptu o nazwie '{prompt_system}'.") + + prompt_answer = files_content.get("prompt_answer") + if prompt_answer is None: + raise KeyError(f"Nie znaleziono promptu o nazwie '{prompt_answer}'.") + + prompt_data = files_content.get("prompt_data") + if prompt_data is None: + raise KeyError(f"Nie znaleziono promptu o nazwie '{prompt_data}'.") + query = request.messages[-1].content if request.messages else "" - keywords = analyze_query(query) + keywords = analyze_query(prompt_seach.format(query=query)) weaviate_results = hybrid_search(keywords) - if not weaviate_results: - context = f""" - Nie znalazłem informacji na temat: {query}. - Proszę poinformuj użytkownika, że nie masz wystarczającej wiedzy, aby udzielić jednoznacznej odpowiedzi. - """ - else: - context = "Znalezione informacje:\n" - for item in weaviate_results: - context += f"Źródło: {item['file_name']}\nFragment: {item['relevant_fragment']}\n\n" + prompt_data = "\n".join([f"Źródło: {doc['file_name']}\n{doc['relevant_fragment']}\n\n" for doc in weaviate_results]) + print(prompt_data) messages_with_context =[ - {"role": "system", "content": context}, - {"role": "user", "content": f""" - Na podstawie powyższych informacji, odpowiedz na pytanie: {query}. - Odwołaj się do konkretnych artykułów lub zacytuj fragmenty źródeł. - """} - ] + {"role": "system", "content": prompt_system}, + {"role": "system", "content": prompt_data}, + {"role": "user", "content": prompt_answer.format(query=query)} + ] if request.stream: return StreamingResponse(stream_chat(request.model, messages_with_context, request.options), media_type="application/json") diff --git a/prompts/prompt_answer.txt b/prompts/prompt_answer.txt new file mode 100644 index 0000000..2a5e54c --- /dev/null +++ b/prompts/prompt_answer.txt @@ -0,0 +1 @@ +Na podstawie powyższych informacji odpowiedz na pytanie: {query}. \ No newline at end of file diff --git a/prompts/prompt_data.txt b/prompts/prompt_data.txt new file mode 100644 index 0000000..169448b --- /dev/null +++ b/prompts/prompt_data.txt @@ -0,0 +1 @@ +Oto fragmenty aktów prawnych i dokumentów powiązanych z pytaniem użytkownika: \n\n \ No newline at end of file diff --git a/prompts/prompt_seach.txt b/prompts/prompt_seach.txt new file mode 100644 index 0000000..8797301 --- /dev/null +++ b/prompts/prompt_seach.txt @@ -0,0 +1,15 @@ +Jesteś precyzyjnym narzędziem do generowania słów kluczowych z zakresu BHP i prawa pracy. Twoje zadanie to podanie WYŁĄCZNIE najistotniejszych słów do wyszukiwania w bazie dokumentów prawnych. + +Ścisłe zasady: +1. Jeśli zapytanie dotyczy konkretnego artykułu: + - Podaj TYLKO numer artykułu i nazwę kodeksu (np. "Art. 154, Kodeks pracy"). + - NIE dodawaj żadnych innych słów. +2. Jeśli zapytanie nie dotyczy konkretnego artykułu: + - Podaj maksymalnie 3 najbardziej specyficzne terminy związane z zapytaniem. + - Unikaj ogólnych słów jak "praca", "pracownik", "pracodawca", chyba że są częścią specjalistycznego terminu. +3. Używaj wyłącznie terminów, które z pewnością występują w dokumentach prawnych lub specjalistycznych opracowaniach. +4. NIE dodawaj własnych interpretacji ani rozszerzeń zapytania. + +Odpowiedz TYLKO listą słów kluczowych oddzielonych przecinkami, bez żadnych dodatkowych wyjaśnień czy komentarzy. + +Zapytanie: '{query}' \ No newline at end of file diff --git a/prompts/prompt_system.txt b/prompts/prompt_system.txt new file mode 100644 index 0000000..d2170b8 --- /dev/null +++ b/prompts/prompt_system.txt @@ -0,0 +1,25 @@ +Jesteś asystentem – ekspertem ds. BHP. Twoim zadaniem jest udzielanie rzeczowych, precyzyjnych i merytorycznych odpowiedzi na pytania użytkownika na podstawie dostępnych aktów prawnych (np. kodeksów, rozporządzeń) oraz innych dokumentów, takich jak instrukcje stanowiskowe czy publikacje ekspertów. + +### 📜 Zasady udzielania odpowiedzi: +1. **Korzystaj z dostępnych źródeł** – Twoje odpowiedzi powinny być oparte na dokumentach dostarczonych w kontekście. +2. **Cytuj akty prawne, jeśli to możliwe** – Jeśli użytkownik pyta o konkretny artykuł, przytocz jego treść w formie cytatu, np. "Art. 3 Kodeksu Pracy stanowi: 'Pracodawcą jest jednostka organizacyjna, choćby nie posiadała osobowości prawnej, a także osoba fizyczna, jeżeli zatrudniają one pracowników.'". +3. **Nie podawaj nazw plików źródłowych** – Możesz powoływać się na źródła (np. "Zgodnie z Kodeksem Pracy, art. 3..."), ale nie możesz ujawniać nazw plików zawierających te informacje. +4. **Wskazuj źródła przepisów** – Jeśli odpowiedź wynika z aktu prawnego, zaznacz to, np. "Zgodnie z art. 237 Kodeksu Pracy...". +5. **Jeżeli pytanie dotyczy zagadnienia, a nie konkretnego artykułu**, odpowiedź może być swobodniejsza, ale nadal musi być oparta na bazie wiedzy. Jeśli to możliwe, wskaż podstawę prawną lub dokument, który odnosi się do danej kwestii. +6. **Nie wymyślaj informacji spoza kontekstu** – Jeśli brakuje Ci danych w dostępnych dokumentach, poinformuj użytkownika, że potrzebne jest inne źródło. + +### 📌 Przykłady odpowiedzi: + +**🟢 Pytanie o konkretny artykuł:** +- **Pytanie:** Jak brzmi art. 3 Kodeksu Pracy? +- **Odpowiedź:** Art. 3 Kodeksu Pracy stanowi: *"Pracodawcą jest jednostka organizacyjna, choćby nie posiadała osobowości prawnej, a także osoba fizyczna, jeżeli zatrudniają one pracowników."* + +**🟢 Pytanie o zagadnienie:** +- **Pytanie:** Kiedy pracownik może iść na urlop? +- **Odpowiedź:** Pracownik nabywa prawo do urlopu proporcjonalnie do przepracowanego okresu. Zgodnie z art. 154 Kodeksu Pracy, wymiar urlopu wynosi 20 dni dla pracownika zatrudnionego krócej niż 10 lat oraz 26 dni dla pracownika z co najmniej 10-letnim stażem. Urlop powinien być udzielany zgodnie z planem urlopowym lub na wniosek pracownika, jeśli pracodawca wyrazi na to zgodę. + +**🟢 Pytanie bez jasnej podstawy prawnej:** +- **Pytanie:** Czy pracodawca musi zapewnić wodę pitną w miejscu pracy? +- **Odpowiedź:** Tak, zgodnie z przepisami BHP pracodawca jest zobowiązany do zapewnienia pracownikom dostępu do wody pitnej. Obowiązek ten wynika z przepisów rozporządzenia dotyczącego ogólnych przepisów BHP, które określają warunki higieniczne w miejscu pracy. + +Dostosuj odpowiedzi do poziomu wiedzy użytkownika i nie podawaj nazw plików, w których znajdują się dokumenty źródłowe. \ No newline at end of file