Este proyecto implementa un RAG híbrido (léxico + semántico) para:
- buscar documentos en PMC,
- rankear candidatos combinando BM25 + embeddings (FAISS),
- extraer snippets cortos como evidencia,
- generar una respuesta en inglés con citas [n] usando un modelo local vía Ollama.
- El usuario escribe una pregunta (en inglés) en la UI (Gradio).
- Se convierte a una query en inglés estilo Lucene (AND/OR/NOT, frases entre comillas, etc.).
- Esto se hace con un modelo local vía Ollama y un prompt few-shot.
Objetivo: producir una query robusta para el buscador de Europe PMC.
- Se consulta el endpoint de PMC con la query generada.
- Se descargan metadatos (título, abstract, año, DOI, links).
Salida: lista de documentos normalizados.
Se construye un índice local para esos documentos:
- BM25 (similitud léxica)
- Se tokenizan los textos (title + abstract) y se busca similitud por BM25.
- Embeddings + FAISS (similitud contextual)
- Se embebe cada documento con SentenceTransformers.
- Se guardan/reusan embeddings en
./biorag_store/:embeddings.npy(vectores)meta.parquet(metadatos + hash por texto normalizado)
- Con esos embeddings se construye un índice FAISS para búsqueda por similitud coseno.
Objetivo: no recalcular embeddings si el mismo texto ya existía (dedupe por hash).
Para rankear:
- Score léxico: BM25 sobre palabras clave extraídas desde la query Lucene.
- Score contextual: FAISS sobre embedding de la pregunta original.
- Score final: combinación lineal
alpha * score_vector + (1 - alpha) * score_bm25
- Para los top docs, se arma un snippet por documento (máx. N snippets).
- Se cortan oraciones del título+abstract y se priorizan oraciones con patrones deseables (p-values, etc.).
- Cada snippet queda corto (ej. <=200 chars) para entrar fácil en el contexto del generador.
- Se construye un prompt con:
- lista de snippets como contexto, cada línea termina con su cita [n]
- instrucción: responder en inglés y solo con evidencia del contexto, citando cada afirmación con [n]
- Se llama a Ollama con un modelo local (por defecto:
gemma3:1b). - Se devuelve:
answer(con citas inline [n])refs(lista formateada de referencias [n] con título, fuente, año, link/DOI)
orquestador.py:- Une todo el pipeline y expone una UI en Gradio (entrada: “Consulta”, salida: query final, respuesta con citas, referencias y top recuperados).
rag_index.py:- Traducción de consulta a Lucene, búsqueda en PMC, normalización de resultados.
Index_coincidencias: BM25 + embeddings + FAISS + score híbrido.
vector_store.py:- Persistencia de embeddings y metadatos en
./biorag_store/(reuso + dedupe).
- Persistencia de embeddings y metadatos en
retriever.py:- Split simple en oraciones y selección de snippets representativos.
generador.py:- Arma el prompt con citas y llama a Ollama de forma robusta (generate/chat).
- Devuelve respuesta + bloque de referencias.
- Instalar dependencias:
pip install -r requirements.txt
- Tener Ollama corriendo y con modelos descargados:
- Query:
qwen2.5-coder:1.5b - Answer:
gemma3:1b
- Query:
- Ejecutar:
python orquestador.py
- Entrar a la interfaz local en: 👉 http://127.0.0.1:7862
Notas:
- Parámetros útiles:
page_size,alpha,top_k,max_snippets. - Persistencia: se crea
./biorag_store/automáticamente.
