JARVIS: asistente de voz local para Linux
Nucleo propio: oye con whisper.cpp, piensa con un modelo de Ollama, habla con Piper, y hace RAG sobre los apuntes del usuario. 100% local, sin cuentas ni claves. Escrito bajo una restriccion dura, 4 GB de VRAM: el cerebro y whisper comparten tarjeta y solo caben porque estan dimensionados para ello. El RAG usa embeddings estaticos con busqueda hibrida; la voz clonada se sirve de una cache de frases. Incluye instalador (install.sh), requisitos, y documentacion del stack, del manejo de root y de las acciones. Los apuntes indexados y el diario NO se incluyen: son privados y el .gitignore los bloquea.
This commit is contained in:
commit
8e4bc8ad94
125 changed files with 25033 additions and 0 deletions
92
nucleo/saber/enriquece/correr_noche.sh
Executable file
92
nucleo/saber/enriquece/correr_noche.sh
Executable file
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env bash
|
||||
# El pipeline de la noche: mejora el RAG hasta nivel pentesting profesional.
|
||||
#
|
||||
# ./correr_noche.sh corre las cuatro fases y decide
|
||||
# ./correr_noche.sh --sin-promo igual, pero NO sustituye el indice vivo
|
||||
#
|
||||
# ── Que hace, en orden ─────────────────────────────────────────────────────
|
||||
#
|
||||
# 1. COSECHA rescata la metodologia de COFRE que el indexador se dejaba
|
||||
# (el OSCP_Vault entero, 0 de 72 notas estaban en el indice).
|
||||
# 2. SINTETIZA por cada fragmento, preguntas en castellano que lo encuentran.
|
||||
# Es la fase larga: horas, con el modelo local. Reanudable.
|
||||
# 3. REINDEXA une vivo + cosecha + sintesis y calcula los vectores. Escribe
|
||||
# a saber.jsonl.nuevo. NO toca el indice vivo.
|
||||
# 4. EVALUA mide recuperacion del vivo contra el candidato, con numeros.
|
||||
#
|
||||
# ── No rompe nada ──────────────────────────────────────────────────────────
|
||||
#
|
||||
# El indice vivo solo se sustituye si evalua DICE que el candidato es mejor, y
|
||||
# antes se guarda una copia con fecha. Si el candidato empeora, se queda el
|
||||
# vivo y el candidato espera revision. Reversible siempre.
|
||||
#
|
||||
# Cada fase se salta si ya esta hecha, asi que relanzarlo continua donde iba.
|
||||
set -uo pipefail
|
||||
|
||||
AQUI=$(cd -P "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)
|
||||
RAIZ=$(cd -P "$AQUI/../.." && pwd) # .../nucleo
|
||||
DATOS="$RAIZ/datos"
|
||||
PY="$RAIZ/venv/bin/python"
|
||||
[ -x "$PY" ] || PY=python3
|
||||
LOG="$DATOS/noche_rag.log"
|
||||
|
||||
# El modelo NO se fija aqui a proposito: sintetiza.py mira que tiene ollama
|
||||
# cargado y usa ESE, para no forzar cambios en la tarjeta de 4 GB. Si el verde
|
||||
# esta abierto, generara con el verde; si no, cae al naranja. Solo se fuerza si
|
||||
# exportas JARVIS_MODELO tu. Aun asi, para la noche mas rapida y limpia, lo
|
||||
# suyo es cerrar el TUI verde: con un solo modelo ollama no recarga nada.
|
||||
|
||||
PROMO=si
|
||||
[ "${1:-}" = "--sin-promo" ] && PROMO=no
|
||||
|
||||
fecha() { date '+%Y-%m-%d %H:%M:%S'; }
|
||||
fase() { echo "" | tee -a "$LOG"; echo "[$(fecha)] === FASE $* ===" | tee -a "$LOG"; }
|
||||
|
||||
echo "[$(fecha)] arranca el pipeline de la noche (modelo $JARVIS_MODELO)" | tee -a "$LOG"
|
||||
|
||||
# ── 1. COSECHA ─────────────────────────────────────────────────────────────
|
||||
fase "1/4 COSECHA"
|
||||
if [ -s "$DATOS/cosecha.jsonl" ]; then
|
||||
echo " ya hecha ($(wc -l <"$DATOS/cosecha.jsonl") fragmentos), se salta" | tee -a "$LOG"
|
||||
else
|
||||
"$PY" "$AQUI/cosecha.py" 2>&1 | tee -a "$LOG"
|
||||
fi
|
||||
|
||||
# ── 2. SINTETIZA (la larga) ────────────────────────────────────────────────
|
||||
fase "2/4 SINTETIZA (horas; reanudable)"
|
||||
# hecha del todo = el .hecho llego al ultimo fragmento
|
||||
TOTAL=$(wc -l <"$DATOS/cosecha.jsonl")
|
||||
HECHO=$(cat "$DATOS/sintesis.jsonl.hecho" 2>/dev/null || echo -1)
|
||||
if [ "$HECHO" -ge "$((TOTAL - 1))" ] 2>/dev/null; then
|
||||
echo " ya completa ($(wc -l <"$DATOS/sintesis.jsonl" 2>/dev/null || echo 0) preguntas)" | tee -a "$LOG"
|
||||
else
|
||||
"$PY" "$AQUI/sintetiza.py" 2>&1 | tee -a "$LOG"
|
||||
fi
|
||||
|
||||
# ── 3. REINDEXA ────────────────────────────────────────────────────────────
|
||||
fase "3/4 REINDEXA"
|
||||
"$PY" "$AQUI/reindexa.py" 2>&1 | tee -a "$LOG"
|
||||
|
||||
# ── 4. EVALUA ──────────────────────────────────────────────────────────────
|
||||
fase "4/4 EVALUA"
|
||||
INFORME="$DATOS/informe_rag.txt"
|
||||
"$PY" "$AQUI/evalua.py" 2>&1 | tee "$INFORME" | tee -a "$LOG"
|
||||
VEREDICTO=$(grep -oE 'VEREDICTO (PROMOCIONAR|MANTENER)' "$INFORME" | awk '{print $2}' | tail -1)
|
||||
|
||||
# ── Decision ───────────────────────────────────────────────────────────────
|
||||
fase "DECISION"
|
||||
if [ "$PROMO" = no ]; then
|
||||
echo " --sin-promo: dejo el candidato en saber.jsonl.nuevo sin tocar el vivo" | tee -a "$LOG"
|
||||
elif [ "$VEREDICTO" = PROMOCIONAR ]; then
|
||||
COPIA="$DATOS/saber.jsonl.antes-$(date +%Y%m%d-%H%M)"
|
||||
cp "$DATOS/saber.jsonl" "$COPIA"
|
||||
mv "$DATOS/saber.jsonl.nuevo" "$DATOS/saber.jsonl"
|
||||
echo " PROMOCIONADO. El candidato es mejor y ya es el indice vivo." | tee -a "$LOG"
|
||||
echo " copia del anterior: $COPIA" | tee -a "$LOG"
|
||||
echo " para deshacer: cp '$COPIA' '$DATOS/saber.jsonl'" | tee -a "$LOG"
|
||||
else
|
||||
echo " MANTENIDO el vivo: el candidato no mejora la evaluacion." | tee -a "$LOG"
|
||||
echo " candidato en saber.jsonl.nuevo e informe en informe_rag.txt para revisar." | tee -a "$LOG"
|
||||
fi
|
||||
|
||||
echo "[$(fecha)] pipeline terminado" | tee -a "$LOG"
|
||||
Loading…
Add table
Add a link
Reference in a new issue