fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.3 KiB
4.3 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0040 | Pipeline hibrido extraccion entidades+relaciones (regex + GLiNER/GLiREL + LLM fallback) | completado | feature | multi-app | media | 2026-05-17 | 2026-05-17 |
0040 — Pipeline hibrido extraccion entidades+relaciones (regex + GLiNER/GLiREL + LLM fallback)
Metadata
| Campo | Valor |
|---|---|
| ID | 0040 |
| Estado | pendiente |
| Prioridad | media |
| Tipo | feature — Python pipeline (python/functions/pipelines/) |
Dependencias
Bloquea-por: 0037 (IoC regex), 0038 (GLiNER), 0039 (GLiREL).
Desbloquea: flujo OSINT/grafo de produccion con coste predecible. Reusable desde apps en apps/*/ y desde notebooks en analysis/*/.
Objetivo
Pipeline que combina los tres extractores en cascada para obtener triplets (entidad, relacion, entidad) masivamente con buen coste/calidad:
- Capa regex (0037) — extrae IoCs tecnicos con precision 100%. Coste 0.
- Capa GLiNER (0038) — extrae entidades semanticas (person, organization, location, event...) zero-shot. Coste bajo.
- Capa GLiREL (0039) — relaciones zero-shot entre las entidades de capa 1+2.
- Capa LLM fallback (existente:
extract_entities_llm+extract_relations_llm) — solo se invoca cuandoconfidence < thresholdo sobre los chunks marcados como "complejos".
Output: (list[EntityCandidate], list[RelationCandidate]) listos para deduplicate_entities → deduplicate_relations → ops_to_sigma_json / ops_to_rdf_triples.
Funcion a crear
| Function ID | Rol |
|---|---|
extract_graph_hybrid_py_pipelines |
Pipeline orquestador. kind: pipeline, purity: impure, uses_functions: [...] con todos los anteriores |
Contrato
def extract_graph_hybrid(
chunks: list[str],
entity_schema: list[dict],
relation_types: list[str],
gliner_model, # inyectado
glirel_model, # inyectado
llm_chat_json: Callable | None = None, # opcional; si None, sin fallback LLM
ioc_types: list[str] | None = None, # None = todos
confidence_threshold: float = 0.6, # bajo este umbral se llama LLM
languages: str = "Respond in Spanish.",
) -> tuple[list[EntityCandidate], list[RelationCandidate]]
Logica interna por chunk:
extract_iocs(chunk, ioc_types)→EntityCandidatecontype_reftecnico (ip/email/hash/...).extract_entities_gliner(chunk, entity_schema, gliner_model)→ entidades semanticas.- Si hay chunks con < N entidades o confidence baja y hay
llm_chat_json→extract_entities_llmsobre esos chunks; mergear. extract_relations_glirel(chunk, entities_del_chunk, relation_types, glirel_model).- Si baja cobertura de relaciones y hay LLM →
extract_relations_llmsobre el chunk. - Devolver listas concatenadas (sin deduplicar — eso lo hace el caller con
deduplicate_*).
Pureza
kind: pipeline → purity: impure (regla del registry).
uses_functions: lista los 5+ extractores invocados. error_type: error_go_core.
Deliverables
python/functions/pipelines/extract_graph_hybrid.py+.md- Test de integracion en
python/functions/pipelines/tests/test_extract_graph_hybrid.pycon un corpus pequeño (2-3 textos OSINT realistas, mock del LLM). .mddocumenta: cuando usar fallback LLM, latencia esperada por chunk, recomendacion de batch size.
Validacion
./fn run extract_graph_hybrid_py_pipelines
Bench end-to-end sobre 100 KB de texto:
- Solo LLM (linea base actual): registrar tiempo y coste estimado.
- Pipeline hibrido: registrar tiempo, coste (solo chunks con fallback) y delta de calidad vs solo-LLM.
Registrar resultados en el .md para tener referencia historica.
Notas
- La deduplicacion fuzzy (Levenshtein + Union-Find) ya esta hecha en
deduplicate_entities— NO replicar aqui. - IoCs y entidades semanticas pueden solapar (ej: GLiNER detecta
apple.comcomo organization, regex como domain). Resolver dejando ambas contype_refdistinto y quededuplicate_entitiesconsame_type_only=Trueno las mezcle. Documentar esta decision. - Pensar en un app
apps/osint_extractor/que use este pipeline + sigma viz como demo. Fuera de scope de este issue — proponer en proposals despues.