feat: Спринт 1 — RAG-ядро, загрузка wiki и Debug UI
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>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import logging
|
||||
|
||||
from services.llm_client import LLMClient
|
||||
from services.vectorstore import VectorStoreService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def rag_query(
|
||||
vectorstore: VectorStoreService,
|
||||
llm_client: LLMClient,
|
||||
question: str,
|
||||
top_k: int = 5,
|
||||
document_ids: list[str] | None = None,
|
||||
temperature: float | None = None,
|
||||
max_tokens: int | None = None,
|
||||
) -> dict:
|
||||
"""Pipeline: retrieve → augment → generate для одиночного вопроса пациента."""
|
||||
logger.info("RAG query: %s", question[:200])
|
||||
|
||||
retrieved = vectorstore.query(
|
||||
query_text=question,
|
||||
top_k=top_k,
|
||||
document_ids=document_ids,
|
||||
)
|
||||
logger.info("Retrieved %d chunks", len(retrieved))
|
||||
|
||||
llm_result = await llm_client.answer(
|
||||
question=question,
|
||||
sources=retrieved,
|
||||
temperature=temperature,
|
||||
max_tokens=max_tokens,
|
||||
)
|
||||
|
||||
sources = []
|
||||
for item in retrieved:
|
||||
meta = item.get("metadata", {})
|
||||
sources.append({
|
||||
"document_id": meta.get("document_id", ""),
|
||||
"document_name": meta.get("document_name", ""),
|
||||
"chunk_text": item["text"][:500],
|
||||
"section": meta.get("section", ""),
|
||||
"page": meta.get("page_number", 0),
|
||||
"relevance_score": round(item.get("relevance_score", 0), 3),
|
||||
})
|
||||
|
||||
return {
|
||||
"answer": llm_result["text"],
|
||||
"sources": sources,
|
||||
"model_used": llm_client.model,
|
||||
"assembled_prompt": llm_result["assembled_prompt"],
|
||||
}
|
||||
Reference in New Issue
Block a user