Este documento describe la fase de Ingesta y Enriquecimiento de Datos del pipeline.
Este paso se encarga de procesar los datos en crudo (raw_dataset.csv) que contienen definiciones estructuradas de repositorios y acoplarles su respectivo documento de agente descargado (almacenado en la caché).
- Lectura de Entrada: El script lee el archivo
dataset/raw_dataset.csv. - Generación de Metadatos: Extrae el nombre del repositorio (
owner/repo) y sus etiquetas (categorías) asociadas de las columnas correspondientes a las Labels. - Validación de Caché: Para cada repositorio, busca si existe el archivo markdown correspondiente (
owner_repo.md) dentro del directorio de caché (dataset/agents_cache/). Si el archivo no está cacheado localmente, el script ignora la fila en cuestión, imprime un aviso ("Skipping...") y continúa, evitando intentos de descarga externos. - Enriquecimiento: Si el archivo caché está presente, se lee su contenido y se inyecta un bloque de metadatos (YAML Frontmatter) en la cabecera. Este bloque incluye el identificador completo del repositorio y el listado de categorías extraídas del CSV original.
- Generación de Salida: Escribe el nuevo documento en la carpeta
dataset/enriched_agents/, conservando el nombre original del archivo cacheado pero ahora enriquecido y estructurado para las próximas fases.
dataset/raw_dataset.csv(oraw-dataset.csv): Archivo CSV base con el listado tabular de repositorios y sus categorías.dataset/agents_cache/: Directorio temporal/repositorio local con todos los archivos markdown crudos para cada agente (owner_repo.md).
dataset/enriched_agents/: Directorio final que contiene los archivos.mdresultantes, con el YAML Frontmatter implementado inyectado al tope de cada documento.
---
repo: "0x-j/aptos-full-stack-template"
categories: ["System Overview", "Architecture", "Development Process", "Test", "Configuration & Environment", "Maintanability"]
---
content...Para propósitos de evaluación académica comparando la eficiencia y fiabilidad de métodos LLM vs métodos determinísticos tradicionales, esta fase cuenta con tres variantes. Todas ellas procesan los archivos resultantes de la Fase 1 y generan un objeto JSON que representa un AST (Abstract Syntax Tree) normalizado del contexto del documento, categorizando las reglas extraídas.
Independientemente de la variante utilizada, el esquema de salida unificado es el siguiente:
{
"projectInfo": {
"repoName": "<nombre_repo>",
"agentsMdSource": "<archivo_origen.md>"
},
"rootNode": {
"id": "root",
"label": "AGENTS.md Context",
"type": "root",
"children": [
{
"id": "macro_<nombre_categoria>",
"label": "<Nombre Categoría Macro (ej. General)>",
"type": "category",
"count": <total_reglas_en_macro_categoria>,
"children": [
{
"id": "cat_<nombre_label>",
"label": "<Nombre Label / Sub-Categoría>",
"type": "label",
"count": <total_reglas_en_label>,
"children": [
{
"id": "rule_<num_secuencial>",
"type": "rule",
"content": {
"text": "<Instrucción completa identificada en el markdown>",
"originalHeader": "<Título de la sección H2/H3 a la que pertenece>"
},
"metadata": {
"format": "<ListItem|Paragraph>"
}
}
]
}
]
}
]
}
}Utiliza un modelo Local Small Language Model (SLM) iterando con un servidor compatible (ej. LMStudio con Qwen 3.5).
- Proceso: El script extrae el bloque de metadatos del archivo y le pasa el texto en crudo al modelo junto con el diccionario maestro de categorías. Luego parsea la salida en crudo garantizando la estructura dictada de JSON.
- Input: Archivos
.mddedataset/enriched_agents/. - Output: Árboles JSON guardados en
dataset/json_trees/llm/.
Utiliza un SLM de última generación (ej. qwen/qwen-3.5-9b) remotamente pasando a través de la API ruteada de OpenRouter, pero preservando la compatibilidad de "Structured Output" del cliente de OpenAI.
- Proceso: Idéntico a la variante 2A local, pero forzando garantizadamente la salida estructurada a nivel de API. Se inyecta la constante
JSON_SCHEMA(esquema JSON duro constrict: TrueyadditionalProperties: False) en el parámetroresponse_formatdel cliente de OpenAI, lo que obliga al modelo a generar una compatibilidad sintáctica perfecta del AST sin alucinaciones. - Dependencias y Auth: Requiere
pip install openaiy configurar la variable de entornoOPENROUTER_API_KEY. - Input: Archivos
.mddedataset/enriched_agents/. - Output: Árboles JSON guardados en una nueva sub-carpeta
dataset/json_trees/llm_forced_output/.
No utiliza IA; emplea heurísticas determinísticas y la estructura generada por Pandoc.
- Proceso:
- Ejecuta la CLI de
pandocsubyacentemente para transformar de Markdown a JSON AST nativo de Pandoc. - Recorre el JSON de manera recursiva asegurando extraer texto de nodos anidados (como
Quoted,Table,Header,Para,BulletList). - Asigna la categoría macheando palabras clave contra el diccionario de categorías general o el array inyectado previamente.
- Ejecuta la CLI de
- Input: Archivos
.mddedataset/enriched_agents/. - Output: Árboles JSON guardados en
dataset/json_trees/parser/.
Utiliza un modelo comercial de alto rendimiento de Anthropic (Claude 4.5 Sonnet) a través de su API oficial.
- Proceso: Similar a la Variante A, extrae contexto y pide la estructuración JSON AST exacta. Destaca por su alta fiabilidad y capacidad intelectual. Requiere una clave de API válida.
- Input: Archivos
.mddedataset/enriched_agents/. - Output: Árboles JSON guardados en
dataset/json_trees/llm_api/.
Para validar cuantitativamente la calidad y la veracidad de los JSON generados por las variantes de la Fase 2 (y mitigar amenazas a la validez), se ejecutan rutinas de testing automáticas.
Para correr los scripts de validación, necesitas instalar el validador oficial de esquemas JSON de Python:
pip install jsonschemasrc/scripts/2d_validate_json_schema.py
- ¿Qué evalúa?: Verifica matemáticamente que los JSON generados cumplan al 100% con la estructura del AST requerida. Asegura que no falten campos obligatorios (
projectInfo,rootNode), que los tipos de datos sean exactos (ej.countdebe ser Integer), y que el LLM no haya inyectado propiedades fantasma. - Métrica obtenida: Schema Compliance Rate (Integridad del Formato). Las variaciones que pasan esta prueba están garantizadas para consumirse por una UI/Visualización downstream sin romper el código.
- Ejecución:
python src/scripts/2d_validate_json_schema.pysrc/scripts/2e_validate_categories.py
- ¿Qué evalúa?: Funciona como un test de alucinación semántica. Lee el array de categorías base original (Ground Truth) inyectado al inicio del
.mden la Fase 1 y lo compara contra los nodoscategorygenerados en el árbol AST de la Fase 2. - Métrica obtenida: Hallucination Rate. Detecta y lista si el LLM o el Parser "inventaron" nuevas categorías para encapsular reglas en lugar de ceñirse estrictamente al array asignado para ese repositorio.
- Ejecución:
python src/scripts/2e_validate_categories.pyEl objetivo de esta fase es reducir drásticamente la carga cognitiva de leer archivos AGENTS.md kilométricos, transformando el JSON AST crudo en interfaces gráficas interactivas renderizadas en el navegador web.
Para garantizar la integridad estricta de los datos inyectados al frontend, la arquitectura pasó de usar diccionarios crudos de Python a un Modelo de Dominio.
Antes de generar cualquier gráfica, el JSON extraído es validado e instanciado imperativamente mediante Pydantic.
La clase AgentASTDocument actúa como el Aggregate Root. Todas las propiedades visuales (como color, radio del nodo, truncamiento de etiquetas y mapeo semántico MUST/SHOULD) están encapsuladas directamente dentro de las entidades (ej: RuleCategory y AgentRule). Esto elimina la lógica de presentación redundante (spaghetti) de los scripts de generación.
Genera un archivo HTML interactivo con una vista dividida (Split-View):
- Izquierda: Muestra el documento Markdown crudo original para lectura por referencias.
- Derecha: Renderiza un grafo de red usando
D3.js(d3.forceSimulation). Los nodos (Reglas) orbitan dinámicamente alrededor de sus Categorías padre. - Interacción: Permite hacer Zoom, Paneo (arrastrar el lienzo) y clic sobre los nodos para abrir un panel lateral con los metadatos profundos de la regla (Formato, Intensidad, Header Original).
Ejecución:
PYTHONPATH=. python src/scripts/3_generate_visualization.py dataset/json_trees/llm_forced_output/<archivo>.jsonGenera un diagrama estático utilizando d3.tree(). Elimina la física caótica de colisiones, permitiendo leer secuencialmente el árbol AST de izquierda a derecha.
El árbol visual desglosa el contexto en cuaatro profundidades secuenciales:
- Nodos Raíz (Root): Origen del árbol representando al repositorio (color gris oscuro).
- Macro-Categorías (Category): Primer nivel de agrupamiento analítico. Existen 6 dominios inmutables con una semaforización de colores fijos que heredan visualmente hacia sus hijos:
- General: Pizarra (
#94a3b8) - Implementation: Azul (
#60a5fa) - Build: Verde (
#4ade80) - Management: Púrpura (
#c084fc) - Quality: Rojo (
#f87171) - Uncategorized: Gris Claro (
#e2e8f0)
- General: Pizarra (
- Etiquetas (Label): Áreas temáticas intermedias inferidas originalmente por el LLM en la Fase 2 (ej. Tests, Architecture, Performance) antes de ser categorizadas en el script de migración. Actúan como el segundo nivel de agrupamiento.
- Instrucciones (Rule): Nodos terminales (hojas) que contienen el texto crudo y descriptivo de la acción extraída del Markdown.
Ejecución:
PYTHONPATH=. python src/scripts/3b_generate_tree_visualization.py dataset/json_trees/llm_forced_output/<archivo>.jsonPara los agrupadores (Category y Label), abandonamos los clásicos nodos redondos en favor de nodos rectangulares responsivos. Aprovechamos la geometría matemática del rectángulo para mapear volumétricamente el tamaño y la carga cognitiva acumulada de sus descendientes:
- Nodos Category: Su altura matemática es la sumatoria de todas las reglas contenidas dentro de todos sus Labels hijos (
50px + rules*8). - Nodos Label: Su altura crece proporcionalmente en base a la cantidad de reglas inmediatas que alberga (
40px + rules*10). - Interpretación: De un solo vistazo vertical se aprecia geométricamente qué áreas del conocimiento concentran la mayor sumatoria de requerimientos técnicos.
- Nodos Category (Diversidad Temática): Su anchura horizontal la determina la cantidad de Labels internos que alberga. Una Category muy ancha indica que el dominio abarca muchos temas/etiquetas diferentes (
140px + labels*25). - Nodos Label (Carga Cognitiva): Su anchura se determina evaluando su texto interno crudo con un motor NLP (
textstat) para calcular la métrica de legibilidad Flesch Reading Ease (FRE). - Interpretación del Label: Un Label corto y contraído alerta de instrucciones con altísima carga cognitiva (jerga, sentencias densas e ingeniería). Un Label horizontalmente ancho, indica instrucciones fluidas o párrafos introductorios fáciles de leer (
80px + FRE Score).
- Lógica: Se mide la proporción de instrucciones que contienen marcadores estructurales exclusivos de código (
{},(),<>,.py,.js, etc.) en relación con el total de instrucciones dentro de esa agrupación. - Interpretación: Un borde grueso y marcado (hasta 8px) resalta inmediatamente que ese agrupamiento es puramente de ingeniería, código duro y comandos. Un borde excepcionalmente fino (1.5px) indica lineamientos organizacionales, procesos, o semántica teórica que carecen de fragmentos de código.