Pipeline de contenido
Cómo llega el contenido a la Academia, desde el inventario de videos y el pipeline de extracción hasta los cursos, los repasos y la base de conocimiento del RAG.
El contenido de la Academia sigue dos caminos:
- Estructura de cursos desde el inventario de videos (
academia_dm_contenido.json) y el manual (manual-academia.json). - Artefactos derivados de los videos (texto para el RAG, preguntas y puntos de control) que produce un pipeline de extracción en un repositorio hermano,
lms-course-scrap.
Repositorio hermano
El repositorio lms-course-scrap no está incluido en esta entrega (no existe junto a lms-moodle en el equipo donde se preparó esta documentación). Lo que se describe de él proviene de los documentos de planificación de docs/ (roadmap.md, roadmap_v3.md y roadmap_v4.md, apéndice A). Su estado real actual y el detalle de sus esquemas (docs/SCHEMA.md de ese repositorio): Por confirmar.
Visión general
Inventario (PDF de currículo → academia_dm_contenido.json)
│
├─► create-courses.php ──► cursos, secciones por tema y actividades (video interactivo / enlace / etiqueta)
│ └─ align-academy-to-manual.php: nombres y temas según el manual
│
└─► lms-course-scrap (catálogo → descarga → transcripción → fragmentación)
├─ chunks.jsonl ...................► RAG (plan: local_dify_sync → base de conocimiento de Dify)
├─ quizzes/{módulo}.gift ...........► repasos (importación GIFT)
└─ interactive/{código}.json
(checkpoints de los videos) ......► import-checkpoints.php → repaso tras cada video1. Del inventario a los cursos
| Paso | Script o componente | Qué hace |
|---|---|---|
| Inventario | docs/modules-info/academia_dm_contenido.json | Módulos y temas con n, codigo (PowerBuilder), tema, objetivo y url. Se copia a la imagen en /opt/academia-dm/. Ver Catálogo de módulos. |
| Creación de cursos | create-courses.php → local_deltamodules\builder | Crea la categoría Academia Deltamontero y un curso por módulo, con una sección por tema (o por grupo temático en Formación Líderes). Traduce los identificadores históricos (modulo_1…) a los del manual para no duplicar cursos. Idempotente: omite los cursos que ya existen. Se ejecuta a mano después de la instalación. |
| Actividades | builder | Enlace de YouTube → actividad video interactivo (mod_interactivevideo); otro enlace → recurso URL; tema sin enlace → etiqueta de contenido pendiente. El código PowerBuilder del tema se escribe en el número de ID de la actividad principal: es el vínculo estable entre la Academia y el sistema de gestión interno. |
| Módulos del manual | restructure-courses-per-manual.php | Crea vacíos, con sus temas, los módulos del manual que no venían del inventario (1, 9, 10, 11 y 12). |
| Nombres y temas | align-academy-to-manual.php | En cada despliegue aplica nombres, temas, descripciones y campos de revisión del manual. |
| Estándar | normalize-academy.php y observadores | Aplica las reglas: completado de videos, repasos, candados y certificado. |
La misma clase builder la usa la función externa local_deltamodules_create_module del agente de gestión. Además, desde la plataforma, Módulos → Nuevo módulo crea un módulo desde un documento (plantilla Excel de la Academia, PDF del currículo, Word, CSV o JSON) con un analizador incluido en la imagen.
Un cambio en el inventario requiere reconstruir la imagen y volver a ejecutar create-courses.php, que solo crea lo que falta. Para regenerar un curso existente hay que borrarlo primero.
2. Artefactos del pipeline de extracción
Según la planificación, lms-course-scrap es un pipeline Python (inicialmente cuadernos Jupyter, en proceso de convertirse en línea de comandos contenerizada) que recorre el catálogo, descarga y transcribe los videos y produce tres artefactos. Se ejecutó en modo piloto sobre el Módulo 1 del inventario.
| Artefacto | Contenido | Consumidor en Moodle | Estado según la planificación |
|---|---|---|---|
chunks.jsonl | Fragmentos de texto con metadatos (identificador de contenido, tema, marcas de tiempo), sin vectores | RAG del chat | Datos del piloto listos; sincronización pendiente |
quizzes/{módulo}.gift | Preguntas de opción múltiple en formato GIFT por módulo | Importación GIFT al banco de preguntas | Datos del piloto listos; importación por pantalla disponible |
interactive/{código}.json | Puntos de control (checkpoints) de cada video: momento, pregunta, opciones, índice de la correcta y retroalimentación | import-checkpoints.php | Datos del piloto; importador disponible |
Principio: el pipeline produce datos y no se acopla al sistema de archivos de Moodle. El plan es publicar los artefactos versionados en un almacenamiento de objetos para que Moodle los consuma; el proveedor y el esquema de versionado están Por confirmar.
Identificador de contenido
Los artefactos se vinculan con los cursos por el identificador de contenido {slug}__{id_del_video}: el slug deriva del módulo y del tema (por ejemplo, m3-1) y la segunda parte es el identificador del video de YouTube. Los importadores buscan ese identificador dentro del enlace de la actividad de video interactivo, lo que funciona aunque la actividad no tenga número de ID.
3. Checkpoints de los videos
Los checkpoints son preguntas de opción múltiple generadas a partir del contenido de cada video.
| Elemento | Detalle |
|---|---|
| Archivos en la imagen | infrastructure/moodle/checkpoints/ se copia a /checkpoints |
c2_authored.json | Diccionario identificador de contenido → lista de checkpoints (time_seconds, question, options, answer_index, feedback) |
Paquetes c2_{identificador}.json | Uno por video: content_id, video_id, url, duration_seconds, tema, objetivo y windows |
| Cobertura actual | 22 videos con checkpoints, 35 preguntas en total: 14 del Módulo 3, 4 del Módulo 7 (Nómina) y 4 del Módulo 8 (Caja Chica) del manual |
Uso:
php /import-checkpoints.php /checkpoints/c2_authored.json [/checkpoints]import-checkpoints.php:
Lee cada identificador de contenido y busca el video interactivo cuyo enlace contiene ese identificador de YouTube. Si no lo encuentra, lo informa y sigue.
Convierte los checkpoints a texto GIFT y los importa con el analizador GIFT nativo de Moodle (qformat_gift) en una categoría de preguntas por curso.
Crea un cuestionario "Repaso: (tema)" con esas preguntas (una por página, respuestas en orden aleatorio) y lo coloca inmediatamente después de su video. El nombre del tema sale del paquete del video.
Es idempotente: si ya existe un repaso con ese nombre en el curso, lo omite. Al final informa nuevos, omitidos y videos no encontrados.
Después, las Reglas de la Academia dan a cada repaso sus intentos, tiempo, nota para aprobar, aviso y candado hasta ver el video.
Control de calidad
Las preguntas generadas automáticamente deben pasar por revisión humana antes de llegar a los colaboradores (gate de QA de la planificación: importar oculto, revisar con Talento Humano o el experto del área y luego publicar). El importador actual crea los repasos visibles; si la revisión de los repasos importados ya se hizo: Por confirmar.
4. Preguntas en formato GIFT y otros formatos
Además de los checkpoints, las preguntas pueden entrar por la plataforma, sin scripts:
- Asistente de nuevo módulo y carga de preguntas de un módulo: un solo archivo con las preguntas de todo el módulo; cada una va al repaso de su tema (títulos
Tema 1,13.1 Nombre, o categorías con el nombre o número del tema). Las que no corresponden a un tema quedan en el banco del módulo. - Formatos: Word o texto escrito a mano, la hoja Preguntas de la plantilla Excel, XML de Moodle, GIFT o Aiken (ver el formato en Pruebas técnicas).
La importación por script de los archivos quizzes/{módulo}.gift del pipeline (import-quizzes.php) figura en la planificación pero no existe en el repositorio.
5. Texto para el RAG
Estado actual del chat
El chat de IA de la Academia funciona hoy con local_ai_manager conectado directamente a Groq, sin RAG sobre los videos. Ver Arquitectura.
Arquitectura planificada (Dify)
La planificación (docs/roadmap.md) define el RAG sobre Dify:
| Pieza | Plan |
|---|---|
| Fuente de verdad | chunks.jsonl: texto y metadatos sin vectores. Los vectores son derivados y se pueden regenerar con cualquier proveedor. |
| Sincronización | Plugin local_dify_sync en el cron de Moodle: tarea programada que trae chunks.jsonl y actualiza la base de conocimiento de Dify por content_hash, y observadores que envían PDF y páginas nativas de Moodle. Tabla de estado local_dify_sync_state. Configuración por interfaz. |
| Modelos en Dify | LLM cambiable por interfaz sin reindexar; embedding bge-m3 fijo (cambiarlo obliga a reindexar); reranker opcional. |
| Recuperación | Prueba de concepto con la base de conocimiento nativa de Dify (un segmento = un fragmento, para conservar los enlaces con marca de tiempo al segundo exacto del video). Si la refragmentación los daña, migrar a External Knowledge API (Qdrant y un endpoint propio). |
| Conexión con Moodle | local_ai_manager apunta al endpoint compatible con OpenAI de Dify; el cambio de proveedor ocurre dentro de Dify. |
El plugin local_dify_sync y el despliegue de Dify están pendientes: el plugin no existe en el repositorio y la carpeta rag-service/ está vacía.
Importador alternativo sin Dify
import-rag-chunks.php es un importador alternativo que lee un chunks.jsonl (cada línea con content_id, texto y, opcionalmente, tema, videourl, ts_inicio y ts_fin), genera el embedding de cada fragmento con la API de embeddings de Gemini (usando el conector Gemini de local_ai_manager) y lo guarda en la tabla local_deltamodules_chunks de la propia base de Moodle. El script advierte en su encabezado que no debe ejecutarse mientras no exista un chunks.jsonl completo y cuota disponible, porque consume cuota de la API. No se usa en el chat actual.
php /import-rag-chunks.php /ruta/a/chunks.jsonl [--force]Pendientes del pipeline
Según la planificación y el estado del repositorio:
- Correr el catálogo completo (fuera del modo piloto), incluidas las fuentes de Google Drive y TikTok.
- Entregar la lista de temas sin enlace como pendientes de grabación (ver Catálogo de módulos).
- Definir el almacenamiento de objetos y el versionado de los artefactos.
- Construir
local_dify_sync, desplegar Dify y conectarlo alocal_ai_manager. - Reubicar los videos del Módulo 5 en los temas del manual.