saber: lo instalado en la maquina y los docs de repos clonados entran al indice

instalado.py lee los .desktop y los paquetes para saber que hay en el equipo y
para que sirve cada cosa. indexa.py lo engancha, y con el los docs markdown de
las herramientas clonadas en CODERS. Las dos fuentes son personales: se quedan
en el indice de la maquina y no entran en el publico.

busca_cli.py expone el mismo motor que usa el cerebro (saber.busca) para
consultar el indice desde la terminal, con --n y --json.

reentrena_noche.sh encadena las fases del reentrenamiento largo y las deja
corriendo horas; cada fase es reanudable por su cuenta.

eval del indice vivo: hit@1 43/57 (75%), hit@5 55/57 (96%), sim 0.909.
This commit is contained in:
sito 2026-08-18 12:14:57 +02:00
parent b1f8118272
commit 7c5381eea7
7 changed files with 369 additions and 2 deletions

View file

@ -43,3 +43,15 @@
{"pregunta": "como escaneo redes wifi y capturo handshakes", "espera": ["airodump", "aircrack", "handshake", "wpa", "airgeddon"]}
{"pregunta": "usar crackmapexec para barrer una red windows", "espera": ["crackmapexec", "cme ", "smb", "--shares", "spray"]}
{"pregunta": "leer un hash ntlm y reutilizarlo por la red", "espera": ["ntlm", "hash", "relay", "responder", "ntlmrelayx"]}
{"pregunta": "alternativa self-hosted a google analytics", "espera": ["analytic", "plausible", "matomo", "goatcounter"]}
{"pregunta": "servidor multimedia para ver peliculas en casa", "espera": ["jellyfin", "plex", "streaming", "media"]}
{"pregunta": "gestor de contraseñas autoalojado", "espera": ["password", "vaultwarden", "bitwarden", "contrasen"]}
{"pregunta": "herramienta de linea de comandos para procesar json", "espera": ["jq", "jp", "fx", "json"]}
{"pregunta": "monitorizar los recursos del sistema en linux", "espera": ["htop", "netdata", "monitor", "glances"]}
{"pregunta": "framework de plugins para la shell zsh", "espera": ["zsh", "oh-my-zsh", "prezto", "shell"]}
{"pregunta": "agente de inteligencia artificial para pentesting automatico", "espera": ["strix", "pentest", "vulnerab"]}
{"pregunta": "programa para modelado 3d y renderizado", "espera": ["blender", "3d"]}
{"pregunta": "software para grabar y mezclar audio multipista", "espera": ["ardour", "audio"]}
{"pregunta": "herramienta para automatizar el hogar domotica", "espera": ["home", "iot", "domot", "assistant"]}
{"pregunta": "distribucion de linux para privacidad", "espera": ["tails", "privac", "linux"]}
{"pregunta": "escaner de vulnerabilidades web", "espera": ["nuclei", "nikto", "sqlmap", "scanner", "vulnerab"]}

View file

@ -0,0 +1,71 @@
#!/usr/bin/env bash
# Reentrenamiento nocturno AMPLIADO del RAG. Encadena las fases y las deja
# corriendo horas, sin tocar gitea. Cada fase es reanudable por su cuenta.
#
# ./reentrena_noche.sh
#
# Fases:
# 1. Espera a que termine cualquier reindex en curso.
# 2. Sintesis FRESCA de todo el contenido nuevo (conocimiento + catalogo +
# apps instaladas + docs de strix) -> preguntas-gancho.
# 3. Reindex personal con los ganchos horneados.
# 4. Evaluacion hit@k (numeros).
# 5. Refresco de COFRE: cosecha + sintesis de los apuntes.
# 6. Reindex final + evaluacion.
#
# Todo el ruido va al log; a la salida estandar solo hitos con hora.
set -uo pipefail
AQUI=$(cd -P "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)
NUCLEO=$(cd "$AQUI/../.." && pwd)
PY="$NUCLEO/venv/bin/python"
[ -x "$PY" ] || PY=python3
DATOS="$NUCLEO/datos"
LOG="${1:-$DATOS/reentrena_noche.log}"
hora() { date +%H:%M:%S; }
hito() { echo "[$(hora)] $*" | tee -a "$LOG"; }
cd "$NUCLEO"
hito "=== ARRANCA reentrenamiento nocturno ampliado ==="
# --- Fase 1: no competir con un reindex en curso ---
while pgrep -f "saber.indexa" | grep -qv $$ 2>/dev/null; do
sleep 20
done
hito "fase 1 ok: no hay reindex compitiendo"
# --- Fase 2: sintesis fresca del contenido nuevo ---
hito "fase 2: sintesis del catalogo+nuevo (fresca, puede tardar 1-2 h)"
rm -f "$DATOS/sintesis-catalogo.jsonl" "$DATOS/sintesis-catalogo.jsonl.hecho"
"$PY" -m saber.enriquece.sintetiza_catalogo >>"$LOG" 2>&1
hito "fase 2 ok: $(wc -l < "$DATOS/sintesis-catalogo.jsonl" 2>/dev/null) preguntas-gancho nuevas"
# --- Fase 3: reindex con los ganchos ---
hito "fase 3: reindex personal con ganchos"
"$PY" -m saber.indexa >>"$LOG" 2>&1
hito "fase 3 ok: indice reconstruido"
# --- Fase 4: evaluacion ---
hito "fase 4: evaluacion hit@k"
"$PY" -m saber.enriquece.evalua "$DATOS/saber.jsonl" "$DATOS/saber.jsonl" 2>>"$LOG" \
| grep -iE "hit@|sim" | head -3 | tee -a "$LOG"
# --- Fase 5: refresco de COFRE (cosecha + sintesis) ---
if [ "${SIN_COFRE:-0}" = "1" ]; then
hito "fase 5: OMITIDA (SIN_COFRE=1, el refresco de COFRE ya se hizo)"
else
hito "fase 5: refresco de COFRE (cosecha + sintesis, largo)"
"$PY" -m saber.enriquece.cosecha >>"$LOG" 2>&1 && hito " cosecha ok" || hito " cosecha fallo (sigo)"
rm -f "$DATOS/sintesis.jsonl.hecho"
"$PY" -m saber.enriquece.sintetiza >>"$LOG" 2>&1 && hito " sintesis COFRE ok" || hito " sintesis COFRE fallo (sigo)"
fi
# --- Fase 6: reindex final + evaluacion ---
hito "fase 6: reindex final"
"$PY" -m saber.indexa >>"$LOG" 2>&1
hito "fase 6: evaluacion final"
"$PY" -m saber.enriquece.evalua "$DATOS/saber.jsonl" "$DATOS/saber.jsonl" 2>>"$LOG" \
| grep -iE "hit@|sim" | head -3 | tee -a "$LOG"
hito "=== FIN del reentrenamiento nocturno ==="

View file

@ -61,6 +61,14 @@ def _fragmentos():
frags.append(e)
for e in awesome.entradas(): # catalogo: ya trae `publico`
frags.append(e)
for e in indexa._instalado(): # apps de esta maquina: personal
e = dict(e)
e["publico"] = False
frags.append(e)
for e in indexa._docs_extra(): # docs de strix, etc.: personal
e = dict(e)
e["publico"] = False
frags.append(e)
frags.sort(key=lambda d: (0 if d.get("publico") else 1,
0 if d.get("tipo") == "metodologia" else 1))
return frags