You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DigPatho · HER2 Clinical Knowledge Module · April 2026
Plataforma de razonamiento diagnóstico HER2 de nivel productivo que combina un grafo de propiedades Neo4j, orquestación multi-agente con LangGraph, e inferencia LLM local vía Ollama.
Características
Continuo HER2 de cinco categorías — Positivo / Equívoco / Low / Ultralow / Null (ASCO/CAP 2023 + Rakha 2026)
Clasificación determinista — Motor de reglas IHC/ISH, sin LLM requerido
Pipeline LLM idempotente — Extracción de entidades y relaciones con MERGE, seguro de re-ejecutar
Multi-agente LangGraph — DiagnosticAgent, EvidenceAgent, ExplanationAgent, ValidationAgent orquestados por un Supervisor
GraphRAG retrieval — Índice vectorial Neo4j + traversal de pathways
Grounding anti-alucinación — Validación post-generación de respuestas LLM contra el KG
Streamlit dashboard — Simulador de casos, visor de pathways, interfaz de consulta
FastAPI REST API — Acceso programático a todas las capacidades de razonamiento clínico
100% local — Corre on-premises con Ollama (qwen3:8b, ministral-3:8b, gemma4:e4b, nomic-embed-text)
flowchart TB
subgraph SOURCES["Fuentes de Conocimiento"]
MD["docs/*.md - Guidelines Markdown\n(ASCO/CAP, Rakha, ESMO)"]
PDF["guides/*.pdf - Guidelines PDF\n(CAP Template, ESMO)"]
end
subgraph PIPELINE["Pipeline LangGraph - 7 fases"]
ING["1. INGEST - Markdown + PDF loaders"]
CHK["2. CHUNK - Segmentacion semantica"]
EXT["3. EXTRACT - LLM entidades+relaciones"]
RES["4. RESOLVE - URIs canonicas NCIt/SNOMED"]
BLD["5. BUILD - Neo4j MERGE idempotente"]
VAL["6. VALIDATE - Reglas Cypher clinicas"]
EXP["7. EXPORT - RDF/OWL + estadisticas"]
ING --> CHK --> EXT --> RES --> BLD --> VAL --> EXP
end
subgraph STORE["Almacenamiento"]
NEO["Neo4j 5.18 - Property Graph + Vector Index"]
RDF2["RDF/OWL Export - NCIt / SNOMED"]
end
subgraph RETRIEVAL["Recuperacion"]
ER["EntityRetriever - Busqueda vectorial"]
PR["PathwayRetriever - Traversal multi-hop"]
GR["GroundingChecker - Anti-alucinacion"]
LR["LightRAGWrapper - Comunidades de grafo"]
end
subgraph AGENTS["Agentes LangGraph"]
SUP["Supervisor - Routing LLM"]
DA["DiagnosticAgent - IHC/ISH"]
EA["EvidenceAgent - Guias"]
XA["ExplanationAgent - Razonamiento"]
VA["ValidationAgent - Consistencia"]
SUP --> DA
SUP --> EA
SUP --> XA
SUP --> VA
end
subgraph INTERFACES["Interfaces"]
API["FastAPI REST :8000"]
UI["Streamlit Dashboard :8501"]
end
SOURCES --> PIPELINE
PIPELINE --> STORE
STORE --> RETRIEVAL
RETRIEVAL --> AGENTS
AGENTS --> INTERFACES
Loading
Ontología HER2
Jerarquía de Clases (Annex A)
classDiagram
class HER2Status {
<<abstract>>
}
class HER2_Positive {
NCIt C68748
IHC 3+ ó ISH Group1/2†
}
class HER2_Negative {
<<abstract>>
}
class HER2_Low {
NCIt C173791
IHC 1+ ó 2+/ISH−
}
class HER2_Ultralow {
NCIt C173792
IHC 0+ (faint ≤10%)
}
class HER2_Null {
NCIt C173793
IHC 0 sin tinción
}
class HER2_Equivocal {
NCIt C173794
IHC 2+, ISH pendiente
}
HER2Status <|-- HER2_Positive
HER2Status <|-- HER2_Negative
HER2Status <|-- HER2_Equivocal
HER2_Negative <|-- HER2_Low
HER2_Negative <|-- HER2_Ultralow
HER2_Negative <|-- HER2_Null
Loading
Predicados del Grafo
Predicado
Sujeto → Objeto
Ejemplo
implies
IHCScore/ISHGroup → ClinicalCategory
Score3Plus → HER2_Positive
requiresReflexTest
IHCScore → Assay
Score2Plus → ISH
impliesIfISHAmplified
IHCScore → ClinicalCategory
Score2Plus → HER2_Positive (ISH+)
impliesIfISHNonAmplified
IHCScore → ClinicalCategory
Score2Plus → HER2_Low (ISH−)
requiresIHCWorkup
ISHGroup → ClinicalCategory
Group2 → HER2_Equivocal
eligibleFor
ClinicalCategory → TherapeuticAgent
HER2_Low → T-DXd
notEligibleFor
ClinicalCategory → TherapeuticAgent
HER2_Null → T-DXd
definedIn
Entity → Guideline/ClinicalTrial
HER2_Ultralow → DESTINY_Breast06
supportedByEvidence
Entity → ClinicalTrial
HER2_Low → DESTINY_Breast04
proposedCorrelation
FractalMetric → ClinicalCategory
FractalDimension_D0>1.85 → HER2_Positive
leadsTo
DiagnosticDecision → DiagnosticDecision
IHC_NODE2 → ISH_NODE_ENTRY
overrides
new Guideline → old Guideline
Rakha_2026 → ASCO_CAP_2018
hasThreshold
ISHGroup/Decision → Threshold
Group1 → ratio≥2.0
Métricas Fractales DigPatho
Métrica
Categoría HER2
Rango Propuesto
FractalDimension D0
HER2-Positive
> 1.85
FractalDimension D0
HER2-Low
1.50 – 1.65
FractalDimension D0
HER2-Equivocal
1.60 – 1.85
FractalDimension D0
HER2-Ultralow
1.35 – 1.50
Lacunaridad
HER2-Positive
< 0.10
MultifractalSpread
HER2-Positive
> 0.40
⚠️ Las correlaciones fractales son hipótesis experimentales (proposedCorrelation, confidence ≤ 0.70), no criterios diagnósticos validados.
Pipeline de Construcción del KG
Fases del Pipeline
flowchart TB
A(["INGEST 6 .md docs 266 chunks"]) --> B(["CHUNK Semántico size=500 overlap=100"])
B --> C(["EXTRACT LLM local entidades+relaciones"])
C --> D{"conf ≥ 0.75?"}
D -- Sí --> E(["RESOLVE URIs canónicas NCIt/SNOMED"])
D -- No --> C
E --> F(["BUILD Neo4j MERGE + seed ontológico + algoritmos"])
F --> G(["VALIDATE Reglas Cypher CRITICAL/HIGH/MEDIUM"])
G --> H{"¿Consistente?"}
H -- Sí --> I(["EXPORT RDF/OWL + stats"])
H -- No --> G
I --> J(["DONE"])
El pipeline usa MERGE en todas las escrituras a Neo4j — es idempotente. Re-ejecutarlo sobre un grafo existente actualiza propiedades sin duplicar nodos ni relaciones. Para partir desde cero ejecutar en Neo4j Browser:
MATCH (n) DETACHDELETEn
Sistema Multi-Agente
sequenceDiagram
participant User
participant API as FastAPI / Streamlit
participant SUP as Supervisor
participant ROUTE as LLM Router
participant DA as DiagnosticAgent
participant EA as EvidenceAgent
participant XA as ExplanationAgent
participant VA as ValidationAgent
participant SYN as Synthesizer LLM
User->>API: POST /query {query, clinical_data}
API->>SUP: invoke(state)
SUP->>ROUTE: ¿qué agentes activar?
ROUTE-->>SUP: ["diagnostic","evidence","validation"]
Note over ROUTE: LLM (Ollama/API) primario<br/>Keyword-routing como fallback
SUP->>DA: run(state)
DA-->>SUP: {classification, pathway, confidence}
SUP->>EA: run(state)
EA-->>SUP: {guidelines, trials, eligibility}
SUP->>VA: run(state)
VA-->>SUP: {issues[], severity, consistent}
SUP->>SYN: synthesize(all_results)
SYN-->>API: {final_response, citations, confidence}
API-->>User: respuesta clínica estructurada
Loading
Roles de los Agentes
Agente
Herramientas
Responsabilidad
DiagnosticAgent
traverse_decision_tree, execute_cypher
Clasificación determinista IHC/ISH, pathway de decisión
EvidenceAgent
get_entity_context, retrieve_pathway
Evidencia de guías, elegibilidad terapéutica, ensayos clínicos
ExplanationAgent
get_entity_context, LLM
Cadenas de razonamiento narrativas, "¿por qué?"
ValidationAgent
execute_cypher, reglas Cypher
Detección de inconsistencias, reglas ASCO/CAP
Supervisor
LLM router + LangGraph
Orquestación, routing, síntesis final
Lógica de Routing
flowchart TD
Q["Consulta del usuario"] --> R{LLM Router}
R -- "clasificar IHC/ISH" --> DA["diagnostic"]
R -- "elegibilidad / guías / trials" --> EA["evidence"]
R -- "¿por qué? / explicar" --> XA["explanation"]
R -- "consistencia / QA / validar" --> VA["validation"]
R -- "caso clinico completo" --> ALL["diagnostic + evidence\n+ explanation + validation"]
DA --> SYN["Synthesizer - respuesta final"]
EA --> SYN
XA --> SYN
VA --> SYN
ALL --> SYN
Loading
Árbol de Decisión Diagnóstico
IHC Algorithm (ASCO/CAP 2023 + Rakha 2026)
flowchart TD
E(["IHC_ENTRY\nIniciar scoring IHC"]) --> N1{"IHC_NODE1\n¿Tinción membrana\ncompleta intensa\nen >10% células?"}
N1 -- SÍ --> R3P["✅ IHC 3+\nHER2-Positive\nASCO/CAP 2023"]
N1 -- NO --> N2{"IHC_NODE2\n¿Tinción completa\ndébil-moderada\nen >10% células?"}
N2 -- SÍ --> R2P["⚠️ IHC 2+\nHER2-Equivocal\n→ ISH REQUERIDO"]
N2 -- NO --> N3{"IHC_NODE3\n¿Tinción incompleta\ntenue en >10%\ncélulas?"}
N3 -- SÍ --> R1P["🟡 IHC 1+\nHER2-Low\nElegible T-DXd\n(DESTINY-B04)"]
N3 -- NO --> N4{"IHC_NODE4\n¿Tinción tenue\nincompleta en\n>0% y ≤10%?\nRakha 2026"}
N4 -- SÍ --> R0P["🟠 IHC 0+\nHER2-Ultralow\nElegible T-DXd HR+\n(DESTINY-B06)"]
N4 -- NO --> R0["⚫ IHC 0\nHER2-Null\nNo elegible T-DXd"]
R2P --> ISH(["ISH Algorithm\n5 grupos ASCO/CAP"])
# Carga el grafo ontológico base (nodos, relaciones, algoritmos) sin extracción LLM
python -m app.cli seed-only
# → http://localhost:7474 MATCH (n) RETURN n LIMIT 80
Opción C — Pipeline completo con LLM local
# Extrae entidades y relaciones de los 6 documentos en docs/
python -m app.cli run-pipeline --llm-mode ollama
# El pipeline es idempotente: re-ejecutar agrega/actualiza sin duplicar
Demo de Agentes (sin Neo4j)
# Caso individual
python demo_agents.py --case diagnostic_3plus
python demo_agents.py --case diagnostic_2plus_ish3
python demo_agents.py --case diagnostic_ultralow
python demo_agents.py --case validation_conflict
# Supervisor multi-agente
python demo_agents.py --supervisor \
--query "IHC 2+, ISH ratio 1.7, Group 3 — clasificar y verificar elegibilidad T-DXd" \
--ihc "2+" --ish-group "Group3"# Todos los casos predefinidos
python demo_agents.py --all
Streamlit Dashboard
streamlit run app/streamlit_app.py
# → http://localhost:8501
# 1. Copiar plantilla de configuración
Copy-Item .env.local .env # Windows# cp .env.local .env # Linux/macOS# 2. Levantar Neo4j local
docker compose up -d neo4j
# 3. Descargar modelos Ollama (una sola vez)
ollama pull qwen3:8b
ollama pull nomic-embed-text
# 4. Poblar el grafo
python -m app.cli run-pipeline --llm-mode ollama
Producción en la nube (AuraDB + OpenAI → Streamlit Cloud)
# 1. Configurar .env con credenciales de AuraDB y OpenAI:# NEO4J_URI=neo4j+s://<id>.databases.neo4j.io# NEO4J_USERNAME=<id># NEO4J_PASSWORD=<password># HER2_KG_LLM_MODE=openai# HER2_KG_EMBEDDING_MODE=openai# OPENAI_API_KEY=sk-...# 2. Poblar AuraDB (idempotente — seguro re-ejecutar)
python -m app.cli run-pipeline --llm-mode openai
# 3. Verificar en AuraDB Browser# MATCH (n) RETURN count(n) → ~460 nodos esperados
Streamlit Cloud: configura las mismas variables de entorno en Settings → Secrets de tu app, y apunta el archivo principal a app/streamlit_app.py.
Sincronización local ↔ AuraDB
El pipeline escribe todas las entidades con MERGE (idempotente). Para cambiar de entorno:
# → Apuntar a localCopy-Item .env.local .env
python -m app.cli run-pipeline --llm-mode ollama
# → Apuntar a AuraDB# (editar .env manualmente o mantener .env.cloud con las credenciales)
python -m app.cli run-pipeline --llm-mode openai
Para exportar el grafo local a RDF y sincronizar AuraDB en un solo paso:
# Exporta output/her2_knowledge_graph_<timestamp>.ttl y .jsonld# y siembra AuraDB con el grafo ontológico corregido (idempotente)
python scripts/export_and_sync_aura.py
El script lee las credenciales de AuraDB directamente desde .env, independientemente de las variables de entorno del shell.
Para limpiar el grafo antes de una re-carga completa:
--Neo4jBrowser/CypherShellMATCH (n) DETACHDELETEn
⚠️ No ejecutes DETACH DELETE en producción (AuraDB) sin hacer backup primero.
Referencia de API
Método
Endpoint
Descripción
GET
/health
Liveness probe
POST
/diagnose
IHC/ISH → clasificación HER2 + pathway
POST
/query
Lenguaje natural → respuesta multi-agente
POST
/validate
Verificación de consistencia clínica
GET
/evidence/{category}
Elegibilidad terapéutica por categoría
GET
/stats
Conteo de nodos y relaciones en el KG
Conversaciones multi-turn: el endpoint /query acepta un campo opcional thread_id. Si se reutiliza el mismo thread_id, el estado de la conversación se recupera automáticamente desde output/checkpoints.db (SQLite). Omitir thread_id genera un UUID privado por solicitud.