Elaizii por dentro
Escrito el 05/11/2026 11:48 CET · Silicio · Karb and Sil · CC BY 4.0 (el texto; los datos, la licencia de cada fuente).
Esta es la puerta de entrada a cómo funciona Elaizii hoy: cómo es, por qué es así y dónde mirar. Lo que cuenta el día a día de los cuarenta y pico encargos (E-1361 … E-1578, trabajo TX-1362) está en [elaizii-en-la-red.md](elaizii-en-la-red.md), que es la historia, en orden; esto es la foto de hoy. Público: interno (Silicio, los agentes, Eduardo).
Las cifras de este documento se midieron sobre la copia de producción de la mesa (
/datos/nvme/elaizii/produccion/mesa.sqlite, abierta en solo lectura,mode=ro) en la nave el 05/11/2026 11:43 CET. La mesa pesa 10,7 GB y su última capa en producción (capa_profarmaco, E-1566) corrió el 05/11/2026 10:17. Las consultas usadas están en § 9.
Diagramas (Archify, validados «showcase»): arquitectura · de las fuentes a la mesa · una pregunta, paso a paso · encargo → recogida → despliegue.
1. Qué es Elaizii y qué contesta
Elaizii es un grafo clínico que se pregunta en lenguaje natural. Reúne, en una sola red consultable, los grandes vocabularios médicos abiertos (SNOMED CT, CIMA, LOINC, Orphanet, HPO, MeSH/DeCS, ClinVar, ChEBI, ChEMBL, los genes de HGNC y Gene Ontology, MONDO, la UMLS, la parte médica de Wikidata y la literatura de PubTator), unidos por código exacto, nunca por parecido del nombre. Hoy tiene 2,01 millones de objetos vigentes y 5,9 millones de relaciones (§ 9).
Tres puertas, un mismo grafo detrás:
- La web [
elaizii.com](https://elaizii.com) (repowebs/elaizii, estática en Cloudflare): caja para preguntar, el explorador de fichas, el semáforo de congestión y el pie «Fuentes y licencias» (tomado de la API, no copiado a mano). - La API [
elaizii-api.wordkers.com](https://elaizii-api.wordkers.com) (contenedorelaizii-apien la nave, tras Caddy): Flask/gunicorn, de solo lectura, con el aviso legal de SNOMED en cada respuesta. Operaciones en [docs/operaciones.md](operaciones.md). Comprobado el 05/11/2026 11:43:/healthresponde (555 030 conceptos SNOMED),/v1/elaizii/estadoen verde. - El MCP
https://elaizii-api.wordkers.com/mcp(HTTP streamable, SDK oficial), para que un agente pregunte con las mismas herramientas. Ficha en [docs/mcp.md](mcp.md).
Quien contesta es Syd 🕸️ (Cypher): un modelo barato (DeepSeek deepseek-v4-flash) que no sabe medicina, solo se fía del grafo, y cada afirmación la respalda un hecho que vio. Syd ya no tiene bucle propio: es una configuración de la red de Elaizii para el respondedor común (dev/grafo red/respondedor.py). Ver § 6 y [docs/syd.md](syd.md) (ese doc describe el Syd anterior, con bucle y recetas; lo vigente es § 6 de esta página).
Comprobado el 05/11/2026: «¿para qué sirve el dabigatrán?» → «Según ChEMBL, el dabigatrán está indicado (aprobado) para: fibrilación auricular, embolia, accidente cerebrovascular… Estas indicaciones llegan a través de sus formas/sales con que se receta (Dabigatran etexilate…). Aparte, solo en investigación…» (forma para_que_sirve, traza buscar→relaciones→ relaciones, DeepSeek).
2. Las fuentes
Dieciocho fuentes dejan hechos en la mesa de producción hoy (§ 9 da los recuentos). Cada lector por lotes vive en dev/grafo red/<fuente>.py y baja la fuente a un snapshot local en la nave (/datos/nvme/elaizii/<fuente>.sqlite); la capa de [grafo/a_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/grafo/a_mesa.py) la pone en la mesa. Lo nuestro (uniones, relaciones deducidas, los 79 tipos de 2018) es CC BY 4.0; cada fuente conserva su licencia en cada hecho, y el aviso que pide sale del hecho ([avisos.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/avisos.py) + [red/consultas.py](https://gitlab.com/wordkers/dev/grafo/-/blob/main/red/consultas.py) CITAS/ATRIBUCIONES), nunca pegado a mano.
| Fuente | Qué aporta | Snapshot / dónde vive | Licencia |
|---|---|---|---|
SNOMED CT (ed. española RF2, es-20260901) | el armazón: conceptos, jerarquía «es un», atributos, mapas a CIE-10 y a Orphanet | base snomed del Postgres de la nave; vistas, no se copia | snomed (afiliado SNS) · no sale de la nave |
| CIMA (AEMPS) | medicamentos y principios activos españoles, ATC, forma, vía | cima.sqlite | aemps (© AEMPS, sin modificar; permiso 29/10/2026) |
| LOINC (Regenstrief, 2.83, con es-ES) | análisis y observaciones de laboratorio y sus seis ejes | loinc.sqlite + ficheros en /datos/nvme/elaizii/loinc/ | loinc · no sale de la nave |
| Orphanet (Orphadata, 1.3.42) | enfermedades raras, su jerarquía y sus alineamientos | orphanet.sqlite | CC BY 4.0 |
| HPO (2026-09-01) | fenotipos (síntomas y signos) y enfermedad → fenotipo, en español | hpo.sqlite | hpo (no alterable) |
| MeSH (NLM, 2026) | el vocabulario de la NLM y su árbol; el puente con DeCS | mesh.sqlite | NLM (dominio público con reconocimiento) |
| DeCS (OPS/BIREME) | MeSH en español (nombres sobre los mesh:) y descriptores propios | lee el XML directo (sin snapshot) | decs (acuerdo BIR-267-26) · no sale de la nave, no va a la estantería común |
| ClinVar (NCBI, 2026-10-26) | gen → enfermedad, con significado clínico y estrellas | clinvar.sqlite | NCBI (dominio público con reconocimiento; no es para diagnóstico) |
| ChEBI (EMBL-EBI, v256) | las sustancias químicas de referencia, su jerarquía y su rol | chebi.sqlite | CC BY 4.0 |
| ChEMBL (EMBL-EBI, 37) | indicaciones: fármaco → enfermedad, con la fase de ensayo | chembl-*.sqlite | CC BY-SA 3.0 |
| HGNC (2026-10-27) | nombres oficiales de los genes humanos y sus familias | hgnc.sqlite | CC0 |
| Gene Ontology (2026-07-26) | qué hace cada gen (función, proceso, lugar) | go.sqlite | CC BY 4.0 |
| MONDO (Monarch, 2026-10-06) | el puente que casa los catálogos de enfermedad | mondo.sqlite | CC BY 4.0 |
| UMLS (NLM, 2026AA) | el CUI como puente entre fuentes (nunca su texto) | umls.sqlite (de MRCONSO.RRF, 2,3 GB) · no sale de la nave | NLM (licencia UTS) |
| Wikidata médica | los puentes por código entre casi todas las fuentes (CC0) | wd-medica.sqlite (+ acotados por capa) | CC0 |
| PubTator3 (NLM) | lo que dice la literatura (extracción automática), aparte de lo curado | pubtator.sqlite (de relation2pubtator3.gz) | dominio público |
| ComplexPortal | complejos de proteínas y sus componentes | dentro del snapshot de genes | CC0 |
| CIE-10 | los códigos (la pirámide), por los mapas de SNOMED | se deriva de SNOMED | snomed (los nombres los pondrá el Ministerio) |
Fuera, por decisión o por licencia (§ 10): OMIM (su acuerdo prohíbe distribuir), los nombres ATC de la OMS (de pago / no comercial; los códigos sí entran por CIMA), y las fuentes de categoría 3 de la UMLS (CIE-10 de la OMS, MedDRA).
3. La mesa
Elaizii no pregunta a la estantería común (red) ni a SNOMED directamente: pregunta a una mesa, un SQLite de solo lectura con exactamente el esquema de la mesa común (dev/grafo red/mesa.sql, que se lee de ahí, no se copia). Así el respondedor común le habla a esta mesa con las mismas herramientas que a las efemérides o al fútbol: un grafo para quien pregunta. SNOMED se queda al lado (decisión [1] de Eduardo, 28/10/2026): su base no sale de la nave y se mira por vistas; lo nuestro (CC BY) va a la estantería; la mesa junta las dos.
Dos ficheros, y por qué.
- La mesa de trabajo
/datos/nvme/elaizii/mesa.sqlite: donde escriben los encargos (a_mesa.py --solo-…). Puede quedar a medias mientras se construye. - La copia de producción
/datos/nvme/elaizii/produccion/mesa.sqlite: la que sirveelaizii-api, montada de solo lectura ([deploy/run.sh](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/deploy/run.sh) monta la carpeta, no el fichero, porquea_mesa.pyreemplaza el fichero conos.replace). Se pone al día solo al recoger un encargo, con sus tests en verde. El 29/10/2026 un encargo cargó a medias en la de trabajo y producción dejó de encontrar la glucosa y el ATC: de ahí la copia fija (ver la cabecera dedeploy/run.sh).
El esquema (común, nueve tablas más el precálculo). En entidad-relación detallado: [docs/mesa-er.md de dev/grafo](https://gitlab.com/wordkers/dev/grafo/-/blob/main/docs/mesa-er.md) y las fuentes en [docs/fuentes-er.md](fuentes-er.md). En llano:
- **
objeto— el nodo mudo**: unidcon prefijo de vocabulario (sct:,cima:,loinc:,orpha:,hp:,mesh:,hgnc:,go:,chebi:,chembl:,mondo:,cie10:,wd:,valor…) y untipo(hallazgo, sustancia, fármaco, gen, análisis…).vigente: lo inactivo no se borra, caduca. - **
apuntador— los nombres** (cada nombre con su lengua, registro,entrapara buscar ysalepara mostrarse: así «golondrino» entra pero sale «hidrosadenitis supurativa»). El concepto es el mismo en todas las lenguas; solo cambian las etiquetas ([docs/modelo.md](modelo.md)). - **
relacion** — la arista, con sutipo_objeto(que también es un objeto), sumarco(JSON con lo que la frase dice de ella), suhecho(la clave que la justifica), suregla(que es a la vez su lote deshacible) y suvigente. - **
hecho— la frase** que respalda una relación, confuente,revisiony **licencia**. SNOMED no trae frases: se le genera «A —tipo→ B». - **
fusion— dos objetos que las reglas dicen que son el mismo** (p. ej.wd:Q…↔sct:…por P5806). Nada se borra: una fusión retirada va avigente=0. - **
grupo/grupo_info(precálculo, E-1487) — las fusiones ya resueltas en grupos: cada grupo es un objeto para quien pregunta y lo representa** susct:si lo hay (preferenciasct:, luegowd:). Sin esto, «paracetamol» (la sustancia SNOMED) no vería los medicamentos de CIMA, que cuelgan del mismo grupo. - **
cuestion— las contradicciones abiertas (dos destinos para una fusión, un ciclo, un candidato por nombre sin segunda señal): no se fusiona, se pregunta**. Hoy hay 24 289 abiertas. - **
sentido,aportacion,meta— el puente con la capa de lengua (vacío aún), lo que pide el constructor, y las cifras y los manifiestos de los lotes** (metallevalote:*,deshacer:*,lotes). - Precálculo (E-1487):
nivel(profundidad por «es un») ycuenta(totales por grupo/tipo/dirección) se calculan al construir y en cadarehacer_*, para que nunca queden desfasados. La mesa crece ~15 % y abrir va 3,9× más rápido.
Un grupo de fusión y su representante. Un principio activo como el ketoprofeno puede llegar como sct: (SNOMED), cima:pa: (CIMA), chebi: (ChEBI), wd:/mesh:/chembl: (la química): si las reglas prueban que son el mismo, caen en un solo grupo, y Syd lo ve como un objeto con todas sus identidades. La regla de oro: cada identidad va al grupo que le toca (la sustancia química a la sustancia, no al producto), y **nunca dos sct: en un grupo** (§ 5).
4. Las capas, en orden
La mesa se construye en [grafo/a_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/grafo/a_mesa.py) (construir), capa a capa, siempre en el mismo orden: cada una lee lo que dejaron las anteriores. Cada capa se puede rehacer sola (--solo-…, copia la mesa con fecha antes) y la mayoría deja un lote deshacible. Esta es la cadena viva hoy (el recuento es de producción, 05/11/2026, § 9; donde no lo medí va el del informe de su encargo, marcado (informe)):
| # | Capa | Encargo | --solo-… | Qué hace / regla |
|---|---|---|---|---|
| 1 | SNOMED | E-1365 | (base) | conceptos sct:, su jerarquía «es un», atributos y nombres es/en; 555 030 conceptos |
| 2 | CIE-10 | E-1377, E-1482 | --solo-cie10 | por los mapas de SNOMED (refset 447562003): cie10: como relación «se codifica en CIE-10 como» (no fusión), la pirámide por el código (E78.0 «es un» E78) y el mapa condicional |
| 3 | Wikidata | E-1378, E-1438 | --solo-wikidata | el wd: médico y todos sus identificadores como puentes por código; fusión wd:↔sct: por P5806 |
| 4 | Orphanet | E-1382, E-1478 | --solo-orphanet | enfermedades raras, jerarquía, alineamientos; fusión orpha:↔wd: por P1550; estado de cada enfermedad |
| 5 | genes | E-1389, E-1521 | --solo-genes | hgnc: (+ familias), términos go: y sus anotaciones; cpx:/rnacentral:/uniprot: separados del gen |
| 6 | LOINC | E-1391 | --solo-loinc | loinc: y sus seis ejes; fusión con partes y con Wikidata (P4338) |
| 7 | CIMA | E-1404 | --solo-cima | cima: medicamentos y cima:pa: principios activos; fusión VTM = sct:, unión por ATC |
| 8 | MeSH | E-1425 | --solo-mesh | mesh:, su árbol como «es un», fusión por P486; «se indexa en MeSH como» desde Orphanet |
| 9 | DeCS | E-1424 | --solo-decs | el español sobre los mesh: (manda la edición de España) y los decs: propios |
| 10 | HPO | E-1426 | --solo-hpo | hp: fenotipos, «tiene el fenotipo» enfermedad → síntoma, fusión por P3841 |
| 11 | ClinVar | E-1427 | --solo-clinvar | «se asocia con (ClinVar)» gen → enfermedad, con significado y estrellas |
| 12 | MONDO | E-1439 | --solo-mondo | casa los catálogos: fusiones con SNOMED/Orphanet/MeSH/Wikidata por código exacto |
| 13 | ChEBI | E-1440 | --solo-chebi | sustancias químicas de referencia; fusión con partes LOINC, «coincide» con Wikidata |
| 14 | mapa SNOMED→Orphanet | E-1452 | --solo-snomed-orphanet | el mapa oficial (refset 784008009): fusión sct:↔orpha: 1↔1 |
| 15 | UMLS | E-1441, E-1543 | --solo-umls | el CUI como dato y como fusión 1↔1 entre fuentes; cinco SAB más de puente |
| 16 | gene:↔hgnc: | E-1486 | --solo-genes-hgnc | fusiona el gen-stub de GO con su gen HGNC por símbolo aprobado |
| 17 | nombres (doble señal) | E-1481 | --solo-nombres | fusión por nombre solo con una segunda señal de código; si no, cuestion |
| 18 | ChEMBL | E-1523 | --solo-chembl | fármacos y sus indicaciones: «está indicado para» (aprobada, fase 4) y «está en investigación para» (< 4) |
| 19 | ChEBI → sustancia pelada | E-1540, E-1543 | --solo-sct-chebi | da chebi: a la sustancia SNOMED pelada por el CUI de la UMLS y Wikidata |
| 20 | sustancia ↔ producto | E-1536 | --solo-sustancia | lleva la química (wd:/mesh:/chembl:) del grupo del producto al de la sustancia, por código |
| 21 | química que queda | E-1550 | --solo-sustancia-extra | la que E-1536 no movió (ChEBI sin InChI, dos ChEBI), por P592/P683/CAS |
| 22 | un solo principio activo | E-1561 | --solo-un-pa | si el producto tiene un PA, su química es la de la sustancia pelada |
| 23 | sal y base | E-1557 | --solo-sal-base | une la sal (donde cuelgan las indicaciones) con su base; si la sal tiene sct: propio, relación «es una sal de» |
| 24 | MeSH/wd de la base | E-1562 | --solo-mesh-wd | deshace el mesh:/wd: de la base pegado al sct: de su sal |
| 25 | ChEBI discrepa | E-1578 | --solo-discrepa | lleva a la sustancia el chebi: de Wikidata que discrepa pero es la misma molécula activa |
| 26 | profármaco / forma de | E-1566 | --solo-forma-de | relación «es una forma de» para el chembl: que sigue en el producto (dabigatrán etexilato) |
| 27 | literatura (PubTator) | E-1538 | --solo-pubtator | 860 635 relaciones «(según la literatura)», separadas de lo curado |
| 28 | derivada | E-1413, E-1442 | --solo-derivadas | compone por regla lo que antes costaba dos o tres saltos: «contiene (principio activo)», «mide», «clasificado en ATC», «gen de», «produce el fenotipo», «se presenta en», «se estudia con», «asociación gen-enfermedad confirmada» |
| 29 | guarda de niveles | E-1481 | --solo-niveles | **ningún grupo con dos sct:**: retira la fusión más débil y deja «más concreto/general que» |
| 30 | características y concentradores | E-1480 | --solo-caracteristicas | marca (en meta) los atributos que son filtro (escala, tiempo…) y los supernodos que no sirven de puente |
| — | precálculo | E-1487 | --solo-precalculo | lo último: grupo, nivel, cuenta, índices y FTS |
La regla sustancia / producto (E-1536 y la cadena E-1540…E-1578). Un principio activo como el ketoprofeno estaba partido en dos grupos: el del producto (sct: VTM «producto con X» + cima:pa:, con la química arrastrada por el ATC) y el de la sustancia (sct: sustancia + chebi:). La química es la sustancia, no el producto: entró en el del producto porque su único puente, el ATC, CIMA lo ancla al SCTID del producto. La cadena de capas la lleva a su grupo, solo por código exacto y **solo cuando la sustancia ya tiene un chebi: al que anclarla; si no hay destino exacto, no se mueve (mejor no unir que unir mal). Cuando dos moléculas no son la misma —una sal con concepto SNOMED propio, un profármaco o éster (dabigatrán etexilato ≠ dabigatrán)— no se funden: se deja una relación con nombre, «es una sal de» (E-1557) o «es una forma de» (E-1566), que el respondedor sigue** con seguir= para alcanzar las indicaciones aprobadas del otro lado (§ 6).
5. Las guardas comunes
Son las reglas que impiden «unir mal», y cada una tiene cómo se comprueba:
- **Nunca dos
sct:en un grupo.** SNOMED es una jerarquía; dos conceptos distintos no son el mismo objeto. La guarda de niveles (capa_niveles, la última de la carga) retira la fusión más débil que los juntaba y, si la jerarquía lo dice, deja «más concreto que» / «más general que». Comprobado: en producción hoy, grupos con dossct:= 0 (capa_nivelesy los tests [tests/test_niveles_nombres_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_niveles_nombres_mesa.py),test_sal_base_mesa.py). - **Dos destinos →
cuestion. Si una fuente reclama que un objeto es a la vez dos cosas (un QID con dos SCTID, un ATC de combinación con dos ChEBI…), no se fusiona**: va acuestion. Hoy hay 24 289 cuestiones abiertas. - Ningún nombre cambia. Los nombres de cada fuente entran sin tocar ni un carácter (lo exige la licencia de CIMA, LOINC, HPO…). Las capas de traslado mueven objetos entre grupos, nunca reescriben un apuntador. Lo fijan los tests
test_*_mesa.pyde cada capa. - La guarda de niveles (arriba) y la fusión por nombre con doble señal: un objeto suelto con nombre idéntico a otro se fusiona solo si hay además una segunda señal de código (mismo CUI, mismo CIE-10, mismo OMIM, o el mismo padre ya fusionado); si no,
cuestioncomo «candidato por nombre» (lo revisan Doc o Eduardo). - «Mejor no unir que unir mal». Una capa de traslado solo mueve por código exacto y solo cuando hay un destino único; ante la duda, no mueve y, si procede, abre
cuestion. - Lotes deshacibles. Cada fusión/relación nueva lleva un lote (en
regla);a_mesa.py --deshacer-lote <lote>lo retira de un tirón (marcavigente=0, nunca borra) y lo deja dicho enmeta['lotes']. Hoy hay manifiestos deE1536-sustancia,E1540-sct-chebi,E1543-sct-chebi,E1557-sal-base,E1561-un-pa,E1562-mesh-wd-a-sustancia,E1578-discrepa,retirada-niveles,nombres-doble-senal,piramide-cie10,rna-go-hgnc,chembl,pubtator. La prueba de que son reversibles:red mesa --publicadeja fuera lo de licenciasnomed/loinc/aemps/decs.
6. Del dato a la respuesta
Quien pregunta no sabe medicina: lo hace todo con herramientas genéricas de dev/grafo red/consultas.py (clase Mesa), que buscan por nombre, siguen relaciones y cuentan, sobre la mesa abierta de solo lectura:
- **
buscar(texto, tipo?)— los objetos cuyo nombre casa (español o inglés), los más citados primero**; elige por regla (nombre exacto → tipo → más citado), da elid, dice con qué sinónimo casó (coincide) y sus **identidades** (sus códigos en cada vocabulario). Marcadudososolo cuando de verdad hay que elegir («DMD» es gen y enfermedad: por eso se pasatipo). - **
ficha(objetos)** — por lotes: tipo, identidades, datos y relaciones con nombre. - **
dentro_de/contiene— suben y bajan por la jerarquía «es un»** (en Elaizii no «está en»): familias y tipos. - **
relaciones(objeto, tipo?, orden_marco?, seguir?)— las relaciones con nombre; avisa cuando corta** (cortado, conpor_tipo) y reparte la muestra (E-1553). **seguir=(una o varias relaciones, E-1560/E-1577) trae en la misma lista** las del objeto y las del otro lado de «es una sal de»/«es una forma de», cada fila con suvia. - **
contar(tipo, de?, a?, ademas?)— cuenta en SQL sin listar;ademas** cruza dos filtros en una cuenta («¿qué análisis de orina son cuantitativos?» =contar("sistema", a="Orina", ademas={relacion:"escala", objeto:"Qn"}), 40 ms). - **
datos,hechos,forma,esquema** — los datos de un objeto, los hechos en que sale, la forma de la red y sus cifras.
El respondedor común ([red/respondedor.py](https://gitlab.com/wordkers/dev/grafo/-/blob/main/red/respondedor.py)): un bucle de pasos JSON cerrado (cada paso pide una herramienta o responde), temperatura 0, hasta 30 pasos y un tope de 60 s por pregunta. La comprobación va en código: la respuesta solo puede citar hechos que vio en esta pregunta; lo que cita de más se le devuelve con el motivo (no se borra en silencio); la lengua la fija y la comprueba el código. La respuesta se arma en dos partes por el código: cumplen (los hechos citados con su frase) y no_consta (lo que falta).
Lo que Syd añade ([syd.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/syd.py)): su alma (FRASES_SYD: quién es, que la jerarquía es «es un», cómo se usan las relaciones con nombre, que la literatura va aparte de lo curado y nunca aconseja), las herramientas de la mesa, y las FORMAS (FORMAS_SYD, E-1506): ante una pregunta conocida («¿qué es X?», «¿qué síntomas da X?», «¿para qué sirve X?»…) el código clasifica y hace el recorrido fijo (y, para las listas, redacta con una plantilla por lengua sin segunda llamada al modelo, E-1522, ~1,5 s); si no encaja, cae al bucle libre. El saber del dominio (qué relación es «síntomas», «código CIE-10», que lo aprobado de la sal es lo aprobado del fármaco) vive aquí, en la forma —su nota—, no en el alma ni en las herramientas.
El sentido de una relación (TX-1670, 09/11/2026): una relación tiene dirección y la forma de la pregunta fija el sentido. relaciones(…, sentido=) acepta «ida» (las que salen del objeto), «vuelta» (las que llegan) o «ambos»; cada paso relaciones de las FORMAS declara el suyo (un test lo exige). «¿Qué síntomas da X?» es «X tiene el fenotipo Y» de ida: el lupus de HPO está fusionado con el de SNOMED y de vuelta salían las enfermedades que lo tienen como fenotipo.
El prospecto desde la sustancia (TX-1663): prospecto(sustancia) baja por el plano a sus presentaciones («contiene (principio activo)» de vuelta, también las de su sal o su forma) y elige UNA por regla, que devuelve en desde_sustancia y Syd dice: con la sección pedida → de esa sustancia sola → no genérico (sin «EFG») → el texto que comparten más → número de registro menor. Metformina → DIANBEN 850 mg (nº 55211). «¿A es un B?» sube además con situar (una marca es del tipo de lo que lleva: Inhixa → enoxaparina → HBPM → heparina).
La voz (TX-1629): SYD_VOZ = «vieja» (por defecto, producción) o «nueva» (primero la respuesta con las palabras de la fuente, el resto de apoyo, sin «el grafo» ni ids). La nueva añade frases al alma (FRASES_VOZ_NUEVA), cambia el texto de las plantillas (PLANTILLAS_VOZ_NUEVA) y quita en código los ids internos que queden (aplicar_voz). Cambia la huella del alma, así que no mezcla la caché. Se enciende con -e SYD_VOZ=nueva en deploy/run.sh (variable SYD_VOZ).
El alma de Syd no lleva recetas ni nombra el motor. El motor es DeepSeek deepseek-v4-flash por wk_llm (proyecto=elaizii, el gasto a llm_gasto); hay un modo opus afinado a mano por la línea de órdenes ([bin/syd-opus](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/bin/syd-opus)), que no se usa desde la web. Doc 🩺 (el médico, [doc.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/doc.py)) no contesta: examina a Syd con el medidor común (exámenes que fabrica la propia mesa, con respuesta conocida) y con preguntas clínicas de rúbrica, y propone mejoras. Ver [docs/doc.md](doc.md) y [docs/syd.md](syd.md).
7. Cómo se trabaja
Formular un encargo para Elaizii. Silicio escribe el encargo (dev/agentes-common/encargos/E-NNNN-…md) con su «hecho» verificable; lo hace Opus en un worktree propio ../elaizii.E-NNNN sobre main. Una capa nueva de la mesa nace con su capa_*, su --solo-*, su lote deshacible y sus tests (sin ellos no está).
Recoger. Se corren los tests: el de juguete y los test_*_mesa.py en el Mac (sin base), y la suite entera en la nave con flock (un pesado a la vez). Antes de nada, mirar el worktree y la rama (clon compartido).
Desplegar (lo hace Silicio, con aviso: es infra compartida). En la nave, con los secretos en el entorno:
export RED_MESA_SQL=…/dev/grafo/red/mesa.sql
set -a; . ~/agents-secrets/snomed.env; . ~/agents-secrets/elaizii.env; set +a
export SNOMED_DB_HOST=127.0.0.1 ELAIZII_DB_HOST=127.0.0.1
nice -n 10 ionice -c3 python3 -m grafo.a_mesa --salida /datos/nvme/elaizii/mesa.sqlite --solo-<capa> # rehace una capa
Con los tests en verde, se copia la mesa de trabajo a la de producción (/datos/nvme/elaizii/produccion/mesa.sqlite) y se levanta el contenedor con [deploy/run.sh](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/deploy/run.sh) (monta la carpeta de la mesa de producción de solo lectura, /opt/grafo por WK_GRAFO, SYD_MOTOR=ds; API en :8030, MCP en :8032, las dos redes tras Caddy). Las órdenes exactas con que Silicio despliega (05/11/2026, en la nave, como root):
F=$(date +%Y%m%d-%H%M)
git -C /root/Projects/wordkers1/dev/grafo pull --ff-only; git -C /root/Projects/wordkers1/apis/elaizii pull --ff-only
cd /root/Projects/wordkers1/apis/elaizii && S=$(git rev-parse --short HEAD) && nice docker build -q -t wordkers-elaizii:$S .
P=/datos/nvme/elaizii/produccion
nice cp /datos/nvme/elaizii/mesa.sqlite $P/mesa.sqlite.nueva && mv $P/mesa.sqlite $P/mesa.sqlite.$F.anterior && mv $P/mesa.sqlite.nueva $P/mesa.sqlite
IMAGEN=wordkers-elaizii:$S RED=postgres_default GRAFO=/root/Projects/wordkers1/dev/grafo \
COMMON=/root/Projects/wordkers1/dev/agentes-common bash deploy/run.sh # el «HTTP 400» del MCP al final es normal
docker network connect despacho_despacho elaizii-api; docker network connect wordkers-net elaizii-api
La imagen lleva por etiqueta el commit (wordkers-elaizii:<commit>), así se sabe qué código sirve. Se guardan tres copias anteriores de producción (mesa.sqlite.<fecha>.anterior); para volver atrás, se mueve una a mesa.sqlite y se relanza run.sh con su imagen. Se comprueba desde fuera:
curl -s https://elaizii-api.wordkers.com/health
curl -s https://elaizii-api.wordkers.com/v1/elaizii/estado
curl -s -X POST https://elaizii-api.wordkers.com/v1/elaizii/preguntar \
-H 'Content-Type: application/json' -d '{"pregunta":"¿para qué sirve el dabigatrán?"}'
Deshacer un lote (sin reconstruir): python3 -m grafo.a_mesa --salida <mesa> --deshacer-lote <lote> (p. ej. E1557-sal-base). Marca vigente=0 y lo anota en meta['lotes']; nada se borra.
8. Tests y oro
- De juguete ([
tests/_mesa_juguete.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/_mesa_juguete.py), [tests/test_a_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_a_mesa.py)): fijan el esquema y el mapeo, sin red ni base. El test de juguete monta una mesa pequeña y comprueba que cada capa hace lo que dice. - Por capa (
tests/test_<fuente>_mesa.py, y los_real.pycontra la base): cada capa tiene su familia, que fija sus cifras y sus guardas (dos destinos → cuestión, ningún nombre cambia, nunca dossct:). - Del respondedor y las normas ([
tests/test_preguntar.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_preguntar.py)): una fila por cada norma de los respondedores (§ 5.1 de [elaizii-en-la-red.md](elaizii-en-la-red.md)): JSON cerrado, comprobación en código, dos partes, temperatura 0, el que pregunta no escribe… - Las preguntas de oro ([
tests/test_preguntar_oro.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_preguntar_oro.py)): las que recorren el grafo de punta a punta (diabetes → 73211009; amoxicilina sube a penicilina; fibrosis quística → sus fenotipos; «¿para qué sirve el dabigatrán?»…). Sirven de contrato cuando una capa cambia. - Qué es flojo y por qué. El ranking de **
buscaren SNOMED fue pobre al principio (ordenaba solo por nombre, sin «apariciones en hechos» que midan relevancia): se afinó por regla en E-1506 (nombre exacto → tipo → más citado), y por eso casos de nombre dispar —la amiloidosis neerlandesa y el síndrome de Fahr— ya se encuentran. Las sales y profármacos (fluoxetina, dabigatrán, DMD**) fueron flojos hasta la cadena E-1557…E-1577, que llevó las indicaciones aprobadas a la sustancia y enseñó al respondedor a seguir «es una sal de» / «es una forma de»; hoy el dabigatrán resuelve (§ 1). Donde la fuente no trae el dato (OMIM, nombres de la CIE-10), Syd dice «el grafo no lo dice», y eso es lo correcto.
9. Las cifras de hoy
Medidas sobre la copia de producción (/datos/nvme/elaizii/produccion/mesa.sqlite, mode=ro) el 05/11/2026 11:43 CET. La consulta, al pie.
| Qué | Cifra |
|---|---|
| Objetos (total / vigentes) | 2 165 990 / 2 013 840 |
| Apuntadores (nombres) | 5 340 637 |
| Hechos | 5 903 781 |
| Relaciones (todas vigentes) | 5 903 781 |
| Fusiones (total / vigentes) | 162 726 / 159 925 |
Grupos de fusión (grupo_info) | 99 991 |
| Cuestiones abiertas | 24 289 |
Grupos de producto (un sct: de tipo producto) | 40 790 |
chembl: que siguen en un grupo de producto | 175 |
wd: que siguen en un grupo de producto | 173 |
chembl: en la mesa (vigentes) | 10 073 |
Grupos con sct: y alguna «está indicado para» (aprobada) | 1 248 |
| Relaciones «está indicado para» / «está en investigación para» | 10 181 / 64 246 |
| Relaciones «(según la literatura)» (PubTator) | 860 635 |
Objetos vigentes por tipo (los mayores): valor 1 069 080 · otro 158 669 · hallazgo 132 223 · análisis 112 405 · procedimiento 60 425 · gen 45 289 · estructura corporal 43 681 · producto 40 790 · organismo 34 700 · enfermedad (MONDO) 32 134 · descriptor MeSH 31 110 · sustancia 29 557 · medicamento 25 511 · proceso biológico 23 974 · fenotipo (HPO) 19 894 · objeto físico 14 143 · calificador 12 795 · código CIE-10 12 207.
Hechos por fuente (18 fuentes): snomed 1 558 358 · pubtator 860 635 · umls 692 801 · loinc 640 488 · hpo 638 148 · gene_ontology 543 134 · wikidata 241 692 · cima 217 110 · hgnc 163 345 · orphanet 81 927 · chembl 78 558 · mondo 56 560 · chebi 45 048 · mesh 43 637 · elaizii 16 894 · clinvar 12 577 · complexportal 8 773 · decs 4 096.
Fusiones vigentes por lote (las mayores): HGNC P354 42 730 · MeSH P486 30 968 · MONDO P5270 (Wikidata) 11 054 · UMLS CUI 10 087 · Orphanet P1550 8 802 · MONDO exactMatch SNOMED 8 775 · MONDO exactMatch Orphanet 8 354 · mapa oficial SNOMED→Orphanet 6 235 · nombres-doble-senal 6 046 · LOINC parte ≡ SNOMED 5 466 · HPO P3841 4 690 · MONDO exactMatch MeSH 3 168 · UMLS confirma 2 533 · VTM de CIMA 2 262 · ChEBI ≡ parte LOINC 1 893 · E1536-sustancia 1 650 · Wikidata P5806 1 265 · E1557-sal-base 1 083 · rna-go-hgnc 668 · E1561-un-pa 654 · E1540-sct-chebi 390 · E1543-sct-chebi 343.
La consulta (SQLite, solo lectura; rep(objeto) sigue las fusiones por la tabla grupo):
SELECT count(*) FROM objeto WHERE vigente=1; -- objetos vigentes
SELECT count(*) FROM relacion WHERE vigente=1; -- relaciones
SELECT count(*) FROM fusion WHERE vigente=1; -- fusiones vigentes
SELECT count(*) FROM grupo_info; -- grupos
SELECT count(*) FROM cuestion WHERE abierta=1; -- cuestiones abiertas
SELECT regla, count(*) FROM fusion WHERE vigente=1 GROUP BY regla; -- fusiones por lote
SELECT fuente, count(*) FROM hecho GROUP BY fuente; -- hechos por fuente
-- grupos de producto, y chembl:/wd: que siguen en ellos:
CREATE TEMP TABLE repmap AS SELECT o.id objeto, COALESCE(g.representante,o.id) rep
FROM objeto o LEFT JOIN grupo g ON g.objeto=o.id WHERE o.vigente=1;
CREATE TEMP TABLE prodrep AS SELECT DISTINCT r.rep FROM repmap r JOIN objeto o ON o.id=r.objeto
WHERE o.tipo='producto' AND o.id LIKE 'sct:%';
SELECT count(*) FROM repmap r WHERE r.objeto LIKE 'chembl:%' AND r.rep IN (SELECT rep FROM prodrep);
-- grupos con sct: y alguna aprobada:
SELECT count(DISTINCT dr.rep) FROM relacion rel JOIN repmap dr ON dr.objeto=rel.de
WHERE rel.vigente=1 AND rel.tipo_objeto='tipo:chembl:indicado'
AND dr.rep IN (SELECT DISTINCT rep FROM repmap WHERE objeto LIKE 'sct:%');
Ojo a la frescura: la
meta«cuando» de la mesa de producción dice2026-10-28T21:29:27(la última construcción entera), pero la mesa se ha ido poniendo al día capa a capa (--solo-*), y la última (capa_profarmaco, E-1566) corrió el 05/11/2026 10:17 (las marcas*_cuandodemetalo dicen). Las cifras de arriba son del contenido vivo, no de esameta.
10. Lo que queda y lo que se decidió no hacer
- Doc entrenando solo (TX-1369, hecha el 29/10/2026 23:19): los programas de Cronos de Doc (dos tandas al día +
doc-semana) están activos en la nave (comprobado engestion.programasel 09/11/2026 10:50).elaizii-en-la-red.md§ 6 paso 5. - **Modo
opusde Syd**: implementado ([bin/syd-opus](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/bin/syd-opus)) pero no cableado desdedoc-tanda; cuando lo esté, se compara la nota de DeepSeek frente a Opus por tipo (modo independiente). - Fuentes por licencia (
elaizii-en-la-red.md§ 6.1–6.3): OMIM queda fuera (su acuerdo prohíbe distribuir y hacer obras derivadas; E-1438/§ 6.2). De la ATC de la OMS no se pide nada (ni el fichero de pago ni la versión en español): los códigos entran por CIMA; los nombres de la OMS solo si salen de CIMA con permiso. La UMLS se pidió (cuenta UTS a nombre de Eduardo, TX-1441); ya está cargada (2026AA). DeCS exigió firmar un acuerdo (OPS/BIREME); cargada, solo en la mesa de Elaizii, no en la estantería común. La CIE-10-ES (los títulos de los códigos) cuelga de un aviso genérico del Ministerio y de una obra base de NCHS: antes de cargar los nombres conviene preguntar al Ministerio, como con CIMA. - La identidad con el resto de la red por P5806 es estrecha (1 449 ítems en Wikidata); por eso la cobertura se amplió con MONDO, la UMLS y los puentes de Wikidata (E-1438/E-1439/E-1441). La CIE-10 de SNOMED es relación, no fusión (un código no es el mismo objeto que un concepto).
11. Índice de encargos (trabajo TX-1362)
Los encargos de fondo del trabajo, por los que la red es como es (los informes están en dev/agentes-common/encargos/E-NNNN-informe.md). Hay además encargos intermedios de despliegue y arreglo con el mismo número de TX; esta tabla recoge los de sustancia citados por [elaizii-en-la-red.md](elaizii-en-la-red.md).
| Encargo | Fecha | Qué hizo | Informe |
|---|---|---|---|
| E-1363 | 2026-10-28 | El respondedor común pasa a la librería (red/respondedor.py), sin saber de ninguna red | E-1363-informe.md |
| E-1364 | 2026-10-28 | El medidor de la red: la propia red fabrica exámenes con respuesta conocida y se puntúa sin juez | E-1364-informe.md |
| E-1365 | 2026-10-28 | La mesa de Elaizii: a_mesa.py vuelca SNOMED al esquema común | E-1365-informe.md |
| E-1367 | 2026-10-28 | Ruta de preguntas para cualquier red, con MCP y consultas enlazables | E-1367-informe.md |
| E-1368 | 2026-10-29 | Syd deja su bucle: pasa a ser configuración Red de Elaizii sobre el respondedor común | E-1368-informe.md |
| E-1377 | 2026-10-29 | capa_cie10: la CIE-10 por los mapas de SNOMED, como relación no fusión | E-1377-informe.md |
| E-1378 | 2026-10-29 | Wikidata médica, unida a SNOMED por P5806 | E-1378-informe.md |
| E-1382 | 2026-10-29 | Orphanet (raras) y capa_orphanet, por código exacto | E-1382-informe.md |
| E-1389 | 2026-10-29 | Genes: HGNC y Gene Ontology (capa_genes) | E-1389-informe.md |
| E-1391 | 2026-10-29 | LOINC a Elaizii (capa_loinc) | E-1391-informe.md |
| E-1404 | 2026-10-29 | Medicamentos de CIMA (AEMPS), unidos por el código ATC | E-1404-informe.md |
| E-1413 | 2026-10-29 | La capa DERIVADA: conectar por regla explícita lo que ayuda a Syd | E-1413-informe.md |
| E-1423 | 2026-10-29 | avisos.py: un texto fijo con los avisos de TODAS las fuentes de la mesa | E-1423-informe.md |
| E-1424 | 2026-10-29 | capa_decs: DeCS (español) sobre MeSH por el UI exacto | E-1424-informe.md |
| E-1425 | 2026-10-29 | MeSH (NLM) y capa_mesh, por código | E-1425-informe.md |
| E-1426 | 2026-10-29 | HPO (fenotipos) y capa_hpo: enfermedad → sus síntomas en español | E-1426-informe.md |
| E-1427 | 2026-10-29 | ClinVar (NCBI) y capa_clinvar: gen → enfermedad | E-1427-informe.md |
| E-1438 | 2026-10-30 | Wikidata ampliado: puentes por código; fusiones 10 591 → 98 073 | E-1438-informe.md |
| E-1439 | 2026-10-30 | MONDO: puente entre los catálogos de enfermedad | E-1439-informe.md |
| E-1440 | 2026-10-30 | ChEBI: la sustancia química, puente del análisis a la sustancia | E-1440-informe.md |
| E-1441 | 2026-10-30 | UMLS: el CUI como puente por código (capa_umls) | E-1441-informe.md |
| E-1442 | 2026-10-30 | Reglas nuevas de la capa derivada (gen → síntoma, etc.) | E-1442-informe.md |
| E-1452 | 2026-10-30 | capa_snomed_orphanet: el mapa oficial SNOMED CT → Orphanet | E-1452-informe.md |
| E-1453 | 2026-10-30 | Narrar bien tres fallos de producción, por regla en consultas.py | E-1453-informe.md |
| E-1478 | 2026-10-30 | Red más tupida: familias de genes HGNC y estado de Orphanet | E-1478-informe.md |
| E-1480 | 2026-10-30 | Características y concentradores (capa_caracteristicas) | E-1480-informe.md |
| E-1481 | 2026-10-31 | Lotes deshacibles, guarda de niveles y fusión por nombre con doble señal | E-1481-informe.md |
| E-1482 | 2026-10-30 | Pirámide de la CIE-10 por código y mapa condicional | E-1482-informe.md |
| E-1486 | 2026-10-31 | El cuelgue de «orina cuantitativa», tope por pregunta, gene:↔hgnc: | E-1486-informe.md |
| E-1487 | 2026-11-01 | La mesa: índices y tablas precalculadas (grupo, nivel, cuenta) | E-1487-informe.md |
| E-1506 | 2026-11-02 | Syd: clasificar en una FORMA y recorrido en código; «buscar» por regla | E-1506-informe.md |
| E-1521 | 2026-11-03 | Gene Ontology: separar ARN y complejos de los genes | E-1521-informe.md |
| E-1522 | 2026-11-03 | Plantillas: el código redacta las listas sin el modelo (~1,5 s) | E-1522-informe.md |
| E-1523 | 2026-11-03 | ChEMBL: enfermedad ↔ tratamiento, con la fase de ensayo | E-1523-informe.md |
| E-1536 | 2026-11-03 | Sustancia y producto: cada identidad química a su grupo | E-1536-informe.md |
| E-1538 | 2026-11-03 | PubTator3 (literatura), agregado y separado de lo curado | E-1538-informe.md |
| E-1540 | 2026-11-03 | chebi: a las sustancias SNOMED peladas, vía UMLS | E-1540-informe.md |
| E-1543 | 2026-11-04 | Las 781 que quedaban: amplía UMLS y puentea por Wikidata | E-1543-informe.md |
| E-1550 | 2026-11-04 | La química que se queda en el producto (capa_sustancia_producto_extra) | E-1550-informe.md |
| E-1553 | 2026-11-04 | relaciones cortaba en 40 sin avisar: reparte la muestra | E-1553-informe.md |
| E-1557 | 2026-11-04 | Las indicaciones cuelgan de la sal: une sal y base | E-1557-informe.md |
| E-1560 | 2026-11-04 | relaciones(seguir=) para «es una sal de» | E-1560-informe.md |
| E-1561 | 2026-11-04 | El producto de un solo PA lleva su química a la sustancia (capa_sustancia_un_pa) | E-1561-informe.md |
| E-1562 | 2026-11-04 | capa_mesh_wd_sustancia: el mesh:/wd: de la base vuelve a la sustancia | E-1562-informe.md |
| E-1566 | 2026-11-05 | capa_profarmaco: «es una forma de» para los chembl: del producto | E-1566-informe.md |
| E-1577 | 2026-11-05 | Juntar los caminos en el dato (seguir= lista): «está aprobado para…» | E-1577-informe.md |
| E-1578 | 2026-11-05 | capa_chebi_discrepa: el chebi: de Wikidata discrepa pero es la misma molécula | E-1578-informe.md |
Firmado Karb and Sil · CC BY 4.0.
12. Fuentes
De dónde sale lo que dice esta página. Los informes de los encargos viven en dev/agentes-common/encargos/, que Ariadna no publica: se enlazan en GitLab. Enlazado por programa el 05/11/2026 (pedido de Eduardo).
Documentos de este repo: doc.md · elaizii-en-la-red.md · fuentes-er.md · mcp.md · modelo.md · operaciones.md · syd.md
Informes de encargos: E-1361 · E-1363 · E-1364 · E-1365 · E-1367 · E-1368 · E-1377 · E-1378 · E-1382 · E-1389 · E-1391 · E-1404 · E-1413 · E-1423 · E-1424 · E-1425 · E-1426 · E-1427 · E-1438 · E-1439 · E-1440 · E-1441 · E-1442 · E-1452 · E-1453 · E-1478 · E-1480 · E-1481 · E-1482 · E-1486 · E-1487 · E-1506 · E-1521 · E-1522 · E-1523 · E-1536 · E-1538 · E-1540 · E-1543 · E-1550 · E-1553 · E-1557 · E-1560 · E-1561 · E-1562 · E-1566 · E-1577 · E-1578
Código: [avisos.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/avisos.py) · [bin/syd-opus](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/bin/syd-opus) · [deploy/run.sh](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/deploy/run.sh) · [doc.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/doc.py) · [grafo/a_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/grafo/a_mesa.py) · [red/consultas.py](https://gitlab.com/wordkers/dev/grafo/-/blob/main/red/consultas.py) · [red/respondedor.py](https://gitlab.com/wordkers/dev/grafo/-/blob/main/red/respondedor.py) · [syd.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/syd.py) · [tests/_mesa_juguete.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/_mesa_juguete.py) · [tests/test_a_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_a_mesa.py) · [tests/test_niveles_nombres_mesa.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_niveles_nombres_mesa.py) · [tests/test_preguntar.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_preguntar.py) · [tests/test_preguntar_oro.py](https://gitlab.com/wordkers/apis/elaizii/-/blob/main/tests/test_preguntar_oro.py)