a7f78d71b2
FastAPI + ChromaDB + E5-large + DeepSeek по паттерну work-pcs-dr-cdss, адаптированному под пациентский контекст: - services: embeddings (E5-large с префиксами), vectorstore (коллекция operators_wiki), document_processor (PDF/DOCX/TXT/MD + чанкер с FAQ- паттерном под wiki), llm_client (системный промпт ассистента клиники), rag_pipeline (одиночный вопрос → retrieval → ответ). - routers: /health, /documents (upload, list, chunks, delete), /query. - static/index.html: шапка со статусом, блок базы знаний с раскрытием чанков по клику, блок тест-вопроса с 3-колоночным ответом (чанки со score / собранный промпт / ответ LLM). - Порт 8003 (8001 занят CDSS, 8002 — voicenote). E2E проверен: загрузка wiki_test.md → 2 чанка, вопрос «как записать ребёнка к лору?» → top score 84.8%, корректный ответ DeepSeek. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
23 lines
897 B
Python
23 lines
897 B
Python
import logging
|
|
|
|
from sentence_transformers import SentenceTransformer
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class EmbeddingService:
|
|
def __init__(self, model_name: str = "intfloat/multilingual-e5-large"):
|
|
logger.info("Loading embedding model: %s", model_name)
|
|
self.model = SentenceTransformer(model_name)
|
|
self.model_name = model_name
|
|
logger.info("Embedding model loaded (dim=%d)", self.model.get_sentence_embedding_dimension())
|
|
|
|
def embed_documents(self, texts: list[str]) -> list[list[float]]:
|
|
prefixed = [f"passage: {t}" for t in texts]
|
|
embeddings = self.model.encode(prefixed, normalize_embeddings=True, show_progress_bar=False)
|
|
return embeddings.tolist()
|
|
|
|
def embed_query(self, query: str) -> list[float]:
|
|
embedding = self.model.encode(f"query: {query}", normalize_embeddings=True)
|
|
return embedding.tolist()
|