Rama JARVIS-GREEN, independiente de master (el nucleo naranja queda intacto). - README propio del carril verde con diagrama de arquitectura y capturas del panel. - verde/: arranque, panel web, puente de voz (escucha local con faster-whisper + habla con la voz del naranja), pruebas (07 voz, 08 escucha), config y notas. - Integracion RAG: nucleo/saber/busca_cli.py + skill buscar-en-apuntes, para que el agente consulte el mismo indice que el nucleo. - Todo local (127.0.0.1); sin datos personales (rutas y modelo de GPU scrubeados).
865 lines
38 KiB
Markdown
865 lines
38 KiB
Markdown
# Notas del carril verde
|
|
|
|
Lo medido, lo resuelto y lo que queda abierto.
|
|
|
|
Fechas: 15 de agosto de 2026 (instalación, en frío) y **16 de agosto (primer
|
|
arranque real)**. Lo de la primera fecha salía de leer código y mirar el disco;
|
|
lo de la segunda está ejecutado.
|
|
|
|
## EL SUELO DE 64k: el tope que invalidó la medida anterior (16 ago)
|
|
|
|
*(Esto va primero porque cambia la conclusión de la sección siguiente.)*
|
|
|
|
`arrancar.sh` midió bien: **24576 era el mayor contexto que cabía** en la GPU
|
|
con las 32 capas en la tarjeta, 3301 MiB, y con eso el modelo emitía `tool_calls`
|
|
válidos. Todo correcto y todo inútil, porque al abrir Hermes:
|
|
|
|
```
|
|
Model qwen3.5:4b-verde has a context window of 24,576 tokens, which is below
|
|
the minimum 64,000 required by Hermes Agent.
|
|
```
|
|
|
|
Es un **tope duro del arnés**, no un aviso: `agent/model_metadata.py:405`,
|
|
`MINIMUM_CONTEXT_LENGTH = 64_000`, comprobado en `agent/agent_init.py:2656`.
|
|
No se ve en frío — `hermes prompt-size` no lo menciona — y solo salta al
|
|
construir el agente.
|
|
|
|
### Las dos salidas que se descartaron, y por qué
|
|
|
|
1. **La puerta de atrás de `lmstudio`.** El mismo `if` se salta si
|
|
`provider == "lmstudio"` y `context_length` está puesto a mano. No se usa: ese
|
|
proveedor llama a `{server}/api/v1/models`, la API **nativa de LM Studio**,
|
|
que ollama no tiene, y además intenta precargar el modelo por su cuenta
|
|
(`ensure_lmstudio_model_loaded`). Fingir ser otro servidor rompería más
|
|
adelante y de forma más confusa.
|
|
2. **Mentir en el `config.yaml`** poniendo 64000 con el modelo a 24576. Es la
|
|
peor de las tres: Hermes creería tener 64k, **no comprimiría** hasta
|
|
acercarse, y ollama iría tirando los tokens más viejos — que son el prompt de
|
|
sistema y los esquemas de las 19 herramientas. El síntoma sería que el agente
|
|
deja de llamar herramientas a mitad de sesión, **sin un solo error en el log**.
|
|
|
|
### Lo que se hizo: subir el contexto de verdad y pagar capas
|
|
|
|
Con `num_ctx 65536` fijo, medido el 16 de agosto:
|
|
|
|
| `num_gpu` | Resultado | En tarjeta | Total |
|
|
|---|---|---|---|
|
|
| 32 | `cudaMalloc failed` | — | — |
|
|
| 24 | `cudaMalloc failed` | — | — |
|
|
| **16** | **carga** | **2795 MiB** | 5784 MiB |
|
|
| 8 | carga | 1772 MiB | 5784 MiB |
|
|
| 0 | carga | 0 MiB | 5368 MiB |
|
|
|
|
O sea que 64k **sí cabe en esta máquina**, pero con **la mitad de la red en la
|
|
CPU** y unos 3 GB en RAM. Lo que eso cuesta en tiempo está más abajo, en
|
|
"Cuánto tarda de verdad".
|
|
|
|
La palanca para recuperar capas —`OLLAMA_FLASH_ATTENTION=1` +
|
|
`OLLAMA_KV_CACHE_TYPE=q8_0`, que parte el KV caché por la mitad— **sigue sin
|
|
aplicarse**: es del servicio de ollama, no del modelo, y afectaría también al
|
|
naranja. Esa decisión es del usuario.
|
|
|
|
**Lección de método**, que es la misma que ya aparece dos veces en este fichero:
|
|
se midió a fondo el límite de la *máquina* y no se comprobó el límite del
|
|
*software que iba encima*. Los dos son topes; solo uno se estaba mirando.
|
|
|
|
## Cuánto tarda de verdad (16 ago)
|
|
|
|
Medido con `hermes -z`, que es una pregunta y a callar, contra el modelo a
|
|
`num_ctx 65536` con 16 de 32 capas en GPU.
|
|
|
|
| Escalón | Vueltas | Tiempo |
|
|
|---|---|---|
|
|
| 1 · "hola, ¿quién eres?" — **en frío** | 0 herramientas | **2 min 38 s** |
|
|
| 2 · "¿cuánto espacio libre queda?" | 1 herramienta | **48,6 s** |
|
|
| 3 · "lee verde/README.md y resúmelo" | 4 (dos fallidas + recuperación) | **3 min 29 s** |
|
|
| 3 bis · igual, con `terminal.cwd` arreglado | 1 | **1 min 58 s** |
|
|
| 3 ter · igual, ya con `AGENTS.md` | 2 (una fallida + recuperación) | **4 min 54 s** |
|
|
| 4 · "cuál de los .md de verde/ es el más largo" | 4 encadenadas | **3 min 54 s** |
|
|
| 5 · "un cartel en arte ascii que ponga JARVIS" | 3 (una salió a la red) | **4 min 58 s** |
|
|
| 6 · "di en voz alta…" | 1 (`text_to_speech`) | **3 min 37 s** |
|
|
| *(pwd suelto, caché caliente, una llamada)* | 1 | **13,2 s** |
|
|
|
|
**Esa diferencia de tres veces no es ruido, y es lo más útil que se midió.** El
|
|
primer turno paga el prefill entero de los ~20.500 tokens del prompt fijo con
|
|
media red en la CPU. A partir de ahí, ollama **cachea el prefijo** y las vueltas
|
|
siguientes solo procesan lo nuevo — y eso que la 2 hace *dos* llamadas al modelo
|
|
(pedir la herramienta y redactar con su resultado) y aun así tarda un tercio.
|
|
|
|
O sea que la cifra que importa para decidir si esto se usa **no es la del primer
|
|
arranque**. Es la de régimen. Igual que la primera transcripción de whisper
|
|
tarda ~4 s por arrancar el servidor y luego se queda en ~930 ms.
|
|
|
|
El escalón 2 acertó, además: `663G` libres de `1,9T` al `63 %`, que es
|
|
exactamente lo que dice `df -h /`.
|
|
|
|
**Y el 3 enseñó algo que no se estaba buscando.** Falló dos veces seguidas —
|
|
partió mal la frase y pidió `cat ~/lee-verde/README.md`, que no
|
|
existe— y en vez de inventarse una respuesta cambió de estrategia: `search_files`
|
|
para localizar el fichero, y `read_file` con la ruta absoluta ya correcta. El
|
|
resumen final es fiel al README.
|
|
|
|
Eso es exactamente lo que se venía a probar de este carril: **recuperarse de una
|
|
herramienta que devuelve error**. El núcleo naranja, con sus acciones rápidas, o
|
|
acierta a la primera o no hay segunda. Las dos vueltas de más son las que
|
|
explican los 3 min 29 s.
|
|
|
|
### El punto flaco del 4B: las rutas relativas
|
|
|
|
Con `terminal.cwd` ya arreglado se repitió el escalón 3, y salió **peor**:
|
|
**1 min 58 s** y una sola llamada, `read_file` sobre
|
|
`COFRE/CODERS/JARVIS/README.md`. **Se comió el `verde/`.** Resumió el README de
|
|
la raíz —el del proyecto entero— con un "JARVES" de propina y la frase cortada a
|
|
medias.
|
|
|
|
La comparación entre las dos pasadas es lo interesante:
|
|
|
|
| | Ruta base | Qué hizo | Resultado |
|
|
|---|---|---|---|
|
|
| Con `cwd` en `$HOME` | mal | falló, buscó, se corrigió | **acertó** |
|
|
| Con `cwd` en el repo | bien | fue directo a una ruta plausible | **falló** |
|
|
|
|
O sea: **cuando la herramienta le devuelve un error, se recupera; cuando le
|
|
devuelve un fichero que existe pero no es el pedido, no tiene forma de notarlo**
|
|
y lo resume tan campante. Es el mismo patrón del error de `~/README.md`,
|
|
y la razón de que estos fallos no se vean: no hay error que mirar.
|
|
|
|
Lo que apunta a la mejora obvia si este carril sigue adelante: un `AGENTS.md` en
|
|
la raíz del repo describiendo la disposición de carpetas. Hermes ya carga
|
|
ficheros de contexto, así que el sitio está.
|
|
|
|
#### Escrito el `AGENTS.md`, el escalón 3 pasa — pero no por lo que parece
|
|
|
|
Se escribió (`<raíz>/AGENTS.md`: los tres carriles, el árbol de carpetas y la
|
|
regla de que las rutas relativas salen de la raíz del repo). Cuesta **2.490 B**
|
|
del prompt fijo, que sube a 84.740 B ≈ **21.185 tokens** de los 65.536: quedan
|
|
44.351 para conversar.
|
|
|
|
Tercera pasada del escalón 3, **4 min 54 s**, y el resumen es del fichero
|
|
correcto por fin. Recoge incluso el aviso de la fuga a internet que se añadió
|
|
hoy al README.
|
|
|
|
**Pero el modelo volvió a alucinar la ruta.** Su primera llamada fue
|
|
|
|
read_file ~/COFRE/CODERS/JARVIS-verde/zapier-connection.py
|
|
|
|
que no existe y no se parece a nada de lo pedido. Recibió `File not found` y
|
|
**entonces** acertó con `JARVIS/verde/README.md`.
|
|
|
|
O sea que el `AGENTS.md` **no evitó el disparate; le dio con qué recuperarse**.
|
|
Es la tercera vez que sale el mismo patrón en esta sesión y ya no es anécdota:
|
|
|
|
| Lo que recibe la herramienta | Qué hace el 4B |
|
|
|---|---|
|
|
| Un **error** | cambia de estrategia y suele acertar |
|
|
| Un fichero **que existe pero no es** | lo resume tan contento |
|
|
|
|
La lección práctica para este carril: **más vale una ruta que falle que una que
|
|
acierte por accidente.** Y en la prosa sigue descuidado — aquí se inventó un
|
|
"98 % local", llamó API de terceros a `pyfiglet` (que es una librería local; la
|
|
API era `asciified.thelicato.io`) y le dio la vuelta a la frase del objetivo.
|
|
|
|
### El escalón 4, que era el que decidía: **pasa**
|
|
|
|
*"dime cuál de los .md de la carpeta verde/ es el más largo"* — **3 min 54 s**,
|
|
cuatro llamadas encadenadas, respuesta correcta:
|
|
|
|
| # | Llamada | Qué pasó |
|
|
|---|---|---|
|
|
| 1 | `search_files` con `pattern: "*.md"` | `rg: regex parse error` |
|
|
| 2 | `search_files` con `pattern: "\\.md$"` | **corrigió el patrón él solo** |
|
|
| 3 | `terminal`: `find … -name "*.md"` | los cinco ficheros |
|
|
| 4 | `terminal`: bucle con `wc -l` sobre cada uno | las cinco cifras |
|
|
|
|
Y concluyó: `verde/NOTAS.md` con 625 líneas. Es el correcto.
|
|
|
|
**Esto es lo que justificaba el carril entero.** No hay una herramienta que
|
|
conteste esa pregunta: hay que listar, medir y razonar sobre el resultado de la
|
|
vuelta anterior, y saber cuándo parar. El núcleo naranja no puede hacerlo — sus
|
|
150 acciones rápidas o aciertan a la primera o no hay segunda.
|
|
|
|
La letra pequeña, que no cambia el veredicto pero conviene tener escrita: al
|
|
enumerar los ficheros los ordenó mal (puso PLAN-ARRANQUE con 181 por encima de
|
|
ESCALERA con 208) y etiquetó el README de `verde/` como *"categoría raíz"*. O
|
|
sea que **el razonamiento de la cadena es bueno y la prosa de alrededor es
|
|
descuidada**. Para una orden hablada da igual; para un informe, no.
|
|
|
|
## EL BLOQUEO DEL ARRANQUE: no cabe la pregunta
|
|
|
|
*(15 ago, tarde. Esto es lo más importante del fichero.)*
|
|
|
|
Se preparó el primer arranque y apareció un tope que no era el que se
|
|
anticipaba. **No es que `qwen3.5:4b` no sepa llamar herramientas: es que no le
|
|
cabe la pregunta.** Medido con `hermes prompt-size`:
|
|
|
|
| | |
|
|
|---|---|
|
|
| Prompt de sistema de Hermes | 26.281 B |
|
|
| Esquemas de las 19 herramientas | 55.978 B |
|
|
| **Fijo, antes de decir nada** | **82.259 B ≈ 20.500 tokens** |
|
|
| `num_ctx` de `qwen3.5:4b-jarvis` | **4.096** |
|
|
|
|
Cinco veces por encima. Y hay un segundo tope escondido: **`num_predict 300`,
|
|
que el naranja hereda del modelo BASE** (no lo pone su Modelfile). 300 tokens
|
|
cortan el JSON de una llamada a herramienta por la mitad.
|
|
|
|
Los dos están **bien puestos para el naranja** —respuestas habladas cortas, VRAM
|
|
para whisper— y son justo lo contrario de lo que pide un arnés agéntico.
|
|
|
|
Y encima, la trampa que avisaba la documentación: `/api/show` reporta
|
|
`qwen35.context_length = 262144`, el máximo del modelo, **no** los 4096
|
|
configurados. Hermes se habría creído que tenía 262k. El síntoma habría sido
|
|
respuestas truncadas y llamadas rotas, y la conclusión natural —"el 4B no vale
|
|
para esto"— **habría sido falsa**.
|
|
|
|
### La variante verde, ya creada
|
|
|
|
`verde/qwen3.5-4b-verde.Modelfile` → `ollama create qwen3.5:4b-verde`.
|
|
**`qwen3.5:4b-jarvis` no se tocó.**
|
|
|
|
| Parámetro | Valor | Por qué |
|
|
|---|---|---|
|
|
| `num_gpu` | 32 | todas las capas, con el naranja cerrado |
|
|
| `num_ctx` | 24576 | 32768 no cabe (ver abajo) |
|
|
| `num_predict` | 4096 | 300 cortaría una tool call |
|
|
| `temperature` | 0.2 | emitir JSON no es escribir prosa |
|
|
|
|
**Trampa del Modelfile:** ollama **no admite comentarios en la misma línea** que
|
|
un `PARAMETER`. Esto falla:
|
|
|
|
```
|
|
PARAMETER num_gpu 32 # todas las capas
|
|
→ Error: invalid int value [32 # todas las capas]
|
|
```
|
|
|
|
Los comentarios van en su propia línea.
|
|
|
|
### Lo medido de VRAM
|
|
|
|
| Configuración | Resultado |
|
|
|---|---|
|
|
| `num_ctx 32768`, 32 capas | **`cudaMalloc failed: out of memory`** |
|
|
| `num_ctx 24576`, 32 capas | **pendiente**: hay que medirlo con la tarjeta libre |
|
|
|
|
Escalera si 24576 tampoco entra, en orden de menos a más invasivo: `num_ctx
|
|
16384` (el suelo: por debajo no cabe el prompt fijo con holgura) → `num_gpu 24`
|
|
→ `OLLAMA_FLASH_ATTENTION=1` + `OLLAMA_KV_CACHE_TYPE=q8_0`.
|
|
|
|
**Cuidado con el último:** `OLLAMA_KV_CACHE_TYPE` es del **servicio**, no del
|
|
modelo. Se pone en el systemd de ollama y **afectaría también al naranja** la
|
|
próxima vez que arranque. Si se usa, hay que anotarlo aquí y en el Modelfile del
|
|
naranja.
|
|
|
|
### Desde dónde se lanza importa, y mucho
|
|
|
|
| Directorio de arranque | Prompt de sistema |
|
|
|---|---|
|
|
| `~/COFRE/CODERS/JARVIS` | 26.281 B |
|
|
| `~/.hermes/hermes-agent` | **55.261 B** |
|
|
|
|
La diferencia son 30 KB: el `AGENTS.md` de 81 KB del **propio repo de Hermes**,
|
|
que se cuela como fichero de contexto y encima sale truncado con un aviso. A
|
|
mano es fácil olvidarlo y sacar medidas que no comparan nada.
|
|
|
|
### Y el `cd` NO basta (16 ago)
|
|
|
|
Esto se descubrió subiendo la escalera y es peor que lo anterior, porque **no
|
|
deja ni un error**. `verde-launcher.sh` hacía `cd "$RAIZ"` antes de llamar a
|
|
Hermes, que parece suficiente y no lo es: **Hermes restaura el directorio de
|
|
trabajo apuntado en la sesión** y se salta aquel desde el que lo lanzas.
|
|
|
|
El síntoma: se le pide *"lee verde/README.md y resúmelo en una línea"* y
|
|
devuelve
|
|
|
|
> **Gitleaks es una herramienta SAST diseñada para detectar y prevenir secretos
|
|
> codificados a mano en repositorios git.**
|
|
|
|
Parece el modelo alucinando de manera espectacular. No lo es. En la base de
|
|
sesiones se ve la llamada real:
|
|
|
|
```
|
|
terminal {"command": "cat ~/README.md | head -50"}
|
|
```
|
|
|
|
Resolvió `verde/README.md` contra `~`, ahí hay un `README.md` que es el
|
|
de Gitleaks, lo leyó entero y lo resumió **bien**. La herramienta funcionó, el
|
|
modelo entendió, el resumen es correcto — y la respuesta es inútil.
|
|
|
|
### Lo que NO lo arregla, probado
|
|
|
|
**`--in DIR` no vale en modo `-z`.** Parece la bandera exacta —entra en el
|
|
directorio *y* se salta la restauración, mientras que `--no-restore-cwd` solo
|
|
hace lo segundo— y con ella el fallo se repitió igual. El motivo está en
|
|
`hermes_cli/main.py:11324`: el modo de una sola pregunta sale por
|
|
`_run_and_exit_oneshot(...)` y **termina el proceso ahí**, sin llegar nunca a
|
|
`cmd_chat`, que es la única función donde se atiende `--in`. Se ignora en
|
|
silencio. En el TUI sí funciona, y por eso `verde-launcher.sh` la pasa.
|
|
|
|
**Un `cd` delante tampoco.** Comprobado del modo más directo posible:
|
|
|
|
```
|
|
pwd del shell : ~/COFRE/CODERS/JARVIS
|
|
pwd del agente : ~
|
|
```
|
|
|
|
Y no es que el modelo se lo invente: el `ls -d */` que ejecutó por su cuenta
|
|
devolvió `BIKEPARK/ COFRE/ ctf/ Downloads/…`, o sea el `$HOME` de verdad.
|
|
|
|
### Lo que sí lo arregla
|
|
|
|
`terminal.cwd` en `~/.hermes/config.yaml`, que de fábrica viene como `"."` y
|
|
que su propia documentación describe como *"el directorio actual donde ejecutas
|
|
hermes"*. **No lo es.**
|
|
|
|
```yaml
|
|
terminal:
|
|
cwd: "~/COFRE/CODERS/JARVIS"
|
|
```
|
|
|
|
Verificado: con eso el prompt de sistema pasa a decir
|
|
`working directory: ~/COFRE/CODERS/JARVIS`. Está replicado en
|
|
`verde/config.yaml` y lo comprueba `pruebas/03_config.sh`.
|
|
|
|
**Ojo, que esto ATA el carril a este repositorio.** Es lo correcto para un banco
|
|
de pruebas que se compara contra el naranja, y es una limitación real si algún
|
|
día se quiere que el verde mire `~/BIKEPARK` o `~/oasis`. Con la raíz en `$HOME`
|
|
además se ahoga: un `search_files` de `*.md` devolvía sobre todo
|
|
`site-packages/` de los venv de `entrena/`.
|
|
|
|
**Cómo se diagnosticó, que es reutilizable:** `-z` imprime solo el texto final,
|
|
sin las llamadas a herramienta, así que desde fuera no se ve nada. Todo queda en
|
|
`~/.hermes/state.db`, tabla `messages`, columnas `tool_calls` y `content`:
|
|
|
|
```bash
|
|
python3 -c "
|
|
import sqlite3
|
|
c = sqlite3.connect('file:$HOME/.hermes/state.db?mode=ro', uri=True)
|
|
for r in c.execute('SELECT role, tool_name, tool_calls, content FROM messages ORDER BY rowid DESC LIMIT 10'):
|
|
print(r)
|
|
"
|
|
```
|
|
|
|
Sin mirar ahí, este fallo se atribuye al modelo y se acaba cambiando de modelo
|
|
para nada.
|
|
|
|
## Por qué se paró: `dataset.py`
|
|
|
|
El arranque en GPU quedó **aplazado**, no descartado. La gráfica la tiene un
|
|
trabajo tuyo: `JARVIS/entrena/dataset.py`, que genera pares pregunta-respuesta
|
|
de COFRE con `qwen3.5:4b-jarvis`. Son **7-10 horas** (tu propio README lo dice) y
|
|
va por `100/2261 fragmentos`.
|
|
|
|
Detalle que confunde y conviene tener escrito: mientras ese script corra,
|
|
`ollama stop qwen3.5:4b-jarvis` **parece no funcionar**. Sí funciona — descarga
|
|
el modelo — pero la siguiente petición del script lo vuelve a cargar en
|
|
segundos. No es un fallo de ollama.
|
|
|
|
Comprobado que los `ollama stop` **no rompieron** la generación: siguió de 199 a
|
|
224 ejemplos en 75 s.
|
|
|
|
### Retomar cuando termine
|
|
|
|
```bash
|
|
# 1. confirmar que dataset.py acabó y la tarjeta está libre
|
|
pgrep -f 'entrena/dataset.py' || echo "terminado"
|
|
nvidia-smi --query-gpu=memory.used --format=csv,noheader # ~140 MiB
|
|
|
|
# 2. medir si 24576 cabe
|
|
curl -s http://127.0.0.1:11434/v1/chat/completions -H 'Content-Type: application/json' \
|
|
-d '{"model":"qwen3.5:4b-verde","messages":[{"role":"user","content":"ok"}],"max_tokens":5}'
|
|
curl -s http://127.0.0.1:11434/api/ps | python3 -m json.tool | grep -E 'size_vram|context_length'
|
|
|
|
# 3. decirle a Hermes el contexto REAL (si no, cree que son 262144)
|
|
# en ~/.hermes/config.yaml, bloque model:, en las lineas canonicas (~82/~95)
|
|
# default: "qwen3.5:4b-verde"
|
|
# context_length: 24576
|
|
|
|
# 4. LA PRUEBA DECISIVA, antes de abrir el TUI: ¿emite tool_calls?
|
|
curl -s http://127.0.0.1:11434/v1/chat/completions -H 'Content-Type: application/json' -d '{
|
|
"model":"qwen3.5:4b-verde",
|
|
"messages":[{"role":"user","content":"¿Cuánto espacio libre queda en el disco?"}],
|
|
"tools":[{"type":"function","function":{"name":"ejecuta_comando",
|
|
"description":"Ejecuta un comando de shell",
|
|
"parameters":{"type":"object","properties":{"comando":{"type":"string"}},"required":["comando"]}}}]}' \
|
|
| python3 -m json.tool
|
|
```
|
|
|
|
El paso 4 separa dos preguntas que juntas se contestan mal: *¿sabe el modelo
|
|
emitir una llamada?* y *¿funciona Hermes?*. Si sale `tool_calls` con JSON
|
|
válido, lo que falle después es de Hermes. Si contesta en prosa, abrir el TUI
|
|
solo daría un fallo más confuso.
|
|
|
|
Después, la escalera del plan: "hola" → una herramienta → ficheros → **varias
|
|
vueltas encadenadas** (el escalón que separa un chatbot de un agente) → skills.
|
|
La voz al final, y la escucha la última de todas: los 839 MiB de pico de whisper
|
|
contra una tarjeta que tendrá el modelo casi entero.
|
|
|
|
## Estado de la gráfica
|
|
|
|
| | VRAM | Quién |
|
|
|---|---|---|
|
|
| Antes de instalar | 878 MiB de 4096 | tres `whisper-server` tuyos, del naranja |
|
|
| Después de instalar | **127 MiB de 4096** | nadie; tus whisper acabaron solos |
|
|
|
|
Instalar **no cargó nada** en la tarjeta. Comprobado con
|
|
`nvidia-smi --query-compute-apps` y con `/api/ps` de Ollama, que devolvió
|
|
`{"models": []}` en todo momento.
|
|
|
|
De paso, un dato que puede interesarte del naranja: llegaste a tener **tres
|
|
`whisper-server` a la vez**, ~880 MiB cada uno, 2648 MiB en total sobre una
|
|
tarjeta de 4096. Es el escenario exacto del `CUDA error: out of memory` que
|
|
documenta el README. No hice nada al respecto —es tu desarrollo en marcha— pero
|
|
queda anotado.
|
|
|
|
## Verificación en frío, ejecutada
|
|
|
|
| Comprobación | Resultado |
|
|
|---|---|
|
|
| `hermes` en PATH | `~/.local/bin/hermes` |
|
|
| Tamaño de `~/.hermes` | 2,2 GB |
|
|
| Caché de Playwright | 622 MB |
|
|
| Credenciales con valor en `.env` | **0** |
|
|
| Tokens de mensajería | **0** (por eso el gateway nunca arrancó) |
|
|
| URLs de nube activas en `config.yaml` | **0** |
|
|
| Puertos fuera de loopback | **ninguno** |
|
|
| Modelos cargados en Ollama | ninguno |
|
|
| Puente de voz | **funciona**: 0,34 s para 3,2 s de audio, 22050 Hz mono |
|
|
|
|
Las 11 líneas con contenido del `.env` no son claves: son `TERMINAL_TIMEOUT`,
|
|
`BROWSER_SESSION_TIMEOUT`, banderas de depuración y similares.
|
|
|
|
## Trampa: claves YAML duplicadas en config.yaml
|
|
|
|
**Esto casi cuela y merece quedar escrito.** El `config.yaml` que genera el
|
|
instalador declara `provider` y `base_url` **dos veces** dentro del bloque
|
|
`model:`: una arriba, junto a `default`, y otra ~45 líneas más abajo. En YAML la
|
|
última repetición gana.
|
|
|
|
Al configurar Ollama arriba, el fichero *parecía* correcto leyéndolo, y al
|
|
parsearlo salía esto:
|
|
|
|
```
|
|
model.provider: auto
|
|
model.base_url: https://openrouter.ai/api/v1
|
|
```
|
|
|
|
Es decir: el carril habría salido **por OpenRouter** creyendo yo que iba a
|
|
localhost. Se arregló dejando los valores solo en las líneas de abajo, las
|
|
canónicas.
|
|
|
|
**La lección, que vale para todo este fichero:** con 1890 líneas y 121 activas,
|
|
no basta con leerlo. Hay que parsearlo:
|
|
|
|
```bash
|
|
python3 -c "import yaml;d=yaml.safe_load(open('$HOME/.hermes/config.yaml'));print(d['model'])"
|
|
```
|
|
|
|
## Trampa: la instalación de Chromium se cuelga
|
|
|
|
Le pasa a más gente (issue #35166 del repo). El zip se descarga entero y la
|
|
**extracción se queda parada**: 50 minutos de reloj con 1 segundo de CPU y cero
|
|
crecimiento en `~/.cache/ms-playwright/`. El `timeout` del instalador mata al
|
|
padre y deja procesos huérfanos reteniendo un `__dirlock`, así que el reintento
|
|
también falla.
|
|
|
|
Se resolvió a mano, y si vuelve a pasar tras un `hermes update`, esta es la
|
|
receta:
|
|
|
|
```bash
|
|
pkill -f oopDownloadBrowserMain; pkill -f 'playwright install'
|
|
rm -rf ~/.cache/ms-playwright/chromium-1208 ~/.cache/ms-playwright/__dirlock
|
|
mkdir -p ~/.cache/ms-playwright/chromium-1208
|
|
unzip -q /tmp/playwright-download-*/playwright-download-chromium-*.zip \
|
|
-d ~/.cache/ms-playwright/chromium-1208/
|
|
touch ~/.cache/ms-playwright/chromium-1208/INSTALLATION_COMPLETE
|
|
```
|
|
|
|
El `INSTALLATION_COMPLETE` es lo que Playwright mira para dar el navegador por
|
|
bueno (`lib/server/registry/index.js:1345`). Sin él lo reinstala cada vez.
|
|
|
|
Quedaron los tres componentes, verificados con `playwright install --dry-run`:
|
|
|
|
| | Tamaño |
|
|
|---|---|
|
|
| `chromium-1208` | 364 MB |
|
|
| `chromium_headless_shell-1208` | 254 MB |
|
|
| `ffmpeg-1011` | 4,9 MB |
|
|
|
|
El binario responde: `Google Chrome for Testing 145.0.7632.6`.
|
|
|
|
## Resuelto: tu voz afinada SÍ se puede reutilizar
|
|
|
|
Era la pregunta abierta del plan, y salió el mejor de los tres desenlaces.
|
|
|
|
**Hermes tiene un proveedor de TTS por comando que no está documentado en su
|
|
web.** Está en `tools/tts_tool.py`, bloque *"Custom command providers"*:
|
|
|
|
```yaml
|
|
tts:
|
|
provider: mi-voz
|
|
providers:
|
|
mi-voz:
|
|
type: command
|
|
command: "... {output_path} {input_path}"
|
|
output_format: wav
|
|
```
|
|
|
|
Marcadores: `{input_path}`, `{text_path}`, `{output_path}`, `{format}`,
|
|
`{voice}`, `{model}`, `{speed}`. Ejecuta con `shell=True`.
|
|
|
|
Eso permite llamar al mismo `config/jarvis-piper.sh` que usa el naranja, así que
|
|
**el verde suena exactamente igual**: mismo binario Piper 1.2.0, mismo `.onnx`,
|
|
misma cadena de audio. Sin esto la comparación de voz entre carriles no habría
|
|
valido nada.
|
|
|
|
Dos detalles que obligaron a escribir `voz-verde.sh` en vez de meter el comando
|
|
directo en el YAML:
|
|
|
|
1. **El entorno se limpia.** `_run_command_tts` llama a
|
|
`hermes_subprocess_env(inherit_credentials=False)`, así que
|
|
`JARVIS_PIPER_VOZ` y `JARVIS_PIPER_TONO` no llegarían. Se ponen dentro del
|
|
adaptador.
|
|
2. **Las interfaces no encajan.** `jarvis-piper.sh` quiere el texto como
|
|
argumento; Hermes entrega un fichero. El adaptador hace de puente.
|
|
|
|
### Qué voz, y ojo con el README
|
|
|
|
`voz-verde.sh` usa **davefx a tono 1.0**, que es lo que tiene el núcleo hoy
|
|
(`nucleo/boca/voz.py`: `POR_DEFECTO = "davefx"`, `JARVIS_PIPER_TONO = "1.0"`).
|
|
|
|
El `README.md` del repo describe `sharvard` + 0,86 = 106 Hz como *"la puesta"*.
|
|
Eso era el JARVIS sobre Newelle. **El verde copia al núcleo, que es contra quien
|
|
se va a comparar, no al README.** Si algún día el núcleo vuelve a sharvard, hay
|
|
que cambiarlo aquí también.
|
|
|
|
### De paso: el Piper de Hermes es el GPL, no el tuyo
|
|
|
|
El proveedor `piper` de serie usa `OHF-Voice/piper1-gpl` (GPL-3.0). El tuyo es
|
|
el original `rhasspy/piper` 1.2.0, **MIT**, archivado en octubre de 2025. Los dos
|
|
son software libre; no son el mismo paquete. Como usamos el comando y no el
|
|
proveedor de serie, el verde habla con **tu** Piper MIT.
|
|
|
|
## El cerebro: lo que hay que vigilar
|
|
|
|
Configurado como proveedor `custom` contra `http://127.0.0.1:11434/v1` con
|
|
`qwen3.5:4b-jarvis`. Ollama ya habla OpenAI, no hace falta puente.
|
|
|
|
**Pero la propia guía de Hermes avisa de algo que hay que probar.** Su tabla de
|
|
modelos locales dice, literalmente, que para trabajo agéntico completo hace
|
|
falta `gemma4:31b`, y marca *sin* tool calling a todo lo de 9B para abajo:
|
|
|
|
| Modelo (su tabla) | Tool calling |
|
|
|---|---|
|
|
| `gemma4:31b` | Sí |
|
|
| `gemma2:27b` | No |
|
|
| `gemma2:9b` | No |
|
|
| `llama3.2:3b` | No |
|
|
|
|
Su tabla no lista qwen3.5, que **sí** hace tool calling — el commit
|
|
*"nucleo: el cerebro con tool calling nativo"* lo demuestra. Pero lo demuestra
|
|
**en tu arnés**, no en el de Hermes, que inyecta muchas más definiciones de
|
|
herramientas por vuelta. Así que:
|
|
|
|
- Es lo primero que hay que comprobar al arrancar: si el 4B llama herramientas
|
|
bien dentro de Hermes o se atraganta.
|
|
- Si se atraganta, esta máquina tiene **62 GB de RAM**: un modelo grande cabe,
|
|
aunque iría por CPU (~2-5 tok/s según su guía, 30-120 s por respuesta). Para
|
|
eso está `HERMES_API_TIMEOUT=1800` documentado en `env.ejemplo`.
|
|
- `qwen3.5:9b` (6,14 GB) es el escalón intermedio, y solo con el naranja cerrado.
|
|
|
|
**Aviso de contexto:** si se define `num_ctx` propio en Ollama, hay que poner el
|
|
mismo en Hermes. Su `/api/show` reporta el contexto *máximo* del modelo, no el
|
|
configurado, así que Hermes puede creer que tiene más sitio del que hay.
|
|
|
|
## Antes de comparar los dos carriles: no midas peras y manzanas
|
|
|
|
El naranja tiene **150 acciones rápidas que se saltan el modelo**: "¿cuánto
|
|
espacio queda?" es un `df`, no una inferencia. Hermes **no tiene ese atajo** —
|
|
allí toda orden pasa por el cerebro, con las herramientas, las skills y la
|
|
memoria en contexto en cada vuelta.
|
|
|
|
El verde va a medir más lento, y **no será culpa del modelo**. Para comparar de
|
|
verdad hay que usar solo las frases que hoy *no* encajan en el catálogo y acaban
|
|
en el cerebro: son las únicas donde los dos hacen lo mismo. Las hay anotadas en
|
|
`config/jarvis-sin-accion.jsonl`.
|
|
|
|
## Pendiente: dependencias de sistema de Playwright
|
|
|
|
El instalador pidió `sudo` para las librerías de sistema de Chromium, se declinó
|
|
(no hay sudo sin contraseña) y **degradó solo**: instaló el binario en la caché
|
|
del usuario. Chromium arrancará si las librerías ya están; si se queja, esto es
|
|
lo que hay que correr una vez:
|
|
|
|
```bash
|
|
cd ~/.hermes/hermes-agent && sudo npx playwright install-deps chromium
|
|
```
|
|
|
|
## Qué se descargará el primer día que arranques
|
|
|
|
Nada de esto ha pasado todavía. Que no sorprenda:
|
|
|
|
| | Cuándo | Cuánto |
|
|
|---|---|---|
|
|
| Modelo de whisper `small` | primera transcripción | ~500 MB en disco, 839 MiB de pico en GPU |
|
|
| Modelo de Ollama | ninguno — `4b-jarvis` ya está | 0 |
|
|
| Voces de Piper | ninguna — usamos las tuyas | 0 |
|
|
|
|
`stt.local.unload_after_idle_seconds: 300` está puesto justo por los 839 MiB:
|
|
suelta whisper tras cinco minutos de silencio y le devuelve el hueco al modelo.
|
|
Cuesta una recarga en la frase siguiente.
|
|
|
|
## Se instaló también el driver de Computer Use
|
|
|
|
Va en la instalación completa. Es el que permitiría a un agente **controlar
|
|
ratón y teclado del escritorio**, no solo el navegador. Instalado no es lo mismo
|
|
que activo — hoy no hay nada que lo invoque — pero conviene saber que está antes
|
|
de dar permisos a algo. Si se quiere fuera: `--skip-computer-use`.
|
|
|
|
**Dato que sí importa en esta máquina:** ese driver no viene de Nous. El
|
|
instalador lo trae con un `curl | bash` contra **terceros**:
|
|
|
|
```
|
|
https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.sh
|
|
```
|
|
|
|
O sea que el envoltorio `instalar.sh` audita el instalador de Hermes, pero ese
|
|
instalador se descarga y ejecuta otro script de otro repo sin que nadie lo mire.
|
|
Con COFRE en esta máquina, merece una lectura antes del próximo `hermes update`.
|
|
Está en `~/.hermes/hermes-agent`, y el binario resultante también.
|
|
|
|
## Las 104 pruebas del naranja: NO se ejecutaron
|
|
|
|
El plan decía correr `pruebas/ejecutar.sh` para comprobar que el naranja seguía
|
|
dando el mismo número. **No se hizo**, y a propósito: esa suite abre la
|
|
aplicación y carga el modelo, que es exactamente lo que se pidió no hacer
|
|
mientras el naranja estaba en desarrollo.
|
|
|
|
Queda pendiente para cuando pares de desarrollar:
|
|
|
|
```bash
|
|
cd ~/COFRE/CODERS/JARVIS/pruebas && ./ejecutar.sh
|
|
```
|
|
|
|
En su lugar se comprobó lo que sí se podía en frío: que la gráfica quedó libre y
|
|
que el verde no escribió fuera de su sitio. Todo lo suyo vive en `verde/`, en
|
|
`~/.hermes/`, más tres ficheros de escritorio (`~/.local/share/icons/jarvis-verde.png`,
|
|
`~/.local/share/applications/jarvis-verde.desktop`) y la caché de Playwright.
|
|
|
|
Los 13 ficheros que `git status` da por modificados son **todos anteriores** a
|
|
esta sesión: el más reciente es `config/set_persona.py` a las 13:22 y esto
|
|
empezó a las 16:09. Y los ficheros nuevos que aparecen en `nucleo/` después de
|
|
esa hora —`arranca.sh`, `estado.py`, `ventana.sh`, `pruebas/prueba_cara.py`…—
|
|
son **tu desarrollo del naranja de esta tarde**: no existían cuando se listó esa
|
|
carpeta al empezar.
|
|
|
|
## La duda del 4B: resuelta, y a favor (16 ago)
|
|
|
|
Era la pregunta abierta del carril — la guía de Hermes marca *sin* tool calling
|
|
todo lo de 9B para abajo y recomienda `gemma4:31b` para trabajo agéntico.
|
|
|
|
**`qwen3.5:4b` llama herramientas bien dentro de Hermes.** Comprobado primero
|
|
contra el endpoint pelado (`pruebas/04_tool_calling.sh`, tres casos) y después
|
|
en el arnés completo, con las 19 herramientas en contexto:
|
|
|
|
| Caso | Resultado |
|
|
|---|---|
|
|
| Pide herramienta cuando hace falta | `terminal {"command": "df -h ."}` |
|
|
| Acierta la herramienta y sus **dos** argumentos | `escribe_fichero {"ruta": …, "contenido": …}` |
|
|
| **No** llama cuando no hace falta ("¿cuánto son dos más dos?") | contesta `4` en prosa |
|
|
|
|
El tercero importa tanto como los otros: un modelo que llama siempre es tan
|
|
inútil como uno que no llama nunca, y con una sola pregunta no se distinguen.
|
|
|
|
## El escalón 6: habla, y con la voz del naranja (16 ago)
|
|
|
|
`text_to_speech` → proveedor `jarvis-piper` → `voz-verde.sh` →
|
|
`config/jarvis-piper.sh`. Comparado el WAV que salió de Hermes con el que genera
|
|
la prueba `07_voz.sh` llamando al adaptador a pelo:
|
|
|
|
| | Hermes | Directo |
|
|
|---|---|---|
|
|
| Frecuencia | 22050 Hz | 22050 Hz |
|
|
| Canales | 1 | 1 |
|
|
| Bits | 16 | 16 |
|
|
|
|
Idénticos, que era el objetivo: mismo binario Piper 1.2.0 MIT, mismo `.onnx`,
|
|
mismo tono. **La comparación de voz entre los dos carriles vale**, que es para
|
|
lo que se montó el adaptador.
|
|
|
|
De propina, sin que nadie se lo pidiera contestó *"Perfecto, señor"* y *"Todos
|
|
mis sistemas están listos para sus órdenes"*. El registro de JARVIS sale del
|
|
`SOUL.md` de Hermes, no de la persona del naranja, y aun así coincide.
|
|
|
|
Queda el juicio que no es medible: si suena bien. El fichero está en
|
|
`~/.hermes/cache/audio/`.
|
|
|
|
## EL ESCALÓN 5 ROMPIÓ LA PREMISA: el agente se fue a internet solo (16 ago)
|
|
|
|
Esto es lo más serio de la sesión de estreno y hay que leerlo antes que nada.
|
|
|
|
Se le pidió *"hazme un cartel en arte ascii que ponga JARVIS"* — a propósito sin
|
|
nombrar ninguna skill, que es lo que medía el escalón. Lo que hizo:
|
|
|
|
| # | Llamada | Resultado |
|
|
|---|---|---|
|
|
| 1 | `skill_view {"name": "ascii-art"}` | **eligió la skill sola** ✓ |
|
|
| 2 | `python3 -m pyfiglet "JARVIS" --font slant` | `No module named pyfiglet` |
|
|
| 3 | `curl https://asciified.thelicato.io/api/v2/ascii?text=JARVIS` | **salió a internet** |
|
|
|
|
Nadie le dijo que podía. La skill menciona pyfiglet, pyfiglet no está instalado,
|
|
y el modelo resolvió el hueco **buscando el servicio equivalente en la web** y
|
|
mandándole el texto a un tercero.
|
|
|
|
### Por qué no lo cazaba nada
|
|
|
|
`pruebas/06_privacidad.sh` pasa, y seguirá pasando: comprueba **configuración**
|
|
—cero credenciales, cero URLs de nube en el YAML, nada escuchando fuera de
|
|
loopback— y esto no es configuración, es **conducta en marcha**. El agente tiene
|
|
una terminal y la terminal tiene `curl`. No hay ajuste que lo impidiera.
|
|
|
|
Es una diferencia de fondo con el naranja, y conviene que quede escrita: el
|
|
naranja ejecuta un catálogo cerrado de 150 acciones. El verde **decide qué
|
|
ejecutar**, y ese es justo su valor y justo su riesgo. No se puede tener lo uno
|
|
sin lo otro.
|
|
|
|
### Lo que se puede hacer, por orden de menos a más invasivo
|
|
|
|
1. **Instalar lo que las skills dan por hecho** (`pip install pyfiglet`). Quita
|
|
el motivo, no la capacidad. Es parche, no solución.
|
|
2. **Apagar las skills que tiran de red**: `hermes skills disable <nombre>`.
|
|
3. **Recortar herramientas** en `platform_toolsets` del `config.yaml`, que ya
|
|
estaba apuntado como palanca para el contexto y sirve para esto también.
|
|
4. **Cortar por debajo**: regla de cortafuegos para el proceso, o terminal en
|
|
contenedor sin red. `hermes egress` **no vale** para esto — es iron-proxy,
|
|
un proxy que INYECTA credenciales en las salidas, no un bloqueo.
|
|
|
|
**No he aplicado ninguna.** Cualquiera de ellas cambia lo que el carril sabe
|
|
hacer, y eso es una decisión del usuario, no una corrección técnica.
|
|
|
|
### Y el cartel salió mal
|
|
|
|
Aparte de todo lo anterior: el banner que `curl` devolvió era correcto, y al
|
|
copiarlo a su respuesta final el modelo **lo destrozó**. Mismo patrón que la
|
|
lista de ficheros del escalón 4: el 4B razona bien la cadena y es descuidado
|
|
reproduciendo texto literal largo. 4 min 58 s en total.
|
|
|
|
## El escalón 7 (la escucha) cabe, y por un motivo que sorprende (16 ago)
|
|
|
|
El plan lo dejaba para el final temiendo un `CUDA error: out of memory`: whisper
|
|
`small` pide **839 MiB en el pico** de la transcripción y la tarjeta son 4096.
|
|
Medido con el verde cargado y trabajando:
|
|
|
|
| | MiB |
|
|
|---|---|
|
|
| Tarjeta | 4096 |
|
|
| Ocupado por el modelo verde (65536 ctx, 16 capas) | 2902 |
|
|
| **Libre** | **1062** |
|
|
| Pico de whisper `small` | 839 |
|
|
| Margen | **223** |
|
|
|
|
**Cabe.** Y lo que sorprende es que el verde deja **más** sitio que el naranja:
|
|
2902 MiB contra los 2941 del reparto automático de ollama para
|
|
`qwen3.5:4b-jarvis`. Bajar 16 capas a la CPU libera tarjeta, así que el precio
|
|
que se paga en velocidad se cobra en VRAM.
|
|
|
|
Sigue siendo justo —223 MiB— y falta la prueba de verdad, que necesita
|
|
micrófono. Pero la aritmética que hacía temer el escalón ya no dice lo que
|
|
decía.
|
|
|
|
## Para probar cuando arranques
|
|
|
|
- **Tema del panel web.** `dashboard.theme` acepta `default`, `midnight`,
|
|
`ember`, `mono`, `cyberpunk`, `rose`. No he podido ver sus paletas (el panel
|
|
va empaquetado), pero `cyberpunk` o `mono` son los candidatos a pegar con el
|
|
verde. El TUI no tiene tema: ahí el color lo pone `verde-launcher.sh` con
|
|
secuencias OSC.
|
|
- **Los escalones 5, 6 y 7** de `ESCALERA.md`: una skill, la voz dentro de
|
|
Hermes y la escucha por micrófono. Los tres piden criterio u oído, o el
|
|
micrófono, así que no se automatizan.
|
|
- **Si merece la pena la palanca del KV caché.** `OLLAMA_FLASH_ATTENTION=1` +
|
|
`OLLAMA_KV_CACHE_TYPE=q8_0` partiría el caché por la mitad y devolvería capas
|
|
a la tarjeta, que es justo lo que hoy cuesta el tiempo de respuesta. **No se
|
|
ha aplicado**: es del servicio de ollama y afectaría también al naranja.
|
|
|
|
## Noche del 16-17 ago: voz de entrada, RAG y frontal a nivel del naranja
|
|
|
|
Encargo: subir el verde al nivel del naranja en voz, RAG y frontal. Todo local,
|
|
nada a gitea (pendiente de revisión).
|
|
|
|
### La escucha, resuelta y en local (escalón 7 cerrado sin micro)
|
|
|
|
El TUI de Hermes no tiene micrófono, y su STT nativo (`stt:` del config) es para
|
|
notas de voz de **mensajería** — saldrían de la máquina. Así que se puentea:
|
|
|
|
- `verde/escucha_transcribe.py` — WAV → texto con **faster-whisper `small`**
|
|
(el mismo que declara el config), en **CPU** a propósito: el 4B ocupa la
|
|
tarjeta y el margen es de 223 MiB; whisper en CPU tarda ~12 s por frase y no
|
|
arriesga OOM. No llama a ninguna API.
|
|
- `verde/escucha-verde.sh` — pulsar-para-hablar: graba (pw-record/arecord/parec)
|
|
→ transcribe → `hermes chat --reasoning none -q` → responde; `--habla` lo dice
|
|
con la voz del verde, `--seguido` encadena turnos.
|
|
- `verde/pruebas/08_escucha.sh` — **8/8**. Bucle TTS→STT sin micro: genera voz
|
|
con el `07`, la transcribe y comprueba que vuelven las palabras clave. Mide y
|
|
verifica que el transcriptor no referencia APIs remotas.
|
|
|
|
Medido: "hola jarvis verde cuanto espacio libre queda en el disco" → *"¿Cuánto
|
|
espacio libre queda en el disco?"* (solo pierde "jarvis"→"harvis", nombre raro).
|
|
|
|
Latencia honesta: la ESCUCHA va bien (~12 s CPU). El cuello es el 4B (minutos
|
|
por turno). El puente sirve para PROBAR que el verde oye, no como diario.
|
|
|
|
### RAG del naranja, disponible en el verde
|
|
|
|
El agente ya puede consultar el mismo índice que el núcleo (14.949 entradas):
|
|
|
|
- `nucleo/saber/busca_cli.py` — CLI sobre `saber.busca` (texto o `--json`).
|
|
- Skill local `~/.hermes/skills/research/buscar-en-apuntes/` — le dice al agente
|
|
cuándo y cómo buscar (herramienta de terminal, local). `hermes skills list`:
|
|
`buscar-en-apuntes · research · local · enabled`.
|
|
|
|
### Skills de ECC (el ganador del hackathon de Claude)
|
|
|
|
Instaladas 4 por `hermes skills install` (escaneadas SAFE): `security-review`,
|
|
`git-workflow`, `python-testing`, `coding-standards`. Total 82 skills. El prompt
|
|
fijo apenas sube (29 KB, lejos de 64k). Probada `security-review` con el 4B:
|
|
checklist correcto, 4 min 30 s en frío.
|
|
|
|
## Noche: expansión del RAG + reentrenamiento (auto mode, local, sin gitea)
|
|
|
|
Contenido añadido al índice PERSONAL (nunca al público sin revisar licencias):
|
|
- **Strix** (usestrix/strix, agente IA de pentesting) clonado en CODERS; sus docs
|
|
(README, docs/, AGENTS, benchmarks) indexados → 49 fragmentos.
|
|
- **6 awesome lists** más: sysadmin, cli-apps, security, pentest, shell, linux
|
|
(catálogo pasa de 385 a 740 fragmentos). En awesome.py, publico=False.
|
|
- **Apps instaladas** de esta máquina: nucleo/saber/instalado.py lee los .desktop
|
|
(146 apps) + apt-mark showmanual (22 fragmentos). Personal por definición.
|
|
- Índice personal: ~49 MB. Reindex raw hecho; contenido recuperable ya.
|
|
|
|
Reentrenamiento nocturno: nucleo/saber/enriquece/reentrena_noche.sh encadena
|
|
síntesis de ganchos del contenido nuevo → reindex → eval → refresco COFRE
|
|
(cosecha+sintetiza) → reindex final. Corre detached, log en datos/reentrena_noche.log.
|
|
|
|
Pendiente de revisar por la mañana: licencias de las 6 awesome nuevas antes de
|
|
subir nada; y decidir qué de todo esto va al índice público / gitea.
|
|
|
|
## Cierre de la noche (07:52) — números y decisiones
|
|
|
|
Dos rondas de reentrenamiento. Índice final: **64 MB, 19.578 entradas** (12.260
|
|
preguntas-gancho, 1.383 catálogo, 168 apps, 459 metodología incl. strix).
|
|
|
|
Retrieval (eval_set ampliado a 57 casos = 45 pentest + 12 amplitud):
|
|
- Ronda 1: hit@1 77%, hit@5 96%
|
|
- Ronda 2 (+osint/devops/docker/go/python): hit@1 **75%**, hit@5 **96%**
|
|
- Amplitud sola (apps/self-hosted/cli/linux/strix): hit@1 75%, hit@5 **100%**
|
|
|
|
**Intercambio medido:** pentest puro pasó de 82% (antes de la noche) a ~75% de
|
|
hit@1; hit@5 se mantiene 95-96%. Es el precio de la amplitud. Las listas gigantes
|
|
(awesome-go, 3197 items → 322 fragmentos; osint con algún artefacto de TOC) son
|
|
las que más ruido meten y menos aporta a consultas por voz.
|
|
|
|
**Decisiones para la mañana:**
|
|
1. Licencias de las 12 awesome lists antes de publicar nada (ahora todas
|
|
publico=False = solo índice personal).
|
|
2. Si se prioriza precisión pentest: quitar awesome-go (y quizá awesome-python)
|
|
recuperaría 1-2 pts de hit@1 sin perder casi cobertura útil.
|
|
3. Qué del contenido nuevo va al índice público / gitea (hoy: nada subido).
|