Saltar al contenido
# Quick Reference: Klaus File Categorization & Policies **Uso rápido:** Consulta esta tabla para validación de archivos sin leer documentación completa. --- ## Matriz de Decisión: ¿Indexar este archivo? ### Paso 1: Detectar extensión | Extensión | Categoría | Indexar | Chunking | Prioridad | |---|---|---|---|---| | **.py** | CODE_PYTHON | ✓ SÍ | AST (func/class) | ⭐⭐⭐ | | **.ts, .tsx** | CODE_TYPESCRIPT | ✓ SÍ | Fixed 500c | ⭐⭐⭐ | | **.js, .jsx** | CODE_JAVASCRIPT | ✓ SÍ | Fixed 500c | ⭐⭐⭐ | | **.sh, .bash** | CODE_SHELL | ✓ SÍ | Fixed 400c | ⭐⭐ | | **.go, .rs, .sql, .java, .rb, .php** | CODE_OTHER | ✓ SÍ | Fixed 500c | ⭐⭐ | | **.md, .rst, .txt** | DOCUMENTATION | ✓ SÍ | Heading split | ⭐⭐⭐ | | **.json, .yaml, .yml, .toml** | CONFIG_STRUCTURED | ⚠️ FILTRADO | Semantic section | ⭐⭐ | | **.ini, .conf, .cfg** | CONFIG_UNSTRUCTURED | ❌ NO | — | ⭐ | | **.html, .xml, .svg** | MARKUP | ❌ NO | — | ⭐ | | **.css, .scss, .less, .sass** | STYLES | ❌ NO | — | ⭐ | | **.csv, .tsv, .parquet** | DATA_TABULAR | ❌ NO | — | ⭐ | | **.png, .jpg, .gif, .webp** | BINARY_IMAGES | ❌ NO | — | ⭐⭐ SKIP | | **.mp4, .mp3, .wav, .pdf, .docx** | BINARY_MEDIA | ❌ NO | — | ⭐⭐ SKIP | | **.zip, .tar, .gz, .7z, .rar** | BINARY_ARCHIVES | ❌ NO | — | ⭐⭐ SKIP | | **.log, .out** | GENERATED_LOGS | ❌ NO | — | ⭐⭐ SKIP | ### Paso 2: Aplicar heurísticos de directorio Si la extensión no está clara, revisar el directorio: | Patrón en Ruta | Categoría | Indexar | |---|---|---| | `.git/`, `node_modules/`, `vendor/`, `venv/`, `dist/`, `build/` | VENDORED | ❌ NO | | `tests/`, `fixtures/`, `__tests__`, `spec/`, `specs/` | TEST_FIXTURES | ❌ NO | | Archivos `.test.`, `.spec.` | TEST_FIXTURES | ❌ NO | | Archivos `.sample`, `.example`, `.template` | CONFIG_STRUCTURED (pero filtrado) | ⚠️ SKIP | ### Paso 3: Aplicar heurísticos de nombre archivo | Patrón en Nombre | Categoría | Indexar | |---|---|---| | Contiene `log`, `debug`, `.out` | GENERATED_LOGS | ❌ NO | | Contiene `mock`, `fixture` | TEST_FIXTURES | ❌ NO | | Archivo vacío o < 40 chars | — | ❌ NO | | Detecta `is_llm_response()` en contenido | — | ❌ NO | | Archivo > 50 MB | — | ❌ NO | --- ## Parámetros de Chunking por Categoría ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ CÓDIGO PYTHON │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: AST parsing (function/class per chunk) │ │ Chunk size: 500 chars max (unbounded for single def) │ │ Overlap: 0 (AST boundaries) │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (function/class names) │ │ Fallback: Fixed-size if SyntaxError │ │ Ejemplo: def my_func():\n ... = 1 chunk │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ CÓDIGO TYPESCRIPT / JAVASCRIPT │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: Symbol extraction + fixed-size │ │ Chunk size: 500 chars │ │ Overlap: 100 chars │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (function/class/export names) │ │ Ejemplo: export function foo() { ... } │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ SHELL SCRIPTS │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: Function-aware + fixed-size │ │ Chunk size: 400 chars │ │ Overlap: 80 chars │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (function names) │ │ Preserve shebang: ✓ │ │ Ejemplo: function deploy() { ... } │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ DOCUMENTACIÓN (MARKDOWN) │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: Split by H2/H3 headings │ │ Chunk size: 800 chars per subsection │ │ Overlap: 120 chars (preserve context) │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (heading text) │ │ Preserve struct: ✓ (no split mid-paragraph) │ │ Ejemplo: ## Installation\n...\n### Step 1\n... │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ CONFIG (JSON/YAML/TOML) │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: Semantic section (top-level keys) │ │ Chunk size: 1000 chars │ │ Overlap: 0 (preserve JSON structure) │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (key paths: db.connection.host) │ │ Preserve struct: ✓ (don't break JSON objects) │ │ Ejemplo: database: { connection: { host: ... } } │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ OTROS LENGUAJES (GO, RUST, SQL) │ ├─────────────────────────────────────────────────────────────────────────┤ │ Estrategia: Symbol extraction + fixed │ │ Chunk size: 500 chars │ │ Overlap: 100 chars │ │ Min chunk: 40 chars │ │ Extract symbols: ✓ (language-specific: func, type, struct) │ │ Ejemplo (Go): func MyFunc() { ... } │ │ Ejemplo (Rust): fn my_func() { ... } │ │ Ejemplo (SQL): CREATE TABLE users { ... } │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## Embedding & Search Thresholds | Concepto | Valor | Uso | |---|---|---| | **Embedding model** | text-embedding-3-small (1536d) | Dense vectors | | **BM25 vocabulary** | 30,000 tokens | Sparse vectors | | **Search strategy** | RRF fusion (dense + sparse) | Hybrid search | | **KB similarity threshold** | 0.75 | General search (permisivo) | | **Symbol query threshold** | 0.638 (0.75 * 0.85) | Reduced for variants | | **Duplicate detection threshold** | 0.92 | Estricto, solo duplicados reales | | **Prefix semantic enrichment** | `{path}: {symbol_type} {name} —` | Cierra semantic gap | --- ## Decision Tree: ¿Indexar este archivo? ``` ┌─ ¿Extensión reconocida? │ ├─ .py, .ts, .jsx, .md, .yaml, .json │ │ └─ ✓ Probablemente sí → ver paso 2 │ │ │ └─ .log, .png, .csv, etc. │ └─ ❌ Probablemente no → ver exclusiones │ ├─ ¿Está en directorio excluido? │ ├─ node_modules/, tests/, .git/, venv/ │ │ └─ ❌ NO INDEXAR (VENDORED / TEST_FIXTURES) │ │ │ └─ proxy/, src/, docs/ │ └─ ✓ Continuar │ ├─ ¿Categoría es CODE o DOCUMENTATION? │ ├─ ✓ SÍ │ │ └─ INDEXAR (high semantic value) │ │ │ └─ ❌ NO → ver paso 4 │ ├─ ¿Categoría es CONFIG_STRUCTURED? │ ├─ ¿Archivo es .sample, .example, .template? │ │ ├─ ✓ SÍ → NO INDEXAR │ │ └─ ❌ NO → ¿Contiene is_llm_response? │ │ ├─ ✓ SÍ → NO INDEXAR │ │ └─ ❌ NO → INDEXAR │ │ │ └─ ❌ NO → ver paso 5 │ ├─ ¿Categoría es CONFIG_UNSTRUCTURED, MARKUP, STYLES? │ ├─ ✓ SÍ → NO INDEXAR (noise, low semantic value) │ └─ ❌ NO → ver paso 6 │ ├─ ¿Categoría es BINARY, LOGS, TEST_FIXTURES? │ ├─ ✓ SÍ → NO INDEXAR (bloat, volatile, mocks) │ └─ ❌ NO → continuación │ └─ ¿Archivo > 50 MB? ├─ ✓ SÍ → NO INDEXAR (bloat) └─ ❌ NO → INDEXAR ✓ ``` --- ## Tabla de Distribución Esperada (9K files) Para validar que tu validación está funcionando correctamente: ``` INDEXADOS (~4000 files, 43%): code_python ~219 ✓ Alta prioridad code_typescript ~54 ✓ Alta prioridad code_javascript ~54 ✓ Alta prioridad code_shell ~75 ✓ Media prioridad code_other ~60 ✓ Media prioridad documentation ~742 ✓ Alta prioridad config_structured ~2854 ⚠️ Filtrado (sin .sample) ───────────────────────────── SUBTOTAL INDEXADOS 4058 SKIPPED (~5300 files, 57%): test_fixtures ~300 ❌ Mocks vendored ~3500 ❌ node_modules, etc. binary_images ~130 ❌ No-textual generated_logs ~100+ ❌ Volatile markup ~52 ❌ Tag noise styles ~54+ ❌ Low semantics config_unstructured ~50 ❌ Noise build_artifacts ~50+ ❌ Compiled ───────────────────────────── SUBTOTAL SKIPPED 4286 ``` **Si tu distribución es muy diferente:** Revisar políticas en `should_index_file()` --- ## Ejemplos: Validación en UNA PASADA ### Ejemplo 1: Archivo Python ```python file_path = "proxy/knowledge.py" category = detect_file_category(file_path) # → FileCategory.CODE_PYTHON should_index, reason = should_index_file(file_path, category) # → (True, "category_code_python_index") policy = ChunkingPolicy.for_category(category) # → ChunkingPolicy(strategy='ast', chunk_size=500, overlap=0, ...) # Acción: INDEXAR con AST parsing ``` ### Ejemplo 2: Archivo Template Config ```python file_path = "config/app.yaml.example" category = detect_file_category(file_path) # → FileCategory.CONFIG_STRUCTURED should_index, reason = should_index_file(file_path, category) # → (False, "config_sample_skip") # Acción: SKIP (es template, no config real) ``` ### Ejemplo 3: Imagen en Tests ```python file_path = "tests/fixtures/logo.png" category = detect_file_category(file_path) # → FileCategory.BINARY_IMAGES should_index, reason = should_index_file(file_path, category) # → (False, "category_binary_images_skip") # Acción: SKIP (es binario) ``` ### Ejemplo 4: Markdown Documentation ```python file_path = "docs/API.md" category = detect_file_category(file_path) # → FileCategory.DOCUMENTATION should_index, reason = should_index_file(file_path, category) # → (True, "category_documentation_index") policy = ChunkingPolicy.for_category(category) # → ChunkingPolicy(strategy='heading', chunk_size=800, overlap=120, ...) # Acción: INDEXAR con heading-split ``` --- ## Debug: Líneas de Código Clave Si necesitas entender qué está pasando: ```python # Detectar categoría: from proxy.file_validator import detect_file_category cat = detect_file_category("proxy/knowledge.py") print(f"Categoría: {cat.value}") # Validar indexación: from proxy.file_validator import should_index_file ok, reason = should_index_file("proxy/knowledge.py", cat) print(f"Indexar: {ok}, Razón: {reason}") # Obtener política: from proxy.file_validator import ChunkingPolicy policy = ChunkingPolicy.for_category(cat) print(f"Estrategia: {policy.strategy}, Chunk size: {policy.chunk_size}") # Ejecutar validación completa: python scripts/ingest_all_with_validation.py --report-only ``` --- ## Cambios Rápidos ### Aumentar indexación (incluir más archivos) 1. Cambiar en `should_index_file()`: ```python # Antes: if category == FileCategory.STYLES: return False, "category_styles_skip" # Después: if category == FileCategory.STYLES: return True, "category_styles_index" ``` 2. Re-ingestionar: ```bash python scripts/ingest_all_with_validation.py --flush ``` ### Reducir indexación (excluir más archivos) 1. Cambiar en `should_index_file()`: ```python # Antes: if category == FileCategory.CONFIG_STRUCTURED: return True, "category_config_structured_index" # Después: if category == FileCategory.CONFIG_STRUCTURED: return False, "category_config_structured_skip" ``` 2. Re-ingestionar: ```bash python scripts/ingest_all_with_validation.py --flush ``` ### Cambiar tamaño de chunk 1. Modificar en `ChunkingPolicy.for_category()`: ```python FileCategory.CODE_PYTHON: ChunkingPolicy( strategy='ast', chunk_size=1000, # ← Cambiar de 500 ... ) ``` 2. Re-ingestionar --- ## Métricas a Monitorear Después de ingestión, validar: ```json { "indexation_rate": 0.89, // Esperado: 0.75-0.95 "total_files": 9368, // ~9K files "indexed": 8328, // ~8-9K "skipped": 1040, // Resto "avg_chunks_per_file": 4.5 // Esperado: 3-8 } ``` **Si indexation_rate < 0.75:** Revisar skip_reasons **Si avg_chunks_per_file > 15:** Posible over-chunking **Si avg_chunks_per_file < 1:** Posible under-chunking --- ## Referencias - **Documentación completa:** `docs/MATRIZ_POLITICAS_INDEXACION.md` - **Runbook:** `docs/RUNBOOK_VALIDACION_INDEXACION.md` - **Código:** `proxy/file_validator.py`, `scripts/ingest_all_with_validation.py` --- **Última actualización:** 2026-07-28