IA & Ingeniería de Software

RAG Against The Machine: Inteligencia sobre Código

Sistema de Generación Aumentada por Recuperación que permite preguntar en lenguaje natural sobre grandes bases de código y obtener respuestas técnicas precisas, contextualizadas y verificables.

Pipeline RAG

Pipeline: Ingesta inteligente → Chunking específico por tipo → BM25 Dual Index → Recuperación con interleaving → Generación con Qwen3-0.6B → Evaluación Recall@k.

El valor añadido de mi perfil

Este proyecto no es solo "conectar un LLM a un repositorio". Mi formación en ADE me permitió identificar el problema de negocio real: el coste de onboarding y context-switching en equipos de ingeniería que trabajan con codebases masivas. Por otro lado, la disciplina de 42 Madrid fue clave para diseñar una arquitectura limpia, con CLI profesional, manejo de errores robusto y rendimiento optimizado. No se trata de un script de Jupyter; es un producto de software con tipado estricto, evaluación automática y métricas cuantificables.

Resumen Ejecutivo

El reto consistió en construir un sistema RAG capaz de ingerir, indexar y responder preguntas sobre el repositorio vLLM — miles de archivos de código y documentación. Desarrollé un pipeline end-to-end con chunking inteligente por tipo de archivo, doble índice BM25 separado para código y documentación, y generación mediante el modelo Qwen3-0.6B ejecutado localmente. El sistema indexa el codebase completo en menos de un minuto y supera los umbrales de recall exigidos por el proyecto.

Conclusiones Técnicas

  • Recall@5 Docs: 81% (threshold requerido ≥ 80%) y Recall@5 Code: 63% (threshold ≥ 50%) superando los objetivos del proyecto.
  • Indexación del codebase completo en ~45 segundos y recuperación de ~200 preguntas en ~25 segundos.
  • Código de producción con Pydantic v2, flake8 y mypy --strict, gestionado con uv para reproducibilidad total.
Deep Dive Técnico

1. Pipeline de Ingesta y Chunking Inteligente

La calidad de un sistema RAG depende del contexto que recibe el LLM. Diseñé un chunking específico por tipo de archivo: para documentación (Markdown, RST, YAML) se dividen los chunks por límites de párrafo, mientras que para código (Python, C++, CUDA) los boundaries son estructurales — funciones, clases y bloques de comentarios. Además, implementé Path Token Boosting: los tokens extraídos de la ruta del archivo se repiten 3 veces en el corpus de código, aumentando la relevancia estructural (por ejemplo, un archivo paged_attention.py responde mejor a consultas sobre PagedAttention).

2. Recuperación Semántica con BM25 Dual

En lugar de un único índice genérico, construí dos índices BM25 separados: uno para documentación y otro para código fuente. Esta separación evita que tokens de sintaxis contaminen la recuperación de docs y viceversa. Para la normalización, desarrollé tokenización avanzada de identificadores que divide snake_case y separa camelCase / PascalCase en palabras individuales. En modo combinado, el Retriever aplica interleaving de resultados (zip) para garantizar un contexto balanceado entre explicaciones técnicas y referencias de implementación.

3. Generación con LLM Local y Evaluación de Métricas

El AnswerGenerator carga el modelo Qwen3-0.6B en GPU (CUDA/MPS) o CPU con precisión float16. Construye un prompt restrictivo — "Answer using ONLY the context provided..." — y genera hasta 100 tokens nuevos, truncando el contexto a 3500 caracteres para respetar la ventana del modelo. Finalmente, el Evaluator calcula métricas Recall@k comparando las fuentes recuperadas contra un dataset de ground truth, con lógica de solapamiento de caracteres que considera un hit si el ratio es ≥ 5%.