Zapis w ElasticSearch

This commit is contained in:
l.gabrysiak 2025-02-28 18:12:08 +01:00
parent 3dbba3f2d6
commit f83da185f8
3 changed files with 93 additions and 16 deletions

View File

@ -12,15 +12,19 @@ import httpx
from typing import List, Optional from typing import List, Optional
import asyncio import asyncio
import os import os
from elasticsearch import Elasticsearch
from datetime import datetime
app = FastAPI() app = FastAPI()
OLLAMA_BASE_URL = "http://ollama:11434" OLLAMA_BASE_URL = "http://ollama:11434"
ES_BASE_URL = "http://elastic:9200"
WEAVIATE_URL = "http://weaviate:8080" WEAVIATE_URL = "http://weaviate:8080"
PROMPT_DIR_PATCH = "./prompts" PROMPT_DIR_PATCH = "./prompts"
# Inicjalizacja klientów # Inicjalizacja klientów
ollama_client = ollama.Client(host=OLLAMA_BASE_URL) ollama_client = ollama.Client(host=OLLAMA_BASE_URL)
es = Elasticsearch(ES_BASE_URL)
weaviate_client = weaviate.WeaviateClient( weaviate_client = weaviate.WeaviateClient(
connection_params=ConnectionParams.from_params( connection_params=ConnectionParams.from_params(
http_host="weaviate", http_host="weaviate",
@ -113,7 +117,7 @@ def hybrid_search(keywords, limit=100, alpha=0.5):
query = " ".join(keywords) query = " ".join(keywords)
print(f"\nWyszukiwanie hybrydowe dla słowa kluczowego: '{query}'") #print(f"\nWyszukiwanie hybrydowe dla słowa kluczowego: '{query}'")
response = collection.query.hybrid( response = collection.query.hybrid(
query=query, query=query,
alpha=alpha, alpha=alpha,
@ -136,7 +140,7 @@ def hybrid_search(keywords, limit=100, alpha=0.5):
"file_name": obj.properties['fileName'], "file_name": obj.properties['fileName'],
"keyword": query "keyword": query
}) })
print(f"Dodano do wyników: {obj.uuid}") #print(f"Dodano do wyników: {obj.uuid}")
if len(results) >= limit: if len(results) >= limit:
break break
@ -183,6 +187,49 @@ async def stream_chat(model, messages, options):
except Exception as e: except Exception as e:
yield json.dumps({"error": str(e)}) + "\n" yield json.dumps({"error": str(e)}) + "\n"
def save_to_elasticsearch(index, request_data, response_data, search_data=None):
try:
def message_to_dict(message):
if isinstance(message, dict):
return {
"role": message.get("role"),
"content": message.get("content")
}
return {
"role": getattr(message, "role", None),
"content": getattr(message, "content", None)
}
if isinstance(request_data.get("messages"), list):
request_data["messages"] = [message_to_dict(msg) for msg in request_data["messages"]]
if "message" in response_data:
response_data["message"] = message_to_dict(response_data["message"])
if "timestamp" in response_data:
response_data["timestamp"] = response_data["timestamp"].isoformat()
document = {
"request": request_data,
"response": response_data,
"timestamp": datetime.utcnow().isoformat(),
}
if search_data:
document["vector_search"] = {
"keywords": search_data.get("keywords", []),
"results": search_data.get("results", [])
}
json_document = json.dumps(document, default=str)
index_name = index
response = es.index(index=index_name, body=json_document)
#print(response)
except Exception as e:
print(f"Error saving to Elasticsearch: {e}")
@app.post("/api/chat") @app.post("/api/chat")
async def chat_endpoint(request: ChatRequest): async def chat_endpoint(request: ChatRequest):
try: try:
@ -209,9 +256,7 @@ async def chat_endpoint(request: ChatRequest):
query = request.messages[-1].content if request.messages else "" query = request.messages[-1].content if request.messages else ""
keywords = analyze_query(prompt_seach.format(query=query)) keywords = analyze_query(prompt_seach.format(query=query))
weaviate_results = hybrid_search(keywords) weaviate_results = hybrid_search(keywords)
prompt_data += "\n".join([f"Źródło: {doc['file_name']}\n{doc['relevant_fragment']}\n\n" for doc in weaviate_results])
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 =[ messages_with_context =[
{"role": "system", "content": prompt_system}, {"role": "system", "content": prompt_system},
@ -228,6 +273,26 @@ async def chat_endpoint(request: ChatRequest):
stream=False, stream=False,
options=request.options options=request.options
) )
request_data = {
"query": query,
"messages": request.messages,
"options": request.options
}
response_data = {
"model": request.model,
"created_at": ollama_response.get('created_at', ''),
"message": ollama_response['message'],
"done": ollama_response.get('done', True),
"total_duration": ollama_response.get('total_duration', 0),
"load_duration": ollama_response.get('load_duration', 0),
"prompt_eval_count": ollama_response.get('prompt_eval_count', 0),
"prompt_eval_duration": ollama_response.get('prompt_eval_duration', 0),
"eval_count": ollama_response.get('eval_count', 0),
"eval_duration": ollama_response.get('eval_duration', 0)
}
save_to_elasticsearch("ably.do", request_data, response_data, {"keywords": keywords, "results": weaviate_results })
return ChatResponse( return ChatResponse(
model=request.model, model=request.model,
created_at=ollama_response.get('created_at', ''), created_at=ollama_response.get('created_at', ''),

View File

@ -1,15 +1,26 @@
Jesteś precyzyjnym narzędziem do generowania słów kluczowych z zakresu BHP i prawa pracy. Twoje zadanie to podanie WYŁĄCZNIE najistotniejszych ów do wyszukiwania w bazie dokumentów prawnych. Jesteś precyzyjnym narzędziem do generowania słów kluczowych z zakresu BHP i prawa pracy. Twoje zadanie to podanie WYŁĄCZNIE najistotniejszych terminów do wyszukiwania w bazie dokumentów prawnych.
Ścisłe zasady: Ścisłe zasady działania:
1. Jeśli zapytanie dotyczy konkretnego artykułu: 1. Jeśli zapytanie dotyczy konkretnego artykułu:
- Podaj TYLKO numer artykułu i nazwę kodeksu (np. "Art. 154, Kodeks pracy"). - Podaj TYLKO numer artykułu i nazwę kodeksu (np. "Art. 154, Kodeks pracy").
- NIE dodawaj żadnych innych słów. - NIE dodawaj żadnych dodatkowych 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. 2. Jeśli zapytanie nie odnosi się do konkretnego artykułu:
- Wybierz maksymalnie 3 najbardziej precyzyjne i specyficzne terminy związane z treścią zapytania.
- Unikaj ogólników takich jak „praca”, „pracownik”, „pracodawca” chyba że są częścią specjalistycznego terminu prawnego.
Zapytanie: '{query}' 3. Używaj wyłącznie terminów, które realnie występują w dokumentach prawnych lub specjalistycznych opracowaniach.
4. Nie dodawaj żadnych interpretacji, rozszerzeń ani dodatkowych komentarzy.
Format odpowiedzi:
- Odpowiedz wyłącznie listą słów kluczowych oddzielonych przecinkami, bez dodatkowego tekstu, wyjaśnień czy formatowania JSON.
Przykład:
- Zapytanie: Jak brzmi art. 3 Kodeksu pracy?
- Odpowiedź: Art. 3, Kodeks pracy
- Zapytanie: Obowiązki pracodawcy w zakresie BHP
- Odpowiedź: obowiązki pracodawcy, BHP, przepisy bezpieczeństwa
Zapytanie: {query}

View File

@ -3,3 +3,4 @@ uvicorn
ollama ollama
weaviate-client weaviate-client
unidecode unidecode
elasticsearch